diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts index c8e58aa6875fc..a56d633217f96 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts @@ -100,9 +100,9 @@ const createActions = (testBed: TestBed) => { find('closeDetailsButton').simulate('click'); }; - const toggleViewItem = (view: 'managed' | 'cloudManaged' | 'system') => { + const toggleViewItem = (view: 'managed' | 'deprecated' | 'cloudManaged' | 'system') => { const { find, component } = testBed; - const views = ['managed', 'cloudManaged', 'system']; + const views = ['managed', 'deprecated', 'cloudManaged', 'system']; // First open the pop over act(() => { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts index be09ed36af8d3..f052317513194 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts @@ -111,6 +111,13 @@ describe('Index Templates tab', () => { type: 'system', }); + const deprecatedTemplate = fixtures.getTemplate({ + name: `.d${getRandomString()}`, + indexPatterns: ['template7Pattern1*'], + type: 'system', + deprecated: true, + }); + const template4 = fixtures.getTemplate({ name: `a${getRandomString()}`, indexPatterns: ['template4Pattern1*', 'template4Pattern2'], @@ -140,7 +147,7 @@ describe('Index Templates tab', () => { type: 'system', }); - const templates = [template1, template2, template3]; + const templates = [template1, template2, template3, deprecatedTemplate]; const legacyTemplates = [template4, template5, template6]; beforeEach(async () => { @@ -245,6 +252,35 @@ describe('Index Templates tab', () => { expect(updatedRows.length).toEqual(legacyTemplates.length); }); + test('should have a switch to view deprecated templates', async () => { + const { table, actions } = testBed; + const { tableCellsValues } = table.getMetaData('templateTable'); + + // None of the available templates should have the deprecated template + tableCellsValues.forEach((row) => { + expect( + removeWhiteSpaceOnArrayValues(row).every( + (cell) => !cell.includes(deprecatedTemplate.name) + ) + ).toBeTruthy(); + }); + + actions.toggleViewItem('system'); + actions.toggleViewItem('deprecated'); + + // After when all the tempaltes are available should have the deprecated template + const { tableCellsValues: updatedTableCellsValues } = table.getMetaData('templateTable'); + + // Find the row that has the deprecated template + const tableCellsWithDeprecatedTemplate = updatedTableCellsValues.filter((row) => { + return removeWhiteSpaceOnArrayValues(row).some((cell) => + cell.includes(deprecatedTemplate.name) + ); + }); + // Assert that it has one row with the deprecated template + expect(tableCellsWithDeprecatedTemplate.length).toBe(1); + }); + test('each row should have a link to the template details panel', async () => { const { find, exists, actions, component } = testBed; diff --git a/x-pack/plugins/index_management/common/lib/component_template_serialization.test.ts b/x-pack/plugins/index_management/common/lib/component_template_serialization.test.ts index 981aa86ea1515..84af60a41e2f9 100644 --- a/x-pack/plugins/index_management/common/lib/component_template_serialization.test.ts +++ b/x-pack/plugins/index_management/common/lib/component_template_serialization.test.ts @@ -63,6 +63,7 @@ describe('Component template serialization', () => { ] ) ).toEqual({ + isDeprecated: false, name: 'my_component_template', version: 1, _meta: { diff --git a/x-pack/plugins/index_management/common/lib/component_template_serialization.ts b/x-pack/plugins/index_management/common/lib/component_template_serialization.ts index c9a272d2e98ee..bffa1a2ad2242 100644 --- a/x-pack/plugins/index_management/common/lib/component_template_serialization.ts +++ b/x-pack/plugins/index_management/common/lib/component_template_serialization.ts @@ -51,7 +51,7 @@ export function deserializeComponentTemplate( indexTemplatesEs: TemplateFromEs[] ) { const { name, component_template: componentTemplate } = componentTemplateEs; - const { template, _meta, version } = componentTemplate; + const { template, _meta, version, deprecated } = componentTemplate; const indexTemplatesToUsedBy = getIndexTemplatesToUsedBy(indexTemplatesEs); @@ -60,6 +60,7 @@ export function deserializeComponentTemplate( template, version, _meta, + isDeprecated: Boolean(deprecated === true), _kbnMeta: { usedBy: indexTemplatesToUsedBy[name] || [], isManaged: Boolean(_meta?.managed === true), @@ -74,13 +75,14 @@ export function deserializeComponentTemplateList( indexTemplatesEs: TemplateFromEs[] ) { const { name, component_template: componentTemplate } = componentTemplateEs; - const { template, _meta } = componentTemplate; + const { template, _meta, deprecated } = componentTemplate; const indexTemplatesToUsedBy = getIndexTemplatesToUsedBy(indexTemplatesEs); const componentTemplateListItem: ComponentTemplateListItem = { name, usedBy: indexTemplatesToUsedBy[name] || [], + isDeprecated: Boolean(deprecated === true), isManaged: Boolean(_meta?.managed === true), hasSettings: hasEntries(template.settings), hasMappings: hasEntries(template.mappings), diff --git a/x-pack/plugins/index_management/common/lib/template_serialization.ts b/x-pack/plugins/index_management/common/lib/template_serialization.ts index 8a38b40258dba..5ec150a85aa17 100644 --- a/x-pack/plugins/index_management/common/lib/template_serialization.ts +++ b/x-pack/plugins/index_management/common/lib/template_serialization.ts @@ -53,6 +53,7 @@ export function deserializeTemplate( _meta, composed_of: composedOf, data_stream: dataStream, + deprecated, allow_auto_create: allowAutoCreate, } = templateEs; const { settings } = template; @@ -78,6 +79,7 @@ export function deserializeTemplate( dataStream, allowAutoCreate, _meta, + deprecated, _kbnMeta: { type, hasDatastream: Boolean(dataStream), diff --git a/x-pack/plugins/index_management/common/types/component_templates.ts b/x-pack/plugins/index_management/common/types/component_templates.ts index 68c58aefc9d06..8eb39dec1da91 100644 --- a/x-pack/plugins/index_management/common/types/component_templates.ts +++ b/x-pack/plugins/index_management/common/types/component_templates.ts @@ -18,12 +18,14 @@ export interface ComponentTemplateSerialized { lifecycle?: DataStream['lifecycle']; }; version?: number; + deprecated?: boolean; _meta?: { [key: string]: any }; lifecycle?: DataRetention; } export interface ComponentTemplateDeserialized extends ComponentTemplateSerialized { name: string; + isDeprecated?: boolean; _kbnMeta: { usedBy: string[]; isManaged: boolean; @@ -42,6 +44,7 @@ export interface ComponentTemplateListItem { hasAliases: boolean; hasSettings: boolean; isManaged: boolean; + isDeprecated?: boolean; } export interface ComponentTemplateDatastreams { diff --git a/x-pack/plugins/index_management/common/types/templates.ts b/x-pack/plugins/index_management/common/types/templates.ts index 7d85bb4d20ae0..756d631202445 100644 --- a/x-pack/plugins/index_management/common/types/templates.ts +++ b/x-pack/plugins/index_management/common/types/templates.ts @@ -21,6 +21,7 @@ export interface TemplateSerialized { mappings?: Mappings; lifecycle?: DataStream['lifecycle']; }; + deprecated?: boolean; composed_of?: string[]; version?: number; priority?: number; @@ -51,6 +52,7 @@ export interface TemplateDeserialized { ilmPolicy?: { name: string; }; + deprecated?: boolean; _meta?: { [key: string]: any }; // Composable template only // Composable template only dataStream?: { @@ -85,6 +87,7 @@ export interface TemplateListItem { hasSettings: boolean; hasAliases: boolean; hasMappings: boolean; + deprecated?: boolean; ilmPolicy?: { name: string; }; @@ -106,6 +109,7 @@ export interface LegacyTemplateSerialized { version?: number; settings?: IndexSettings; aliases?: Aliases; + deprecated?: boolean; mappings?: Mappings; order?: number; } 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 501d14042def3..203f162bf3a47 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 @@ -15,6 +15,7 @@ const { setup } = pageHelpers.componentTemplateDetails; const COMPONENT_TEMPLATE: ComponentTemplateDeserialized = { name: 'comp-1', + isDeprecated: true, template: { mappings: { properties: { ip_address: { type: 'ip' } } }, aliases: { mydata: {} }, @@ -62,6 +63,9 @@ describe('', () => { // Verify footer does not display since "actions" prop was not provided expect(exists('footer')).toBe(false); + // Verify the deprecated badge is displayed + expect(exists('deprecatedComponentTemplateBadge')).toBe(true); + // Verify tabs exist expect(exists('settingsTab')).toBe(true); expect(exists('mappingsTab')).toBe(true); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_edit.test.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_edit.test.tsx index 7c6fa35fbec4f..d113c66302ecd 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_edit.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_edit.test.tsx @@ -74,6 +74,7 @@ describe('', () => { const COMPONENT_TEMPLATE_NAME = 'comp-1'; const COMPONENT_TEMPLATE_TO_EDIT = { name: COMPONENT_TEMPLATE_NAME, + isDeprecated: true, template: { settings: { number_of_shards: 1 }, }, @@ -106,6 +107,7 @@ describe('', () => { const { exists, find } = testBed; expect(exists('pageTitle')).toBe(true); + expect(exists('deprecatedTemplateCallout')).toBe(true); expect(find('pageTitle').text()).toEqual( `Edit component template '${COMPONENT_TEMPLATE_NAME}'` ); 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 d0325dfb4a177..c4595998bcd20 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 @@ -43,6 +43,7 @@ describe('', () => { hasSettings: true, usedBy: [], isManaged: false, + isDeprecated: false, }; const componentTemplate2: ComponentTemplateListItem = { @@ -52,6 +53,7 @@ describe('', () => { hasSettings: true, usedBy: ['test_index_template_1'], isManaged: false, + isDeprecated: false, }; const componentTemplate3: ComponentTemplateListItem = { @@ -61,6 +63,7 @@ describe('', () => { hasSettings: true, usedBy: ['test_index_template_1', 'test_index_template_2'], isManaged: false, + isDeprecated: true, }; const componentTemplates = [componentTemplate1, componentTemplate2, componentTemplate3]; @@ -89,7 +92,7 @@ describe('', () => { const { tableCellsValues: ascTableCellsValues } = table.getMetaData('componentTemplatesTable'); const ascUsageCountValues = ascTableCellsValues.map((row) => row[2]); - expect(ascUsageCountValues).toEqual(['Not in use', '1', '2']); + expect(ascUsageCountValues).toEqual(['Not in use', '1']); // Sort descending await actions.clickTableColumnSortButton(1); @@ -97,7 +100,24 @@ describe('', () => { const { tableCellsValues: descTableCellsValues } = table.getMetaData('componentTemplatesTable'); const descUsageCountValues = descTableCellsValues.map((row) => row[2]); - expect(descUsageCountValues).toEqual(['2', '1', 'Not in use']); + expect(descUsageCountValues).toEqual(['1', 'Not in use']); + }); + + test('Hides deprecated component templates by default', async () => { + const { component, find } = testBed; + + // Initially the switch is off so we should not see any deprecated component templates + let deprecatedList = find('deprecatedComponentTemplateBadge'); + expect(deprecatedList.length).toBe(0); + + testBed.find('componentTemplatesFiltersButton').simulate('click'); + testBed.find('componentTemplates--deprecatedFilter').simulate('click'); + + component.update(); + + // Now we should see all deprecated component templates + deprecatedList = find('deprecatedComponentTemplateBadge'); + expect(deprecatedList.length).toBe(1); }); test('should reload the component templates data', async () => { 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 44a78e0d0666f..98d9003dc307d 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 @@ -86,6 +86,7 @@ export type ComponentTemplateDetailsTestSubjects = | 'noMappingsCallout' | 'settingsTabContent' | 'noSettingsCallout' + | 'deprecatedComponentTemplateBadge' | 'manageComponentTemplateButton' | 'manageComponentTemplateContextMenu' | 'manageComponentTemplateContextMenu.action'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_form.helpers.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_form.helpers.ts index d809bb230ffaa..03aff69a548af 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_form.helpers.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_form.helpers.ts @@ -183,6 +183,7 @@ export type ComponentTemplateFormTestSubjects = | 'stepReview.summaryTab' | 'stepReview.requestTab' | 'valueDataRetentionField' + | 'deprecatedTemplateCallout' | 'dataRetentionToggle.input' | 'versionField' | 'aliasesEditor' diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts index a7087b5b45100..1bd0152c86d40 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/component_template_list.helpers.ts @@ -104,4 +104,7 @@ export type ComponentTemplateTestSubjects = | 'sectionLoading' | 'componentTemplatesLoadError' | 'deleteComponentTemplateButton' - | 'reloadButton'; + | 'deprecatedComponentTemplateBadge' + | 'reloadButton' + | 'componentTemplatesFiltersButton' + | 'componentTemplates--deprecatedFilter'; 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 51d98ea2ea1c8..3f053b9aa3fd0 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 @@ -29,6 +29,7 @@ import { attemptToURIDecode, } from '../shared_imports'; import { useComponentTemplatesContext } from '../component_templates_context'; +import { DeprecatedBadge } from '../components'; import { TabSummary } from './tab_summary'; import { ComponentTemplateTabs, TabType } from './tabs'; import { ManageButton, ManageAction } from './manage_button'; @@ -120,6 +121,9 @@ export const ComponentTemplateDetailsFlyoutContent: React.FunctionComponent @@ -132,7 +136,14 @@ export const ComponentTemplateDetailsFlyoutContent: React.FunctionComponent - {componentTemplateDetails?._kbnMeta.isManaged ? ( + {isDeprecated && ( + + {' '} + + + )} + + {isManaged && ( {' '} @@ -142,7 +153,7 @@ export const ComponentTemplateDetailsFlyoutContent: React.FunctionComponent - ) : null} + )} 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 b8b371f6e4e01..f4d9c55407fd9 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 @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FunctionComponent, useState } from 'react'; +import React, { FunctionComponent, useState, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { METRIC_TYPE } from '@kbn/analytics'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -17,12 +17,37 @@ import { EuiIcon, EuiLink, EuiBadge, + EuiPopover, + EuiFilterGroup, + EuiSelectable, + EuiFilterButton, + EuiSelectableOption, } from '@elastic/eui'; import { ScopedHistory } from '@kbn/core/public'; import { ComponentTemplateListItem, reactRouterNavigate } from '../shared_imports'; import { UIM_COMPONENT_TEMPLATE_DETAILS } from '../constants'; import { useComponentTemplatesContext } from '../component_templates_context'; +import { DeprecatedBadge } from '../components'; + +const inUseFilterLabel = i18n.translate( + 'xpack.idxMgmt.componentTemplatesList.table.inUseFilterLabel', + { + defaultMessage: 'In use', + } +); +const managedFilterLabel = i18n.translate( + 'xpack.idxMgmt.componentTemplatesList.table.managedFilterLabel', + { + defaultMessage: 'Managed', + } +); +const deprecatedFilterLabel = i18n.translate( + 'xpack.idxMgmt.componentTemplatesList.table.deprecatedFilterLabel', + { + defaultMessage: 'Deprecated', + } +); export interface Props { componentTemplates: ComponentTemplateListItem[]; @@ -43,8 +68,64 @@ export const ComponentTable: FunctionComponent = ({ }) => { const { trackMetric } = useComponentTemplatesContext(); + // By default, we want to show all the component templates that are not deprecated. + const [filterOptions, setFilterOptions] = useState([ + { key: 'inUse', label: inUseFilterLabel, 'data-test-subj': 'componentTemplates--inUseFilter' }, + { + key: 'managed', + label: managedFilterLabel, + 'data-test-subj': 'componentTemplates--managedFilter', + }, + { + key: 'deprecated', + label: deprecatedFilterLabel, + 'data-test-subj': 'componentTemplates--deprecatedFilter', + checked: 'off', + }, + ]); + const [selection, setSelection] = useState([]); + const filteredComponentTemplates = useMemo(() => { + const inUseFilter = filterOptions.find(({ key }) => key === 'inUse')?.checked; + const managedFilter = filterOptions.find(({ key }) => key === 'managed')?.checked; + const deprecatedFilter = filterOptions.find(({ key }) => key === 'deprecated')?.checked; + return (componentTemplates || []).filter((component) => { + return !( + (deprecatedFilter === 'off' && component.isDeprecated) || + (deprecatedFilter === 'on' && !component.isDeprecated) || + (managedFilter === 'off' && component.isManaged) || + (managedFilter === 'on' && !component.isManaged) || + (inUseFilter === 'off' && component.usedBy.length >= 1) || + (inUseFilter === 'on' && component.usedBy.length === 0) + ); + }); + }, [componentTemplates, filterOptions]); + + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const onButtonClick = () => { + setIsPopoverOpen(!isPopoverOpen); + }; + const closePopover = () => { + setIsPopoverOpen(false); + }; + const button = ( + item.checked !== 'off').length} + hasActiveFilters={!!filterOptions.find((item) => item.checked === 'on')} + numActiveFilters={filterOptions.filter((item) => item.checked === 'on').length} + > + {i18n.translate('xpack.idxMgmt.componentTemplatesList.table.filtersButtonLabel', { + defaultMessage: 'Filters', + })} + + ); + const tableProps: EuiInMemoryTableProps = { tableLayout: 'auto', itemId: 'name', @@ -110,37 +191,33 @@ export const ComponentTable: FunctionComponent = ({ }, filters: [ { - type: 'is', - field: 'isManaged', - name: i18n.translate('xpack.idxMgmt.componentTemplatesList.table.isManagedFilterLabel', { - defaultMessage: 'Managed', - }), - }, - { - type: 'field_value_toggle_group', - field: 'usedBy.length', - items: [ - { - value: 1, - name: i18n.translate( - 'xpack.idxMgmt.componentTemplatesList.table.inUseFilterOptionLabel', - { - defaultMessage: 'In use', - } - ), - operator: 'gte', - }, - { - value: 0, - name: i18n.translate( - 'xpack.idxMgmt.componentTemplatesList.table.notInUseFilterOptionLabel', - { - defaultMessage: 'Not in use', - } - ), - operator: 'eq', - }, - ], + type: 'custom_component', + component: () => { + return ( + + + + {(list) =>
{list}
} +
+
+
+ ); + }, }, ], }, @@ -170,6 +247,12 @@ export const ComponentTable: FunctionComponent = ({ > {name} + {item.isDeprecated && ( + <> +   + + + )} {item.isManaged && ( <> {' '} @@ -294,7 +377,7 @@ export const ComponentTable: FunctionComponent = ({ ], }, ], - items: componentTemplates ?? [], + items: filteredComponentTemplates, }; return ; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx index 334a8295d9c2e..220acb8121212 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx @@ -8,7 +8,7 @@ import React, { useState, useEffect, useMemo } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiPageSection, EuiPageHeader, EuiSpacer } from '@elastic/eui'; +import { EuiPageSection, EuiPageHeader, EuiSpacer, EuiCallOut } from '@elastic/eui'; import { breadcrumbService, IndexManagementBreadcrumb } from '../../../../services/breadcrumbs'; import { useComponentTemplatesContext } from '../../component_templates_context'; @@ -125,6 +125,28 @@ export const ComponentTemplateEdit: React.FunctionComponent + {componentTemplate?.isDeprecated && ( + <> + + } + iconType="warning" + color="warning" + data-test-subj="deprecatedTemplateCallout" + > + + + + + )} + { + return ( + + + {i18n.translate('xpack.idxMgmt.componentTemplate.deprecatedTemplateBadgeText', { + defaultMessage: 'Deprecated', + })} + + + ); +}; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/components/index.ts b/x-pack/plugins/index_management/public/application/components/component_templates/components/index.ts new file mode 100644 index 0000000000000..463da26756d70 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/component_templates/components/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { DeprecatedBadge } from './deprecated_badge'; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/components/index.ts b/x-pack/plugins/index_management/public/application/sections/home/template_list/components/index.ts index 8b756be535ed2..af90df8cd113c 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/components/index.ts +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/components/index.ts @@ -6,3 +6,4 @@ */ export { TemplateTypeIndicator } from './template_type_indicator'; +export { TemplateDeprecatedBadge } from './template_deprecated_badge'; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/components/template_deprecated_badge.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/components/template_deprecated_badge.tsx new file mode 100644 index 0000000000000..bc8a2416d155b --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/components/template_deprecated_badge.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiToolTip, EuiBadge } from '@elastic/eui'; + +export const TemplateDeprecatedBadge = () => { + return ( + + + {i18n.translate('xpack.idxMgmt.templateList.table.deprecatedTemplateBadgeText', { + defaultMessage: 'Deprecated', + })} + + + ); +}; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx index 4f00409d2c3cf..d2156d1aa958e 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx @@ -38,7 +38,7 @@ import { TemplateDeleteModal, SectionError, Error } from '../../../../components import { useLoadIndexTemplate } from '../../../../services/api'; import { useServices } from '../../../../app_context'; import { TabAliases, TabMappings, TabSettings } from '../../../../components/shared'; -import { TemplateTypeIndicator } from '../components'; +import { TemplateTypeIndicator, TemplateDeprecatedBadge } from '../components'; import { TabSummary, TabPreview } from './tabs'; const SUMMARY_TAB_ID = 'summary'; @@ -120,6 +120,12 @@ export const TemplateDetailsContent = ({ {templateName} {templateDetails && ( <> + {templateDetails.deprecated && ( + <> +   + + + )}   diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx index 53292944cf158..322d2075adb60 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx @@ -48,16 +48,22 @@ import { TemplateTable } from './template_table'; import { TemplateDetails } from './template_details'; import { LegacyTemplateTable } from './legacy_templates/template_table'; -type FilterName = 'managed' | 'cloudManaged' | 'system'; +type FilterName = 'managed' | 'deprecated' | 'cloudManaged' | 'system'; interface MatchParams { templateName?: string; } function filterTemplates(templates: TemplateListItem[], types: string[]): TemplateListItem[] { return templates.filter((template) => { + // Exclude deprecated templates by default, unless 'deprecated' is specified in types + if (template.deprecated && !types.includes('deprecated')) { + return false; + } + if (template._kbnMeta.type === 'default') { return true; } + return types.includes(template._kbnMeta.type); }); } @@ -92,6 +98,12 @@ export const TemplateList: React.FunctionComponent = ({ > {name} {' '} + {item.deprecated && ( + <> +   + + + )} +   ); diff --git a/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx b/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx index 9c68d602e4e02..3dd8cac943c0e 100644 --- a/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx +++ b/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx @@ -70,6 +70,7 @@ export const TemplateEdit: React.FunctionComponent )} + {isDeprecatedTemplate && ( + <> + + } + iconType="warning" + color="warning" + data-test-subj="deprecatedIndexTemplateCallout" + > + + + + + )}