Skip to content

Commit

Permalink
[8.15] fix(slo): timestamp field was allowing mutliple values (#194311)…
Browse files Browse the repository at this point in the history
… (#194611)

# Backport

This will backport the following commits from `main` to `8.15`:
- [fix(slo): timestamp field was allowing mutliple values
(#194311)](#194311)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Kevin
Delemme","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-10-01T12:22:24Z","message":"fix(slo):
timestamp field was allowing mutliple values
(#194311)","sha":"c4e2a7256b76cc94c08f34bb6dc3faeff58777f1","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","v9.0.0","backport:prev-major","ci:project-deploy-observability","Team:obs-ux-management","v8.16.0"],"number":194311,"url":"https://github.com/elastic/kibana/pull/194311","mergeCommit":{"message":"fix(slo):
timestamp field was allowing mutliple values
(#194311)","sha":"c4e2a7256b76cc94c08f34bb6dc3faeff58777f1"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194311","number":194311,"mergeCommit":{"message":"fix(slo):
timestamp field was allowing mutliple values
(#194311)","sha":"c4e2a7256b76cc94c08f34bb6dc3faeff58777f1"}},{"branch":"8.x","label":"v8.16.0","labelRegex":"^v8.16.0$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/194562","number":194562,"state":"MERGED","mergeCommit":{"sha":"6bcd396a593882fd79f55afbce08965e763028bf","message":"[8.x]
fix(slo): timestamp field was allowing mutliple values (#194311)
(#194562)\n\n# Backport\n\nThis will backport the following commits from
`main` to `8.x`:\n- [fix(slo): timestamp field was allowing mutliple
values\n(#194311)](https://github.com/elastic/kibana/pull/194311)\n\n<!---
Backport version: 9.4.3 -->\n\n### Questions ?\nPlease refer to the
[Backport
tool\ndocumentation](https://github.com/sqren/backport)\n\n<!--BACKPORT
[{\"author\":{\"name\":\"Kevin\nDelemme\",\"email\":\"[email protected]\"},\"sourceCommit\":{\"committedDate\":\"2024-10-01T12:22:24Z\",\"message\":\"fix(slo):\ntimestamp
field was allowing mutliple
values\n(#194311)\",\"sha\":\"c4e2a7256b76cc94c08f34bb6dc3faeff58777f1\",\"branchLabelMapping\":{\"^v9.0.0$\":\"main\",\"^v8.16.0$\":\"8.x\",\"^v(\\\\d+).(\\\\d+).\\\\d+$\":\"$1.$2\"}},\"sourcePullRequest\":{\"labels\":[\"release_note:fix\",\"v9.0.0\",\"backport:prev-major\",\"ci:project-deploy-observability\",\"Team:obs-ux-management\",\"v8.16.0\"],\"title\":\"fix(slo):\ntimestamp
field was allowing
mutliple\nvalues\",\"number\":194311,\"url\":\"https://github.com/elastic/kibana/pull/194311\",\"mergeCommit\":{\"message\":\"fix(slo):\ntimestamp
field was allowing mutliple
values\n(#194311)\",\"sha\":\"c4e2a7256b76cc94c08f34bb6dc3faeff58777f1\"}},\"sourceBranch\":\"main\",\"suggestedTargetBranches\":[\"8.x\"],\"targetPullRequestStates\":[{\"branch\":\"main\",\"label\":\"v9.0.0\",\"branchLabelMappingKey\":\"^v9.0.0$\",\"isSourceBranch\":true,\"state\":\"MERGED\",\"url\":\"https://github.com/elastic/kibana/pull/194311\",\"number\":194311,\"mergeCommit\":{\"message\":\"fix(slo):\ntimestamp
field was allowing mutliple
values\n(#194311)\",\"sha\":\"c4e2a7256b76cc94c08f34bb6dc3faeff58777f1\"}},{\"branch\":\"8.x\",\"label\":\"v8.16.0\",\"branchLabelMappingKey\":\"^v8.16.0$\",\"isSourceBranch\":false,\"state\":\"NOT_CREATED\"}]}]\nBACKPORT-->\n\nCo-authored-by:
Kevin Delemme <[email protected]>"}}]}] BACKPORT-->
  • Loading branch information
kdelemme authored Oct 1, 2024
1 parent 1d2e2fe commit ff216c5
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 173 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@
* 2.0.
*/

import { ALL_VALUE, QuerySchema } from '@kbn/slo-schema';
import { i18n } from '@kbn/i18n';
import { EuiIconTip } from '@elastic/eui';
import React from 'react';
import { DataView, FieldSpec } from '@kbn/data-views-plugin/common';
import { QuerySchema } from '@kbn/slo-schema';
import React from 'react';
import { useFormContext } from 'react-hook-form';
import { OptionalText } from './optional_text';
import { CreateSLOForm } from '../../types';
import { IndexFieldSelector } from './index_field_selector';
import { GroupByCardinality } from './group_by_cardinality';
import { GroupByFieldSelector } from './group_by_field_selector';

export function GroupByField({
dataView,
Expand All @@ -32,27 +29,8 @@ export function GroupByField({

return (
<>
<IndexFieldSelector
<GroupByFieldSelector
indexFields={groupByFields}
name="groupBy"
defaultValue={ALL_VALUE}
label={
<span>
{i18n.translate('xpack.slo.sloEdit.groupBy.label', {
defaultMessage: 'Group by',
})}{' '}
<EuiIconTip
content={i18n.translate('xpack.slo.sloEdit.groupBy.tooltip', {
defaultMessage: 'Create individual SLOs for each value of the selected field.',
})}
position="top"
/>
</span>
}
labelAppend={<OptionalText />}
placeholder={i18n.translate('xpack.slo.sloEdit.groupBy.placeholder', {
defaultMessage: 'Select an optional field to group by',
})}
isLoading={!!index && isLoading}
isDisabled={!index}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* 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 { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow, EuiIconTip } from '@elastic/eui';
import { FieldSpec } from '@kbn/data-views-plugin/common';
import { i18n } from '@kbn/i18n';
import { ALL_VALUE } from '@kbn/slo-schema';
import React, { useEffect, useState } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { Option, createOptionsFromFields } from '../../helpers/create_options';
import { CreateSLOForm } from '../../types';
import { OptionalText } from './optional_text';

interface Props {
indexFields: FieldSpec[];
isDisabled: boolean;
isLoading: boolean;
}

const placeholder = i18n.translate('xpack.slo.sloEdit.groupBy.placeholder', {
defaultMessage: 'Select an optional field to group by',
});

export function GroupByFieldSelector({ indexFields, isDisabled, isLoading }: Props) {
const { control, getFieldState } = useFormContext<CreateSLOForm>();
const [options, setOptions] = useState<Option[]>(createOptionsFromFields(indexFields));

useEffect(() => {
setOptions(createOptionsFromFields(indexFields));
}, [indexFields]);

const getSelectedItems = (value: string | string[]) => {
const values = [value].flat();
const selectedItems: Array<EuiComboBoxOptionOption<string>> = [];
indexFields.forEach((field) => {
if (values.includes(field.name)) {
selectedItems.push({ value: field.name, label: field.name });
}
});
return selectedItems;
};

return (
<EuiFormRow
label={
<span>
{i18n.translate('xpack.slo.sloEdit.groupBy.label', {
defaultMessage: 'Group by',
})}{' '}
<EuiIconTip
content={i18n.translate('xpack.slo.sloEdit.groupBy.tooltip', {
defaultMessage: 'Create individual SLOs for each value of the selected field.',
})}
position="top"
/>
</span>
}
isInvalid={getFieldState('groupBy').invalid}
labelAppend={<OptionalText />}
>
<Controller
defaultValue={[ALL_VALUE]}
name={'groupBy'}
control={control}
render={({ field, fieldState }) => {
return (
<EuiComboBox<string>
{...field}
async
placeholder={placeholder}
aria-label={placeholder}
isClearable
isDisabled={isLoading || isDisabled}
isInvalid={fieldState.invalid}
isLoading={isLoading}
onChange={(selected: EuiComboBoxOptionOption[]) => {
if (selected.length) {
return field.onChange(selected.map((selection) => selection.value));
}

field.onChange([ALL_VALUE]);
}}
options={options}
onSearchChange={(searchValue: string) => {
setOptions(
createOptionsFromFields(indexFields, ({ value }) => value.includes(searchValue))
);
}}
selectedOptions={!!indexFields && !!field.value ? getSelectedItems(field.value) : []}
/>
);
}}
/>
</EuiFormRow>
);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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 { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui';
import { FieldSpec } from '@kbn/data-views-plugin/common';
import { i18n } from '@kbn/i18n';
import React, { useEffect, useState } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { Option, createOptionsFromFields } from '../../helpers/create_options';
import { CreateSLOForm } from '../../types';

interface Props {
fields: FieldSpec[];
isDisabled: boolean;
isLoading: boolean;
}

const placeholder = i18n.translate('xpack.slo.sloEdit.timestampField.placeholder', {
defaultMessage: 'Select a timestamp field',
});

export function TimestampFieldSelector({ fields, isDisabled, isLoading }: Props) {
const { control, getFieldState } = useFormContext<CreateSLOForm>();
const [options, setOptions] = useState<Option[]>(createOptionsFromFields(fields));

useEffect(() => {
setOptions(createOptionsFromFields(fields));
}, [fields]);

return (
<EuiFormRow
label={i18n.translate('xpack.slo.sloEdit.timestampField.label', {
defaultMessage: 'Timestamp field',
})}
isInvalid={getFieldState('indicator.params.timestampField').invalid}
>
<Controller
name={'indicator.params.timestampField'}
control={control}
rules={{ required: !isDisabled }}
render={({ field, fieldState }) => {
return (
<EuiComboBox<string>
{...field}
async
placeholder={placeholder}
aria-label={placeholder}
isClearable
isDisabled={isLoading || isDisabled}
isInvalid={fieldState.invalid}
isLoading={isLoading}
onChange={(selected: EuiComboBoxOptionOption[]) => {
if (selected.length) {
return field.onChange(selected[0].value);
}

field.onChange('');
}}
singleSelection={{ asPlainText: true }}
options={options}
onSearchChange={(searchValue: string) => {
setOptions(
createOptionsFromFields(fields, ({ value }) => value.includes(searchValue))
);
}}
selectedOptions={
!!fields && !!field.value ? [{ value: field.value, label: field.value }] : []
}
/>
);
}}
/>
</EuiFormRow>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { GroupByField } from '../common/group_by_field';
import { useCreateDataView } from '../../../../hooks/use_create_data_view';
import { CreateSLOForm } from '../../types';
import { DataPreviewChart } from '../common/data_preview_chart';
import { IndexFieldSelector } from '../common/index_field_selector';
import { QueryBuilder } from '../common/query_builder';
import { DATA_VIEW_FIELD, IndexSelection } from '../custom_common/index_selection';
import { TimestampFieldSelector } from '../common/timestamp_field_selector';

export function CustomKqlIndicatorTypeForm() {
const { watch } = useFormContext<CreateSLOForm>();
Expand All @@ -35,19 +35,13 @@ export function CustomKqlIndicatorTypeForm() {
<IndexSelection selectedDataView={dataView} />
</EuiFlexItem>

<IndexFieldSelector
indexFields={timestampFields}
name="indicator.params.timestampField"
label={i18n.translate('xpack.slo.sloEdit.timestampField.label', {
defaultMessage: 'Timestamp field',
})}
placeholder={i18n.translate('xpack.slo.sloEdit.timestampField.placeholder', {
defaultMessage: 'Select a timestamp field',
})}
isLoading={!!index && isIndexFieldsLoading}
isDisabled={!index}
isRequired
/>
<EuiFlexItem>
<TimestampFieldSelector
fields={timestampFields}
isLoading={!!index && isIndexFieldsLoading}
isDisabled={!index}
/>
</EuiFlexItem>
</EuiFlexGroup>

<EuiFlexItem>
Expand Down
Loading

0 comments on commit ff216c5

Please sign in to comment.