diff --git a/x-pack/plugins/observability/public/hooks/slo/use_fetch_index_pattern_fields.ts b/x-pack/plugins/observability/public/hooks/slo/use_fetch_index_pattern_fields.ts
deleted file mode 100644
index 5aedb92219da6..0000000000000
--- a/x-pack/plugins/observability/public/hooks/slo/use_fetch_index_pattern_fields.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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 { FieldSpec } from '@kbn/data-views-plugin/common';
-import { useQuery } from '@tanstack/react-query';
-import { useKibana } from '../../utils/kibana_react';
-
-export interface UseFetchIndexPatternFieldsResponse {
- isLoading: boolean;
- isSuccess: boolean;
- isError: boolean;
- data: FieldSpec[] | undefined;
-}
-
-export function useFetchIndexPatternFields(
- indexPattern?: string
-): UseFetchIndexPatternFieldsResponse {
- const { dataViews } = useKibana().services;
-
- const { isLoading, isError, isSuccess, data } = useQuery({
- queryKey: ['fetchIndexPatternFields', indexPattern],
- queryFn: async ({ signal }) => {
- if (!indexPattern) {
- return [];
- }
- try {
- return await dataViews.getFieldsForWildcard({ pattern: indexPattern, allowNoIndex: true });
- } catch (error) {
- throw new Error(`Something went wrong. Error: ${error}`);
- }
- },
- retry: false,
- refetchOnWindowFocus: false,
- enabled: Boolean(indexPattern),
- });
-
- return { isLoading, isError, isSuccess, data };
-}
diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/apm_availability/apm_availability_indicator_type_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/apm_availability/apm_availability_indicator_type_form.tsx
index 78afcc71cae58..ade6cc5c32008 100644
--- a/x-pack/plugins/observability/public/pages/slo_edit/components/apm_availability/apm_availability_indicator_type_form.tsx
+++ b/x-pack/plugins/observability/public/pages/slo_edit/components/apm_availability/apm_availability_indicator_type_form.tsx
@@ -5,18 +5,16 @@
* 2.0.
*/
-import { EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiIconTip } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiIconTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { ALL_VALUE } from '@kbn/slo-schema/src/schema/common';
import React, { useEffect } from 'react';
import { useFormContext } from 'react-hook-form';
-import { useFetchGroupByCardinality } from '../../../../hooks/slo/use_fetch_group_by_cardinality';
+import { useCreateDataView } from '../../../../hooks/use_create_data_view';
+import { GroupByField } from '../common/group_by_field';
import { useFetchApmIndex } from '../../../../hooks/slo/use_fetch_apm_indices';
-import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields';
import { CreateSLOForm } from '../../types';
import { FieldSelector } from '../apm_common/field_selector';
import { DataPreviewChart } from '../common/data_preview_chart';
-import { IndexFieldSelector } from '../common/index_field_selector';
import { QueryBuilder } from '../common/query_builder';
export function ApmAvailabilityIndicatorTypeForm() {
@@ -28,15 +26,10 @@ export function ApmAvailabilityIndicatorTypeForm() {
setValue('indicator.params.index', apmIndex);
}
}, [setValue, apmIndex]);
- const timestampField = watch('indicator.params.timestampField');
- const groupByField = watch('groupBy');
- const { isLoading: isIndexFieldsLoading, data: indexFields = [] } =
- useFetchIndexPatternFields(apmIndex);
-
- const { isLoading: isGroupByCardinalityLoading, data: groupByCardinality } =
- useFetchGroupByCardinality(apmIndex, timestampField, groupByField);
- const groupByFields = indexFields.filter((field) => field.aggregatable);
+ const { dataView, loading: isIndexFieldsLoading } = useCreateDataView({
+ indexPatternString: apmIndex,
+ });
return (
@@ -140,42 +133,7 @@ export function ApmAvailabilityIndicatorTypeForm() {
-
- {i18n.translate('xpack.observability.slo.sloEdit.groupBy.label', {
- defaultMessage: 'Group by',
- })}{' '}
-
-
- }
- placeholder={i18n.translate('xpack.observability.slo.sloEdit.groupBy.placeholder', {
- defaultMessage: 'Select an optional field to group by',
- })}
- isLoading={!!apmIndex && isIndexFieldsLoading}
- isDisabled={!apmIndex}
- />
-
- {!isGroupByCardinalityLoading && !!groupByCardinality && (
-
- )}
+
diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/apm_latency/apm_latency_indicator_type_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/apm_latency/apm_latency_indicator_type_form.tsx
index dcb4be69d272d..b93596458a437 100644
--- a/x-pack/plugins/observability/public/pages/slo_edit/components/apm_latency/apm_latency_indicator_type_form.tsx
+++ b/x-pack/plugins/observability/public/pages/slo_edit/components/apm_latency/apm_latency_indicator_type_form.tsx
@@ -5,25 +5,16 @@
* 2.0.
*/
-import {
- EuiCallOut,
- EuiFieldNumber,
- EuiFlexGroup,
- EuiFlexItem,
- EuiFormRow,
- EuiIconTip,
-} from '@elastic/eui';
+import { EuiFieldNumber, EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiIconTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { ALL_VALUE } from '@kbn/slo-schema/src/schema/common';
import React, { useEffect } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
-import { useFetchGroupByCardinality } from '../../../../hooks/slo/use_fetch_group_by_cardinality';
+import { GroupByField } from '../common/group_by_field';
+import { useCreateDataView } from '../../../../hooks/use_create_data_view';
import { useFetchApmIndex } from '../../../../hooks/slo/use_fetch_apm_indices';
-import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields';
import { CreateSLOForm } from '../../types';
import { FieldSelector } from '../apm_common/field_selector';
import { DataPreviewChart } from '../common/data_preview_chart';
-import { IndexFieldSelector } from '../common/index_field_selector';
import { QueryBuilder } from '../common/query_builder';
export function ApmLatencyIndicatorTypeForm() {
@@ -36,15 +27,9 @@ export function ApmLatencyIndicatorTypeForm() {
}
}, [setValue, apmIndex]);
- const timestampField = watch('indicator.params.timestampField');
- const groupByField = watch('groupBy');
-
- const { isLoading: isIndexFieldsLoading, data: indexFields = [] } =
- useFetchIndexPatternFields(apmIndex);
-
- const { isLoading: isGroupByCardinalityLoading, data: groupByCardinality } =
- useFetchGroupByCardinality(apmIndex, timestampField, groupByField);
- const groupByFields = indexFields.filter((field) => field.aggregatable);
+ const { dataView, loading: isIndexFieldsLoading } = useCreateDataView({
+ indexPatternString: apmIndex,
+ });
return (
@@ -191,42 +176,7 @@ export function ApmLatencyIndicatorTypeForm() {
-
- {i18n.translate('xpack.observability.slo.sloEdit.groupBy.label', {
- defaultMessage: 'Group by',
- })}{' '}
-
-
- }
- placeholder={i18n.translate('xpack.observability.slo.sloEdit.groupBy.placeholder', {
- defaultMessage: 'Select an optional field to group by',
- })}
- isLoading={!!apmIndex && isIndexFieldsLoading}
- isDisabled={!apmIndex}
- />
-
- {!isGroupByCardinalityLoading && !!groupByCardinality && (
-
- )}
+
diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/common/group_by_field.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/common/group_by_field.tsx
new file mode 100644
index 0000000000000..103e3dc3c93b8
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/slo_edit/components/common/group_by_field.tsx
@@ -0,0 +1,70 @@
+/*
+ * 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 { ALL_VALUE } from '@kbn/slo-schema';
+import { i18n } from '@kbn/i18n';
+import { EuiCallOut, EuiIconTip } from '@elastic/eui';
+import React from 'react';
+import { DataView } from '@kbn/data-views-plugin/common';
+import { useFormContext } from 'react-hook-form';
+import { OptionalText } from './optional_text';
+import { useFetchGroupByCardinality } from '../../../../hooks/slo/use_fetch_group_by_cardinality';
+import { CreateSLOForm } from '../../types';
+import { IndexFieldSelector } from './index_field_selector';
+
+export function GroupByField({ dataView, isLoading }: { dataView?: DataView; isLoading: boolean }) {
+ const { watch } = useFormContext();
+
+ const groupByFields = dataView?.fields?.filter((field) => field.aggregatable) ?? [];
+ const index = watch('indicator.params.index');
+ const timestampField = watch('indicator.params.timestampField');
+ const groupByField = watch('groupBy');
+
+ const { isLoading: isGroupByCardinalityLoading, data: groupByCardinality } =
+ useFetchGroupByCardinality(index, timestampField, groupByField);
+
+ return (
+ <>
+
+ {i18n.translate('xpack.observability.slo.sloEdit.groupBy.label', {
+ defaultMessage: 'Group by',
+ })}{' '}
+
+
+ }
+ labelAppend={}
+ placeholder={i18n.translate('xpack.observability.slo.sloEdit.groupBy.placeholder', {
+ defaultMessage: 'Select an optional field to group by',
+ })}
+ isLoading={!!index && isLoading}
+ isDisabled={!index}
+ />
+ {!isGroupByCardinalityLoading && !!groupByCardinality && (
+
+ )}
+ >
+ );
+}
diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/common/index_field_selector.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/common/index_field_selector.tsx
index 46d4af15de628..aa5b663f75770 100644
--- a/x-pack/plugins/observability/public/pages/slo_edit/components/common/index_field_selector.tsx
+++ b/x-pack/plugins/observability/public/pages/slo_edit/components/common/index_field_selector.tsx
@@ -21,11 +21,13 @@ interface Props {
isLoading: boolean;
isRequired?: boolean;
defaultValue?: string;
+ labelAppend?: ReactNode;
}
export function IndexFieldSelector({
indexFields,
name,
label,
+ labelAppend,
placeholder,
isDisabled,
isLoading,
@@ -41,7 +43,7 @@ export function IndexFieldSelector({
return (
-
+
+ {i18n.translate('xpack.observability.slo.sloEdit.optionalLabel', {
+ defaultMessage: 'Optional',
+ })}
+
+ );
+}
diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/common/query_builder.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/common/query_builder.tsx
index db451234b6e31..0bd66f7881820 100644
--- a/x-pack/plugins/observability/public/pages/slo_edit/components/common/query_builder.tsx
+++ b/x-pack/plugins/observability/public/pages/slo_edit/components/common/query_builder.tsx
@@ -11,6 +11,7 @@ import { Controller, FieldPath, useFormContext } from 'react-hook-form';
import { useCreateDataView } from '../../../../hooks/use_create_data_view';
import { useKibana } from '../../../../utils/kibana_react';
import { CreateSLOForm } from '../../types';
+import { OptionalText } from './optional_text';
export interface Props {
dataTestSubj: string;
@@ -54,6 +55,7 @@ export function QueryBuilder({
label
)
}
+ labelAppend={!required ? : undefined}
isInvalid={getFieldState(name).invalid}
fullWidth
>
@@ -62,14 +64,12 @@ export function QueryBuilder({
name={name}
control={control}
rules={{
- required: Boolean(required),
+ required: Boolean(required) && Boolean(dataView),
}}
render={({ field, fieldState }) => (
();
const index = watch('indicator.params.index');
- const timestampField = watch('indicator.params.timestampField');
- const groupByField = watch('groupBy');
const { dataView, loading: isIndexFieldsLoading } = useCreateDataView({
indexPatternString: index,
});
const timestampFields = dataView?.fields?.filter((field) => field.type === 'date') ?? [];
- const groupByFields = dataView?.fields?.filter((field) => field.aggregatable) ?? [];
-
- const { isLoading: isGroupByCardinalityLoading, data: groupByCardinality } =
- useFetchGroupByCardinality(index, timestampField, groupByField);
return (
@@ -142,42 +135,7 @@ export function CustomKqlIndicatorTypeForm() {
/>
-
- {i18n.translate('xpack.observability.slo.sloEdit.groupBy.label', {
- defaultMessage: 'Group by',
- })}{' '}
-
-
- }
- placeholder={i18n.translate('xpack.observability.slo.sloEdit.groupBy.placeholder', {
- defaultMessage: 'Select an optional field to group by',
- })}
- isLoading={!!index && isIndexFieldsLoading}
- isDisabled={!index}
- />
-
- {!isGroupByCardinalityLoading && !!groupByCardinality && (
-
- )}
+
diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx
index 2db17479ffd2d..b40a7cd43227a 100644
--- a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx
+++ b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx
@@ -6,7 +6,6 @@
*/
import {
- EuiCallOut,
EuiFlexGroup,
EuiFlexItem,
EuiHorizontalRule,
@@ -16,11 +15,10 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
-import { ALL_VALUE } from '@kbn/slo-schema/src/schema/common';
import React from 'react';
import { useFormContext } from 'react-hook-form';
-import { useFetchGroupByCardinality } from '../../../../hooks/slo/use_fetch_group_by_cardinality';
-import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields';
+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';
@@ -35,17 +33,13 @@ const SUPPORTED_METRIC_FIELD_TYPES = ['number', 'histogram'];
export function CustomMetricIndicatorTypeForm() {
const { watch } = useFormContext();
const index = watch('indicator.params.index');
- const timestampField = watch('indicator.params.timestampField');
- const groupByField = watch('groupBy');
- const { isLoading: isIndexFieldsLoading, data: indexFields = [] } =
- useFetchIndexPatternFields(index);
- const { isLoading: isGroupByCardinalityLoading, data: groupByCardinality } =
- useFetchGroupByCardinality(index, timestampField, groupByField);
+ const { dataView, loading: isIndexFieldsLoading } = useCreateDataView({
+ indexPatternString: index,
+ });
- const timestampFields = indexFields.filter((field) => field.type === 'date');
- const groupByFields = indexFields.filter((field) => field.aggregatable);
- const metricFields = indexFields.filter((field) =>
+ const timestampFields = dataView?.fields.filter((field) => field.type === 'date');
+ const metricFields = dataView?.fields.filter((field) =>
SUPPORTED_METRIC_FIELD_TYPES.includes(field.type)
);
@@ -67,7 +61,7 @@ export function CustomMetricIndicatorTypeForm() {
@@ -150,7 +144,7 @@ export function CustomMetricIndicatorTypeForm() {
@@ -159,42 +153,7 @@ export function CustomMetricIndicatorTypeForm() {
-
- {i18n.translate('xpack.observability.slo.sloEdit.groupBy.label', {
- defaultMessage: 'Group by',
- })}{' '}
-
-
- }
- placeholder={i18n.translate('xpack.observability.slo.sloEdit.groupBy.placeholder', {
- defaultMessage: 'Select an optional field to group by',
- })}
- isLoading={!!index && isIndexFieldsLoading}
- isDisabled={!index}
- />
-
- {!isGroupByCardinalityLoading && !!groupByCardinality && (
-
- )}
+
diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx
index 992547dc2802f..9abe0828b6695 100644
--- a/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx
+++ b/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx
@@ -6,7 +6,6 @@
*/
import {
- EuiCallOut,
EuiFlexGroup,
EuiFlexItem,
EuiHorizontalRule,
@@ -16,11 +15,10 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
-import { ALL_VALUE } from '@kbn/slo-schema/src/schema/common';
import React from 'react';
import { useFormContext } from 'react-hook-form';
-import { useFetchGroupByCardinality } from '../../../../hooks/slo/use_fetch_group_by_cardinality';
-import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields';
+import { useCreateDataView } from '../../../../hooks/use_create_data_view';
+import { GroupByField } from '../common/group_by_field';
import { CreateSLOForm } from '../../types';
import { DataPreviewChart } from '../common/data_preview_chart';
import { IndexFieldSelector } from '../common/index_field_selector';
@@ -31,17 +29,13 @@ import { HistogramIndicator } from './histogram_indicator';
export function HistogramIndicatorTypeForm() {
const { watch } = useFormContext();
const index = watch('indicator.params.index');
- const timestampField = watch('indicator.params.timestampField');
- const groupByField = watch('groupBy');
- const { isLoading: isIndexFieldsLoading, data: indexFields = [] } =
- useFetchIndexPatternFields(index);
- const { isLoading: isGroupByCardinalityLoading, data: groupByCardinality } =
- useFetchGroupByCardinality(index, timestampField, groupByField);
+ const { dataView, loading: isIndexFieldsLoading } = useCreateDataView({
+ indexPatternString: index,
+ });
- const histogramFields = indexFields.filter((field) => field.type === 'histogram');
- const timestampFields = indexFields.filter((field) => field.type === 'date');
- const groupByFields = indexFields.filter((field) => field.aggregatable);
+ const histogramFields = dataView?.fields.filter((field) => field.type === 'histogram');
+ const timestampFields = dataView?.fields.filter((field) => field.type === 'date');
return (
<>
@@ -61,7 +55,7 @@ export function HistogramIndicatorTypeForm() {
@@ -137,7 +131,7 @@ export function HistogramIndicatorTypeForm() {
@@ -145,42 +139,7 @@ export function HistogramIndicatorTypeForm() {
-
- {i18n.translate('xpack.observability.slo.sloEdit.groupBy.label', {
- defaultMessage: 'Group by',
- })}{' '}
-
-
- }
- placeholder={i18n.translate('xpack.observability.slo.sloEdit.groupBy.placeholder', {
- defaultMessage: 'Select an optional field to group by',
- })}
- isLoading={!!index && isIndexFieldsLoading}
- isDisabled={!index}
- />
-
- {!isGroupByCardinalityLoading && !!groupByCardinality && (
-
- )}
+
diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form_description_section.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form_description_section.tsx
index 6b7c25f57025e..8e4e2f26ea19a 100644
--- a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form_description_section.tsx
+++ b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form_description_section.tsx
@@ -19,6 +19,7 @@ import {
import { i18n } from '@kbn/i18n';
import React from 'react';
import { Controller, useFormContext } from 'react-hook-form';
+import { OptionalText } from './common/optional_text';
import { CreateSLOForm } from '../types';
import { maxWidth } from './slo_edit_form';
@@ -74,6 +75,7 @@ export function SloEditFormDescriptionSection() {
label={i18n.translate('xpack.observability.slo.sloEdit.description.sloDescription', {
defaultMessage: 'Description',
})}
+ labelAppend={}
>
();
const index = watch('indicator.params.index');
- const timestampField = watch('indicator.params.timestampField');
- const groupByField = watch('groupBy');
- const { isLoading: isIndexFieldsLoading, data: indexFields = [] } =
- useFetchIndexPatternFields(index);
- const { isLoading: isGroupByCardinalityLoading, data: groupByCardinality } =
- useFetchGroupByCardinality(index, timestampField, groupByField);
+ const { dataView, loading: isIndexFieldsLoading } = useCreateDataView({
+ indexPatternString: index,
+ });
- const timestampFields = indexFields.filter((field) => field.type === 'date');
- const groupByFields = indexFields.filter((field) => field.aggregatable);
+ const timestampFields = dataView?.fields.filter((field) => field.type === 'date');
const { uiSettings } = useKibana().services;
const threshold = watch('indicator.params.metric.threshold');
const comparator = watch('indicator.params.metric.comparator');
@@ -69,7 +63,7 @@ export function TimesliceMetricIndicatorTypeForm() {
-
+
-
- {i18n.translate('xpack.observability.slo.sloEdit.groupBy.label', {
- defaultMessage: 'Group by',
- })}{' '}
-
-
- }
- placeholder={i18n.translate('xpack.observability.slo.sloEdit.groupBy.placeholder', {
- defaultMessage: 'Select an optional field to group by',
- })}
- isLoading={!!index && isIndexFieldsLoading}
- isDisabled={!index}
- />
-
- {!isGroupByCardinalityLoading && !!groupByCardinality && (
-
- )}
+
{
isLoading: false,
data: ['some-index', 'index-2'],
});
- useFetchIndexPatternFieldsMock.mockReturnValue({
- isLoading: false,
- data: [
- { name: 'field', type: 'date', aggregatable: false, searchable: false },
- { name: 'field_text', type: 'text', aggregatable: true, searchable: true },
- ],
- });
useCreateSloMock.mockReturnValue({
isLoading: false,