Skip to content

Commit

Permalink
Merge branch 'main' into maintenance-windows-rule-management
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitaindik authored Apr 24, 2023
2 parents 3fb0b77 + 275c360 commit 45b6683
Show file tree
Hide file tree
Showing 366 changed files with 11,509 additions and 4,658 deletions.
2 changes: 2 additions & 0 deletions .buildkite/scripts/steps/storybooks/build_and_upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const STORYBOOKS = [
'apm',
'canvas',
'cases',
'cell_actions',
'ci_composite',
'cloud_chat',
'coloring',
Expand All @@ -34,6 +35,7 @@ const STORYBOOKS = [
'expression_shape',
'expression_tagcloud',
'fleet',
'grouping',
'home',
'infra',
'kibana_react',
Expand Down
2 changes: 1 addition & 1 deletion examples/controls_example/public/edit_example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export const EditExample = () => {
iconType="plusInCircle"
isDisabled={controlGroupAPI === undefined}
onClick={() => {
controlGroupAPI!.openAddDataControlFlyout(controlInputTransform);
controlGroupAPI!.openAddDataControlFlyout({ controlInputTransform });
}}
>
Add control
Expand Down
2 changes: 1 addition & 1 deletion packages/content-management/table_list/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@

export { TableListView, TableListViewProvider, TableListViewKibanaProvider } from './src';

export type { UserContentCommonSchema } from './src';
export type { UserContentCommonSchema, RowActions } from './src';
export type { TableListViewKibanaDependencies } from './src/services';
33 changes: 29 additions & 4 deletions packages/content-management/table_list/src/components/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import {
SearchFilterConfig,
Direction,
Query,
type EuiTableSelectionType,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';

import { useServices } from '../services';
import type { Action } from '../actions';
Expand All @@ -26,6 +28,7 @@ import type {
Props as TableListViewProps,
UserContentCommonSchema,
} from '../table_list_view';
import type { TableItemsRowActions } from '../types';
import { TableSortSelect } from './table_sort_select';
import { TagFilterPanel } from './tag_filter_panel';
import { useTagFilterPanel } from './use_tag_filter_panel';
Expand All @@ -51,6 +54,7 @@ interface Props<T extends UserContentCommonSchema> extends State<T>, TagManageme
tableColumns: Array<EuiBasicTableColumn<T>>;
hasUpdatedAtMetadata: boolean;
deleteItems: TableListViewProps<T>['deleteItems'];
tableItemsRowActions: TableItemsRowActions;
onSortChange: (column: SortColumnField, direction: Direction) => void;
onTableChange: (criteria: CriteriaWithPagination<T>) => void;
onTableSearchChange: (arg: { query: Query | null; queryText: string }) => void;
Expand All @@ -70,6 +74,7 @@ export function Table<T extends UserContentCommonSchema>({
entityName,
entityNamePlural,
tagsToTableItemMap,
tableItemsRowActions,
deleteItems,
tableCaption,
onTableChange,
Expand Down Expand Up @@ -105,13 +110,32 @@ export function Table<T extends UserContentCommonSchema>({
);
}, [deleteItems, dispatch, entityName, entityNamePlural, selectedIds.length]);

const selection = deleteItems
? {
const selection = useMemo<EuiTableSelectionType<T> | undefined>(() => {
if (deleteItems) {
return {
onSelectionChange: (obj: T[]) => {
dispatch({ type: 'onSelectionChange', data: obj });
},
}
: undefined;
selectable: (obj) => {
const actions = tableItemsRowActions[obj.id];
return actions?.delete?.enabled !== false;
},
selectableMessage: (selectable, obj) => {
if (!selectable) {
const actions = tableItemsRowActions[obj.id];
return (
actions?.delete?.reason ??
i18n.translate('contentManagement.tableList.actionsDisabledLabel', {
defaultMessage: 'Actions disabled for this item',
})
);
}
return '';
},
initialSelected: [],
};
}
}, [deleteItems, dispatch, tableItemsRowActions]);

const {
isPopoverOpen,
Expand Down Expand Up @@ -214,6 +238,7 @@ export function Table<T extends UserContentCommonSchema>({
data-test-subj="itemsInMemTable"
rowHeader="attributes.title"
tableCaption={tableCaption}
isSelectable
/>
);
}
2 changes: 2 additions & 0 deletions packages/content-management/table_list/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ export type {
} from './table_list_view';

export { TableListViewProvider, TableListViewKibanaProvider } from './services';

export type { RowActions } from './types';
105 changes: 105 additions & 0 deletions packages/content-management/table_list/src/table_list_view.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1067,4 +1067,109 @@ describe('TableListView', () => {
expect(router?.history.location?.search).toBe('?sort=title&sortdir=desc');
});
});

describe('row item actions', () => {
const hits: UserContentCommonSchema[] = [
{
id: '123',
updatedAt: twoDaysAgo.toISOString(),
type: 'dashboard',
attributes: {
title: 'Item 1',
description: 'Item 1 description',
},
references: [],
},
{
id: '456',
updatedAt: yesterday.toISOString(),
type: 'dashboard',
attributes: {
title: 'Item 2',
description: 'Item 2 description',
},
references: [],
},
];

const setupTest = async (props?: Partial<TableListViewProps>) => {
let testBed: TestBed | undefined;
const deleteItems = jest.fn();
await act(async () => {
testBed = await setup({
findItems: jest.fn().mockResolvedValue({ total: hits.length, hits }),
deleteItems,
...props,
});
});

testBed!.component.update();
return { testBed: testBed!, deleteItems };
};

test('should allow select items to be deleted', async () => {
const {
testBed: { table, find, exists, component, form },
deleteItems,
} = await setupTest();

const { tableCellsValues } = table.getMetaData('itemsInMemTable');

expect(tableCellsValues).toEqual([
['', 'Item 2Item 2 description', yesterdayToString], // First empty col is the "checkbox"
['', 'Item 1Item 1 description', twoDaysAgoToString],
]);

const selectedHit = hits[1];

expect(exists('deleteSelectedItems')).toBe(false);
act(() => {
// Select the second item
form.selectCheckBox(`checkboxSelectRow-${selectedHit.id}`);
});
component.update();
// Delete button is now visible
expect(exists('deleteSelectedItems')).toBe(true);

// Click delete and validate that confirm modal opens
expect(component.exists('.euiModal--confirmation')).toBe(false);
act(() => {
find('deleteSelectedItems').simulate('click');
});
component.update();
expect(component.exists('.euiModal--confirmation')).toBe(true);

await act(async () => {
find('confirmModalConfirmButton').simulate('click');
});
expect(deleteItems).toHaveBeenCalledWith([selectedHit]);
});

test('should allow to disable the "delete" action for a row', async () => {
const reasonMessage = 'This file cannot be deleted.';

const {
testBed: { find },
} = await setupTest({
rowItemActions: (obj) => {
if (obj.id === hits[1].id) {
return {
delete: {
enabled: false,
reason: reasonMessage,
},
};
}
},
});

const firstCheckBox = find(`checkboxSelectRow-${hits[0].id}`);
const secondCheckBox = find(`checkboxSelectRow-${hits[1].id}`);

expect(firstCheckBox.props().disabled).toBe(false);
expect(secondCheckBox.props().disabled).toBe(true);
// EUI changes the check "title" from "Select this row" to the reason to disable the checkbox
expect(secondCheckBox.props().title).toBe(reasonMessage);
});
});
});
35 changes: 31 additions & 4 deletions packages/content-management/table_list/src/table_list_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { getReducer } from './reducer';
import type { SortColumnField } from './components';
import { useTags } from './use_tags';
import { useInRouterContext, useUrlState } from './use_url_state';
import { RowActions, TableItemsRowActions } from './types';

interface ContentEditorConfig
extends Pick<OpenContentEditorParams, 'isReadonly' | 'onSave' | 'customValidators'> {
Expand All @@ -67,6 +68,11 @@ export interface Props<T extends UserContentCommonSchema = UserContentCommonSche
headingId?: string;
/** An optional id for the listing. Used to generate unique data-test-subj. Default: "userContent" */
id?: string;
/**
* Configuration of the table row item actions. Disable specific action for a table row item.
* Currently only the "delete" ite action can be disabled.
*/
rowItemActions?: (obj: T) => RowActions | undefined;
children?: ReactNode | undefined;
findItems(
searchQuery: string,
Expand Down Expand Up @@ -241,6 +247,7 @@ function TableListViewComp<T extends UserContentCommonSchema>({
urlStateEnabled = true,
customTableColumn,
emptyPrompt,
rowItemActions,
findItems,
createItem,
editItem,
Expand Down Expand Up @@ -580,6 +587,15 @@ function TableListViewComp<T extends UserContentCommonSchema>({
return selectedIds.map((selectedId) => itemsById[selectedId]);
}, [selectedIds, itemsById]);

const tableItemsRowActions = useMemo(() => {
return items.reduce<TableItemsRowActions>((acc, item) => {
return {
...acc,
[item.id]: rowItemActions ? rowItemActions(item) : undefined,
};
}, {});
}, [items, rowItemActions]);

// ------------
// Callbacks
// ------------
Expand Down Expand Up @@ -854,17 +870,27 @@ function TableListViewComp<T extends UserContentCommonSchema>({
};
}, []);

const PageTemplate = useMemo<typeof KibanaPageTemplate>(() => {
return withoutPageTemplateWrapper
? ((({
children: _children,
'data-test-subj': dataTestSubj,
}: {
children: React.ReactNode;
['data-test-subj']?: string;
}) => (
<div data-test-subj={dataTestSubj}>{_children}</div>
)) as unknown as typeof KibanaPageTemplate)
: KibanaPageTemplate;
}, [withoutPageTemplateWrapper]);

// ------------
// Render
// ------------
if (!hasInitialFetchReturned) {
return null;
}

const PageTemplate = withoutPageTemplateWrapper
? (React.Fragment as unknown as typeof KibanaPageTemplate)
: KibanaPageTemplate;

if (!showFetchError && hasNoItems) {
return (
<PageTemplate panelled isEmptyState={true} data-test-subj={pageDataTestSubject}>
Expand Down Expand Up @@ -929,6 +955,7 @@ function TableListViewComp<T extends UserContentCommonSchema>({
tagsToTableItemMap={tagsToTableItemMap}
deleteItems={deleteItems}
tableCaption={tableListTitle}
tableItemsRowActions={tableItemsRowActions}
onTableChange={onTableChange}
onTableSearchChange={onTableSearchChange}
onSortChange={onSortChange}
Expand Down
13 changes: 13 additions & 0 deletions packages/content-management/table_list/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,16 @@ export interface Tag {
description: string;
color: string;
}

export type TableRowAction = 'delete';

export type RowActions = {
[action in TableRowAction]?: {
enabled: boolean;
reason?: string;
};
};

export interface TableItemsRowActions {
[id: string]: RowActions | undefined;
}
1 change: 1 addition & 0 deletions packages/kbn-doc-links/src/get_doc_links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
licenseManagement: `${ENTERPRISE_SEARCH_DOCS}license-management.html`,
machineLearningStart: `${ENTERPRISE_SEARCH_DOCS}machine-learning-start.html`,
mailService: `${ENTERPRISE_SEARCH_DOCS}mailer-configuration.html`,
mlDocumentEnrichment: `${ENTERPRISE_SEARCH_DOCS}document-enrichment.html`,
start: `${ENTERPRISE_SEARCH_DOCS}start.html`,
syncRules: `${ENTERPRISE_SEARCH_DOCS}sync-rules.html`,
troubleshootSetup: `${ENTERPRISE_SEARCH_DOCS}troubleshoot-setup.html`,
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-doc-links/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export interface DocLinks {
readonly licenseManagement: string;
readonly machineLearningStart: string;
readonly mailService: string;
readonly mlDocumentEnrichment: string;
readonly start: string;
readonly syncRules: string;
readonly troubleshootSetup: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-io-ts-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

export type { IndexPatternType } from './src/index_pattern_rt';
export type { NonEmptyStringBrand } from './src/non_empty_string_rt';
export type { NonEmptyString, NonEmptyStringBrand } from './src/non_empty_string_rt';

export { deepExactRt } from './src/deep_exact_rt';
export { indexPatternRt } from './src/index_pattern_rt';
Expand Down
9 changes: 9 additions & 0 deletions packages/kbn-securitysolution-grouping/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

module.exports = require('@kbn/storybook').defaultConfig;
3 changes: 0 additions & 3 deletions packages/kbn-securitysolution-grouping/README.md

This file was deleted.

3 changes: 3 additions & 0 deletions packages/kbn-securitysolution-grouping/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @kbn/securitysolution-grouping

Grouping component and query. Currently only consumed by security solution alerts table.
8 changes: 5 additions & 3 deletions packages/kbn-securitysolution-grouping/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@
* Side Public License, v 1.
*/

import { RawBucket, StatRenderer, getGroupingQuery, isNoneGroup, useGrouping } from './src';
import { getGroupingQuery, isNoneGroup, useGrouping } from './src';
import type {
DynamicGroupingProps,
GroupOption,
GroupingAggregation,
GroupingFieldTotalAggregation,
NamedAggregation,
RawBucket,
StatRenderer,
} from './src';

export { getGroupingQuery, isNoneGroup, useGrouping };

export type {
DynamicGroupingProps,
GroupOption,
GroupingAggregation,
GroupingFieldTotalAggregation,
NamedAggregation,
RawBucket,
StatRenderer,
Expand Down
Loading

0 comments on commit 45b6683

Please sign in to comment.