mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Discourage use of legacy index templates (#101533)
* Hide legacy index templates table if the user doesn't have any. * Render deprecation warning above legacy index templates table and in legacy index template wizard. * Update index template doc link to point to the new docs.
This commit is contained in:
parent
6e0aed79c3
commit
55a0dbbc09
15 changed files with 247 additions and 47 deletions
|
@ -8,18 +8,39 @@
|
|||
|
||||
import React, { Component, ComponentType } from 'react';
|
||||
import { MemoryRouter, Route, withRouter } from 'react-router-dom';
|
||||
import * as H from 'history';
|
||||
import { History, LocationDescriptor } from 'history';
|
||||
|
||||
export const WithMemoryRouter = (initialEntries: string[] = ['/'], initialIndex: number = 0) => (
|
||||
WrappedComponent: ComponentType
|
||||
) => (props: any) => (
|
||||
const stringifyPath = (path: LocationDescriptor): string => {
|
||||
if (typeof path === 'string') {
|
||||
return path;
|
||||
}
|
||||
|
||||
return path.pathname || '/';
|
||||
};
|
||||
|
||||
const locationDescriptorToRoutePath = (
|
||||
paths: LocationDescriptor | LocationDescriptor[]
|
||||
): string | string[] => {
|
||||
if (Array.isArray(paths)) {
|
||||
return paths.map((path: LocationDescriptor) => {
|
||||
return stringifyPath(path);
|
||||
});
|
||||
}
|
||||
|
||||
return stringifyPath(paths);
|
||||
};
|
||||
|
||||
export const WithMemoryRouter = (
|
||||
initialEntries: LocationDescriptor[] = ['/'],
|
||||
initialIndex: number = 0
|
||||
) => (WrappedComponent: ComponentType) => (props: any) => (
|
||||
<MemoryRouter initialEntries={initialEntries} initialIndex={initialIndex}>
|
||||
<WrappedComponent {...props} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
export const WithRoute = (
|
||||
componentRoutePath: string | string[] = '/',
|
||||
componentRoutePath: LocationDescriptor | LocationDescriptor[] = ['/'],
|
||||
onRouter = (router: any) => {}
|
||||
) => (WrappedComponent: ComponentType) => {
|
||||
// Create a class component that will catch the router
|
||||
|
@ -40,16 +61,16 @@ export const WithRoute = (
|
|||
|
||||
return (props: any) => (
|
||||
<Route
|
||||
path={componentRoutePath}
|
||||
path={locationDescriptorToRoutePath(componentRoutePath)}
|
||||
render={(routerProps) => <CatchRouter {...routerProps} {...props} />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
interface Router {
|
||||
history: Partial<H.History>;
|
||||
history: Partial<History>;
|
||||
route: {
|
||||
location: H.Location;
|
||||
location: LocationDescriptor;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import { Store } from 'redux';
|
||||
import { ReactWrapper } from 'enzyme';
|
||||
import { LocationDescriptor } from 'history';
|
||||
|
||||
export type SetupFunc<T> = (props?: any) => TestBed<T> | Promise<TestBed<T>>;
|
||||
|
||||
|
@ -161,11 +162,11 @@ export interface MemoryRouterConfig {
|
|||
/** Flag to add or not the `MemoryRouter`. If set to `false`, there won't be any router and the component won't be wrapped on a `<Route />`. */
|
||||
wrapComponent?: boolean;
|
||||
/** The React Router **initial entries** setting ([see documentation](https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/MemoryRouter.md)) */
|
||||
initialEntries?: string[];
|
||||
initialEntries?: LocationDescriptor[];
|
||||
/** The React Router **initial index** setting ([see documentation](https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/MemoryRouter.md)) */
|
||||
initialIndex?: number;
|
||||
/** The route **path** for the mounted component (defaults to `"/"`) */
|
||||
componentRoutePath?: string | string[];
|
||||
componentRoutePath?: LocationDescriptor | LocationDescriptor[];
|
||||
/** A callBack that will be called with the React Router instance once mounted */
|
||||
onRouter?: (router: any) => void;
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ export class DocLinksService {
|
|||
dataStreams: `${ELASTICSEARCH_DOCS}data-streams.html`,
|
||||
indexModules: `${ELASTICSEARCH_DOCS}index-modules.html`,
|
||||
indexSettings: `${ELASTICSEARCH_DOCS}index-modules.html#index-modules-settings`,
|
||||
indexTemplates: `${ELASTICSEARCH_DOCS}indices-templates.html`,
|
||||
indexTemplates: `${ELASTICSEARCH_DOCS}index-templates.html`,
|
||||
mapping: `${ELASTICSEARCH_DOCS}mapping.html`,
|
||||
mappingAnalyzer: `${ELASTICSEARCH_DOCS}analyzer.html`,
|
||||
mappingCoerce: `${ELASTICSEARCH_DOCS}coerce.html`,
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('Index Templates tab', () => {
|
|||
server.restore();
|
||||
});
|
||||
|
||||
describe('when there are no index templates', () => {
|
||||
describe('when there are no index templates of either kind', () => {
|
||||
test('should display an empty prompt', async () => {
|
||||
httpRequestsMockHelpers.setLoadTemplatesResponse({ templates: [], legacyTemplates: [] });
|
||||
|
||||
|
@ -46,6 +46,26 @@ describe('Index Templates tab', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when there are composable index templates but no legacy index templates', () => {
|
||||
test('only the composable index templates table is visible', async () => {
|
||||
httpRequestsMockHelpers.setLoadTemplatesResponse({
|
||||
templates: [fixtures.getComposableTemplate()],
|
||||
legacyTemplates: [],
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
testBed = await setup();
|
||||
});
|
||||
const { exists, component } = testBed;
|
||||
component.update();
|
||||
|
||||
expect(exists('sectionLoading')).toBe(false);
|
||||
expect(exists('emptyPrompt')).toBe(false);
|
||||
expect(exists('templateTable')).toBe(true);
|
||||
expect(exists('legacyTemplateTable')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when there are index templates', () => {
|
||||
// Add a default loadIndexTemplate response
|
||||
httpRequestsMockHelpers.setLoadTemplateResponse(fixtures.getTemplate());
|
||||
|
|
|
@ -11,17 +11,23 @@ import { WithAppDependencies } from '../helpers';
|
|||
|
||||
import { formSetup, TestSubjects } from './template_form.helpers';
|
||||
|
||||
const testBedConfig: TestBedConfig = {
|
||||
memoryRouter: {
|
||||
initialEntries: [`/create_template`],
|
||||
componentRoutePath: `/create_template`,
|
||||
},
|
||||
doMountAsync: true,
|
||||
export const setup: any = (isLegacy: boolean = false) => {
|
||||
const route = isLegacy
|
||||
? { pathname: '/create_template', search: '?legacy=true' }
|
||||
: { pathname: '/create_template' };
|
||||
|
||||
const testBedConfig: TestBedConfig = {
|
||||
memoryRouter: {
|
||||
initialEntries: [route],
|
||||
componentRoutePath: route,
|
||||
},
|
||||
doMountAsync: true,
|
||||
};
|
||||
|
||||
const initTestBed = registerTestBed<TestSubjects>(
|
||||
WithAppDependencies(TemplateCreate),
|
||||
testBedConfig
|
||||
);
|
||||
|
||||
return formSetup.call(null, initTestBed);
|
||||
};
|
||||
|
||||
const initTestBed = registerTestBed<TestSubjects>(
|
||||
WithAppDependencies(TemplateCreate),
|
||||
testBedConfig
|
||||
);
|
||||
|
||||
export const setup: any = formSetup.bind(null, initTestBed);
|
||||
|
|
|
@ -101,7 +101,7 @@ describe('<TemplateCreate />', () => {
|
|||
(window as any)['__react-beautiful-dnd-disable-dev-warnings'] = false;
|
||||
});
|
||||
|
||||
describe('on component mount', () => {
|
||||
describe('composable index template', () => {
|
||||
beforeEach(async () => {
|
||||
await act(async () => {
|
||||
testBed = await setup();
|
||||
|
@ -115,6 +115,11 @@ describe('<TemplateCreate />', () => {
|
|||
expect(find('pageTitle').text()).toEqual('Create template');
|
||||
});
|
||||
|
||||
test('renders no deprecation warning', async () => {
|
||||
const { exists } = testBed;
|
||||
expect(exists('legacyIndexTemplateDeprecationWarning')).toBe(false);
|
||||
});
|
||||
|
||||
test('should not let the user go to the next step with invalid fields', async () => {
|
||||
const { find, actions, component } = testBed;
|
||||
|
||||
|
@ -129,6 +134,26 @@ describe('<TemplateCreate />', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('legacy index template', () => {
|
||||
beforeEach(async () => {
|
||||
await act(async () => {
|
||||
testBed = await setup(true);
|
||||
});
|
||||
});
|
||||
|
||||
test('should set the correct page title', () => {
|
||||
const { exists, find } = testBed;
|
||||
|
||||
expect(exists('pageTitle')).toBe(true);
|
||||
expect(find('pageTitle').text()).toEqual('Create legacy template');
|
||||
});
|
||||
|
||||
test('renders deprecation warning', async () => {
|
||||
const { exists } = testBed;
|
||||
expect(exists('legacyIndexTemplateDeprecationWarning')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('form validation', () => {
|
||||
beforeEach(async () => {
|
||||
await act(async () => {
|
||||
|
@ -150,6 +175,11 @@ describe('<TemplateCreate />', () => {
|
|||
expect(find('stepTitle').text()).toEqual('Component templates (optional)');
|
||||
});
|
||||
|
||||
it(`doesn't render the deprecated legacy index template warning`, () => {
|
||||
const { exists } = testBed;
|
||||
expect(exists('legacyIndexTemplateDeprecationWarning')).toBe(false);
|
||||
});
|
||||
|
||||
it('should list the available component templates', () => {
|
||||
const {
|
||||
actions: {
|
||||
|
|
|
@ -306,6 +306,7 @@ export type TestSubjects =
|
|||
| 'indexPatternsField'
|
||||
| 'indexPatternsWarning'
|
||||
| 'indexPatternsWarningDescription'
|
||||
| 'legacyIndexTemplateDeprecationWarning'
|
||||
| 'mappingsEditorFieldEdit'
|
||||
| 'mockCodeEditor'
|
||||
| 'mockComboBox'
|
||||
|
|
|
@ -5,4 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './simulate_template';
|
||||
export {
|
||||
SimulateTemplateFlyoutContent,
|
||||
simulateTemplateFlyoutProps,
|
||||
SimulateTemplateProps,
|
||||
SimulateTemplate,
|
||||
SimulateTemplateFilters,
|
||||
} from './simulate_template';
|
||||
|
||||
export { LegacyIndexTemplatesDeprecation } from './legacy_index_template_deprecation';
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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 { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiCallOut, EuiLink } from '@elastic/eui';
|
||||
import { ScopedHistory } from 'kibana/public';
|
||||
import { reactRouterNavigate } from '../../../shared_imports';
|
||||
import { documentationService } from '../../services/documentation';
|
||||
|
||||
interface Props {
|
||||
history?: ScopedHistory;
|
||||
showCta?: boolean;
|
||||
}
|
||||
|
||||
export const LegacyIndexTemplatesDeprecation: React.FunctionComponent<Props> = ({
|
||||
history,
|
||||
showCta,
|
||||
}) => {
|
||||
return (
|
||||
<EuiCallOut
|
||||
title={i18n.translate('xpack.idxMgmt.legacyIndexTemplatesDeprecation.title', {
|
||||
defaultMessage:
|
||||
'Legacy index templates are deprecated in favor of composable index templates',
|
||||
})}
|
||||
color="warning"
|
||||
iconType="alert"
|
||||
data-test-subj="legacyIndexTemplateDeprecationWarning"
|
||||
>
|
||||
{showCta && history && (
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.idxMgmt.legacyIndexTemplatesDeprecation.description"
|
||||
defaultMessage="{createTemplateButton} or {learnMoreLink}"
|
||||
values={{
|
||||
createTemplateButton: (
|
||||
<EuiLink
|
||||
data-test-subj="createTemplateButton"
|
||||
{...reactRouterNavigate(history, '/create_template')}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.idxMgmt.legacyIndexTemplatesDeprecation.createTemplatesButtonLabel"
|
||||
defaultMessage="Create composable template"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
learnMoreLink: (
|
||||
<EuiLink
|
||||
href={documentationService.getTemplatesDocumentationLink()}
|
||||
target="_blank"
|
||||
external
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.idxMgmt.home.legacyIndexTemplatesDeprecation.ctaLearnMoreLinkText',
|
||||
{
|
||||
defaultMessage: 'learn more.',
|
||||
}
|
||||
)}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
|
||||
{!showCta && (
|
||||
<EuiLink
|
||||
href={documentationService.getTemplatesDocumentationLink()}
|
||||
target="_blank"
|
||||
external
|
||||
>
|
||||
{i18n.translate('xpack.idxMgmt.home.legacyIndexTemplatesDeprecation.learnMoreLinkText', {
|
||||
defaultMessage: 'Learn more.',
|
||||
})}
|
||||
</EuiLink>
|
||||
)}
|
||||
</EuiCallOut>
|
||||
);
|
||||
};
|
|
@ -9,17 +9,10 @@ import React, { useState, useCallback, useRef } from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiSpacer, EuiButton } from '@elastic/eui';
|
||||
import { ScopedHistory } from 'kibana/public';
|
||||
|
||||
import { TemplateDeserialized } from '../../../../common';
|
||||
import { serializers, Forms, GlobalFlyout } from '../../../shared_imports';
|
||||
import { SectionError } from '../section_error';
|
||||
import {
|
||||
SimulateTemplateFlyoutContent,
|
||||
SimulateTemplateProps,
|
||||
simulateTemplateFlyoutProps,
|
||||
SimulateTemplateFilters,
|
||||
} from '../index_templates';
|
||||
import { StepLogisticsContainer, StepComponentContainer, StepReviewContainer } from './steps';
|
||||
import {
|
||||
CommonWizardSteps,
|
||||
StepSettingsContainer,
|
||||
|
@ -27,6 +20,15 @@ import {
|
|||
StepAliasesContainer,
|
||||
} from '../shared';
|
||||
import { documentationService } from '../../services/documentation';
|
||||
import { SectionError } from '../section_error';
|
||||
import {
|
||||
SimulateTemplateFlyoutContent,
|
||||
SimulateTemplateProps,
|
||||
simulateTemplateFlyoutProps,
|
||||
SimulateTemplateFilters,
|
||||
LegacyIndexTemplatesDeprecation,
|
||||
} from '../index_templates';
|
||||
import { StepLogisticsContainer, StepComponentContainer, StepReviewContainer } from './steps';
|
||||
|
||||
const { stripEmptyFields } = serializers;
|
||||
const { FormWizard, FormWizardStep } = Forms;
|
||||
|
@ -38,6 +40,7 @@ interface Props {
|
|||
clearSaveError: () => void;
|
||||
isSaving: boolean;
|
||||
saveError: any;
|
||||
history?: ScopedHistory;
|
||||
isLegacy?: boolean;
|
||||
defaultValue?: TemplateDeserialized;
|
||||
isEditing?: boolean;
|
||||
|
@ -98,6 +101,7 @@ export const TemplateForm = ({
|
|||
saveError,
|
||||
clearSaveError,
|
||||
onSave,
|
||||
history,
|
||||
}: Props) => {
|
||||
const [wizardContent, setWizardContent] = useState<Forms.Content<WizardContent> | null>(null);
|
||||
const { addContent: addContentToGlobalFlyout, closeFlyout } = useGlobalFlyout();
|
||||
|
@ -283,12 +287,20 @@ export const TemplateForm = ({
|
|||
);
|
||||
};
|
||||
|
||||
const isLegacyIndexTemplate = indexTemplate._kbnMeta.isLegacy === true;
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Form header */}
|
||||
{title}
|
||||
|
||||
<EuiSpacer size="l" />
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
{isLegacyIndexTemplate && (
|
||||
<LegacyIndexTemplatesDeprecation history={history} showCta={true} />
|
||||
)}
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
<FormWizard<WizardContent, WizardSection>
|
||||
defaultValue={wizardDefaultValue}
|
||||
|
@ -311,7 +323,7 @@ export const TemplateForm = ({
|
|||
/>
|
||||
</FormWizardStep>
|
||||
|
||||
{indexTemplate._kbnMeta.isLegacy !== true && (
|
||||
{!isLegacyIndexTemplate && (
|
||||
<FormWizardStep id={wizardSections.components.id} label={wizardSections.components.label}>
|
||||
<StepComponentContainer />
|
||||
</FormWizardStep>
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './template_type_indicator';
|
||||
export { TemplateTypeIndicator } from './template_type_indicator';
|
||||
|
|
|
@ -24,7 +24,13 @@ import {
|
|||
|
||||
import { UIM_TEMPLATE_LIST_LOAD } from '../../../../../common/constants';
|
||||
import { TemplateListItem } from '../../../../../common';
|
||||
import { SectionError, SectionLoading, Error } from '../../../components';
|
||||
import { attemptToURIDecode } from '../../../../shared_imports';
|
||||
import {
|
||||
SectionError,
|
||||
SectionLoading,
|
||||
Error,
|
||||
LegacyIndexTemplatesDeprecation,
|
||||
} from '../../../components';
|
||||
import { useLoadIndexTemplates } from '../../../services/api';
|
||||
import { documentationService } from '../../../services/documentation';
|
||||
import { useServices } from '../../../app_context';
|
||||
|
@ -34,11 +40,10 @@ import {
|
|||
getTemplateCloneLink,
|
||||
} from '../../../services/routing';
|
||||
import { getIsLegacyFromQueryParams } from '../../../lib/index_templates';
|
||||
import { FilterListButton, Filters } from '../components';
|
||||
import { TemplateTable } from './template_table';
|
||||
import { TemplateDetails } from './template_details';
|
||||
import { LegacyTemplateTable } from './legacy_templates/template_table';
|
||||
import { FilterListButton, Filters } from '../components';
|
||||
import { attemptToURIDecode } from '../../../../shared_imports';
|
||||
|
||||
type FilterName = 'managed' | 'cloudManaged' | 'system';
|
||||
interface MatchParams {
|
||||
|
@ -130,7 +135,7 @@ export const TemplateList: React.FunctionComponent<RouteComponentProps<MatchPara
|
|||
<EuiText color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.idxMgmt.home.indexTemplatesDescription"
|
||||
defaultMessage="Use index templates to automatically apply settings, mappings, and aliases to indices. {learnMoreLink}"
|
||||
defaultMessage="Use composable index templates to automatically apply settings, mappings, and aliases to indices. {learnMoreLink}"
|
||||
values={{
|
||||
learnMoreLink: (
|
||||
<EuiLink
|
||||
|
@ -196,7 +201,13 @@ export const TemplateList: React.FunctionComponent<RouteComponentProps<MatchPara
|
|||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
<EuiSpacer />
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
<LegacyIndexTemplatesDeprecation />
|
||||
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
<LegacyTemplateTable
|
||||
templates={filteredTemplates.legacyTemplates}
|
||||
reload={reload}
|
||||
|
@ -253,8 +264,8 @@ export const TemplateList: React.FunctionComponent<RouteComponentProps<MatchPara
|
|||
{/* Composable index templates table */}
|
||||
{renderTemplatesTable()}
|
||||
|
||||
{/* Legacy index templates table */}
|
||||
{renderLegacyTemplatesTable()}
|
||||
{/* Legacy index templates table. We discourage their adoption if the user isn't already using them. */}
|
||||
{filteredTemplates.legacyTemplates.length > 0 && renderLegacyTemplatesTable()}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import React, { useEffect, useState } from 'react';
|
|||
import { RouteComponentProps } from 'react-router-dom';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiPageBody, EuiPageContent, EuiTitle } from '@elastic/eui';
|
||||
import { ScopedHistory } from 'kibana/public';
|
||||
|
||||
import { TemplateDeserialized } from '../../../../common';
|
||||
import { TemplateForm, SectionLoading, SectionError, Error } from '../../components';
|
||||
|
@ -114,6 +115,7 @@ export const TemplateClone: React.FunctionComponent<RouteComponentProps<MatchPar
|
|||
saveError={saveError}
|
||||
clearSaveError={clearSaveError}
|
||||
isLegacy={isLegacy}
|
||||
history={history as ScopedHistory}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,10 +11,11 @@ import { FormattedMessage } from '@kbn/i18n/react';
|
|||
import { EuiPageBody, EuiPageContent, EuiTitle } from '@elastic/eui';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { parse } from 'query-string';
|
||||
import { ScopedHistory } from 'kibana/public';
|
||||
|
||||
import { TemplateDeserialized } from '../../../../common';
|
||||
import { TemplateForm } from '../../components';
|
||||
import { breadcrumbService } from '../../services/breadcrumbs';
|
||||
import { TemplateDeserialized } from '../../../../common';
|
||||
import { saveTemplate } from '../../services/api';
|
||||
import { getTemplateDetailsLink } from '../../services/routing';
|
||||
|
||||
|
@ -76,6 +77,7 @@ export const TemplateCreate: React.FunctionComponent<RouteComponentProps> = ({ h
|
|||
saveError={saveError}
|
||||
clearSaveError={clearSaveError}
|
||||
isLegacy={isLegacy}
|
||||
history={history as ScopedHistory}
|
||||
/>
|
||||
</EuiPageContent>
|
||||
</EuiPageBody>
|
||||
|
|
|
@ -9,14 +9,15 @@ import React, { useEffect, useState, Fragment } from 'react';
|
|||
import { RouteComponentProps } from 'react-router-dom';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiPageBody, EuiPageContent, EuiTitle, EuiSpacer, EuiCallOut } from '@elastic/eui';
|
||||
import { ScopedHistory } from 'kibana/public';
|
||||
|
||||
import { TemplateDeserialized } from '../../../../common';
|
||||
import { attemptToURIDecode } from '../../../shared_imports';
|
||||
import { breadcrumbService } from '../../services/breadcrumbs';
|
||||
import { useLoadIndexTemplate, updateTemplate } from '../../services/api';
|
||||
import { getTemplateDetailsLink } from '../../services/routing';
|
||||
import { SectionLoading, SectionError, TemplateForm, Error } from '../../components';
|
||||
import { getIsLegacyFromQueryParams } from '../../lib/index_templates';
|
||||
import { attemptToURIDecode } from '../../../shared_imports';
|
||||
|
||||
interface MatchParams {
|
||||
name: string;
|
||||
|
@ -154,6 +155,7 @@ export const TemplateEdit: React.FunctionComponent<RouteComponentProps<MatchPara
|
|||
clearSaveError={clearSaveError}
|
||||
isEditing={true}
|
||||
isLegacy={isLegacy}
|
||||
history={history as ScopedHistory}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue