From 765f96271a6f0306628c2b907b720fb84b21188d Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 5 Mar 2020 16:53:24 +0100 Subject: [PATCH] --- .../components/list_manage_drilldowns/i18n.ts | 36 +++++++ .../list_manage_drilldowns/index.tsx | 7 ++ .../list_manage_drilldowns.story.tsx | 14 +++ .../list_manage_drilldowns.test.tsx | 61 ++++++++++++ .../list_manage_drilldowns.tsx | 97 +++++++++++++++++++ .../list_manage_drilldowns/test_data.ts | 11 +++ 6 files changed, 226 insertions(+) create mode 100644 x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/i18n.ts create mode 100644 x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/index.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.story.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.test.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/test_data.ts diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/i18n.ts b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/i18n.ts new file mode 100644 index 0000000000000..fbc7c9dcfb4a1 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/i18n.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const txtCreateDrilldown = i18n.translate( + 'xpack.drilldowns.components.ListManageDrilldowns.createDrilldownButtonLabel', + { + defaultMessage: 'Create new', + } +); + +export const txtEditDrilldown = i18n.translate( + 'xpack.drilldowns.components.ListManageDrilldowns.editDrilldownButtonLabel', + { + defaultMessage: 'Edit', + } +); + +export const txtDeleteDrilldowns = (count: number) => + i18n.translate('xpack.drilldowns.components.ListManageDrilldowns.deleteDrilldownsButtonLabel', { + defaultMessage: 'Delete ({count})', + values: { + count, + }, + }); + +export const txtSelectDrilldown = i18n.translate( + 'xpack.drilldowns.components.ListManageDrilldowns.selectThisDrilldownCheckboxLabel', + { + defaultMessage: 'Select this drilldown', + } +); diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/index.tsx b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/index.tsx new file mode 100644 index 0000000000000..82b6ce27af6d4 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/index.tsx @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './list_manage_drilldowns'; diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.story.tsx b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.story.tsx new file mode 100644 index 0000000000000..ae1b063449928 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.story.tsx @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as React from 'react'; +import { storiesOf } from '@storybook/react'; +import { ListManageDrilldowns } from './list_manage_drilldowns'; +import { drilldowns } from './test_data'; + +storiesOf('components/ListManageDrilldowns', module).add('default', () => ( + +)); diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.test.tsx b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.test.tsx new file mode 100644 index 0000000000000..2ad83f684b339 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.test.tsx @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { cleanup, fireEvent, render } from '@testing-library/react'; +import '@testing-library/jest-dom/extend-expect'; // TODO: this should be global +import { drilldowns } from './test_data'; +import { ListManageDrilldowns, TEST_SUBJ_DRILLDOWN_ITEM } from './list_manage_drilldowns'; + +// TODO: for some reason global cleanup from RTL doesn't work +// afterEach is not available for it globally during setup +afterEach(cleanup); + +test('Render list of drilldowns', () => { + const screen = render(); + expect(screen.getAllByTestId(TEST_SUBJ_DRILLDOWN_ITEM)).toHaveLength(drilldowns.length); +}); + +test('Emit onEdit() when clicking on edit drilldown', () => { + const fn = jest.fn(); + const screen = render(); + + const editButtons = screen.getAllByText('Edit'); + expect(editButtons).toHaveLength(drilldowns.length); + fireEvent.click(editButtons[1]); + expect(fn).toBeCalledWith(drilldowns[1].id); +}); + +test('Emit onCreate() when clicking on create drilldown', () => { + const fn = jest.fn(); + const screen = render(); + fireEvent.click(screen.getByText('Create new')); + expect(fn).toBeCalled(); +}); + +test('Delete button is not visible when non is selected', () => { + const fn = jest.fn(); + const screen = render(); + expect(screen.queryByText(/Delete/i)).not.toBeInTheDocument(); + expect(screen.queryByText(/Create/i)).toBeInTheDocument(); +}); + +test('Can delete drilldowns', () => { + const fn = jest.fn(); + const screen = render(); + + const checkboxes = screen.getAllByLabelText(/Select this drilldown/i); + expect(checkboxes).toHaveLength(3); + + fireEvent.click(checkboxes[1]); + fireEvent.click(checkboxes[2]); + + expect(screen.queryByText(/Create/i)).not.toBeInTheDocument(); + + fireEvent.click(screen.getByText(/Delete \(2\)/i)); + + expect(fn).toBeCalledWith([drilldowns[1].id, drilldowns[2].id]); +}); diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.tsx b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.tsx new file mode 100644 index 0000000000000..71e566d1020f5 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.tsx @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiBasicTable, + EuiBasicTableColumn, + EuiButton, + EuiButtonEmpty, + EuiSpacer, +} from '@elastic/eui'; +import React, { useState } from 'react'; +import { + txtEditDrilldown, + txtCreateDrilldown, + txtDeleteDrilldowns, + txtSelectDrilldown, +} from './i18n'; + +// TODO: interface is temporary +export interface DrilldownListItem { + id: string; + actionTypeDisplayName: string; + name: string; +} + +export interface ListManageDrilldownsProps { + drilldowns: DrilldownListItem[]; + + onEdit?: (id: string) => void; + onCreate?: () => void; + onDelete?: (ids: string[]) => void; +} + +const noop = () => {}; + +export const TEST_SUBJ_DRILLDOWN_ITEM = 'list-manage-drilldowns-item'; + +export function ListManageDrilldowns({ + drilldowns, + onEdit = noop, + onCreate = noop, + onDelete = noop, +}: ListManageDrilldownsProps) { + const [selectedDrilldowns, setSelectedDrilldowns] = useState([]); + + const columns: Array> = [ + { + field: 'name', + name: 'Name', + truncateText: true, + }, + { + field: 'actionTypeDisplayName', + name: 'Action', + truncateText: true, + }, + { + render: (drilldown: DrilldownListItem) => ( + onEdit(drilldown.id)}> + {txtEditDrilldown} + + ), + }, + ]; + + return ( + <> + { + setSelectedDrilldowns(selection.map(drilldown => drilldown.id)); + }, + selectableMessage: () => txtSelectDrilldown, + }} + rowProps={{ 'data-test-subj': TEST_SUBJ_DRILLDOWN_ITEM }} + hasActions={true} + /> + + {selectedDrilldowns.length === 0 ? ( + onCreate()}> + {txtCreateDrilldown} + + ) : ( + onDelete(selectedDrilldowns)}> + {txtDeleteDrilldowns(selectedDrilldowns.length)} + + )} + + ); +} diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/test_data.ts b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/test_data.ts new file mode 100644 index 0000000000000..862c3efafa189 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/test_data.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const drilldowns = [ + { id: '1', actionTypeDisplayName: 'Dashboard', name: 'Drilldown 1' }, + { id: '2', actionTypeDisplayName: 'Dashboard', name: 'Drilldown 2' }, + { id: '3', actionTypeDisplayName: 'Dashboard', name: 'Drilldown 3' }, +];