-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ML][Fleet] Adds link to anomaly detection configurations from Integration > Assets tab #193105
Changes from 4 commits
61c6f83
28d258d
3c72ce1
97ba426
f4cde98
dd3d917
6434887
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,18 +6,32 @@ | |
*/ | ||
|
||
import React, { useCallback, useMemo, useState } from 'react'; | ||
import type { SearchFilterConfig, FieldValueOptionType } from '@elastic/eui'; | ||
import { EuiCard, EuiIcon, EuiFlexGrid, EuiFlexItem, EuiSearchBar, EuiSpacer } from '@elastic/eui'; | ||
import type { SearchFilterConfig, FieldValueOptionType, EuiSearchBarProps } from '@elastic/eui'; | ||
import { | ||
EuiCard, | ||
EuiIcon, | ||
EuiFlexGrid, | ||
EuiFlexItem, | ||
EuiFormRow, | ||
EuiSearchBar, | ||
EuiSpacer, | ||
} from '@elastic/eui'; | ||
import { i18n } from '@kbn/i18n'; | ||
import { usePageUrlState, type PageUrlState } from '@kbn/ml-url-state'; | ||
import useMountedState from 'react-use/lib/useMountedState'; | ||
import useMount from 'react-use/lib/useMount'; | ||
import { isPopulatedObject } from '@kbn/ml-is-populated-object'; | ||
import { useMlKibana } from '../contexts/kibana'; | ||
import type { Module } from '../../../common/types/modules'; | ||
import { ML_PAGES } from '../../../common/constants/locator'; | ||
import { LoadingIndicator } from '../components/loading_indicator'; | ||
import { filterModules } from './utils'; | ||
import { SuppliedConfigurationsFlyout } from './supplied_configurations_flyout'; | ||
|
||
interface SuppliedConfigurationsPageUrlState { | ||
queryText: string; | ||
} | ||
|
||
export function isLogoObject(arg: unknown): arg is { icon: string } { | ||
return isPopulatedObject(arg) && Object.hasOwn(arg, 'icon'); | ||
} | ||
|
@@ -31,9 +45,14 @@ export const SuppliedConfigurations = () => { | |
}, | ||
} = useMlKibana(); | ||
|
||
const [suppliedConfigurationsPageState, setSuppliedConfigurationsPageState] = | ||
usePageUrlState<PageUrlState>(ML_PAGES.SUPPLIED_CONFIGURATIONS, { | ||
queryText: '', | ||
}); | ||
|
||
const [modules, setModules] = useState<Module[]>([]); | ||
const [isLoading, setIsLoading] = useState<boolean>(false); | ||
const [query, setQuery] = useState(EuiSearchBar.Query.MATCH_ALL); | ||
const [searchError, setSearchError] = useState<string | undefined>(); | ||
const [isFlyoutVisible, setIsFlyoutVisible] = useState<boolean>(false); | ||
const [selectedModuleId, setSelectedModuleId] = useState<string | undefined>(); | ||
|
||
|
@@ -82,22 +101,46 @@ export const SuppliedConfigurations = () => { | |
]; | ||
}, [modules]); | ||
|
||
const schema = { | ||
strict: true, | ||
fields: { | ||
tags: { | ||
type: 'string', | ||
const schema = useMemo( | ||
() => ({ | ||
strict: true, | ||
fields: { | ||
tags: { | ||
type: 'string', | ||
}, | ||
}, | ||
}), | ||
[] | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like it's just initialized once without any options, could it be moved outside the component without the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh good catch - updated in 6434887 |
||
|
||
const setSearchQueryText = useCallback( | ||
(value: string) => { | ||
setSuppliedConfigurationsPageState({ queryText: value }); | ||
}, | ||
[setSuppliedConfigurationsPageState] | ||
); | ||
|
||
const query = useMemo(() => { | ||
const searchQueryText = (suppliedConfigurationsPageState as SuppliedConfigurationsPageUrlState) | ||
.queryText; | ||
return searchQueryText !== '' ? EuiSearchBar.Query.parse(searchQueryText) : undefined; | ||
}, [suppliedConfigurationsPageState]); | ||
|
||
const onChange: EuiSearchBarProps['onChange'] = (search) => { | ||
if (search.error !== null) { | ||
setSearchError(search.error.message); | ||
return; | ||
} | ||
|
||
setSearchError(undefined); | ||
setSearchQueryText(search.queryText); | ||
}; | ||
|
||
const filteredModules = useMemo(() => { | ||
const clauses = query?.ast?.clauses ?? []; | ||
return clauses.length > 0 ? filterModules(modules, clauses) : modules; | ||
}, [query, modules]); | ||
|
||
const onChange = useCallback(({ query: onChangeQuery }) => setQuery(onChangeQuery), [setQuery]); | ||
|
||
if (isLoading === true) return <LoadingIndicator />; | ||
|
||
return ( | ||
|
@@ -117,6 +160,13 @@ export const SuppliedConfigurations = () => { | |
filters={filters} | ||
onChange={onChange} | ||
/> | ||
<EuiFormRow | ||
data-test-subj="mlAnomalyJobSelectionControls" | ||
isInvalid={searchError !== undefined} | ||
error={searchError} | ||
> | ||
<></> | ||
</EuiFormRow> | ||
<EuiSpacer size="l" /> | ||
<EuiFlexGrid gutterSize="l" columns={4}> | ||
{filteredModules.map(({ description, id, logo, title }) => { | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit. I think it should be sentence case:
When we use
anomaly detection
as the name of a menu item in the nav, it'sAnomaly Detection
, otherwise sentence case is preferred.