[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:
parent
0337d7d933
commit
2bb2629fec
8 changed files with 94 additions and 100 deletions
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 []}
|
||||
/>
|
||||
`;
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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())}>
|
||||
|
|
Loading…
Reference in a new issue