[ML] Transforms: Adds missing bucket checkbox to group by popover form. (#91650)

Adds missing bucket checkbox to group by popover form.
This commit is contained in:
Walter Rafelsberger 2021-02-18 01:54:39 +01:00 committed by GitHub
parent 0337d7d933
commit 2bb2629fec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 94 additions and 100 deletions

View file

@ -53,6 +53,8 @@ readonly links: {
readonly base: string;
};
readonly aggs: {
readonly composite: string;
readonly composite_missing_bucket: string;
readonly date_histogram: string;
readonly date_range: string;
readonly date_format_pattern: string;

File diff suppressed because one or more lines are too long

View file

@ -72,6 +72,8 @@ export class DocLinksService {
base: `${ELASTIC_WEBSITE_URL}guide/en/beats/winlogbeat/${DOC_LINK_VERSION}`,
},
aggs: {
composite: `${ELASTICSEARCH_DOCS}search-aggregations-bucket-composite-aggregation.html`,
composite_missing_bucket: `${ELASTICSEARCH_DOCS}search-aggregations-bucket-composite-aggregation.html#_missing_bucket`,
date_histogram: `${ELASTICSEARCH_DOCS}search-aggregations-bucket-datehistogram-aggregation.html`,
date_range: `${ELASTICSEARCH_DOCS}search-aggregations-bucket-daterange-aggregation.html`,
date_format_pattern: `${ELASTICSEARCH_DOCS}search-aggregations-bucket-daterange-aggregation.html#date-format-pattern`,
@ -301,6 +303,8 @@ export interface DocLinksStart {
readonly base: string;
};
readonly aggs: {
readonly composite: string;
readonly composite_missing_bucket: string;
readonly date_histogram: string;
readonly date_range: string;
readonly date_format_pattern: string;

View file

@ -523,6 +523,8 @@ export interface DocLinksStart {
readonly base: string;
};
readonly aggs: {
readonly composite: string;
readonly composite_missing_bucket: string;
readonly date_histogram: string;
readonly date_range: string;
readonly date_format_pattern: string;

View file

@ -11,6 +11,7 @@ export const useDocumentationLinks = () => {
const deps = useAppDependencies();
const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = deps.docLinks;
return {
esAggsCompositeMissingBucket: deps.docLinks.links.aggs.composite_missing_bucket,
esIndicesCreateIndex: deps.docLinks.links.apis.createIndex,
esPluginDocBasePath: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/plugins/${DOC_LINK_VERSION}/`,
esQueryDsl: deps.docLinks.links.query.queryDsl,

View file

@ -1,93 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Transform: Group By <PopoverForm /> Minimal initialization 1`] = `
<EuiForm
style={
<PopoverForm
defaultData={
Object {
"width": "300px",
"agg": "date_histogram",
"aggName": "the-agg-name",
"calendar_interval": "1m",
"dropDownName": "the-drop-down-name",
"field": "the-field",
}
}
>
<EuiFormRow
describedByIds={Array []}
display="row"
error={false}
fullWidth={false}
hasChildLabel={true}
hasEmptyLabelSpace={false}
helpText=""
isInvalid={false}
label="Group by name"
labelType="label"
>
<EuiFieldText
defaultValue="the-agg-name"
isInvalid={false}
onChange={[Function]}
/>
</EuiFormRow>
<EuiFormRow
describedByIds={Array []}
display="row"
error={false}
fullWidth={false}
hasChildLabel={true}
hasEmptyLabelSpace={false}
isInvalid={false}
label="Interval"
labelType="label"
>
<EuiSelect
onChange={[Function]}
options={
Array [
Object {
"text": "1m",
"value": "1m",
},
Object {
"text": "1h",
"value": "1h",
},
Object {
"text": "1d",
"value": "1d",
},
Object {
"text": "1w",
"value": "1w",
},
Object {
"text": "1M",
"value": "1M",
},
Object {
"text": "1q",
"value": "1q",
},
Object {
"text": "1y",
"value": "1y",
},
]
}
value="1m"
/>
</EuiFormRow>
<EuiFormRow
describedByIds={Array []}
display="row"
fullWidth={false}
hasChildLabel={true}
hasEmptyLabelSpace={true}
labelType="label"
>
<EuiButton
isDisabled={false}
onClick={[Function]}
>
Apply
</EuiButton>
</EuiFormRow>
</EuiForm>
onChange={[Function]}
options={Object {}}
otherAggNames={Array []}
/>
`;

View file

@ -8,6 +8,12 @@
import { shallow } from 'enzyme';
import React from 'react';
import { KibanaContextProvider } from '../../../../../../../../../src/plugins/kibana_react/public';
import { coreMock } from '../../../../../../../../../src/core/public/mocks';
import { dataPluginMock } from '../../../../../../../../../src/plugins/data/public/mocks';
const startMock = coreMock.createStart();
import { AggName } from '../../../../../../common/types/aggregations';
import { PIVOT_SUPPORTED_GROUP_BY_AGGS, PivotGroupByConfig } from '../../../../common';
@ -88,15 +94,24 @@ describe('Transform: Group By <PopoverForm />', () => {
const otherAggNames: AggName[] = [];
const onChange = (item: PivotGroupByConfig) => {};
// mock services for QueryStringInput
const services = {
...startMock,
data: dataPluginMock.createStartContract(),
appName: 'the-test-app',
};
const wrapper = shallow(
<PopoverForm
defaultData={defaultData}
otherAggNames={otherAggNames}
options={{}}
onChange={onChange}
/>
<KibanaContextProvider services={services}>
<PopoverForm
defaultData={defaultData}
otherAggNames={otherAggNames}
options={{}}
onChange={onChange}
/>
</KibanaContextProvider>
);
expect(wrapper).toMatchSnapshot();
expect(wrapper.find(PopoverForm)).toMatchSnapshot();
});
});

View file

@ -5,16 +5,19 @@
* 2.0.
*/
import React, { Fragment, useState } from 'react';
import React, { useMemo, useState } from 'react';
import { i18n } from '@kbn/i18n';
import {
htmlIdGenerator,
EuiButton,
EuiCheckbox,
EuiCodeEditor,
EuiFieldText,
EuiForm,
EuiFormRow,
EuiLink,
EuiSelect,
EuiSpacer,
} from '@elastic/eui';
@ -22,6 +25,8 @@ import {
import { AggName } from '../../../../../../common/types/aggregations';
import { dictionaryToArray } from '../../../../../../common/types/common';
import { useDocumentationLinks } from '../../../../hooks/use_documentation_links';
import {
dateHistogramIntervalFormatRegex,
getEsAggFromGroupByConfig,
@ -94,6 +99,8 @@ interface Props {
}
export const PopoverForm: React.FC<Props> = ({ defaultData, otherAggNames, onChange, options }) => {
const { esAggsCompositeMissingBucket } = useDocumentationLinks();
const isUnsupportedAgg = !isPivotGroupByConfigWithUiSupport(defaultData);
const [agg, setAgg] = useState(defaultData.agg);
@ -102,9 +109,14 @@ export const PopoverForm: React.FC<Props> = ({ defaultData, otherAggNames, onCha
isPivotGroupByConfigWithUiSupport(defaultData) ? defaultData.field : ''
);
const [interval, setInterval] = useState(getDefaultInterval(defaultData));
const [missingBucket, setMissingBucket] = useState(
isPivotGroupByConfigWithUiSupport(defaultData) && defaultData.missing_bucket
);
const missingBucketSwitchId = useMemo(() => htmlIdGenerator()(), []);
function getUpdatedItem(): PivotGroupByConfig {
const updatedItem = { ...defaultData, agg, aggName, field };
const updatedItem = { ...defaultData, agg, aggName, field, missing_bucket: missingBucket };
if (isGroupByHistogram(updatedItem) && interval !== undefined) {
updatedItem.interval = interval;
@ -225,7 +237,7 @@ export const PopoverForm: React.FC<Props> = ({ defaultData, otherAggNames, onCha
defaultMessage: 'Interval',
})}
>
<Fragment>
<>
{isGroupByHistogram(defaultData) && (
<EuiFieldText
defaultValue={interval}
@ -248,11 +260,43 @@ export const PopoverForm: React.FC<Props> = ({ defaultData, otherAggNames, onCha
onChange={(e) => setInterval(e.target.value)}
/>
)}
</Fragment>
</>
</EuiFormRow>
)}
{!isUnsupportedAgg && (
<EuiFormRow
helpText={
<>
{i18n.translate('xpack.transform.groupBy.popoverForm.missingBucketCheckboxHelpText', {
defaultMessage: 'Select to include documents without a value.',
})}
<br />
<EuiLink href={esAggsCompositeMissingBucket} target="_blank">
{i18n.translate(
'xpack.transform.stepDetailsForm.missingBucketCheckboxHelpTextLink',
{
defaultMessage: `Learn more`,
}
)}
</EuiLink>
</>
}
>
<EuiCheckbox
id={missingBucketSwitchId}
label={i18n.translate(
'xpack.transform.groupby.popoverForm.missingBucketCheckboxLabel',
{
defaultMessage: 'Include missing buckets',
}
)}
checked={missingBucket}
onChange={() => setMissingBucket(!missingBucket)}
/>
</EuiFormRow>
)}
{isUnsupportedAgg && (
<Fragment>
<>
<EuiSpacer size="m" />
<EuiCodeEditor
mode="json"
@ -264,7 +308,7 @@ export const PopoverForm: React.FC<Props> = ({ defaultData, otherAggNames, onCha
isReadOnly
aria-label="Read only code editor"
/>
</Fragment>
</>
)}
<EuiFormRow hasEmptyLabelSpace>
<EuiButton isDisabled={!formValid} onClick={() => onChange(getUpdatedItem())}>