From 641a84386fe67b02c1ecdc724ba9602ac5694612 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Fri, 29 May 2020 15:10:56 -0400 Subject: [PATCH 01/11] add details flyout --- .../component_template_list.tsx | 33 ++- .../details_flyout/details_flyout.tsx | 202 ++++++++++++++++++ .../details_flyout/index.ts | 7 + .../details_flyout/tab_content/index.ts | 10 + .../tab_content/tab_aliases.tsx | 42 ++++ .../tab_content/tab_mappings.tsx | 42 ++++ .../tab_content/tab_settings.tsx | 42 ++++ .../tab_content/tab_summary.tsx | 81 +++++++ .../details_flyout/tabs.tsx | 90 ++++++++ .../component_template_list/table.tsx | 20 ++ .../component_templates/constants.ts | 8 + .../components/component_templates/lib/api.ts | 10 +- .../public/application/sections/home/home.tsx | 9 +- 13 files changed, 592 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/details_flyout.tsx create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/index.ts create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/index.ts create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tabs.tsx diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx index 41fa608ef538b..28d24a50f44a5 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx @@ -5,24 +5,39 @@ */ import React, { useState, useEffect } from 'react'; +import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; +import { ScopedHistory } from 'kibana/public'; import { SectionLoading } from '../shared_imports'; import { useComponentTemplatesContext } from '../component_templates_context'; import { UIM_COMPONENT_TEMPLATE_LIST_LOAD } from '../constants'; - import { EmptyPrompt } from './empty_prompt'; import { ComponentTable } from './table'; import { LoadError } from './error'; import { ComponentTemplatesDeleteModal } from './delete_modal'; +import { ComponentTemplateDetailsFlyout } from './details_flyout'; + +interface MatchParams { + componentTemplateName?: string; +} -export const ComponentTemplateList: React.FunctionComponent = () => { +export const ComponentTemplateList: React.FunctionComponent> = ({ + match: { + params: { componentTemplateName }, + }, + history, +}) => { const { api, trackMetric } = useComponentTemplatesContext(); const { data, isLoading, error, sendRequest } = api.useLoadComponentTemplates(); const [componentTemplatesToDelete, setComponentTemplatesToDelete] = useState([]); + const goToList = () => { + return history.push('component_templates'); + }; + // Track component loaded useEffect(() => { trackMetric('loaded', UIM_COMPONENT_TEMPLATE_LIST_LOAD); @@ -49,6 +64,7 @@ export const ComponentTemplateList: React.FunctionComponent = () => { componentTemplates={data} onReloadClick={sendRequest} onDeleteClick={setComponentTemplatesToDelete} + history={history as ScopedHistory} /> ); } else if (error) { @@ -58,18 +74,31 @@ export const ComponentTemplateList: React.FunctionComponent = () => { return (
{content} + + {/* delete modal */} {componentTemplatesToDelete?.length > 0 ? ( { if (deleteResponse?.hasDeletedComponentTemplates) { // refetch the component templates sendRequest(); + // go back to list view (if deleted from details flyout) + goToList(); } setComponentTemplatesToDelete([]); }} componentTemplatesToDelete={componentTemplatesToDelete} /> ) : null} + + {/* details flyout */} + {componentTemplateName && ( + + )}
); }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/details_flyout.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/details_flyout.tsx new file mode 100644 index 0000000000000..cba8816a1b3f9 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/details_flyout.tsx @@ -0,0 +1,202 @@ +/* + * 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, { useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { + EuiFlyout, + EuiFlyoutHeader, + EuiTitle, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, + EuiSpacer, + EuiPopover, + EuiButton, + EuiContextMenu, + EuiCallOut, +} from '@elastic/eui'; + +import { SectionLoading } from '../../shared_imports'; +import { ComponentTemplateDeserialized } from '../../types'; +import { useComponentTemplatesContext } from '../../component_templates_context'; +import { TabSummary, TabSettings, TabAliases, TabMappings } from './tab_content'; +import { ComponentTemplateTabs, TabType, Tab } from './tabs'; + +const tabToComponentMap: { + [key: string]: React.FunctionComponent<{ + componentTemplateDetails: ComponentTemplateDeserialized; + }>; +} = { + [TabType.Summary]: TabSummary, + [TabType.Settings]: TabSettings, + [TabType.Mappings]: TabMappings, + [TabType.Aliases]: TabAliases, +}; + +interface Props { + componentTemplateName: string; + onDeleteClick: (componentTemplateName: string[]) => void; + onClose: () => void; +} + +export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ + componentTemplateName, + onClose, + onDeleteClick, +}) => { + const { api } = useComponentTemplatesContext(); + + const { data: componentTemplateDetails, isLoading, error } = api.useLoadComponentTemplate( + componentTemplateName + ); + + const [activeTab, setActiveTab] = useState(TabType.Summary); + const [isPopoverOpen, setIsPopOverOpen] = useState(false); + + let content; + + if (isLoading) { + content = ( + + + + ); + } else if (error) { + content = ( + + } + color="danger" + iconType="alert" + data-test-subj="sectionError" + > +

{error.message}

+
+ ); + } else if (componentTemplateDetails) { + const TabContent = tabToComponentMap[activeTab]; + + content = ( + <> + + + + + + + ); + } + + return ( + + + +

+ {componentTemplateName} +

+
+
+ + {content} + + + + {/* "Close" link */} + + + + + + + {/* "Manage" context menu */} + {componentTemplateDetails && ( + + setIsPopOverOpen((prevBoolean) => !prevBoolean)} + > + + + } + isOpen={isPopoverOpen} + closePopover={() => setIsPopOverOpen(false)} + panelPaddingSize="none" + withTitle + anchorPosition="rightUp" + repositionOnScroll + > + 0, + onClick: () => { + setIsPopOverOpen(false); + onDeleteClick([componentTemplateName]); + }, + }, + ], + }, + ]} + /> + + + )} + + +
+ ); +}; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/index.ts b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/index.ts new file mode 100644 index 0000000000000..e992da37c54a7 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/index.ts @@ -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 { ComponentTemplateDetailsFlyout } from './details_flyout'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/index.ts b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/index.ts new file mode 100644 index 0000000000000..bfb5debcff59e --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/index.ts @@ -0,0 +1,10 @@ +/* + * 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 { TabSummary } from './tab_summary'; +export { TabAliases } from './tab_aliases'; +export { TabMappings } from './tab_mappings'; +export { TabSettings } from './tab_settings'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx new file mode 100644 index 0000000000000..32e0efc192e3a --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx @@ -0,0 +1,42 @@ +/* + * 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 { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCodeBlock, EuiCallOut } from '@elastic/eui'; + +import { ComponentTemplateDeserialized } from '../../../types'; + +interface Props { + componentTemplateDetails: ComponentTemplateDeserialized; +} + +export const TabAliases: React.FunctionComponent = ({ componentTemplateDetails }) => { + const { + template: { aliases }, + } = componentTemplateDetails; + + if (aliases && Object.keys(aliases).length) { + return ( +
+ {JSON.stringify(aliases, null, 2)} +
+ ); + } + + return ( + + } + iconType="pin" + data-test-subj="noAliasesCallout" + /> + ); +}; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx new file mode 100644 index 0000000000000..6a3174ab87a5b --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx @@ -0,0 +1,42 @@ +/* + * 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 { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCodeBlock, EuiCallOut } from '@elastic/eui'; + +import { ComponentTemplateDeserialized } from '../../../types'; + +interface Props { + componentTemplateDetails: ComponentTemplateDeserialized; +} + +export const TabMappings: React.FunctionComponent = ({ componentTemplateDetails }) => { + const { + template: { mappings }, + } = componentTemplateDetails; + + if (mappings && Object.keys(mappings).length) { + return ( +
+ {JSON.stringify(mappings, null, 2)} +
+ ); + } + + return ( + + } + iconType="pin" + data-test-subj="noMappingsCallout" + /> + ); +}; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx new file mode 100644 index 0000000000000..a6d3901de5ae4 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx @@ -0,0 +1,42 @@ +/* + * 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 { FormattedMessage } from '@kbn/i18n/react'; +import { EuiCodeBlock, EuiCallOut } from '@elastic/eui'; + +import { ComponentTemplateDeserialized } from '../../../types'; + +interface Props { + componentTemplateDetails: ComponentTemplateDeserialized; +} + +export const TabSettings: React.FunctionComponent = ({ componentTemplateDetails }) => { + const { + template: { settings }, + } = componentTemplateDetails; + + if (settings && Object.keys(settings).length) { + return ( +
+ {JSON.stringify(settings, null, 2)} +
+ ); + } + + return ( + + } + iconType="pin" + data-test-subj="noSettingsCallout" + /> + ); +}; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx new file mode 100644 index 0000000000000..61f2c597e813d --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx @@ -0,0 +1,81 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { + EuiDescriptionList, + EuiDescriptionListTitle, + EuiDescriptionListDescription, + EuiHealth, + EuiCodeBlock, +} from '@elastic/eui'; +import { ComponentTemplateDeserialized } from '../../../types'; + +interface Props { + componentTemplateDetails: ComponentTemplateDeserialized; +} + +export const TabSummary: React.FunctionComponent = ({ componentTemplateDetails }) => { + const { version, _meta, _kbnMeta } = componentTemplateDetails; + + const { usedBy } = _kbnMeta; + const templateIsInUse = usedBy.length > 0; + + const statusLabel = templateIsInUse + ? i18n.translate('xpack.idxMgmt.componentTemplateDetails.summaryTab.inUseDescription', { + defaultMessage: 'In use', + }) + : i18n.translate('xpack.idxMgmt.componentTemplateDetails.summaryTab.notInUseDescription', { + defaultMessage: 'Not in use', + }); + + const statusColor = templateIsInUse ? 'success' : 'danger'; + + return ( + + {/* Status */} + + + + + {statusLabel} + + + {/* Version (optional) */} + {version && ( + <> + + + + {version} + + )} + + {/* Metadata (optional) */} + {_meta && ( + <> + + + + + {JSON.stringify(_meta, null, 2)} + + + )} + + ); +}; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tabs.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tabs.tsx new file mode 100644 index 0000000000000..56818bb7b403a --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tabs.tsx @@ -0,0 +1,90 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { EuiTab, EuiTabs } from '@elastic/eui'; + +import { + UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SUMMARY_TAB, + UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SETTINGS_TAB, + UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_MAPPINGS_TAB, + UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_ALIASES_TAB, +} from '../../constants'; +import { useComponentTemplatesContext } from '../../component_templates_context'; + +export type Tab = TabType.Summary | TabType.Mappings | TabType.Aliases | TabType.Settings; + +export enum TabType { + Summary = 'summary', + Mappings = 'mappings', + Aliases = 'aliases', + Settings = 'settings', +} + +interface Props { + setActiveTab: (id: Tab) => void; + activeTab: Tab; +} + +const TABS = [ + { + id: TabType.Summary, + name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.summaryTabTitle', { + defaultMessage: 'Summary', + }), + }, + { + id: TabType.Settings, + name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.settingsTabTitle', { + defaultMessage: 'Settings', + }), + }, + { + id: TabType.Mappings, + name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.mappingsTabTitle', { + defaultMessage: 'Mappings', + }), + }, + { + id: TabType.Aliases, + name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.aliasesTabTitle', { + defaultMessage: 'Aliases', + }), + }, +]; + +const tabToUiMetricMap: { [key: string]: string } = { + [TabType.Summary]: UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SUMMARY_TAB, + [TabType.Settings]: UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SETTINGS_TAB, + [TabType.Mappings]: UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_MAPPINGS_TAB, + [TabType.Aliases]: UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_ALIASES_TAB, +}; + +export const ComponentTemplateTabs: React.FunctionComponent = ({ + setActiveTab, + activeTab, +}) => { + const { trackMetric } = useComponentTemplatesContext(); + + return ( + + {TABS.map((tab) => ( + { + trackMetric('click', tabToUiMetricMap[tab.id]); + setActiveTab(tab.id); + }} + isSelected={tab.id === activeTab} + key={tab.id} + data-test-subj="tab" + > + {tab.name} + + ))} + + ); +}; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx index 2d9557e64e6e7..bcb8d51bd7dd0 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx @@ -12,20 +12,25 @@ import { EuiInMemoryTableProps, EuiTextColor, EuiIcon, + EuiLink, } from '@elastic/eui'; +import { ScopedHistory } from 'kibana/public'; +import { reactRouterNavigate } from '../../../../../../../../src/plugins/kibana_react/public'; import { ComponentTemplateListItem } from '../types'; export interface Props { componentTemplates: ComponentTemplateListItem[]; onReloadClick: () => void; onDeleteClick: (componentTemplateName: string[]) => void; + history: ScopedHistory; } export const ComponentTable: FunctionComponent = ({ componentTemplates, onReloadClick, onDeleteClick, + history, }) => { const [selection, setSelection] = useState([]); @@ -120,6 +125,21 @@ export const ComponentTable: FunctionComponent = ({ defaultMessage: 'Name', }), sortable: true, + render: (name: string) => ( + /* eslint-disable-next-line @elastic/eui/href-or-on-click */ + uiMetricService.trackMetric('click', UIM_TEMPLATE_SHOW_DETAILS_CLICK) + )} + data-test-subj="templateDetailsLink" + > + {name} + + ), }, { field: 'usedBy', diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/constants.ts b/x-pack/plugins/index_management/public/application/components/component_templates/constants.ts index 3e763119fa9fb..fec8de134cad5 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/constants.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/constants.ts @@ -8,3 +8,11 @@ export const UIM_COMPONENT_TEMPLATE_LIST_LOAD = 'component_template_list_load'; export const UIM_COMPONENT_TEMPLATE_DELETE = 'component_template_delete'; export const UIM_COMPONENT_TEMPLATE_DELETE_MANY = 'component_template_delete_many'; +export const UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SUMMARY_TAB = + 'component_template_details_summary_tab'; +export const UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SETTINGS_TAB = + 'component_template_details_settings_tab'; +export const UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_MAPPINGS_TAB = + 'component_template_details_mappings_tab'; +export const UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_ALIASES_TAB = + 'component_template_details_aliases_tab'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts b/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts index 351e83c6c0cb5..975d9450a873a 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ComponentTemplateListItem } from '../types'; +import { ComponentTemplateListItem, ComponentTemplateDeserialized } from '../types'; import { UseRequestHook, SendRequestHook } from './request'; import { UIM_COMPONENT_TEMPLATE_DELETE_MANY, UIM_COMPONENT_TEMPLATE_DELETE } from '../constants'; @@ -37,8 +37,16 @@ export const getApi = ( return result; } + function useLoadComponentTemplate(name: string) { + return useRequest({ + path: `${apiBasePath}/component_templates/${encodeURIComponent(name)}`, + method: 'get', + }); + } + return { useLoadComponentTemplates, deleteComponentTemplates, + useLoadComponentTemplate, }; }; diff --git a/x-pack/plugins/index_management/public/application/sections/home/home.tsx b/x-pack/plugins/index_management/public/application/sections/home/home.tsx index 51deaf42cc72c..7bd04cdbf0c91 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/home.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/home.tsx @@ -150,7 +150,14 @@ export const IndexManagementHome: React.FunctionComponent - + From 899643a04065891a0ed25e1411e0b66ce6beb0c5 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Thu, 4 Jun 2020 13:59:08 -0400 Subject: [PATCH 02/11] cleanup --- .../tab_content/tab_aliases.tsx | 1 + .../tab_content/tab_mappings.tsx | 1 + .../tab_content/tab_settings.tsx | 1 + .../tab_content/tab_summary.tsx | 120 +++++++++++------- 4 files changed, 75 insertions(+), 48 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx index 32e0efc192e3a..254d9a3d2fc2d 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx @@ -37,6 +37,7 @@ export const TabAliases: React.FunctionComponent = ({ componentTemplateDe } iconType="pin" data-test-subj="noAliasesCallout" + size="s" /> ); }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx index 6a3174ab87a5b..e4323460c72f8 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx @@ -37,6 +37,7 @@ export const TabMappings: React.FunctionComponent = ({ componentTemplateD } iconType="pin" data-test-subj="noMappingsCallout" + size="s" /> ); }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx index a6d3901de5ae4..a284f727620a0 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx @@ -37,6 +37,7 @@ export const TabSettings: React.FunctionComponent = ({ componentTemplateD } iconType="pin" data-test-subj="noSettingsCallout" + size="s" /> ); }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx index 61f2c597e813d..5e801127a5ba0 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx @@ -5,14 +5,15 @@ */ import React from 'react'; -import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiDescriptionList, EuiDescriptionListTitle, EuiDescriptionListDescription, - EuiHealth, EuiCodeBlock, + EuiTitle, + EuiCallOut, + EuiSpacer, } from '@elastic/eui'; import { ComponentTemplateDeserialized } from '../../../types'; @@ -26,56 +27,79 @@ export const TabSummary: React.FunctionComponent = ({ componentTemplateDe const { usedBy } = _kbnMeta; const templateIsInUse = usedBy.length > 0; - const statusLabel = templateIsInUse - ? i18n.translate('xpack.idxMgmt.componentTemplateDetails.summaryTab.inUseDescription', { - defaultMessage: 'In use', - }) - : i18n.translate('xpack.idxMgmt.componentTemplateDetails.summaryTab.notInUseDescription', { - defaultMessage: 'Not in use', - }); - - const statusColor = templateIsInUse ? 'success' : 'danger'; - return ( - - {/* Status */} - - - - - {statusLabel} - - - {/* Version (optional) */} - {version && ( + <> + {/* Callout when component template is not in use */} + {!templateIsInUse && ( <> - - - - {version} + + } + iconType="pin" + data-test-subj="notInUseCallout" + size="s" + /> + )} - {/* Metadata (optional) */} - {_meta && ( - <> - - - - - {JSON.stringify(_meta, null, 2)} - - - )} - + {/* Summary description list */} + + {/* Used by templates */} + {templateIsInUse && ( + <> + + + + +
    + {usedBy.map((templateName: string) => ( +
  • + + {templateName} + +
  • + ))} +
+
+ + )} + + {/* Version (optional) */} + {version && ( + <> + + + + {version} + + )} + + {/* Metadata (optional) */} + {_meta && ( + <> + + + + + {JSON.stringify(_meta, null, 2)} + + + )} +
+ ); }; From ef9734faf2da153c9605be893a4dc532f7764714 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Thu, 4 Jun 2020 22:30:06 -0400 Subject: [PATCH 03/11] refactor --- .../component_template_details.tsx} | 172 +++++++++--------- .../index.ts | 2 +- .../tab_content/index.ts | 0 .../tab_content/tab_aliases.tsx | 2 +- .../tab_content/tab_mappings.tsx | 2 +- .../tab_content/tab_settings.tsx | 2 +- .../tab_content/tab_summary.tsx | 3 +- .../tabs.tsx | 18 -- .../component_template_list.tsx | 5 +- .../component_template_list/table.tsx | 8 +- .../component_templates/constants.ts | 9 +- .../components/component_templates/index.ts | 2 + 12 files changed, 107 insertions(+), 118 deletions(-) rename x-pack/plugins/index_management/public/application/components/component_templates/{component_template_list/details_flyout/details_flyout.tsx => component_template_details/component_template_details.tsx} (52%) rename x-pack/plugins/index_management/public/application/components/component_templates/{component_template_list/details_flyout => component_template_details}/index.ts (75%) rename x-pack/plugins/index_management/public/application/components/component_templates/{component_template_list/details_flyout => component_template_details}/tab_content/index.ts (100%) rename x-pack/plugins/index_management/public/application/components/component_templates/{component_template_list/details_flyout => component_template_details}/tab_content/tab_aliases.tsx (94%) rename x-pack/plugins/index_management/public/application/components/component_templates/{component_template_list/details_flyout => component_template_details}/tab_content/tab_mappings.tsx (94%) rename x-pack/plugins/index_management/public/application/components/component_templates/{component_template_list/details_flyout => component_template_details}/tab_content/tab_settings.tsx (94%) rename x-pack/plugins/index_management/public/application/components/component_templates/{component_template_list/details_flyout => component_template_details}/tab_content/tab_summary.tsx (98%) rename x-pack/plugins/index_management/public/application/components/component_templates/{component_template_list/details_flyout => component_template_details}/tabs.tsx (68%) diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/details_flyout.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx similarity index 52% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/details_flyout.tsx rename to x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx index cba8816a1b3f9..03312f51eac29 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/details_flyout.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx @@ -23,9 +23,9 @@ import { EuiCallOut, } from '@elastic/eui'; -import { SectionLoading } from '../../shared_imports'; -import { ComponentTemplateDeserialized } from '../../types'; -import { useComponentTemplatesContext } from '../../component_templates_context'; +import { SectionLoading } from '../shared_imports'; +import { ComponentTemplateDeserialized } from '../types'; +import { useComponentTemplatesContext } from '../component_templates_context'; import { TabSummary, TabSettings, TabAliases, TabMappings } from './tab_content'; import { ComponentTemplateTabs, TabType, Tab } from './tabs'; @@ -42,14 +42,16 @@ const tabToComponentMap: { interface Props { componentTemplateName: string; - onDeleteClick: (componentTemplateName: string[]) => void; onClose: () => void; + onDeleteClick: (componentTemplateName: string[]) => void; + showFooter?: boolean; } export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ componentTemplateName, onClose, onDeleteClick, + showFooter, }) => { const { api } = useComponentTemplatesContext(); @@ -60,7 +62,7 @@ export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ const [activeTab, setActiveTab] = useState(TabType.Summary); const [isPopoverOpen, setIsPopOverOpen] = useState(false); - let content; + let content: React.ReactNode | undefined; if (isLoading) { content = ( @@ -101,6 +103,87 @@ export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ ); } + const footer: React.ReactNode = ( + + + {/* "Close" link */} + + + + + + + {/* "Manage" context menu */} + {componentTemplateDetails && ( + + setIsPopOverOpen((prevBoolean) => !prevBoolean)} + > + + + } + isOpen={isPopoverOpen} + closePopover={() => setIsPopOverOpen(false)} + panelPaddingSize="none" + withTitle + anchorPosition="rightUp" + repositionOnScroll + > + 0, + onClick: () => { + setIsPopOverOpen(false); + onDeleteClick([componentTemplateName]); + }, + }, + ], + }, + ]} + /> + + + )} + + + ); + return ( = ({ {content} - - - {/* "Close" link */} - - - - - - - {/* "Manage" context menu */} - {componentTemplateDetails && ( - - setIsPopOverOpen((prevBoolean) => !prevBoolean)} - > - - - } - isOpen={isPopoverOpen} - closePopover={() => setIsPopOverOpen(false)} - panelPaddingSize="none" - withTitle - anchorPosition="rightUp" - repositionOnScroll - > - 0, - onClick: () => { - setIsPopOverOpen(false); - onDeleteClick([componentTemplateName]); - }, - }, - ], - }, - ]} - /> - - - )} - - + {showFooter ? footer : null} ); }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/index.ts b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/index.ts similarity index 75% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/index.ts rename to x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/index.ts index e992da37c54a7..11aac200a2f14 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/index.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { ComponentTemplateDetailsFlyout } from './details_flyout'; +export { ComponentTemplateDetailsFlyout } from './component_template_details'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/index.ts b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/index.ts similarity index 100% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/index.ts rename to x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/index.ts diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_aliases.tsx similarity index 94% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx rename to x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_aliases.tsx index 254d9a3d2fc2d..ec3d015b45d0d 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_aliases.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_aliases.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCodeBlock, EuiCallOut } from '@elastic/eui'; -import { ComponentTemplateDeserialized } from '../../../types'; +import { ComponentTemplateDeserialized } from '../../types'; interface Props { componentTemplateDetails: ComponentTemplateDeserialized; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_mappings.tsx similarity index 94% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx rename to x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_mappings.tsx index e4323460c72f8..5bdf8e1083456 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_mappings.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_mappings.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCodeBlock, EuiCallOut } from '@elastic/eui'; -import { ComponentTemplateDeserialized } from '../../../types'; +import { ComponentTemplateDeserialized } from '../../types'; interface Props { componentTemplateDetails: ComponentTemplateDeserialized; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_settings.tsx similarity index 94% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx rename to x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_settings.tsx index a284f727620a0..3c4d9680ef6ba 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_settings.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_settings.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCodeBlock, EuiCallOut } from '@elastic/eui'; -import { ComponentTemplateDeserialized } from '../../../types'; +import { ComponentTemplateDeserialized } from '../../types'; interface Props { componentTemplateDetails: ComponentTemplateDeserialized; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_summary.tsx similarity index 98% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx rename to x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_summary.tsx index 5e801127a5ba0..d02d9d083308b 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tab_content/tab_summary.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_summary.tsx @@ -15,7 +15,8 @@ import { EuiCallOut, EuiSpacer, } from '@elastic/eui'; -import { ComponentTemplateDeserialized } from '../../../types'; + +import { ComponentTemplateDeserialized } from '../../types'; interface Props { componentTemplateDetails: ComponentTemplateDeserialized; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tabs.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tabs.tsx similarity index 68% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tabs.tsx rename to x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tabs.tsx index 56818bb7b403a..ef3a25c9b3409 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/details_flyout/tabs.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tabs.tsx @@ -8,14 +8,6 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiTab, EuiTabs } from '@elastic/eui'; -import { - UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SUMMARY_TAB, - UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SETTINGS_TAB, - UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_MAPPINGS_TAB, - UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_ALIASES_TAB, -} from '../../constants'; -import { useComponentTemplatesContext } from '../../component_templates_context'; - export type Tab = TabType.Summary | TabType.Mappings | TabType.Aliases | TabType.Settings; export enum TabType { @@ -57,25 +49,15 @@ const TABS = [ }, ]; -const tabToUiMetricMap: { [key: string]: string } = { - [TabType.Summary]: UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SUMMARY_TAB, - [TabType.Settings]: UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SETTINGS_TAB, - [TabType.Mappings]: UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_MAPPINGS_TAB, - [TabType.Aliases]: UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_ALIASES_TAB, -}; - export const ComponentTemplateTabs: React.FunctionComponent = ({ setActiveTab, activeTab, }) => { - const { trackMetric } = useComponentTemplatesContext(); - return ( {TABS.map((tab) => ( { - trackMetric('click', tabToUiMetricMap[tab.id]); setActiveTab(tab.id); }} isSelected={tab.id === activeTab} diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx index 28d24a50f44a5..0c8eeb828abb4 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx @@ -10,13 +10,13 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { ScopedHistory } from 'kibana/public'; import { SectionLoading } from '../shared_imports'; -import { useComponentTemplatesContext } from '../component_templates_context'; import { UIM_COMPONENT_TEMPLATE_LIST_LOAD } from '../constants'; +import { useComponentTemplatesContext } from '../component_templates_context'; +import { ComponentTemplateDetailsFlyout } from '../component_template_details'; import { EmptyPrompt } from './empty_prompt'; import { ComponentTable } from './table'; import { LoadError } from './error'; import { ComponentTemplatesDeleteModal } from './delete_modal'; -import { ComponentTemplateDetailsFlyout } from './details_flyout'; interface MatchParams { componentTemplateName?: string; @@ -97,6 +97,7 @@ export const ComponentTemplateList: React.FunctionComponent )} diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx index bcb8d51bd7dd0..e177dba680d6d 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx @@ -18,6 +18,8 @@ import { ScopedHistory } from 'kibana/public'; import { reactRouterNavigate } from '../../../../../../../../src/plugins/kibana_react/public'; import { ComponentTemplateListItem } from '../types'; +import { UIM_COMPONENT_TEMPLATE_DETAILS } from '../constants'; +import { useComponentTemplatesContext } from '../component_templates_context'; export interface Props { componentTemplates: ComponentTemplateListItem[]; @@ -32,6 +34,8 @@ export const ComponentTable: FunctionComponent = ({ onDeleteClick, history, }) => { + const { trackMetric } = useComponentTemplatesContext(); + const [selection, setSelection] = useState([]); const tableProps: EuiInMemoryTableProps = { @@ -132,8 +136,8 @@ export const ComponentTable: FunctionComponent = ({ history, { pathname: `/component_templates/${name}`, - } - // () => uiMetricService.trackMetric('click', UIM_TEMPLATE_SHOW_DETAILS_CLICK) + }, + () => trackMetric('click', UIM_COMPONENT_TEMPLATE_DETAILS) )} data-test-subj="templateDetailsLink" > diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/constants.ts b/x-pack/plugins/index_management/public/application/components/component_templates/constants.ts index fec8de134cad5..cf13ce40456dd 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/constants.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/constants.ts @@ -8,11 +8,4 @@ export const UIM_COMPONENT_TEMPLATE_LIST_LOAD = 'component_template_list_load'; export const UIM_COMPONENT_TEMPLATE_DELETE = 'component_template_delete'; export const UIM_COMPONENT_TEMPLATE_DELETE_MANY = 'component_template_delete_many'; -export const UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SUMMARY_TAB = - 'component_template_details_summary_tab'; -export const UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_SETTINGS_TAB = - 'component_template_details_settings_tab'; -export const UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_MAPPINGS_TAB = - 'component_template_details_mappings_tab'; -export const UIM_COMPONENT_TEMPLATE_DETAIL_PANEL_ALIASES_TAB = - 'component_template_details_aliases_tab'; +export const UIM_COMPONENT_TEMPLATE_DETAILS = 'component_template_details'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/index.ts b/x-pack/plugins/index_management/public/application/components/component_templates/index.ts index e0219ec71787f..bc609cd77e05b 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/index.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/index.ts @@ -8,4 +8,6 @@ export { ComponentTemplatesProvider } from './component_templates_context'; export { ComponentTemplateList } from './component_template_list'; +export { ComponentTemplateDetailsFlyout } from './component_template_details'; + export * from './types'; From 9c8e18300c7e31de93a62a300fcb220819e62a16 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Fri, 5 Jun 2020 12:35:57 -0400 Subject: [PATCH 04/11] refactor: make actions optional + create separate component for context menu --- .../component_template_details.tsx | 123 +++++------------- .../manage_button.tsx | 95 ++++++++++++++ .../component_template_list.tsx | 18 ++- 3 files changed, 144 insertions(+), 92 deletions(-) create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx index 03312f51eac29..f70f361aa64b8 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx @@ -6,7 +6,6 @@ import React, { useState } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; import { EuiFlyout, EuiFlyoutHeader, @@ -17,9 +16,6 @@ import { EuiFlexItem, EuiButtonEmpty, EuiSpacer, - EuiPopover, - EuiButton, - EuiContextMenu, EuiCallOut, } from '@elastic/eui'; @@ -28,6 +24,7 @@ import { ComponentTemplateDeserialized } from '../types'; import { useComponentTemplatesContext } from '../component_templates_context'; import { TabSummary, TabSettings, TabAliases, TabMappings } from './tab_content'; import { ComponentTemplateTabs, TabType, Tab } from './tabs'; +import { ManageButton, ManageAction } from './manage_button'; const tabToComponentMap: { [key: string]: React.FunctionComponent<{ @@ -43,15 +40,14 @@ const tabToComponentMap: { interface Props { componentTemplateName: string; onClose: () => void; - onDeleteClick: (componentTemplateName: string[]) => void; showFooter?: boolean; + actions?: ManageAction[]; } export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ componentTemplateName, onClose, - onDeleteClick, - showFooter, + actions, }) => { const { api } = useComponentTemplatesContext(); @@ -60,7 +56,6 @@ export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ ); const [activeTab, setActiveTab] = useState(TabType.Summary); - const [isPopoverOpen, setIsPopOverOpen] = useState(false); let content: React.ReactNode | undefined; @@ -103,87 +98,6 @@ export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ ); } - const footer: React.ReactNode = ( - - - {/* "Close" link */} - - - - - - - {/* "Manage" context menu */} - {componentTemplateDetails && ( - - setIsPopOverOpen((prevBoolean) => !prevBoolean)} - > - - - } - isOpen={isPopoverOpen} - closePopover={() => setIsPopOverOpen(false)} - panelPaddingSize="none" - withTitle - anchorPosition="rightUp" - repositionOnScroll - > - 0, - onClick: () => { - setIsPopOverOpen(false); - onDeleteClick([componentTemplateName]); - }, - }, - ], - }, - ]} - /> - - - )} - - - ); - return ( = ({ {content} - {showFooter ? footer : null} + {actions && ( + + + {/* "Close" link */} + + + + + + + {/* "Manage" context menu */} + {componentTemplateDetails && ( + + + + )} + + + )} ); }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx new file mode 100644 index 0000000000000..a9bc7b988d464 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx @@ -0,0 +1,95 @@ +/* + * 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, { useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { + EuiPopover, + EuiButton, + EuiContextMenu, + EuiContextMenuPanelItemDescriptor, +} from '@elastic/eui'; +import { ComponentTemplateDeserialized } from '../types'; + +export interface ManageAction { + name: string; + icon: string; + handleActionClick: () => void; + getIsDisabled?: (data: ComponentTemplateDeserialized) => boolean; + closePopoverOnClick?: boolean; +} + +interface Props { + actions: ManageAction[]; + componentTemplateDetails: ComponentTemplateDeserialized; +} + +export const ManageButton: React.FunctionComponent = ({ + actions, + componentTemplateDetails, +}) => { + const [isPopoverOpen, setIsPopOverOpen] = useState(false); + + const items: EuiContextMenuPanelItemDescriptor[] = actions.map( + ({ name, icon, getIsDisabled, closePopoverOnClick, handleActionClick }) => { + return { + name, + icon, + disabled: getIsDisabled ? getIsDisabled(componentTemplateDetails) : false, + onClick: () => { + handleActionClick(); + + if (closePopoverOnClick) { + setIsPopOverOpen(false); + } + }, + }; + } + ); + + return ( + setIsPopOverOpen((prevBoolean) => !prevBoolean)} + > + + + } + isOpen={isPopoverOpen} + closePopover={() => setIsPopOverOpen(false)} + panelPaddingSize="none" + withTitle + anchorPosition="rightUp" + repositionOnScroll + > + + + ); +}; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx index 0c8eeb828abb4..6b47a88bb5cc3 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx @@ -6,11 +6,13 @@ import React, { useState, useEffect } from 'react'; import { RouteComponentProps } from 'react-router-dom'; +import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { ScopedHistory } from 'kibana/public'; import { SectionLoading } from '../shared_imports'; import { UIM_COMPONENT_TEMPLATE_LIST_LOAD } from '../constants'; +import { ComponentTemplateDeserialized } from '../types'; import { useComponentTemplatesContext } from '../component_templates_context'; import { ComponentTemplateDetailsFlyout } from '../component_template_details'; import { EmptyPrompt } from './empty_prompt'; @@ -95,9 +97,21 @@ export const ComponentTemplateList: React.FunctionComponent + details._kbnMeta.usedBy.length > 0, + closePopoverOnClick: true, + handleActionClick: () => { + setComponentTemplatesToDelete([componentTemplateName]); + }, + }, + ]} /> )} From 4d214ef55d467b555919a165288c0bba9cda199f Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Sat, 6 Jun 2020 22:26:48 -0400 Subject: [PATCH 05/11] add component integration tests --- .../component_template_details.test.ts | 218 ++++++++++++++++++ .../component_template_details.helpers.ts | 101 ++++++++ .../helpers/http_requests.ts | 26 ++- .../client_integration/helpers/index.ts | 2 + .../component_template_details.tsx | 2 +- .../tab_content/tab_aliases.tsx | 2 +- .../tab_content/tab_mappings.tsx | 2 +- .../tab_content/tab_settings.tsx | 2 +- .../tab_content/tab_summary.tsx | 8 +- .../component_template_details/tabs.tsx | 2 +- 10 files changed, 354 insertions(+), 11 deletions(-) create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts new file mode 100644 index 0000000000000..40a497541cfc4 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts @@ -0,0 +1,218 @@ +/* + * 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 { act } from 'react-dom/test-utils'; + +import { setupEnvironment, pageHelpers } from './helpers'; +import { ComponentTemplateDetailsTestBed } from './helpers/component_template_details.helpers'; +import { ComponentTemplateDeserialized } from '../../types'; + +const { setup } = pageHelpers.componentTemplateDetails; + +jest.mock('ui/i18n', () => { + const I18nContext = ({ children }: any) => children; + return { I18nContext }; +}); + +const COMPONENT_TEMPLATE: ComponentTemplateDeserialized = { + name: 'comp-1', + template: { + mappings: { properties: { ip_address: { type: 'ip' } } }, + aliases: { mydata: {} }, + settings: { number_of_shards: 1 }, + }, + version: 1, + _meta: { description: 'component template test' }, + _kbnMeta: { usedBy: ['template_1'] }, +}; + +const COMPONENT_TEMPLATE_REQUIRED_FIELDS: ComponentTemplateDeserialized = { + name: 'comp-base', + template: {}, + _kbnMeta: { usedBy: [] }, +}; + +describe('', () => { + const { server, httpRequestsMockHelpers } = setupEnvironment(); + let testBed: ComponentTemplateDetailsTestBed; + + afterAll(() => { + server.restore(); + }); + + describe('With component template details', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setLoadComponentTemplateResponse(COMPONENT_TEMPLATE); + + await act(async () => { + testBed = setup({ + componentTemplateName: COMPONENT_TEMPLATE.name, + onClose: () => {}, + }); + }); + + testBed.component.update(); + }); + + test('renders the details flyout', () => { + const { exists, find, actions, component } = testBed; + + // Verify flyout exists with correct title + expect(exists('componentTemplateDetails')).toBe(true); + expect(find('componentTemplateDetails.title').text()).toBe(COMPONENT_TEMPLATE.name); + + // Verify footer does not display since "actions" prop was not provided + expect(exists('componentTemplateDetails.footer')).toBe(false); + + // Verify tabs exist + expect(exists('settingsTab')).toBe(true); + expect(exists('mappingsTab')).toBe(true); + expect(exists('aliasesTab')).toBe(true); + // Summary tab should be active by default + expect(find('summaryTab').props()['aria-selected']).toBe(true); + + // [Summary tab] Verify description list items + expect(exists('summaryTabContent.usedByTitle')).toBe(true); + expect(exists('summaryTabContent.versionTitle')).toBe(true); + expect(exists('summaryTabContent.metaTitle')).toBe(true); + + // [Settings tab] Navigate to tab and verify content + act(() => { + actions.clickSettingsTab(); + }); + + component.update(); + + expect(exists('settingsTabContent')).toBe(true); + + // [Mappings tab] Navigate to tab and verify content + act(() => { + actions.clickMappingsTab(); + }); + + component.update(); + expect(exists('mappingsTabContent')).toBe(true); + + // [Aliases tab] Navigate to tab and verify content + act(() => { + actions.clickAliasesTab(); + }); + + component.update(); + expect(exists('aliasesTabContent')).toBe(true); + }); + }); + + describe('With only required component template fields', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setLoadComponentTemplateResponse(COMPONENT_TEMPLATE_REQUIRED_FIELDS); + + await act(async () => { + testBed = setup({ + componentTemplateName: COMPONENT_TEMPLATE_REQUIRED_FIELDS.name, + onClose: () => {}, + }); + }); + + testBed.component.update(); + }); + + test('renders the details flyout', () => { + const { exists, actions, component } = testBed; + + // [Summary tab] Verify description list items do not display + expect(exists('summaryTabContent.usedByTitle')).toBe(false); + expect(exists('summaryTabContent.versionTitle')).toBe(false); + expect(exists('summaryTabContent.metaTitle')).toBe(false); + // Verify callout renders indicating the component template is not in use + expect(exists('notInUseCallout')).toBe(true); + + // [Settings tab] Navigate to tab and verify info callout + act(() => { + actions.clickSettingsTab(); + }); + + component.update(); + + expect(exists('noSettingsCallout')).toBe(true); + + // [Mappings tab] Navigate to tab and verify info callout + act(() => { + actions.clickMappingsTab(); + }); + + component.update(); + expect(exists('noMappingsCallout')).toBe(true); + + // [Aliases tab] Navigate to tab and verify info callout + act(() => { + actions.clickAliasesTab(); + }); + + component.update(); + expect(exists('noAliasesCallout')).toBe(true); + }); + }); + + describe('With actions', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setLoadComponentTemplateResponse(COMPONENT_TEMPLATE); + + await act(async () => { + testBed = setup({ + componentTemplateName: COMPONENT_TEMPLATE.name, + onClose: () => {}, + actions: [ + { + name: 'Test', + icon: 'info', + closePopoverOnClick: true, + handleActionClick: () => {}, + }, + ], + }); + }); + + testBed.component.update(); + }); + + test('should render a footer with context menu', () => { + const { exists } = testBed; + + // Verify footer exists + expect(exists('componentTemplateDetails.footer')).toBe(true); + expect(exists('manageComponentTemplateButton')).toBe(true); + }); + }); + + describe('Error handling', () => { + const error = { + status: 500, + error: 'Internal server error', + message: 'Internal server error', + }; + + beforeEach(async () => { + httpRequestsMockHelpers.setLoadComponentTemplateResponse(undefined, { body: error }); + + await act(async () => { + testBed = setup({ + componentTemplateName: COMPONENT_TEMPLATE.name, + onClose: () => {}, + }); + }); + + testBed.component.update(); + }); + + test('should render an error message if error fetching pipelines', async () => { + const { exists, find } = testBed; + + expect(exists('sectionError')).toBe(true); + expect(find('sectionError').text()).toContain('Error loading component template'); + }); + }); +}); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts new file mode 100644 index 0000000000000..89a27f2de9b22 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts @@ -0,0 +1,101 @@ +/* + * 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 { act } from 'react-dom/test-utils'; + +import { BASE_PATH } from '../../../../../../../common'; +import { + registerTestBed, + TestBed, + TestBedConfig, + findTestSubject, + nextTick, +} from '../../../../../../../../../test_utils'; +import { WithAppDependencies } from './setup_environment'; +import { ComponentTemplateDetailsFlyout } from '../../../component_template_details'; + +const getTestBedConfig = (props: Record) => { + const testBed: TestBedConfig = { + memoryRouter: { + wrapComponent: false, + }, + defaultProps: props, + }; + return testBed; +}; + +const initTestBed = (props: Record) => + registerTestBed(WithAppDependencies(ComponentTemplateDetailsFlyout), getTestBedConfig(props)); + +export type ComponentTemplateDetailsTestBed = TestBed & { + actions: ReturnType; +}; + +const createActions = (testBed: TestBed) => { + const { find } = testBed; + + /** + * User Actions + */ + const clickSettingsTab = () => { + find('settingsTab').simulate('click'); + }; + + const clickMappingsTab = () => { + find('mappingsTab').simulate('click'); + }; + + const clickAliasesTab = () => { + find('aliasesTab').simulate('click'); + }; + + return { + clickSettingsTab, + clickAliasesTab, + clickMappingsTab, + }; +}; + +export const setup = (props: any): ComponentTemplateDetailsTestBed => { + const setupTestBed = registerTestBed( + WithAppDependencies(ComponentTemplateDetailsFlyout), + { + memoryRouter: { + wrapComponent: false, + }, + defaultProps: props, + } + ); + + const testBed = setupTestBed() as ComponentTemplateDetailsTestBed; + + return { + ...testBed, + actions: createActions(testBed), + }; +}; + +export type ComponentTemplateDetailsTestSubjects = + | 'componentTemplateDetails' + | 'componentTemplateDetails.title' + | 'componentTemplateDetails.footer' + | 'summaryTab' + | 'mappingsTab' + | 'settingsTab' + | 'aliasesTab' + | 'sectionError' + | 'summaryTabContent' + | 'summaryTabContent.usedByTitle' + | 'summaryTabContent.versionTitle' + | 'summaryTabContent.metaTitle' + | 'notInUseCallout' + | 'aliasesTabContent' + | 'noAliasesCallout' + | 'mappingsTabContent' + | 'noMappingsCallout' + | 'settingsTabContent' + | 'noSettingsCallout' + | 'manageComponentTemplateButton'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts index 8473041ee0af3..f8cdad2291f48 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts @@ -5,11 +5,18 @@ */ import sinon, { SinonFakeServer } from 'sinon'; -import { API_BASE_PATH } from '../../../../../../../common'; +import { + API_BASE_PATH, + ComponentTemplateListItem, + ComponentTemplateDeserialized, +} from '../../../../../../../common'; // Register helpers to mock HTTP Requests const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { - const setLoadComponentTemplatesResponse = (response?: any[], error?: any) => { + const setLoadComponentTemplatesResponse = ( + response?: ComponentTemplateListItem[], + error?: any + ) => { const status = error ? error.status || 400 : 200; const body = error ? error.body : response; @@ -20,6 +27,20 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { ]); }; + const setLoadComponentTemplateResponse = ( + response?: ComponentTemplateDeserialized, + error?: any + ) => { + const status = error ? error.status || 400 : 200; + const body = error ? error.body : response; + + server.respondWith('GET', `${API_BASE_PATH}/component_templates/:name`, [ + status, + { 'Content-Type': 'application/json' }, + JSON.stringify(body), + ]); + }; + const setDeleteComponentTemplateResponse = (response?: object) => { server.respondWith('DELETE', `${API_BASE_PATH}/component_templates/:name`, [ 200, @@ -31,6 +52,7 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { return { setLoadComponentTemplatesResponse, setDeleteComponentTemplateResponse, + setLoadComponentTemplateResponse, }; }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/index.ts index c1d75b3c2dd9b..93eb65aac0761 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/index.ts @@ -5,6 +5,7 @@ */ import { setup as componentTemplatesListSetup } from './component_template_list.helpers'; +import { setup as componentTemplateDetailsSetup } from './component_template_details.helpers'; export { nextTick, getRandomString, findTestSubject } from '../../../../../../../../../test_utils'; @@ -12,4 +13,5 @@ export { setupEnvironment } from './setup_environment'; export const pageHelpers = { componentTemplateList: { setup: componentTemplatesListSetup }, + componentTemplateDetails: { setup: componentTemplateDetailsSetup }, }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx index f70f361aa64b8..3be7a6d829333 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx @@ -117,7 +117,7 @@ export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ {content} {actions && ( - + {/* "Close" link */} diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_aliases.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_aliases.tsx index ec3d015b45d0d..ec464f22c796f 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_aliases.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_aliases.tsx @@ -21,7 +21,7 @@ export const TabAliases: React.FunctionComponent = ({ componentTemplateDe if (aliases && Object.keys(aliases).length) { return ( -
+
{JSON.stringify(aliases, null, 2)}
); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_mappings.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_mappings.tsx index 5bdf8e1083456..78d58bc7cd02a 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_mappings.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_mappings.tsx @@ -21,7 +21,7 @@ export const TabMappings: React.FunctionComponent = ({ componentTemplateD if (mappings && Object.keys(mappings).length) { return ( -
+
{JSON.stringify(mappings, null, 2)}
); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_settings.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_settings.tsx index 3c4d9680ef6ba..344ffa71ff0e3 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_settings.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_settings.tsx @@ -21,7 +21,7 @@ export const TabSettings: React.FunctionComponent = ({ componentTemplateD if (settings && Object.keys(settings).length) { return ( -
+
{JSON.stringify(settings, null, 2)}
); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_summary.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_summary.tsx index d02d9d083308b..d6eac4e5feb5a 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_summary.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_summary.tsx @@ -49,11 +49,11 @@ export const TabSummary: React.FunctionComponent = ({ componentTemplateDe )} {/* Summary description list */} - + {/* Used by templates */} {templateIsInUse && ( <> - + = ({ componentTemplateDe {/* Version (optional) */} {version && ( <> - + = ({ componentTemplateDe {/* Metadata (optional) */} {_meta && ( <> - + = ({ }} isSelected={tab.id === activeTab} key={tab.id} - data-test-subj="tab" + data-test-subj={`${tab.id}Tab`} > {tab.name} From 115a816718af71e53d97040e1121c6da5517b5a6 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 10 Jun 2020 10:40:05 -0400 Subject: [PATCH 06/11] fix linter --- .../component_template_details.test.ts | 10 ++++---- .../component_template_details.helpers.ts | 24 +------------------ 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts index 40a497541cfc4..e28da86764afe 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts @@ -29,7 +29,7 @@ const COMPONENT_TEMPLATE: ComponentTemplateDeserialized = { _kbnMeta: { usedBy: ['template_1'] }, }; -const COMPONENT_TEMPLATE_REQUIRED_FIELDS: ComponentTemplateDeserialized = { +const COMPONENT_TEMPLATE_ONLY_REQUIRED_FIELDS: ComponentTemplateDeserialized = { name: 'comp-base', template: {}, _kbnMeta: { usedBy: [] }, @@ -108,11 +108,13 @@ describe('', () => { describe('With only required component template fields', () => { beforeEach(async () => { - httpRequestsMockHelpers.setLoadComponentTemplateResponse(COMPONENT_TEMPLATE_REQUIRED_FIELDS); + httpRequestsMockHelpers.setLoadComponentTemplateResponse( + COMPONENT_TEMPLATE_ONLY_REQUIRED_FIELDS + ); await act(async () => { testBed = setup({ - componentTemplateName: COMPONENT_TEMPLATE_REQUIRED_FIELDS.name, + componentTemplateName: COMPONENT_TEMPLATE_ONLY_REQUIRED_FIELDS.name, onClose: () => {}, }); }); @@ -123,7 +125,7 @@ describe('', () => { test('renders the details flyout', () => { const { exists, actions, component } = testBed; - // [Summary tab] Verify description list items do not display + // [Summary tab] Verify optional description list items do not display expect(exists('summaryTabContent.usedByTitle')).toBe(false); expect(exists('summaryTabContent.versionTitle')).toBe(false); expect(exists('summaryTabContent.metaTitle')).toBe(false); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts index 89a27f2de9b22..4288d3829cc20 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts @@ -4,32 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { act } from 'react-dom/test-utils'; - -import { BASE_PATH } from '../../../../../../../common'; -import { - registerTestBed, - TestBed, - TestBedConfig, - findTestSubject, - nextTick, -} from '../../../../../../../../../test_utils'; +import { registerTestBed, TestBed } from '../../../../../../../../../test_utils'; import { WithAppDependencies } from './setup_environment'; import { ComponentTemplateDetailsFlyout } from '../../../component_template_details'; -const getTestBedConfig = (props: Record) => { - const testBed: TestBedConfig = { - memoryRouter: { - wrapComponent: false, - }, - defaultProps: props, - }; - return testBed; -}; - -const initTestBed = (props: Record) => - registerTestBed(WithAppDependencies(ComponentTemplateDetailsFlyout), getTestBedConfig(props)); - export type ComponentTemplateDetailsTestBed = TestBed & { actions: ReturnType; }; From 39e18e4742cae7ea7d83f8114783345987bf0fa2 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 10 Jun 2020 11:16:06 -0400 Subject: [PATCH 07/11] remove unused appBasePath --- .../client_integration/helpers/setup_environment.tsx | 1 - .../component_templates/component_templates_context.tsx | 8 ++------ .../plugins/index_management/public/application/index.tsx | 3 +-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx index c0aeb70166b5b..5432d8e7c8c4f 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx @@ -23,7 +23,6 @@ const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); const appDependencies = { httpClient: (mockHttpClient as unknown) as HttpSetup, apiBasePath: API_BASE_PATH, - appBasePath: BASE_PATH, trackMetric: () => {}, docLinks: docLinksServiceMock.createStartContract(), toasts: notificationServiceMock.createSetupContract().toasts, diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_templates_context.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_templates_context.tsx index 6f5f5bdebd6d0..6d53fa6cd0282 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_templates_context.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_templates_context.tsx @@ -14,7 +14,6 @@ const ComponentTemplatesContext = createContext(undefined); interface Props { httpClient: HttpSetup; apiBasePath: string; - appBasePath: string; trackMetric: (type: 'loaded' | 'click' | 'count', eventName: string) => void; docLinks: DocLinksSetup; toasts: NotificationsSetup['toasts']; @@ -25,7 +24,6 @@ interface Context { documentation: ReturnType; trackMetric: (type: 'loaded' | 'click' | 'count', eventName: string) => void; toasts: NotificationsSetup['toasts']; - appBasePath: string; } export const ComponentTemplatesProvider = ({ @@ -35,7 +33,7 @@ export const ComponentTemplatesProvider = ({ value: Props; children: React.ReactNode; }) => { - const { httpClient, apiBasePath, trackMetric, docLinks, toasts, appBasePath } = value; + const { httpClient, apiBasePath, trackMetric, docLinks, toasts } = value; const useRequest = getUseRequest(httpClient); const sendRequest = getSendRequest(httpClient); @@ -44,9 +42,7 @@ export const ComponentTemplatesProvider = ({ const documentation = getDocumentation(docLinks); return ( - + {children} ); diff --git a/x-pack/plugins/index_management/public/application/index.tsx b/x-pack/plugins/index_management/public/application/index.tsx index 5d1096c9ee24e..ff54b4b1bfe35 100644 --- a/x-pack/plugins/index_management/public/application/index.tsx +++ b/x-pack/plugins/index_management/public/application/index.tsx @@ -10,7 +10,7 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { CoreStart } from '../../../../../src/core/public'; -import { API_BASE_PATH, BASE_PATH } from '../../common'; +import { API_BASE_PATH } from '../../common'; import { AppContextProvider, AppDependencies } from './app_context'; import { App } from './app'; @@ -32,7 +32,6 @@ export const renderApp = ( const componentTemplateProviderValues = { httpClient: services.httpService.httpClient, apiBasePath: API_BASE_PATH, - appBasePath: BASE_PATH, trackMetric: services.uiMetricService.trackMetric.bind(services.uiMetricService), docLinks, toasts: notifications.toasts, From 65b4c11f1c802039376dbbd7abc7b472f489feb4 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 10 Jun 2020 11:52:08 -0400 Subject: [PATCH 08/11] remove unused import --- .../__jest__/client_integration/helpers/setup_environment.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx index 5432d8e7c8c4f..1ca55d54617e9 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx @@ -9,7 +9,7 @@ import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; import { HttpSetup } from 'kibana/public'; -import { BASE_PATH, API_BASE_PATH } from '../../../../../../../common/constants'; +import { API_BASE_PATH } from '../../../../../../../common/constants'; import { notificationServiceMock, docLinksServiceMock, From 27ff24fa496a331a1e6d36e611ceaf6188fb8d8f Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Fri, 12 Jun 2020 14:53:06 -0400 Subject: [PATCH 09/11] move tab content to shared directory --- .../component_template_details.test.ts | 2 +- .../component_template_list.test.ts | 6 ++-- .../helpers/http_requests.ts | 8 ++--- .../component_template_details.tsx | 33 ++++++++++--------- .../manage_button.tsx | 2 +- .../{tab_content => }/tab_summary.tsx | 2 +- .../component_template_list.tsx | 11 +++---- .../component_template_list_container.tsx | 16 +++++++-- .../component_template_list/table.tsx | 2 +- .../components/component_templates/index.ts | 2 -- .../components/component_templates/lib/api.ts | 4 +-- .../component_templates/shared_imports.ts | 8 +++++ .../components/component_templates/types.ts | 17 ---------- .../components/details_panel}/index.ts | 1 - .../components/details_panel}/tab_aliases.tsx | 12 +++---- .../details_panel}/tab_mappings.tsx | 13 +++----- .../details_panel}/tab_settings.tsx | 13 +++----- .../components/shared/components/index.ts | 7 ++++ .../application/components/shared/index.ts | 7 ++++ 19 files changed, 83 insertions(+), 83 deletions(-) rename x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/{tab_content => }/tab_summary.tsx (98%) delete mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/types.ts rename x-pack/plugins/index_management/public/application/components/{component_templates/component_template_details/tab_content => shared/components/details_panel}/index.ts (89%) rename x-pack/plugins/index_management/public/application/components/{component_templates/component_template_details/tab_content => shared/components/details_panel}/tab_aliases.tsx (69%) rename x-pack/plugins/index_management/public/application/components/{component_templates/component_template_details/tab_content => shared/components/details_panel}/tab_mappings.tsx (69%) rename x-pack/plugins/index_management/public/application/components/{component_templates/component_template_details/tab_content => shared/components/details_panel}/tab_settings.tsx (69%) create mode 100644 x-pack/plugins/index_management/public/application/components/shared/components/index.ts create mode 100644 x-pack/plugins/index_management/public/application/components/shared/index.ts diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts index e28da86764afe..ba7e4a9547bf5 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts @@ -8,7 +8,7 @@ import { act } from 'react-dom/test-utils'; import { setupEnvironment, pageHelpers } from './helpers'; import { ComponentTemplateDetailsTestBed } from './helpers/component_template_details.helpers'; -import { ComponentTemplateDeserialized } from '../../types'; +import { ComponentTemplateDeserialized } from '../../shared_imports'; const { setup } = pageHelpers.componentTemplateDetails; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts index 830cc0ee6a980..73e1921fd5c3a 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts @@ -6,10 +6,12 @@ import { act } from 'react-dom/test-utils'; +import { ComponentTemplateListItem } from '../../shared_imports'; + import { setupEnvironment, pageHelpers } from './helpers'; import { ComponentTemplateListTestBed } from './helpers/component_template_list.helpers'; -import { API_BASE_PATH } from '../../../../../../common/constants'; -import { ComponentTemplateListItem } from '../../types'; + +const API_BASE_PATH = '/api/index_management'; const { setup } = pageHelpers.componentTemplateList; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts index f8cdad2291f48..de4fea83eb3e1 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts @@ -5,11 +5,9 @@ */ import sinon, { SinonFakeServer } from 'sinon'; -import { - API_BASE_PATH, - ComponentTemplateListItem, - ComponentTemplateDeserialized, -} from '../../../../../../../common'; +import { ComponentTemplateListItem, ComponentTemplateDeserialized } from '../../../shared_imports'; + +const API_BASE_PATH = '/api/index_management'; // Register helpers to mock HTTP Requests const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx index 3be7a6d829333..06307b6930db4 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx @@ -19,24 +19,12 @@ import { EuiCallOut, } from '@elastic/eui'; -import { SectionLoading } from '../shared_imports'; -import { ComponentTemplateDeserialized } from '../types'; +import { SectionLoading, TabSettings, TabAliases, TabMappings } from '../shared_imports'; import { useComponentTemplatesContext } from '../component_templates_context'; -import { TabSummary, TabSettings, TabAliases, TabMappings } from './tab_content'; +import { TabSummary } from './tab_summary'; import { ComponentTemplateTabs, TabType, Tab } from './tabs'; import { ManageButton, ManageAction } from './manage_button'; -const tabToComponentMap: { - [key: string]: React.FunctionComponent<{ - componentTemplateDetails: ComponentTemplateDeserialized; - }>; -} = { - [TabType.Summary]: TabSummary, - [TabType.Settings]: TabSettings, - [TabType.Mappings]: TabMappings, - [TabType.Aliases]: TabAliases, -}; - interface Props { componentTemplateName: string; onClose: () => void; @@ -85,7 +73,20 @@ export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ ); } else if (componentTemplateDetails) { - const TabContent = tabToComponentMap[activeTab]; + const { + template: { settings, mappings, aliases }, + } = componentTemplateDetails; + + const tabToComponentMap: { + [key: string]: React.ReactNode; + } = { + [TabType.Summary]: , + [TabType.Settings]: , + [TabType.Mappings]: , + [TabType.Aliases]: , + }; + + const tabContent = tabToComponentMap[activeTab]; content = ( <> @@ -93,7 +94,7 @@ export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ - + {tabContent} ); } diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx index a9bc7b988d464..e904b10592e77 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx @@ -13,7 +13,7 @@ import { EuiContextMenu, EuiContextMenuPanelItemDescriptor, } from '@elastic/eui'; -import { ComponentTemplateDeserialized } from '../types'; +import { ComponentTemplateDeserialized } from '../shared_imports'; export interface ManageAction { name: string; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_summary.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_summary.tsx similarity index 98% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_summary.tsx rename to x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_summary.tsx index d6eac4e5feb5a..401186f6c962e 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_summary.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_summary.tsx @@ -16,7 +16,7 @@ import { EuiSpacer, } from '@elastic/eui'; -import { ComponentTemplateDeserialized } from '../../types'; +import { ComponentTemplateDeserialized } from '../shared_imports'; interface Props { componentTemplateDetails: ComponentTemplateDeserialized; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx index 6b47a88bb5cc3..78cb60a220979 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx @@ -12,7 +12,7 @@ import { ScopedHistory } from 'kibana/public'; import { SectionLoading } from '../shared_imports'; import { UIM_COMPONENT_TEMPLATE_LIST_LOAD } from '../constants'; -import { ComponentTemplateDeserialized } from '../types'; +import { ComponentTemplateDeserialized } from '../shared_imports'; import { useComponentTemplatesContext } from '../component_templates_context'; import { ComponentTemplateDetailsFlyout } from '../component_template_details'; import { EmptyPrompt } from './empty_prompt'; @@ -20,14 +20,13 @@ import { ComponentTable } from './table'; import { LoadError } from './error'; import { ComponentTemplatesDeleteModal } from './delete_modal'; -interface MatchParams { +interface Props { componentTemplateName?: string; + history: RouteComponentProps['history']; } -export const ComponentTemplateList: React.FunctionComponent> = ({ - match: { - params: { componentTemplateName }, - }, +export const ComponentTemplateList: React.FunctionComponent = ({ + componentTemplateName, history, }) => { const { api, trackMetric } = useComponentTemplatesContext(); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list_container.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list_container.tsx index af8ab1b94c790..d0636da8cf93a 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list_container.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list_container.tsx @@ -5,16 +5,28 @@ */ import React from 'react'; +import { RouteComponentProps } from 'react-router-dom'; import { ComponentTemplatesAuthProvider } from './auth_provider'; import { ComponentTemplatesWithPrivileges } from './with_privileges'; import { ComponentTemplateList } from './component_template_list'; -export const ComponentTemplateListContainer: React.FunctionComponent = () => { +interface MatchParams { + componentTemplateName?: string; +} + +export const ComponentTemplateListContainer: React.FunctionComponent> = ({ + match: { + params: { componentTemplateName }, + }, + history, +}) => { return ( - + ); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx index e177dba680d6d..b67a249ae6976 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/table.tsx @@ -17,7 +17,7 @@ import { import { ScopedHistory } from 'kibana/public'; import { reactRouterNavigate } from '../../../../../../../../src/plugins/kibana_react/public'; -import { ComponentTemplateListItem } from '../types'; +import { ComponentTemplateListItem } from '../shared_imports'; import { UIM_COMPONENT_TEMPLATE_DETAILS } from '../constants'; import { useComponentTemplatesContext } from '../component_templates_context'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/index.ts b/x-pack/plugins/index_management/public/application/components/component_templates/index.ts index bc609cd77e05b..72e79a57ae413 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/index.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/index.ts @@ -9,5 +9,3 @@ export { ComponentTemplatesProvider } from './component_templates_context'; export { ComponentTemplateList } from './component_template_list'; export { ComponentTemplateDetailsFlyout } from './component_template_details'; - -export * from './types'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts b/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts index 975d9450a873a..4a8cf965adfb9 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ComponentTemplateListItem, ComponentTemplateDeserialized } from '../types'; -import { UseRequestHook, SendRequestHook } from './request'; +import { ComponentTemplateListItem, ComponentTemplateDeserialized } from '../shared_imports'; import { UIM_COMPONENT_TEMPLATE_DELETE_MANY, UIM_COMPONENT_TEMPLATE_DELETE } from '../constants'; +import { UseRequestHook, SendRequestHook } from './request'; export const getApi = ( useRequest: UseRequestHook, diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/shared_imports.ts b/x-pack/plugins/index_management/public/application/components/component_templates/shared_imports.ts index 049204f03c0c1..4e56f4a8c9818 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/shared_imports.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/shared_imports.ts @@ -19,3 +19,11 @@ export { useAuthorizationContext, NotAuthorizedSection, } from '../../../../../../../src/plugins/es_ui_shared/public'; + +export { TabMappings, TabSettings, TabAliases } from '../shared'; + +export { + ComponentTemplateSerialized, + ComponentTemplateDeserialized, + ComponentTemplateListItem, +} from '../../../../common'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/types.ts b/x-pack/plugins/index_management/public/application/components/component_templates/types.ts deleted file mode 100644 index 0aab3b6b0a94a..0000000000000 --- a/x-pack/plugins/index_management/public/application/components/component_templates/types.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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. - */ - -// Ideally, we shouldn't depend on anything in index management that is -// outside of the components_templates directory -// We could consider creating shared types or duplicating the types here if -// the component_templates app were to move outside of index management -import { - ComponentTemplateSerialized, - ComponentTemplateDeserialized, - ComponentTemplateListItem, -} from '../../../../common'; - -export { ComponentTemplateSerialized, ComponentTemplateDeserialized, ComponentTemplateListItem }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/index.ts b/x-pack/plugins/index_management/public/application/components/shared/components/details_panel/index.ts similarity index 89% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/index.ts rename to x-pack/plugins/index_management/public/application/components/shared/components/details_panel/index.ts index bfb5debcff59e..af5cd500a286a 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/index.ts +++ b/x-pack/plugins/index_management/public/application/components/shared/components/details_panel/index.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export { TabSummary } from './tab_summary'; export { TabAliases } from './tab_aliases'; export { TabMappings } from './tab_mappings'; export { TabSettings } from './tab_settings'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_aliases.tsx b/x-pack/plugins/index_management/public/application/components/shared/components/details_panel/tab_aliases.tsx similarity index 69% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_aliases.tsx rename to x-pack/plugins/index_management/public/application/components/shared/components/details_panel/tab_aliases.tsx index ec464f22c796f..bcf59fd13bad6 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_aliases.tsx +++ b/x-pack/plugins/index_management/public/application/components/shared/components/details_panel/tab_aliases.tsx @@ -8,17 +8,13 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCodeBlock, EuiCallOut } from '@elastic/eui'; -import { ComponentTemplateDeserialized } from '../../types'; +import { Aliases } from '../../../../../../common'; interface Props { - componentTemplateDetails: ComponentTemplateDeserialized; + aliases: Aliases | undefined; } -export const TabAliases: React.FunctionComponent = ({ componentTemplateDetails }) => { - const { - template: { aliases }, - } = componentTemplateDetails; - +export const TabAliases: React.FunctionComponent = ({ aliases }) => { if (aliases && Object.keys(aliases).length) { return (
@@ -31,7 +27,7 @@ export const TabAliases: React.FunctionComponent = ({ componentTemplateDe } diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_mappings.tsx b/x-pack/plugins/index_management/public/application/components/shared/components/details_panel/tab_mappings.tsx similarity index 69% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_mappings.tsx rename to x-pack/plugins/index_management/public/application/components/shared/components/details_panel/tab_mappings.tsx index 78d58bc7cd02a..3c3d88345e5a1 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_mappings.tsx +++ b/x-pack/plugins/index_management/public/application/components/shared/components/details_panel/tab_mappings.tsx @@ -7,18 +7,13 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCodeBlock, EuiCallOut } from '@elastic/eui'; - -import { ComponentTemplateDeserialized } from '../../types'; +import { Mappings } from '../../../../../../common'; interface Props { - componentTemplateDetails: ComponentTemplateDeserialized; + mappings: Mappings | undefined; } -export const TabMappings: React.FunctionComponent = ({ componentTemplateDetails }) => { - const { - template: { mappings }, - } = componentTemplateDetails; - +export const TabMappings: React.FunctionComponent = ({ mappings }) => { if (mappings && Object.keys(mappings).length) { return (
@@ -31,7 +26,7 @@ export const TabMappings: React.FunctionComponent = ({ componentTemplateD } diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_settings.tsx b/x-pack/plugins/index_management/public/application/components/shared/components/details_panel/tab_settings.tsx similarity index 69% rename from x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_settings.tsx rename to x-pack/plugins/index_management/public/application/components/shared/components/details_panel/tab_settings.tsx index 344ffa71ff0e3..6d5cf09588a1c 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/tab_content/tab_settings.tsx +++ b/x-pack/plugins/index_management/public/application/components/shared/components/details_panel/tab_settings.tsx @@ -7,18 +7,13 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCodeBlock, EuiCallOut } from '@elastic/eui'; - -import { ComponentTemplateDeserialized } from '../../types'; +import { IndexSettings } from '../../../../../../common'; interface Props { - componentTemplateDetails: ComponentTemplateDeserialized; + settings: IndexSettings | undefined; } -export const TabSettings: React.FunctionComponent = ({ componentTemplateDetails }) => { - const { - template: { settings }, - } = componentTemplateDetails; - +export const TabSettings: React.FunctionComponent = ({ settings }) => { if (settings && Object.keys(settings).length) { return (
@@ -31,7 +26,7 @@ export const TabSettings: React.FunctionComponent = ({ componentTemplateD } diff --git a/x-pack/plugins/index_management/public/application/components/shared/components/index.ts b/x-pack/plugins/index_management/public/application/components/shared/components/index.ts new file mode 100644 index 0000000000000..90d66bd1a5da4 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/shared/components/index.ts @@ -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 { TabAliases, TabMappings, TabSettings } from './details_panel'; diff --git a/x-pack/plugins/index_management/public/application/components/shared/index.ts b/x-pack/plugins/index_management/public/application/components/shared/index.ts new file mode 100644 index 0000000000000..e015ef72e244f --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/shared/index.ts @@ -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 { TabAliases, TabMappings, TabSettings } from './components'; From 1f485b642325b9ecaf4fb5e9ef7cf95146d38149 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Fri, 12 Jun 2020 15:12:37 -0400 Subject: [PATCH 10/11] cleanup --- .../client_integration/component_template_list.test.ts | 3 +-- .../__jest__/client_integration/helpers/constants.ts | 7 +++++++ .../__jest__/client_integration/helpers/http_requests.ts | 3 +-- .../client_integration/helpers/setup_environment.tsx | 5 +++-- 4 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/constants.ts diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts index 73e1921fd5c3a..86eb88017b77f 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts @@ -10,8 +10,7 @@ import { ComponentTemplateListItem } from '../../shared_imports'; import { setupEnvironment, pageHelpers } from './helpers'; import { ComponentTemplateListTestBed } from './helpers/component_template_list.helpers'; - -const API_BASE_PATH = '/api/index_management'; +import { API_BASE_PATH } from './helpers/constants'; const { setup } = pageHelpers.componentTemplateList; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/constants.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/constants.ts new file mode 100644 index 0000000000000..00b07fadd0c08 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/constants.ts @@ -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 const API_BASE_PATH = '/api/index_management'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts index de4fea83eb3e1..b7b674292dd98 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/http_requests.ts @@ -6,8 +6,7 @@ import sinon, { SinonFakeServer } from 'sinon'; import { ComponentTemplateListItem, ComponentTemplateDeserialized } from '../../../shared_imports'; - -const API_BASE_PATH = '/api/index_management'; +import { API_BASE_PATH } from './constants'; // Register helpers to mock HTTP Requests const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx index 1ca55d54617e9..a2194bbfa0186 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx @@ -9,15 +9,16 @@ import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; import { HttpSetup } from 'kibana/public'; -import { API_BASE_PATH } from '../../../../../../../common/constants'; import { notificationServiceMock, docLinksServiceMock, } from '../../../../../../../../../../src/core/public/mocks'; -import { init as initHttpRequests } from './http_requests'; import { ComponentTemplatesProvider } from '../../../component_templates_context'; +import { init as initHttpRequests } from './http_requests'; +import { API_BASE_PATH } from './constants'; + const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); const appDependencies = { From 7f02d729eadd00709023dfa9cc4e6468eef465be Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Tue, 16 Jun 2020 14:05:56 -0400 Subject: [PATCH 11/11] address review feedback --- .../component_template_details.test.ts | 12 ++++++++- .../component_template_details.helpers.ts | 9 ++++++- .../component_template_details.tsx | 16 +++++------- .../manage_button.tsx | 12 ++++++++- .../component_template_details/tabs.tsx | 26 +++++++++---------- .../component_template_list.tsx | 3 +-- 6 files changed, 50 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts index ba7e4a9547bf5..7c17dde119c42 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_details.test.ts @@ -182,11 +182,21 @@ describe('', () => { }); test('should render a footer with context menu', () => { - const { exists } = testBed; + const { exists, actions, component, find } = testBed; // Verify footer exists expect(exists('componentTemplateDetails.footer')).toBe(true); expect(exists('manageComponentTemplateButton')).toBe(true); + + // Click manage button and verify actions + act(() => { + actions.clickManageButton(); + }); + + component.update(); + + expect(exists('manageComponentTemplateContextMenu')).toBe(true); + expect(find('manageComponentTemplateContextMenu.action').length).toEqual(1); }); }); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts index 4288d3829cc20..25c2d654fd900 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_details.helpers.ts @@ -30,10 +30,15 @@ const createActions = (testBed: TestBed) = find('aliasesTab').simulate('click'); }; + const clickManageButton = () => { + find('manageComponentTemplateButton').simulate('click'); + }; + return { clickSettingsTab, clickAliasesTab, clickMappingsTab, + clickManageButton, }; }; @@ -76,4 +81,6 @@ export type ComponentTemplateDetailsTestSubjects = | 'noMappingsCallout' | 'settingsTabContent' | 'noSettingsCallout' - | 'manageComponentTemplateButton'; + | 'manageComponentTemplateButton' + | 'manageComponentTemplateContextMenu' + | 'manageComponentTemplateContextMenu.action'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx index 06307b6930db4..a8007c6363584 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx @@ -22,7 +22,7 @@ import { import { SectionLoading, TabSettings, TabAliases, TabMappings } from '../shared_imports'; import { useComponentTemplatesContext } from '../component_templates_context'; import { TabSummary } from './tab_summary'; -import { ComponentTemplateTabs, TabType, Tab } from './tabs'; +import { ComponentTemplateTabs, TabType } from './tabs'; import { ManageButton, ManageAction } from './manage_button'; interface Props { @@ -43,7 +43,7 @@ export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ componentTemplateName ); - const [activeTab, setActiveTab] = useState(TabType.Summary); + const [activeTab, setActiveTab] = useState('summary'); let content: React.ReactNode | undefined; @@ -77,13 +77,11 @@ export const ComponentTemplateDetailsFlyout: React.FunctionComponent = ({ template: { settings, mappings, aliases }, } = componentTemplateDetails; - const tabToComponentMap: { - [key: string]: React.ReactNode; - } = { - [TabType.Summary]: , - [TabType.Settings]: , - [TabType.Mappings]: , - [TabType.Aliases]: , + const tabToComponentMap: Record = { + summary: , + settings: , + mappings: , + aliases: , }; const tabContent = tabToComponentMap[activeTab]; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx index e904b10592e77..c3a4f9b4dce35 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/manage_button.tsx @@ -36,10 +36,18 @@ export const ManageButton: React.FunctionComponent = ({ const items: EuiContextMenuPanelItemDescriptor[] = actions.map( ({ name, icon, getIsDisabled, closePopoverOnClick, handleActionClick }) => { + const isDisabled = getIsDisabled ? getIsDisabled(componentTemplateDetails) : false; + return { name, icon, - disabled: getIsDisabled ? getIsDisabled(componentTemplateDetails) : false, + disabled: isDisabled, + toolTipContent: isDisabled ? ( + + ) : null, onClick: () => { handleActionClick(); @@ -47,6 +55,7 @@ export const ManageButton: React.FunctionComponent = ({ setIsPopOverOpen(false); } }, + 'data-test-subj': 'action', }; } ); @@ -77,6 +86,7 @@ export const ManageButton: React.FunctionComponent = ({ > void; + activeTab: TabType; } -interface Props { - setActiveTab: (id: Tab) => void; - activeTab: Tab; +interface Tab { + id: TabType; + name: string; } -const TABS = [ +const TABS: Tab[] = [ { - id: TabType.Summary, + id: 'summary', name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.summaryTabTitle', { defaultMessage: 'Summary', }), }, { - id: TabType.Settings, + id: 'settings', name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.settingsTabTitle', { defaultMessage: 'Settings', }), }, { - id: TabType.Mappings, + id: 'mappings', name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.mappingsTabTitle', { defaultMessage: 'Mappings', }), }, { - id: TabType.Aliases, + id: 'aliases', name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.aliasesTabTitle', { defaultMessage: 'Aliases', }), diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx index 78cb60a220979..05a5ed462d8f7 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx @@ -10,9 +10,8 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { ScopedHistory } from 'kibana/public'; -import { SectionLoading } from '../shared_imports'; +import { SectionLoading, ComponentTemplateDeserialized } from '../shared_imports'; import { UIM_COMPONENT_TEMPLATE_LIST_LOAD } from '../constants'; -import { ComponentTemplateDeserialized } from '../shared_imports'; import { useComponentTemplatesContext } from '../component_templates_context'; import { ComponentTemplateDetailsFlyout } from '../component_template_details'; import { EmptyPrompt } from './empty_prompt';