Skip to content

Commit

Permalink
Extract timestamp field selector component and improve search
Browse files Browse the repository at this point in the history
  • Loading branch information
kdelemme committed Aug 29, 2023
1 parent 4c8229d commit 1d259af
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 188 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* 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 { i18n } from '@kbn/i18n';
import React, { useEffect, useState } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import {
Field,
useFetchIndexPatternFields,
} from '../../../../hooks/slo/use_fetch_index_pattern_fields';
import { createOptionsFromFields, Option } from '../../helpers/create_options';
import { CreateSLOForm } from '../../types';

interface Props {
index?: string;
}
export function TimestampFieldSelector({ index }: Props) {
const { control, getFieldState } = useFormContext<CreateSLOForm>();
const [options, setOptions] = useState<Option[]>([]);

const { isLoading, data: indexFields = [] } = useFetchIndexPatternFields(index);
const [timestampFields, setTimestampFields] = useState<Field[]>([]);

useEffect(() => {
if (indexFields.length > 0) {
const indexFieldsTimestamp = indexFields.filter((field) => field.type === 'date');
setTimestampFields(indexFieldsTimestamp);
setOptions(createOptionsFromFields(indexFieldsTimestamp));
}
}, [indexFields]);

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

field.onChange('');
}}
options={options}
onSearchChange={(searchValue: string) => {
setOptions(
createOptionsFromFields(timestampFields, ({ value }) => value.includes(searchValue))
);
}}
selectedOptions={
!!index &&
!!field.value &&
timestampFields.some((timestampField) => timestampField.name === field.value)
? [{ value: field.value, label: field.value }]
: []
}
singleSelection
/>
)}
/>
</EuiFormRow>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,88 +5,30 @@
* 2.0.
*/

import {
EuiComboBox,
EuiComboBoxOptionOption,
EuiFlexGroup,
EuiFlexItem,
EuiFormRow,
EuiIconTip,
} from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiIconTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields';
import { createOptionsFromFields } from '../../helpers/create_options';
import { useFormContext } from 'react-hook-form';
import { CreateSLOForm } from '../../types';
import { DataPreviewChart } from '../common/data_preview_chart';
import { GroupByFieldSelector } from '../common/group_by_field_selector';
import { QueryBuilder } from '../common/query_builder';
import { TimestampFieldSelector } from '../common/timestamp_field_selector';
import { IndexSelection } from '../custom_common/index_selection';

export function CustomKqlIndicatorTypeForm() {
const { control, watch, getFieldState } = useFormContext<CreateSLOForm>();

const { watch } = useFormContext<CreateSLOForm>();
const index = watch('indicator.params.index');
const { isLoading, data: indexFields } = useFetchIndexPatternFields(index);
const timestampFields = (indexFields ?? []).filter((field) => field.type === 'date');

return (
<EuiFlexGroup direction="column" gutterSize="l">
<EuiFlexGroup direction="row" gutterSize="l">
<EuiFlexItem>
<IndexSelection />
</EuiFlexItem>
<EuiFlexItem>
<EuiFormRow
label={i18n.translate(
'xpack.observability.slo.sloEdit.sliType.customKql.timestampField.label',
{ defaultMessage: 'Timestamp field' }
)}
isInvalid={getFieldState('indicator.params.timestampField').invalid}
>
<Controller
name="indicator.params.timestampField"
defaultValue=""
rules={{ required: true }}
control={control}
render={({ field: { ref, ...field }, fieldState }) => (
<EuiComboBox
{...field}
async
placeholder={i18n.translate(
'xpack.observability.slo.sloEdit.sliType.customKql.timestampField.placeholder',
{ defaultMessage: 'Select a timestamp field' }
)}
aria-label={i18n.translate(
'xpack.observability.slo.sloEdit.sliType.customKql.timestampField.placeholder',
{ defaultMessage: 'Select a timestamp field' }
)}
data-test-subj="customKqlIndicatorFormTimestampFieldSelect"
isClearable
isDisabled={!index}
isInvalid={fieldState.invalid}
isLoading={!!index && isLoading}
onChange={(selected: EuiComboBoxOptionOption[]) => {
if (selected.length) {
return field.onChange(selected[0].value);
}

field.onChange('');
}}
options={createOptionsFromFields(timestampFields)}
selectedOptions={
!!index &&
!!field.value &&
timestampFields.some((timestampField) => timestampField.name === field.value)
? [{ value: field.value, label: field.value }]
: []
}
singleSelection
/>
)}
/>
</EuiFormRow>
<EuiFlexItem>
<TimestampFieldSelector index={index} />
</EuiFlexItem>
</EuiFlexGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,32 @@
*/

import {
EuiComboBox,
EuiComboBoxOptionOption,
EuiFlexGroup,
EuiFlexItem,
EuiFormRow,
EuiHorizontalRule,
EuiIconTip,
EuiSpacer,
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { FormattedMessage } from '@kbn/i18n-react';
import React from 'react';
import { useFormContext } from 'react-hook-form';
import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields';
import { createOptionsFromFields } from '../../helpers/create_options';
import { CreateSLOForm } from '../../types';
import { DataPreviewChart } from '../common/data_preview_chart';
import { GroupByFieldSelector } from '../common/group_by_field_selector';
import { QueryBuilder } from '../common/query_builder';
import { TimestampFieldSelector } from '../common/timestamp_field_selector';
import { IndexSelection } from '../custom_common/index_selection';
import { MetricIndicator } from './metric_indicator';
import { GroupByFieldSelector } from '../common/group_by_field_selector';

export { NEW_CUSTOM_METRIC } from './metric_indicator';

export function CustomMetricIndicatorTypeForm() {
const { control, watch, getFieldState } = useFormContext<CreateSLOForm>();

const { watch } = useFormContext<CreateSLOForm>();
const index = watch('indicator.params.index');
const { isLoading, data: indexFields } = useFetchIndexPatternFields(index);
const timestampFields = (indexFields ?? []).filter((field) => field.type === 'date');

return (
<>
Expand All @@ -55,61 +50,7 @@ export function CustomMetricIndicatorTypeForm() {
<IndexSelection />
</EuiFlexItem>
<EuiFlexItem>
<EuiFormRow
label={i18n.translate(
'xpack.observability.slo.sloEdit.sliType.customMetric.timestampField.label',
{ defaultMessage: 'Timestamp field' }
)}
isInvalid={getFieldState('indicator.params.timestampField').invalid}
>
<Controller
name="indicator.params.timestampField"
defaultValue=""
rules={{ required: true }}
control={control}
render={({ field: { ref, ...field }, fieldState }) => (
<EuiComboBox
{...field}
async
placeholder={i18n.translate(
'xpack.observability.slo.sloEdit.sliType.customMetric.timestampField.placeholder',
{ defaultMessage: 'Select a timestamp field' }
)}
aria-label={i18n.translate(
'xpack.observability.slo.sloEdit.sliType.customMetric.timestampField.placeholder',
{ defaultMessage: 'Select a timestamp field' }
)}
data-test-subj="customMetricIndicatorFormTimestampFieldSelect"
isClearable
isDisabled={!watch('indicator.params.index')}
isInvalid={fieldState.invalid}
isLoading={!!watch('indicator.params.index') && isLoading}
onChange={(selected: EuiComboBoxOptionOption[]) => {
if (selected.length) {
return field.onChange(selected[0].value);
}

field.onChange('');
}}
options={createOptionsFromFields(timestampFields)}
selectedOptions={
!!watch('indicator.params.index') &&
!!field.value &&
timestampFields.some((timestampField) => timestampField.name === field.value)
? [
{
value: field.value,
label: field.value,
'data-test-subj': `customMetricIndicatorFormTimestampFieldSelectedValue`,
},
]
: []
}
singleSelection={{ asPlainText: true }}
/>
)}
/>
</EuiFormRow>
<TimestampFieldSelector index={index} />
</EuiFlexItem>
</EuiFlexGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,30 @@
*/

import {
EuiComboBox,
EuiComboBoxOptionOption,
EuiFlexGroup,
EuiFlexItem,
EuiFormRow,
EuiHorizontalRule,
EuiIconTip,
EuiSpacer,
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { FormattedMessage } from '@kbn/i18n-react';
import React from 'react';
import { useFormContext } from 'react-hook-form';
import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields';
import { createOptionsFromFields } from '../../helpers/create_options';
import { CreateSLOForm } from '../../types';
import { DataPreviewChart } from '../common/data_preview_chart';
import { GroupByFieldSelector } from '../common/group_by_field_selector';
import { QueryBuilder } from '../common/query_builder';
import { TimestampFieldSelector } from '../common/timestamp_field_selector';
import { IndexSelection } from '../custom_common/index_selection';
import { HistogramIndicator } from './histogram_indicator';
import { GroupByFieldSelector } from '../common/group_by_field_selector';

export function HistogramIndicatorTypeForm() {
const { control, watch, getFieldState } = useFormContext<CreateSLOForm>();

const { watch } = useFormContext<CreateSLOForm>();
const index = watch('indicator.params.index');
const { isLoading, data: indexFields } = useFetchIndexPatternFields(index);
const timestampFields = (indexFields ?? []).filter((field) => field.type === 'date');

return (
<>
Expand All @@ -53,55 +48,7 @@ export function HistogramIndicatorTypeForm() {
<IndexSelection />
</EuiFlexItem>
<EuiFlexItem>
<EuiFormRow
label={i18n.translate(
'xpack.observability.slo.sloEdit.sliType.histogram.timestampField.label',
{ defaultMessage: 'Timestamp field' }
)}
isInvalid={getFieldState('indicator.params.timestampField').invalid}
>
<Controller
name="indicator.params.timestampField"
defaultValue=""
rules={{ required: true }}
control={control}
render={({ field: { ref, ...field }, fieldState }) => (
<EuiComboBox
{...field}
async
placeholder={i18n.translate(
'xpack.observability.slo.sloEdit.sliType.histogram.timestampField.placeholder',
{ defaultMessage: 'Select a timestamp field' }
)}
aria-label={i18n.translate(
'xpack.observability.slo.sloEdit.sliType.histogram.timestampField.placeholder',
{ defaultMessage: 'Select a timestamp field' }
)}
data-test-subj="histogramIndicatorFormTimestampFieldSelect"
isClearable
isDisabled={!index}
isInvalid={fieldState.invalid}
isLoading={!!index && isLoading}
onChange={(selected: EuiComboBoxOptionOption[]) => {
if (selected.length) {
return field.onChange(selected[0].value);
}

field.onChange('');
}}
options={createOptionsFromFields(timestampFields)}
selectedOptions={
!!index &&
!!field.value &&
timestampFields.some((timestampField) => timestampField.name === field.value)
? [{ value: field.value, label: field.value }]
: []
}
singleSelection={{ asPlainText: true }}
/>
)}
/>
</EuiFormRow>
<TimestampFieldSelector index={index} />
</EuiFlexItem>
</EuiFlexGroup>

Expand Down

0 comments on commit 1d259af

Please sign in to comment.