mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
adds a check to allow only data views with time fields
This commit is contained in:
parent
2b58567771
commit
a01975dba7
4 changed files with 105 additions and 46 deletions
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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 { EuiSpacer, EuiCallOut } from '@elastic/eui';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export const TimeFieldWarning = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<EuiCallOut
|
||||||
|
size="s"
|
||||||
|
title={i18n.translate(
|
||||||
|
'xpack.aiops.logCategorization.embeddableMenu.timeFieldWarning.title',
|
||||||
|
{
|
||||||
|
defaultMessage: 'The selected data view does not contain a time field.',
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
color="warning"
|
||||||
|
iconType="warning"
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
{i18n.translate(
|
||||||
|
'xpack.aiops.logCategorization.embeddableMenu.timeFieldWarning.title.description',
|
||||||
|
{
|
||||||
|
defaultMessage: 'Pattern analysis can only be run on data views with a time field.',
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</EuiCallOut>
|
||||||
|
<EuiSpacer />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -8,6 +8,7 @@
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import React, { useEffect, useMemo, useState, useCallback } from 'react';
|
import React, { useEffect, useMemo, useState, useCallback } from 'react';
|
||||||
import { pick } from 'lodash';
|
import { pick } from 'lodash';
|
||||||
|
import useMountedState from 'react-use/lib/useMountedState';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiFlyoutHeader,
|
EuiFlyoutHeader,
|
||||||
|
@ -20,6 +21,7 @@ import {
|
||||||
EuiFlexGroup,
|
EuiFlexGroup,
|
||||||
EuiFlexItem,
|
EuiFlexItem,
|
||||||
EuiFlyoutFooter,
|
EuiFlyoutFooter,
|
||||||
|
EuiSpacer,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
import type { IndexPatternSelectProps } from '@kbn/unified-search-plugin/public';
|
import type { IndexPatternSelectProps } from '@kbn/unified-search-plugin/public';
|
||||||
|
@ -29,6 +31,8 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
||||||
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
|
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
|
||||||
import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
|
import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
|
||||||
|
|
||||||
|
import { TimeFieldWarning } from '../../components/time_field_warning';
|
||||||
|
|
||||||
import type { LogRateAnalysisEmbeddableRuntimeState } from './types';
|
import type { LogRateAnalysisEmbeddableRuntimeState } from './types';
|
||||||
|
|
||||||
export interface LogRateAnalysisEmbeddableInitializerProps {
|
export interface LogRateAnalysisEmbeddableInitializerProps {
|
||||||
|
@ -52,13 +56,22 @@ export const LogRateAnalysisEmbeddableInitializer: FC<
|
||||||
onPreview,
|
onPreview,
|
||||||
isNewPanel,
|
isNewPanel,
|
||||||
}) => {
|
}) => {
|
||||||
|
const isMounted = useMountedState();
|
||||||
|
|
||||||
const [formInput, setFormInput] = useState<LogRateAnalysisEmbeddableRuntimeState>(
|
const [formInput, setFormInput] = useState<LogRateAnalysisEmbeddableRuntimeState>(
|
||||||
pick(initialInput ?? {}, ['dataViewId']) as LogRateAnalysisEmbeddableRuntimeState
|
pick(initialInput ?? {}, ['dataViewId']) as LogRateAnalysisEmbeddableRuntimeState
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// State to track if the selected data view is time based, undefined is used
|
||||||
|
// to track that the check is in progress.
|
||||||
|
const [isDataViewTimeBased, setIsDataViewTimeBased] = useState<boolean | undefined>();
|
||||||
|
|
||||||
const isFormValid = useMemo(
|
const isFormValid = useMemo(
|
||||||
() => isPopulatedObject(formInput, ['dataViewId']) && formInput.dataViewId !== '',
|
() =>
|
||||||
[formInput]
|
isPopulatedObject(formInput, ['dataViewId']) &&
|
||||||
|
formInput.dataViewId !== '' &&
|
||||||
|
isDataViewTimeBased === true,
|
||||||
|
[formInput, isDataViewTimeBased]
|
||||||
);
|
);
|
||||||
|
|
||||||
const updatedProps = useMemo(() => {
|
const updatedProps = useMemo(() => {
|
||||||
|
@ -78,7 +91,7 @@ export const LogRateAnalysisEmbeddableInitializer: FC<
|
||||||
onPreview(updatedProps);
|
onPreview(updatedProps);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[isFormValid, onPreview, updatedProps]
|
[isFormValid, onPreview, updatedProps, isDataViewTimeBased]
|
||||||
);
|
);
|
||||||
|
|
||||||
const setDataViewId = useCallback(
|
const setDataViewId = useCallback(
|
||||||
|
@ -87,10 +100,36 @@ export const LogRateAnalysisEmbeddableInitializer: FC<
|
||||||
...formInput,
|
...formInput,
|
||||||
dataViewId: dataViewId ?? '',
|
dataViewId: dataViewId ?? '',
|
||||||
});
|
});
|
||||||
|
setIsDataViewTimeBased(undefined);
|
||||||
},
|
},
|
||||||
[formInput]
|
[formInput]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
function checkIsDataViewTimeBased() {
|
||||||
|
setIsDataViewTimeBased(undefined);
|
||||||
|
|
||||||
|
const { dataViewId } = formInput;
|
||||||
|
|
||||||
|
if (!dataViewId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataViews
|
||||||
|
.get(dataViewId)
|
||||||
|
.then((dataView) => {
|
||||||
|
if (!isMounted()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setIsDataViewTimeBased(dataView.isTimeBased());
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setIsDataViewTimeBased(undefined);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[dataViews, formInput, isMounted]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<EuiFlyoutHeader
|
<EuiFlyoutHeader
|
||||||
|
@ -121,21 +160,29 @@ export const LogRateAnalysisEmbeddableInitializer: FC<
|
||||||
defaultMessage: 'Data view',
|
defaultMessage: 'Data view',
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<IndexPatternSelect
|
<>
|
||||||
autoFocus={!formInput.dataViewId}
|
<IndexPatternSelect
|
||||||
fullWidth
|
autoFocus={!formInput.dataViewId}
|
||||||
compressed
|
fullWidth
|
||||||
indexPatternId={formInput.dataViewId}
|
compressed
|
||||||
placeholder={i18n.translate(
|
indexPatternId={formInput.dataViewId}
|
||||||
'xpack.aiops.embeddableLogRateAnalysis.config.dataViewSelectorPlaceholder',
|
placeholder={i18n.translate(
|
||||||
{
|
'xpack.aiops.embeddableLogRateAnalysis.config.dataViewSelectorPlaceholder',
|
||||||
defaultMessage: 'Select data view',
|
{
|
||||||
}
|
defaultMessage: 'Select data view',
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
onChange={(newId) => {
|
||||||
|
setDataViewId(newId ?? '');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{isDataViewTimeBased === false && (
|
||||||
|
<>
|
||||||
|
<EuiSpacer size="m" />
|
||||||
|
<TimeFieldWarning />
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
onChange={(newId) => {
|
</>
|
||||||
setDataViewId(newId ?? '');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</EuiFormRow>
|
</EuiFormRow>
|
||||||
</EuiForm>
|
</EuiForm>
|
||||||
</EuiFlyoutBody>
|
</EuiFlyoutBody>
|
||||||
|
|
|
@ -33,6 +33,7 @@ import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
|
||||||
import { DataSourceContextProvider } from '../../hooks/use_data_source';
|
import { DataSourceContextProvider } from '../../hooks/use_data_source';
|
||||||
import type { PatternAnalysisEmbeddableRuntimeState } from './types';
|
import type { PatternAnalysisEmbeddableRuntimeState } from './types';
|
||||||
import { PatternAnalysisSettings } from '../../components/log_categorization/log_categorization_for_embeddable/embeddable_menu';
|
import { PatternAnalysisSettings } from '../../components/log_categorization/log_categorization_for_embeddable/embeddable_menu';
|
||||||
|
import { TimeFieldWarning } from '../../components/time_field_warning';
|
||||||
import { RandomSampler } from '../../components/log_categorization/sampling_menu';
|
import { RandomSampler } from '../../components/log_categorization/sampling_menu';
|
||||||
import {
|
import {
|
||||||
DEFAULT_PROBABILITY,
|
DEFAULT_PROBABILITY,
|
||||||
|
@ -394,31 +395,3 @@ const TextFieldWarning = () => {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const TimeFieldWarning = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<EuiCallOut
|
|
||||||
size="s"
|
|
||||||
title={i18n.translate(
|
|
||||||
'xpack.aiops.logCategorization.embeddableMenu.timeFieldWarning.title',
|
|
||||||
{
|
|
||||||
defaultMessage: 'The selected data view does not contain a time field.',
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
color="warning"
|
|
||||||
iconType="warning"
|
|
||||||
>
|
|
||||||
<p>
|
|
||||||
{i18n.translate(
|
|
||||||
'xpack.aiops.logCategorization.embeddableMenu.timeFieldWarning.title.description',
|
|
||||||
{
|
|
||||||
defaultMessage: 'Pattern analysis can only be run on data views with a time field.',
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
</EuiCallOut>
|
|
||||||
<EuiSpacer />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
|
@ -146,6 +146,7 @@ const LogRateAnalysisEmbeddableWrapperWithDeps: FC<LogRateAnalysisPropsWithDeps>
|
||||||
setRerenderFlag((prev) => !prev);
|
setRerenderFlag((prev) => !prev);
|
||||||
}
|
}
|
||||||
}, [dataViewId, prevDataViewId]);
|
}, [dataViewId, prevDataViewId]);
|
||||||
|
const showComponent = prevDataViewId === undefined || prevDataViewId === dataViewId;
|
||||||
|
|
||||||
// TODO: Remove data-shared-item as part of https://github.com/elastic/kibana/issues/179376>
|
// TODO: Remove data-shared-item as part of https://github.com/elastic/kibana/issues/179376>
|
||||||
return (
|
return (
|
||||||
|
@ -159,7 +160,7 @@ const LogRateAnalysisEmbeddableWrapperWithDeps: FC<LogRateAnalysisPropsWithDeps>
|
||||||
padding: '10px',
|
padding: '10px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{prevDataViewId === dataViewId && (
|
{showComponent && (
|
||||||
<Router history={history}>
|
<Router history={history}>
|
||||||
<ReloadContextProvider reload$={resultObservable$}>
|
<ReloadContextProvider reload$={resultObservable$}>
|
||||||
<AiopsAppContext.Provider value={aiopsAppContextValue}>
|
<AiopsAppContext.Provider value={aiopsAppContextValue}>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue