Skip to content

Commit

Permalink
[Ingest Pipelines] UI improvements to list view (#179596)
Browse files Browse the repository at this point in the history
  • Loading branch information
sabarasaba authored Apr 4, 2024
1 parent 655b916 commit 94a4b47
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('<PipelinesList />', () => {

// Verify documentation link
expect(exists('documentationLink')).toBe(true);
expect(find('documentationLink').text()).toBe('Ingest Pipelines docs');
expect(find('documentationLink').text()).toBe('Documentation');

// Verify create dropdown exists
expect(exists('createPipelineDropdown')).toBe(true);
Expand All @@ -70,7 +70,14 @@ describe('<PipelinesList />', () => {
tableCellsValues.forEach((row, i) => {
const pipeline = pipelines[i];

expect(row).toEqual(['', pipeline.name, 'EditDelete']);
expect(row).toEqual([
'',
pipeline.name,
'',
`test_pipeline${i + 1} description`,
'0',
'EditDelete',
]);
});
});

Expand Down Expand Up @@ -162,7 +169,7 @@ describe('<PipelinesList />', () => {

expect(exists('sectionLoading')).toBe(false);
expect(exists('emptyList')).toBe(true);
expect(find('emptyList.title').text()).toEqual('Start by creating a pipeline');
expect(find('emptyList.title').text()).toEqual('Create your first pipeline');
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ export const EmptyList: FunctionComponent = () => {

return (
<EuiPageTemplate.EmptyPrompt
iconType="managementApp"
iconType="pipelineApp"
iconColor="default"
data-test-subj="emptyList"
title={
<h2 data-test-subj="title">
{i18n.translate('xpack.ingestPipelines.list.table.emptyPromptTitle', {
defaultMessage: 'Start by creating a pipeline',
defaultMessage: 'Create your first pipeline',
})}
</h2>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@ import { RouteComponentProps } from 'react-router-dom';
import { FormattedMessage } from '@kbn/i18n-react';
import { Location } from 'history';
import { parse } from 'query-string';
import { i18n } from '@kbn/i18n';

import { EuiPageHeader, EuiButtonEmpty, EuiButton, EuiSpacer, EuiPageTemplate } from '@elastic/eui';
import { reactRouterNavigate } from '@kbn/kibana-react-plugin/public';
import {
EuiPageHeader,
EuiButtonEmpty,
EuiButton,
EuiSpacer,
EuiPageTemplate,
EuiContextMenu,
EuiPopover,
} from '@elastic/eui';

import { Pipeline } from '../../../../common/types';
import { useKibana, SectionLoading } from '../../../shared_imports';
Expand Down Expand Up @@ -39,6 +49,7 @@ export const PipelinesList: React.FunctionComponent<RouteComponentProps> = ({

const [selectedPipeline, setSelectedPipeline] = useState<Pipeline | undefined>(undefined);
const [showFlyout, setShowFlyout] = useState<boolean>(false);
const [showPopover, setShowPopover] = useState<boolean>(false);

const [pipelinesToDelete, setPipelinesToDelete] = useState<string[]>([]);

Expand Down Expand Up @@ -100,7 +111,7 @@ export const PipelinesList: React.FunctionComponent<RouteComponentProps> = ({
);
}

if (isLoading) {
if (isLoading && !data) {
return (
<SectionLoading data-test-subj="sectionLoading">
<FormattedMessage
Expand All @@ -115,6 +126,29 @@ export const PipelinesList: React.FunctionComponent<RouteComponentProps> = ({
return <EmptyList />;
}

const createMenuItems = [
/**
* Create pipeline
*/
{
name: i18n.translate('xpack.ingestPipelines.list.table.createPipelineButtonLabel', {
defaultMessage: 'New pipeline',
}),
...reactRouterNavigate(history, '/create'),
'data-test-subj': `createNewPipeline`,
},
/**
* Create pipeline from CSV
*/
{
name: i18n.translate('xpack.ingestPipelines.list.table.createPipelineFromCsvButtonLabel', {
defaultMessage: 'New pipeline from CSV',
}),
...reactRouterNavigate(history, '/csv_create'),
'data-test-subj': `createPipelineFromCsv`,
},
];

const renderFlyout = (): React.ReactNode => {
if (!showFlyout) {
return;
Expand Down Expand Up @@ -154,10 +188,42 @@ export const PipelinesList: React.FunctionComponent<RouteComponentProps> = ({
description={
<FormattedMessage
id="xpack.ingestPipelines.list.pipelinesDescription"
defaultMessage="Use pipelines to remove or transform fields, extract values from text, and enrich your data before indexing."
defaultMessage="Use ingest pipelines to remove or transform fields, extract values from text, and enrich your data before indexing into Elasticsearch."
/>
}
rightSideItems={[
<EuiPopover
key="createPipelinePopover"
isOpen={showPopover}
closePopover={() => setShowPopover(false)}
button={
<EuiButton
fill
iconSide="right"
iconType="arrowDown"
data-test-subj="createPipelineDropdown"
key="createPipelineDropdown"
onClick={() => setShowPopover((previousBool) => !previousBool)}
>
{i18n.translate('xpack.ingestPipelines.list.table.createPipelineDropdownLabel', {
defaultMessage: 'Create pipeline',
})}
</EuiButton>
}
panelPaddingSize="none"
repositionOnScroll
>
<EuiContextMenu
initialPanelId={0}
data-test-subj="autoFollowPatternActionContextMenu"
panels={[
{
id: 0,
items: createMenuItems,
},
]}
/>
</EuiPopover>,
<EuiButtonEmpty
href={services.documentation.getIngestNodeUrl()}
target="_blank"
Expand All @@ -166,7 +232,7 @@ export const PipelinesList: React.FunctionComponent<RouteComponentProps> = ({
>
<FormattedMessage
id="xpack.ingestPipelines.list.pipelinesDocsLinkText"
defaultMessage="Ingest Pipelines docs"
defaultMessage="Documentation"
/>
</EuiButtonEmpty>,
]}
Expand All @@ -175,6 +241,7 @@ export const PipelinesList: React.FunctionComponent<RouteComponentProps> = ({
<EuiSpacer size="l" />

<PipelineTable
isLoading={isLoading}
onReloadClick={resendRequest}
onEditPipelineClick={goToEditPipeline}
onDeletePipelineClick={setPipelinesToDelete}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ import {
EuiInMemoryTable,
EuiLink,
EuiButton,
EuiButtonIcon,
EuiInMemoryTableProps,
EuiTableFieldDataColumnType,
EuiPopover,
EuiContextMenu,
EuiBadge,
EuiToolTip,
EuiFilterGroup,
EuiSelectable,
EuiFilterButton,
EuiSelectableOption,
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';
import { reactRouterNavigate } from '@kbn/kibana-react-plugin/public';

Expand All @@ -31,6 +33,7 @@ import { useKibana } from '../../../shared_imports';
export interface Props {
pipelines: Pipeline[];
onReloadClick: () => void;
isLoading: boolean;
onEditPipelineClick: (pipelineName: string) => void;
onClonePipelineClick: (pipelineName: string) => void;
onDeletePipelineClick: (pipelineName: string[]) => void;
Expand Down Expand Up @@ -59,6 +62,7 @@ const managedFilterLabel = i18n.translate('xpack.ingestPipelines.list.table.mana

export const PipelineTable: FunctionComponent<Props> = ({
pipelines,
isLoading,
onReloadClick,
onEditPipelineClick,
onClonePipelineClick,
Expand All @@ -70,30 +74,6 @@ export const PipelineTable: FunctionComponent<Props> = ({
]);
const { history } = useKibana().services;
const [selection, setSelection] = useState<Pipeline[]>([]);
const [showPopover, setShowPopover] = useState(false);

const createMenuItems = [
/**
* Create pipeline
*/
{
name: i18n.translate('xpack.ingestPipelines.list.table.createPipelineButtonLabel', {
defaultMessage: 'New pipeline',
}),
...reactRouterNavigate(history, '/create'),
'data-test-subj': `createNewPipeline`,
},
/**
* Create pipeline from CSV
*/
{
name: i18n.translate('xpack.ingestPipelines.list.table.createPipelineFromCsvButtonLabel', {
defaultMessage: 'New pipeline from CSV',
}),
...reactRouterNavigate(history, '/csv_create'),
'data-test-subj': `createPipelineFromCsv`,
},
];

const filteredPipelines = useMemo(() => {
return (pipelines || []).filter((pipeline) => {
Expand Down Expand Up @@ -166,49 +146,16 @@ export const PipelineTable: FunctionComponent<Props> = ({
</EuiButton>
) : undefined,
toolsRight: [
<EuiButton
<EuiButtonIcon
key="reloadButton"
iconType="refresh"
color="success"
aria-label="refresh button"
data-test-subj="reloadButton"
size="m"
display="base"
onClick={onReloadClick}
>
{i18n.translate('xpack.ingestPipelines.list.table.reloadButtonLabel', {
defaultMessage: 'Reload',
})}
</EuiButton>,
<EuiPopover
key="createPipelinePopover"
isOpen={showPopover}
closePopover={() => setShowPopover(false)}
button={
<EuiButton
fill
iconSide="right"
iconType="arrowDown"
data-test-subj="createPipelineDropdown"
key="createPipelineDropdown"
onClick={() => setShowPopover((previousBool) => !previousBool)}
>
{i18n.translate('xpack.ingestPipelines.list.table.createPipelineDropdownLabel', {
defaultMessage: 'Create pipeline',
})}
</EuiButton>
}
panelPaddingSize="none"
repositionOnScroll
>
<EuiContextMenu
initialPanelId={0}
data-test-subj="autoFollowPatternActionContextMenu"
panels={[
{
id: 0,
items: createMenuItems,
},
]}
/>
</EuiPopover>,
/>,
],
box: {
incremental: true,
Expand Down Expand Up @@ -253,12 +200,13 @@ export const PipelineTable: FunctionComponent<Props> = ({
},
columns: [
{
width: '25%',
field: 'name',
name: i18n.translate('xpack.ingestPipelines.list.table.nameColumnTitle', {
defaultMessage: 'Name',
}),
sortable: true,
render: (name: string, pipeline) => (
render: (name: string) => (
<EuiLink
data-test-subj="pipelineDetailsLink"
{...reactRouterNavigate(history, {
Expand All @@ -267,30 +215,55 @@ export const PipelineTable: FunctionComponent<Props> = ({
})}
>
{name}
{pipeline.deprecated && (
<>
&nbsp;
<EuiToolTip content={deprecatedPipelineBadge.badgeTooltip}>
<EuiBadge color="warning" data-test-subj="isDeprecatedBadge">
{deprecatedPipelineBadge.badge}
</EuiBadge>
</EuiToolTip>
</>
)}
{pipeline.isManaged && (
<>
&nbsp;
<EuiBadge color="hollow" data-test-subj="isManagedBadge">
{i18n.translate('xpack.ingestPipelines.list.table.managedBadgeLabel', {
defaultMessage: 'Managed',
})}
</EuiBadge>
</>
)}
</EuiLink>
),
},
{
width: '100px',
render: (pipeline: Pipeline) => {
return (
<EuiFlexGroup direction="column" gutterSize="xs" alignItems="center">
{pipeline.isManaged && (
<EuiFlexItem grow={false}>
<EuiBadge color="hollow" data-test-subj="isManagedBadge">
{i18n.translate('xpack.ingestPipelines.list.table.managedBadgeLabel', {
defaultMessage: 'Managed',
})}
</EuiBadge>
</EuiFlexItem>
)}
{pipeline.deprecated && (
<EuiFlexItem grow={false}>
<EuiToolTip content={deprecatedPipelineBadge.badgeTooltip}>
<EuiBadge color="warning" data-test-subj="isDeprecatedBadge">
{deprecatedPipelineBadge.badge}
</EuiBadge>
</EuiToolTip>
</EuiFlexItem>
)}
</EuiFlexGroup>
);
},
},
{
field: 'description',
sortable: true,
name: i18n.translate('xpack.ingestPipelines.list.table.descriptionColumnTitle', {
defaultMessage: 'Description',
}),
},
{
width: '120px',
name: i18n.translate('xpack.ingestPipelines.list.table.preprocessorsColumnTitle', {
defaultMessage: 'Preprocessors',
}),
align: 'right',
dataType: 'number',
sortable: ({ processors }: Pipeline) => processors.length,
render: ({ processors }: Pipeline) => processors.length,
},
{
width: '120px',
name: (
<FormattedMessage
id="xpack.ingestPipelines.list.table.actionColumnTitle"
Expand Down Expand Up @@ -339,6 +312,7 @@ export const PipelineTable: FunctionComponent<Props> = ({
},
],
items: filteredPipelines,
loading: isLoading,
};

return <EuiInMemoryTable {...tableProps} />;
Expand Down
Loading

0 comments on commit 94a4b47

Please sign in to comment.