From 94a42b71b3004b365eb7434db1fe061bd75c44a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Tue, 10 Nov 2020 11:09:37 +0100 Subject: [PATCH] Fix ilm navigation (#81664) * Fix edit policy page navigation * Fix edit policy page navigation * Add links to PR for explanation * Added more tests and linked to a github issue about navigation issues * Fix decoding function for undefined values * Fix type check issues * Renamed dollar sign to percent sign, added a method for (double) encoded paths and better description in test names * Deleted Index Management from required bundles in ILM * Fixed merge conflicts * Revert "Deleted Index Management from required bundles in ILM" This reverts commit 5a735dfe Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../public/url/attempt_to_uri_decode.test.ts | 49 +++- .../public/url/attempt_to_uri_decode.ts | 8 +- .../client_integration/app/app.helpers.tsx | 74 +++++ .../client_integration/app/app.test.ts | 252 ++++++++++++++++++ .../edit_policy/constants.ts | 20 ++ .../edit_policy/edit_policy.test.ts | 3 +- .../client_integration/helpers/index.ts | 3 + .../public/application/app.tsx | 40 +-- .../public/application/index.tsx | 8 +- .../edit_policy/edit_policy.container.tsx | 6 +- .../sections/edit_policy/edit_policy.tsx | 2 +- .../public/shared_imports.ts | 2 + .../component_template_details.tsx | 2 +- .../component_template_list.tsx | 6 +- .../component_template_clone.tsx | 2 +- .../component_template_edit.tsx | 2 +- .../data_stream_list/data_stream_list.tsx | 2 +- .../home/template_list/template_list.tsx | 2 +- .../template_clone/template_clone.tsx | 2 +- .../sections/template_edit/template_edit.tsx | 2 +- .../pipelines_clone/pipelines_clone.tsx | 2 +- .../pipelines_edit/pipelines_edit.tsx | 2 +- 22 files changed, 448 insertions(+), 43 deletions(-) create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts diff --git a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts index 15750c7667800..6654611faa18b 100644 --- a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts +++ b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts @@ -19,14 +19,51 @@ import { attemptToURIDecode } from './attempt_to_uri_decode'; +// this function doesn't work for % with other special chars or sequence %25 +// known issue https://github.com/elastic/kibana/issues/82440 test('decodes an encoded string', () => { - const encodedString = 'test%3F'; - expect(attemptToURIDecode(encodedString)).toBe('test?'); + const originalName = 'test;,/?:@&=+$#'; + const encodedName = encodeURIComponent(originalName); + // react router v5 automatically decodes route match params + const reactRouterDecoded = decodeURI(encodedName); + + expect(attemptToURIDecode(encodedName)).toBe(originalName); + expect(attemptToURIDecode(reactRouterDecoded)).toBe(originalName); }); -// react router partially decodes %25 sequence to % in match params -// https://github.com/elastic/kibana/pull/81664 test('ignores the error if a string is already decoded', () => { - const decodedString = 'test%'; - expect(attemptToURIDecode(decodedString)).toBe(decodedString); + const originalName = 'test%'; + + const encodedName = encodeURIComponent(originalName); + // react router v5 automatically decodes route match params + const reactRouterDecoded = decodeURI(encodedName); + + expect(attemptToURIDecode(encodedName)).toBe(originalName); + expect(attemptToURIDecode(reactRouterDecoded)).toBe(originalName); +}); + +test('returns wrong decoded value for %25 sequence', () => { + const originalName = 'test%25'; + + const encodedName = encodeURIComponent(originalName); + // react router v5 automatically decodes route match params + const reactRouterDecoded = decodeURI(encodedName); + + expect(attemptToURIDecode(encodedName)).toBe(originalName); + expect(attemptToURIDecode(reactRouterDecoded)).not.toBe(originalName); +}); + +test('returns wrong decoded value for % with other escaped characters', () => { + const originalName = 'test%?#'; + + const encodedName = encodeURIComponent(originalName); + // react router v5 automatically decodes route match params + const reactRouterDecoded = decodeURI(encodedName); + + expect(attemptToURIDecode(encodedName)).toBe(originalName); + expect(attemptToURIDecode(reactRouterDecoded)).not.toBe(originalName); +}); + +test("doesn't convert undefined to a string", () => { + expect(attemptToURIDecode(undefined)).toBeUndefined(); }); diff --git a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts index 65444b83f77bb..37e4761106e44 100644 --- a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts +++ b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts @@ -19,12 +19,14 @@ /* * Use this function with any match params coming from react router to safely decode values. - * https://github.com/elastic/kibana/pull/81664 + * After an update to react router v6, this functions should be deprecated. + * Known issue for navigation with special characters in paths + * https://github.com/elastic/kibana/issues/82440 */ -export const attemptToURIDecode = (value: string) => { +export const attemptToURIDecode = (value?: string): string | undefined => { let result = value; try { - result = decodeURIComponent(value); + result = value ? decodeURIComponent(value) : value; } catch (e) { // do nothing } diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx new file mode 100644 index 0000000000000..de7242a6c5ddf --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx @@ -0,0 +1,74 @@ +/* + * 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 { act } from 'react-dom/test-utils'; +import { registerTestBed, TestBed, TestBedConfig } from '../../../../../test_utils'; +import { App } from '../../../public/application/app'; +import { TestSubjects } from '../helpers'; +import { createBreadcrumbsMock } from '../../../public/application/services/breadcrumbs.mock'; +import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public/context'; + +const breadcrumbService = createBreadcrumbsMock(); + +const AppWithContext = (props: any) => { + return ( + + + + ); +}; + +const getTestBedConfig = (initialEntries: string[]): TestBedConfig => ({ + memoryRouter: { + initialEntries, + }, + defaultProps: { + getUrlForApp: () => {}, + navigateToApp: () => {}, + }, +}); + +const initTestBed = (initialEntries: string[]) => + registerTestBed(AppWithContext, getTestBedConfig(initialEntries))(); + +export interface AppTestBed extends TestBed { + actions: { + clickPolicyNameLink: () => void; + clickCreatePolicyButton: () => void; + }; +} + +export const setup = async (initialEntries: string[]): Promise => { + const testBed = await initTestBed(initialEntries); + + const clickPolicyNameLink = async () => { + const { component, find } = testBed; + await act(async () => { + find('policyTablePolicyNameLink').simulate('click', { button: 0 }); + }); + component.update(); + }; + + const clickCreatePolicyButton = async () => { + const { component, find } = testBed; + await act(async () => { + find('createPolicyButton').simulate('click', { button: 0 }); + }); + component.update(); + }; + + return { + ...testBed, + actions: { clickPolicyNameLink, clickCreatePolicyButton }, + }; +}; + +export const getEncodedPolicyEditPath = (policyName: string): string => + `/policies/edit/${encodeURIComponent(policyName)}`; + +export const getDoubleEncodedPolicyEditPath = (policyName: string): string => + encodeURI(getEncodedPolicyEditPath(policyName)); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts new file mode 100644 index 0000000000000..9052cf2847baa --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts @@ -0,0 +1,252 @@ +/* + * 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 { + AppTestBed, + getDoubleEncodedPolicyEditPath, + getEncodedPolicyEditPath, + setup, +} from './app.helpers'; +import { setupEnvironment } from '../helpers/setup_environment'; +import { getDefaultHotPhasePolicy, POLICY_NAME } from '../edit_policy/constants'; +import { act } from 'react-dom/test-utils'; + +const SPECIAL_CHARS_NAME = 'test?#$+=&@:'; +const PERCENT_SIGN_NAME = 'test%'; +// navigation doesn't work for % with other special chars or sequence %25 +// known issue https://github.com/elastic/kibana/issues/82440 +const PERCENT_SIGN_WITH_OTHER_CHARS_NAME = 'test%#'; +const PERCENT_SIGN_25_SEQUENCE = 'test%25'; + +window.scrollTo = jest.fn(); + +describe('', () => { + let testBed: AppTestBed; + const { server, httpRequestsMockHelpers } = setupEnvironment(); + afterAll(() => { + server.restore(); + }); + + describe('new policy creation', () => { + test('when there are no policies', async () => { + httpRequestsMockHelpers.setLoadPolicies([]); + await act(async () => { + testBed = await setup(['/']); + }); + + const { component, actions } = testBed; + component.update(); + + await actions.clickCreatePolicyButton(); + component.update(); + + expect(testBed.find('policyTitle').text()).toBe(`Create an index lifecycle policy`); + expect(testBed.find('policyNameField').props().value).toBe(''); + }); + + test('when there are policies', async () => { + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(POLICY_NAME)]); + await act(async () => { + testBed = await setup(['/']); + }); + + const { component, actions } = testBed; + component.update(); + + await actions.clickCreatePolicyButton(); + component.update(); + + expect(testBed.find('policyTitle').text()).toBe(`Create an index lifecycle policy`); + expect(testBed.find('policyNameField').props().value).toBe(''); + }); + }); + + describe('navigation with special characters', () => { + beforeAll(async () => { + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(SPECIAL_CHARS_NAME)]); + }); + + test('clicking policy name in the table works', async () => { + await act(async () => { + testBed = await setup(['/']); + }); + + const { component, actions } = testBed; + component.update(); + + await actions.clickPolicyNameLink(); + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` + ); + }); + + test('loading edit policy page url works', async () => { + await act(async () => { + testBed = await setup([getEncodedPolicyEditPath(SPECIAL_CHARS_NAME)]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` + ); + }); + + // using double encoding to counteract react-router's v5 internal decodeURI call + // when those links are open in a new tab, address bar contains double encoded url + test('loading edit policy page url with double encoding works', async () => { + await act(async () => { + testBed = await setup([getDoubleEncodedPolicyEditPath(SPECIAL_CHARS_NAME)]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` + ); + }); + }); + + describe('navigation with percent sign', () => { + beforeAll(async () => { + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(PERCENT_SIGN_NAME)]); + }); + + test('loading edit policy page url works', async () => { + await act(async () => { + testBed = await setup([getEncodedPolicyEditPath(PERCENT_SIGN_NAME)]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${PERCENT_SIGN_NAME}` + ); + }); + + test('loading edit policy page url with double encoding works', async () => { + await act(async () => { + testBed = await setup([getDoubleEncodedPolicyEditPath(PERCENT_SIGN_NAME)]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${PERCENT_SIGN_NAME}` + ); + }); + }); + + describe('navigation with percent sign with other special characters', () => { + beforeAll(async () => { + httpRequestsMockHelpers.setLoadPolicies([ + getDefaultHotPhasePolicy(PERCENT_SIGN_WITH_OTHER_CHARS_NAME), + ]); + }); + + test('clicking policy name in the table works', async () => { + await act(async () => { + testBed = await setup(['/']); + }); + + const { component, actions } = testBed; + component.update(); + + await actions.clickPolicyNameLink(); + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` + ); + }); + + test("loading edit policy page url doesn't work", async () => { + await act(async () => { + testBed = await setup([getEncodedPolicyEditPath(PERCENT_SIGN_WITH_OTHER_CHARS_NAME)]); + }); + + const { component } = testBed; + component.update(); + + // known issue https://github.com/elastic/kibana/issues/82440 + expect(testBed.find('policyTitle').text()).not.toBe( + `Edit index lifecycle policy ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` + ); + }); + + // using double encoding to counteract react-router's v5 internal decodeURI call + // when those links are open in a new tab, address bar contains double encoded url + test('loading edit policy page url with double encoding works', async () => { + await act(async () => { + testBed = await setup([getDoubleEncodedPolicyEditPath(PERCENT_SIGN_WITH_OTHER_CHARS_NAME)]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` + ); + }); + }); + + describe('navigation with %25 sequence', () => { + beforeAll(async () => { + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(PERCENT_SIGN_25_SEQUENCE)]); + }); + + test('clicking policy name in the table works correctly', async () => { + await act(async () => { + testBed = await setup(['/']); + }); + + const { component, actions } = testBed; + component.update(); + + await actions.clickPolicyNameLink(); + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${PERCENT_SIGN_25_SEQUENCE}` + ); + }); + + test("loading edit policy page url doesn't work", async () => { + await act(async () => { + testBed = await setup([getEncodedPolicyEditPath(PERCENT_SIGN_25_SEQUENCE)]); + }); + + const { component } = testBed; + component.update(); + + // known issue https://github.com/elastic/kibana/issues/82440 + expect(testBed.find('policyTitle').text()).not.toBe( + `Edit index lifecycle policy ${PERCENT_SIGN_25_SEQUENCE}` + ); + }); + + // using double encoding to counteract react-router's v5 internal decodeURI call + // when those links are open in a new tab, address bar contains double encoded url + test('loading edit policy page url with double encoding works', async () => { + await act(async () => { + testBed = await setup([getDoubleEncodedPolicyEditPath(PERCENT_SIGN_25_SEQUENCE)]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${PERCENT_SIGN_25_SEQUENCE}` + ); + }); + }); +}); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts index 3d430cf31621e..00c7d705c1f44 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts @@ -121,6 +121,26 @@ export const DELETE_PHASE_POLICY: PolicyFromES = { name: POLICY_NAME, }; +export const getDefaultHotPhasePolicy = (policyName: string): PolicyFromES => ({ + version: 1, + modified_date: Date.now().toString(), + policy: { + name: policyName, + phases: { + hot: { + min_age: '0ms', + actions: { + rollover: { + max_age: '30d', + max_size: '50gb', + }, + }, + }, + }, + }, + name: policyName, +}); + export const POLICY_WITH_NODE_ATTR_AND_OFF_ALLOCATION: PolicyFromES = { version: 1, modified_date: Date.now().toString(), diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts index 4ee67d1ed8a19..c91ee3e2a1c06 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts @@ -19,6 +19,7 @@ import { POLICY_WITH_INCLUDE_EXCLUDE, POLICY_WITH_NODE_ATTR_AND_OFF_ALLOCATION, POLICY_WITH_NODE_ROLE_ALLOCATION, + getDefaultHotPhasePolicy, } from './constants'; window.scrollTo = jest.fn(); @@ -33,7 +34,7 @@ describe('', () => { describe('hot phase', () => { describe('serialization', () => { beforeEach(async () => { - httpRequestsMockHelpers.setLoadPolicies([DEFAULT_POLICY]); + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy('my_policy')]); httpRequestsMockHelpers.setLoadSnapshotPolicies([]); await act(async () => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts index e8ebc2963d16a..aff9151da61f9 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts @@ -17,5 +17,8 @@ export type TestSubjects = | 'hot-selectedMaxDocuments' | 'hot-selectedMaxAge' | 'hot-selectedMaxAgeUnits' + | 'policyTablePolicyNameLink' + | 'policyTitle' + | 'createPolicyButton' | 'freezeSwitch' | string; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/app.tsx b/x-pack/plugins/index_lifecycle_management/public/application/app.tsx index 856981fe5c4f9..20185b02064bc 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/app.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/app.tsx @@ -15,7 +15,7 @@ import { PolicyTable } from './sections/policy_table'; import { trackUiMetric } from './services/ui_metric'; import { ROUTES } from './services/navigation'; -export const App = ({ +export const AppWithRouter = ({ history, navigateToApp, getUrlForApp, @@ -23,23 +23,33 @@ export const App = ({ history: ScopedHistory; navigateToApp: ApplicationStart['navigateToApp']; getUrlForApp: ApplicationStart['getUrlForApp']; +}) => ( + + + +); + +export const App = ({ + navigateToApp, + getUrlForApp, +}: { + navigateToApp: ApplicationStart['navigateToApp']; + getUrlForApp: ApplicationStart['getUrlForApp']; }) => { useEffect(() => trackUiMetric(METRIC_TYPE.LOADED, UIM_APP_LOAD), []); return ( - - - - } - /> - } - /> - - + + + } + /> + } + /> + ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/index.tsx b/x-pack/plugins/index_lifecycle_management/public/application/index.tsx index 3d4cc7dbbd1d4..bb1a4810ba2d2 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/index.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/index.tsx @@ -12,7 +12,7 @@ import { CloudSetup } from '../../../cloud/public'; import { KibanaContextProvider } from '../shared_imports'; -import { App } from './app'; +import { AppWithRouter } from './app'; import { BreadcrumbService } from './services/breadcrumbs'; @@ -28,7 +28,11 @@ export const renderApp = ( render( - + , element diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx index ebef80871b83d..4c0cc2c8957e1 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx @@ -9,7 +9,7 @@ import { RouteComponentProps } from 'react-router-dom'; import { EuiButton, EuiEmptyPrompt, EuiLoadingSpinner } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { useKibana } from '../../../shared_imports'; +import { useKibana, attemptToURIDecode } from '../../../shared_imports'; import { useLoadPoliciesList } from '../../services/api'; import { getPolicyByName } from '../../lib/policies'; @@ -90,13 +90,13 @@ export const EditPolicy: React.FunctionComponent = ({ history }) => { verticalPosition="center" horizontalPosition="center" > - +

{isNewPolicy ? i18n.translate('xpack.indexLifecycleMgmt.editPolicy.createPolicyMessage', { diff --git a/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts b/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts index a127574d5bad0..a5844af0bf6dd 100644 --- a/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts +++ b/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts @@ -32,6 +32,8 @@ export { TextField, } from '../../../../src/plugins/es_ui_shared/static/forms/components'; +export { attemptToURIDecode } from '../../../../src/plugins/es_ui_shared/public'; + export { KibanaContextProvider } from '../../../../src/plugins/kibana_react/public'; export const useKibana = () => _useKibana(); 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 6d9aa58d6c86b..2fb16874cf943 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 @@ -52,7 +52,7 @@ export const ComponentTemplateDetailsFlyoutContent: React.FunctionComponent { const { api } = useComponentTemplatesContext(); - const decodedComponentTemplateName = attemptToURIDecode(componentTemplateName); + const decodedComponentTemplateName = attemptToURIDecode(componentTemplateName)!; const { data: componentTemplateDetails, isLoading, error } = api.useLoadComponentTemplate( decodedComponentTemplateName 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 00ea3ebf794ee..e8424ae46c6d2 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 @@ -84,7 +84,7 @@ export const ComponentTemplateList: React.FunctionComponent = ({ }), icon: 'pencil', handleActionClick: () => - goToEditComponentTemplate(attemptToURIDecode(componentTemplateName)), + goToEditComponentTemplate(attemptToURIDecode(componentTemplateName)!), }, { name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.cloneActionLabel', { @@ -92,7 +92,7 @@ export const ComponentTemplateList: React.FunctionComponent = ({ }), icon: 'copy', handleActionClick: () => - goToCloneComponentTemplate(attemptToURIDecode(componentTemplateName)), + goToCloneComponentTemplate(attemptToURIDecode(componentTemplateName)!), }, { name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.deleteButtonLabel', { @@ -103,7 +103,7 @@ export const ComponentTemplateList: React.FunctionComponent = ({ details._kbnMeta.usedBy.length > 0, closePopoverOnClick: true, handleActionClick: () => { - setComponentTemplatesToDelete([attemptToURIDecode(componentTemplateName)]); + setComponentTemplatesToDelete([attemptToURIDecode(componentTemplateName)!]); }, }, ]; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx index 6c03fcf5d9972..e6b403543f4b0 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx @@ -19,7 +19,7 @@ export interface Params { export const ComponentTemplateClone: FunctionComponent> = (props) => { const { sourceComponentTemplateName } = props.match.params; - const decodedSourceName = attemptToURIDecode(sourceComponentTemplateName); + const decodedSourceName = attemptToURIDecode(sourceComponentTemplateName)!; const { toasts, api } = useComponentTemplatesContext(); 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 934f86f7d7590..500c84a97d222 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 @@ -31,7 +31,7 @@ export const ComponentTemplateEdit: React.FunctionComponent(false); const [saveError, setSaveError] = useState(null); - const decodedName = attemptToURIDecode(name); + const decodedName = attemptToURIDecode(name)!; const { error, data: componentTemplate, isLoading } = api.useLoadComponentTemplate(decodedName); diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx index ba79319b566bf..20b93d9d71d04 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx @@ -231,7 +231,7 @@ export const DataStreamList: React.FunctionComponent { history.push(`/${Section.DataStreams}`); 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 f3e82223c30e6..3689a875e28b2 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 @@ -101,7 +101,7 @@ export const TemplateList: React.FunctionComponent { - const decodedTemplateName = attemptToURIDecode(name); + const decodedTemplateName = attemptToURIDecode(name)!; const isLegacy = getIsLegacyFromQueryParams(location); const [isSaving, setIsSaving] = useState(false); 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 3e62f7f880f74..e3cb40b3a36e1 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 @@ -27,7 +27,7 @@ export const TemplateEdit: React.FunctionComponent { - const decodedTemplateName = attemptToURIDecode(name); + const decodedTemplateName = attemptToURIDecode(name)!; const isLegacy = getIsLegacyFromQueryParams(location); const [isSaving, setIsSaving] = useState(false); diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_clone/pipelines_clone.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_clone/pipelines_clone.tsx index 9465117b6b589..df60907973156 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_clone/pipelines_clone.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_clone/pipelines_clone.tsx @@ -25,7 +25,7 @@ export const PipelinesClone: FunctionComponent> const { sourceName } = props.match.params; const { services } = useKibana(); - const decodedSourceName = attemptToURIDecode(sourceName); + const decodedSourceName = attemptToURIDecode(sourceName)!; const { error, data: pipeline, isLoading, isInitialRequest } = services.api.useLoadPipeline( decodedSourceName ); diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_edit/pipelines_edit.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_edit/pipelines_edit.tsx index 7e2e85ab23fb3..2b53fdb6a6375 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_edit/pipelines_edit.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_edit/pipelines_edit.tsx @@ -38,7 +38,7 @@ export const PipelinesEdit: React.FunctionComponent(false); const [saveError, setSaveError] = useState(null); - const decodedPipelineName = attemptToURIDecode(name); + const decodedPipelineName = attemptToURIDecode(name)!; const { error, data: pipeline, isLoading } = services.api.useLoadPipeline(decodedPipelineName);