Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Index template] Add filters to simulate preview #74497

Merged
merged 8 commits into from
Aug 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ $heightHeader: $euiSizeL * 2;

.componentTemplates {
border: $euiBorderThin;
border-radius: $euiBorderRadius;
border-top: none;
height: 100%;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,31 @@

&__selection {
border: $euiBorderThin;
border-radius: $euiBorderRadius;

padding: 0 $euiSize $euiSize;
color: $euiColorDarkShade;
padding: 0 $euiSize $euiSize;
color: $euiColorDarkShade;

&--is-empty {
align-items: center;
justify-content: center;
}
&--is-empty {
align-items: center;
justify-content: center;
}

&__header {
background-color: $euiColorLightestShade;
border-bottom: $euiBorderThin;
color: $euiColorInk;
height: $euiSizeXXL; // [1]
line-height: $euiSizeXXL; // [1]
font-size: $euiSizeM;
margin-bottom: $euiSizeS;
margin-left: $euiSize * -1;
margin-right: $euiSize * -1;
padding-left: $euiSize;
&__header {
background-color: $euiColorLightestShade;
border-bottom: $euiBorderThin;
color: $euiColorInk;
height: $euiSizeXXL; // [1]
line-height: $euiSizeXXL; // [1]
font-size: $euiSizeM;
margin-bottom: $euiSizeS;
margin-left: $euiSize * -1;
margin-right: $euiSize * -1;
padding-left: $euiSize;

&__count {
font-weight: 600;
}
&__count {
font-weight: 600;
}
}

&__content {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,19 @@ export const ComponentTemplatesSelector = ({
</div>
</>
) : (
<div>
<FormattedMessage
id="xpack.idxMgmt.componentTemplatesSelector.noComponentSelectedLabel"
defaultMessage="No component template selected."
/>
</div>
<EuiText textAlign="center">
<p>
<FormattedMessage
id="xpack.idxMgmt.componentTemplatesSelector.noComponentSelectedLabel-1"
defaultMessage="Add component template building blocks to this template."
/>
<br />
<FormattedMessage
id="xpack.idxMgmt.componentTemplatesSelector.noComponentSelectedLabel-2"
defaultMessage="Component templates are applied in the order specified."
/>
</p>
</EuiText>
)}
</EuiFlexItem>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 {
useForm,
Form,
getUseField,
FormDataProvider,
} from '../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib';

export { CheckBoxField } from '../../../../../../../src/plugins/es_ui_shared/static/forms/components';
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ export {
Props as SimulateTemplateProps,
} from './simulate_template_flyout';

export { SimulateTemplate } from './simulate_template';
export { SimulateTemplate, Filters as SimulateTemplateFilters } from './simulate_template';
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
*/
import React, { useState, useCallback, useEffect } from 'react';
import uuid from 'uuid';
import { EuiCodeBlock } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiCodeBlock, EuiCallOut } from '@elastic/eui';

import { serializers } from '../../../../shared_imports';
import { TemplateDeserialized } from '../../../../../common';
Expand All @@ -14,12 +15,18 @@ import { simulateIndexTemplate } from '../../../services';

const { stripEmptyFields } = serializers;

export interface Filters {
mappings: boolean;
settings: boolean;
aliases: boolean;
}

interface Props {
template: { [key: string]: any };
minHeightCodeBlock?: string;
filters?: Filters;
}

export const SimulateTemplate = React.memo(({ template, minHeightCodeBlock }: Props) => {
export const SimulateTemplate = React.memo(({ template, filters }: Props) => {
const [templatePreview, setTemplatePreview] = useState('{}');

const updatePreview = useCallback(async () => {
Expand All @@ -34,26 +41,60 @@ export const SimulateTemplate = React.memo(({ template, minHeightCodeBlock }: Pr
indexTemplate.index_patterns = [uuid.v4()];

const { data, error } = await simulateIndexTemplate(indexTemplate);
let filteredTemplate = data;

if (data) {
// "Overlapping" info is only useful when simulating against an index
// which we don't do here.
delete data.overlapping;

if (data.template && data.template.mappings === undefined) {
// Adding some extra logic to return an empty object for "mappings" as ES does not
// return one in that case (empty objects _are_ returned for "settings" and "aliases")
// Issue: https://github.com/elastic/elasticsearch/issues/60968
data.template.mappings = {};
}

if (filters) {
filteredTemplate = Object.entries(filters).reduce(
(acc, [key, value]) => {
if (!value) {
delete acc[key];
}
return acc;
},
{ ...data.template } as any
);
}
}

setTemplatePreview(JSON.stringify(data ?? error, null, 2));
}, [template]);
setTemplatePreview(JSON.stringify(filteredTemplate ?? error, null, 2));
}, [template, filters]);

useEffect(() => {
updatePreview();
}, [updatePreview]);

return templatePreview === '{}' ? null : (
<EuiCodeBlock
style={{ minHeight: minHeightCodeBlock }}
lang="json"
data-test-subj="simulateTemplatePreview"
>
const isEmpty = templatePreview === '{}';
const hasFilters = Boolean(filters);

if (isEmpty && hasFilters) {
return (
<EuiCallOut
title={
<FormattedMessage
id="xpack.idxMgmt.simulateTemplate.noFilterSelected"
defaultMessage="Select at least one option to preview."
/>
}
iconType="pin"
size="s"
/>
);
}

return isEmpty ? null : (
<EuiCodeBlock lang="json" data-test-subj="simulateTemplatePreview">
{templatePreview}
</EuiCodeBlock>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
import React, { useState, useCallback, useEffect, useRef } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import {
EuiFlyoutHeader,
EuiTitle,
Expand All @@ -19,28 +20,56 @@ import {
EuiSpacer,
} from '@elastic/eui';

import { SimulateTemplate } from './simulate_template';
import { useForm, Form, getUseField, CheckBoxField, FormDataProvider } from '../shared_imports';
import { SimulateTemplate, Filters } from './simulate_template';

const CheckBox = getUseField({ component: CheckBoxField });

export interface Props {
onClose(): void;
getTemplate: () => { [key: string]: any };
filters: Filters;
onFiltersChange: (filters: Filters) => void;
}

export const defaultFlyoutProps = {
'data-test-subj': 'simulateTemplateFlyout',
'aria-labelledby': 'simulateTemplateFlyoutTitle',
};

export const SimulateTemplateFlyoutContent = ({ onClose, getTemplate }: Props) => {
const i18nTexts = {
filters: {
label: i18n.translate('xpack.idxMgmt.simulateTemplate.filters.label', {
defaultMessage: 'Include:',
}),
mappings: i18n.translate('xpack.idxMgmt.simulateTemplate.filters.mappings', {
defaultMessage: 'Mappings',
}),
indexSettings: i18n.translate('xpack.idxMgmt.simulateTemplate.filters.indexSettings', {
defaultMessage: 'Index settings',
}),
aliases: i18n.translate('xpack.idxMgmt.simulateTemplate.filters.aliases', {
defaultMessage: 'Aliases',
}),
},
};

export const SimulateTemplateFlyoutContent = ({
onClose,
getTemplate,
filters,
onFiltersChange,
}: Props) => {
const isMounted = useRef(false);
const [heightCodeBlock, setHeightCodeBlock] = useState(0);
const [template, setTemplate] = useState<{ [key: string]: any }>({});
const { form } = useForm<Filters>({ defaultValue: filters });
const { subscribe } = form;

useEffect(() => {
setHeightCodeBlock(
document.getElementsByClassName('euiFlyoutBody__overflow')[0].clientHeight - 96
);
}, []);
subscribe((formState) => {
onFiltersChange(formState.data.format());
});
}, [subscribe, onFiltersChange]);

const updatePreview = useCallback(async () => {
const indexTemplate = await getTemplate();
Expand Down Expand Up @@ -71,16 +100,37 @@ export const SimulateTemplateFlyoutContent = ({ onClose, getTemplate }: Props) =
<p>
<FormattedMessage
id="xpack.idxMgmt.simulateTemplate.descriptionText"
defaultMessage="This is the final template that will be applied to your indices based on the
components templates you have selected and any overrides you've added."
defaultMessage="This is the final template that will be applied to matching indices based on the
component templates you have selected and any overrides you've added."
/>
</p>
</EuiText>
</EuiTextColor>
</EuiFlyoutHeader>

<EuiFlyoutBody data-test-subj="content">
<SimulateTemplate template={template} minHeightCodeBlock={`${heightCodeBlock}px`} />
<Form form={form}>
<EuiFlexGroup alignItems="center">
<EuiFlexItem grow={false}>{i18nTexts.filters.label}</EuiFlexItem>
<EuiFlexItem grow={false}>
<CheckBox path="mappings" config={{ label: i18nTexts.filters.mappings }} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<CheckBox path="settings" config={{ label: i18nTexts.filters.indexSettings }} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<CheckBox path="aliases" config={{ label: i18nTexts.filters.aliases }} />
</EuiFlexItem>
</EuiFlexGroup>

<EuiSpacer />

<FormDataProvider>
{(formData) => {
return <SimulateTemplate template={template} filters={formData as Filters} />;
}}
</FormDataProvider>
</Form>
</EuiFlyoutBody>

<EuiFlyoutFooter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const i18nTexts = {
description: (
<FormattedMessage
id="xpack.idxMgmt.formWizard.stepComponents.componentsDescription"
defaultMessage="Components templates let you save index settings, mappings and aliases and inherit from them in index templates."
defaultMessage="Component templates let you save index settings, mappings and aliases and inherit from them in index templates."
/>
),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const PreviewTab = ({ template }: { template: { [key: string]: any } }) => {
<p>
<FormattedMessage
id="xpack.idxMgmt.templateForm.stepReview.previewTab.descriptionText"
defaultMessage="This is the final template that will be applied to your indices."
defaultMessage="This is the final template that will be applied to matching indices. Component templates are applied in the order specified. Explicit mappings, settings, and aliases override the component templates."
/>
</p>
</EuiText>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* 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, useCallback } from 'react';
import React, { useState, useCallback, useRef } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiSpacer, EuiButton } from '@elastic/eui';
Expand All @@ -15,6 +15,7 @@ import {
SimulateTemplateFlyoutContent,
SimulateTemplateProps,
simulateTemplateFlyoutProps,
SimulateTemplateFilters,
} from '../index_templates';
import { StepLogisticsContainer, StepComponentContainer, StepReviewContainer } from './steps';
import {
Expand Down Expand Up @@ -98,6 +99,11 @@ export const TemplateForm = ({
}: Props) => {
const [wizardContent, setWizardContent] = useState<Forms.Content<WizardContent> | null>(null);
const { addContent: addContentToGlobalFlyout, closeFlyout } = useGlobalFlyout();
const simulateTemplateFilters = useRef<SimulateTemplateFilters>({
mappings: true,
settings: true,
aliases: true,
});

const indexTemplate = defaultValue ?? {
name: '',
Expand Down Expand Up @@ -234,13 +240,19 @@ export const TemplateForm = ({
return template;
}, [buildTemplateObject, indexTemplate, wizardContent]);

const onSimulateTemplateFiltersChange = useCallback((filters: SimulateTemplateFilters) => {
simulateTemplateFilters.current = filters;
}, []);

const showPreviewFlyout = () => {
addContentToGlobalFlyout<SimulateTemplateProps>({
id: 'simulateTemplate',
Component: SimulateTemplateFlyoutContent,
props: {
getTemplate: getSimulateTemplate,
onClose: closeFlyout,
filters: simulateTemplateFilters.current,
onFiltersChange: onSimulateTemplateFiltersChange,
},
flyoutProps: simulateTemplateFlyoutProps,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const TabPreview = ({ templateDetails }: Props) => {
<p>
<FormattedMessage
id="xpack.idxMgmt.templateDetails.previewTab.descriptionText"
defaultMessage="This is the final template that will be applied to your indices."
defaultMessage="This is the final template that will be applied to matching indices."
/>
</p>
</EuiText>
Expand Down
Loading