Skip to content
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

[RAM] [Rule Form V2] Add new rule type selection modal #179285

Merged
merged 28 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a3ef788
Add initial select rule type modal with visual design
Zacqary Mar 22, 2024
46e94aa
Connect rule type modal to rule add flyout, o11y, filtering
Zacqary Mar 22, 2024
aba8e8a
Merge remote-tracking branch 'upstream/main' into 179104-rule-type-se…
Zacqary Mar 22, 2024
47ef2d0
Improve empty prompt
Zacqary Mar 22, 2024
df69645
Merge remote-tracking branch 'upstream/main' into 179104-rule-type-se…
Zacqary Mar 25, 2024
8ee863b
Restructure and add tests
Zacqary Mar 25, 2024
4862a8c
Rename rule type index hook
Zacqary Mar 25, 2024
752b013
Fix hook export name
Zacqary Mar 25, 2024
dbc2456
Move loaCombine load rule types query hook into common
Zacqary Mar 25, 2024
5d890e8
Remove unused exports
Zacqary Mar 25, 2024
0f34f1d
Fix hook import
Zacqary Mar 26, 2024
376cfd4
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Mar 26, 2024
00c8b81
Fix i18n
Zacqary Mar 26, 2024
5fefd12
Merge branch '179104-rule-type-selection-modal' of https://github.com…
Zacqary Mar 26, 2024
e912b80
Fix filenames
Zacqary Mar 26, 2024
c94cdcf
Reset accidental commits
Zacqary Mar 27, 2024
10e9a66
Fix import
Zacqary Mar 27, 2024
de0b6aa
Fix import
Zacqary Mar 27, 2024
c7514ce
Fix stack and o11y functional tests
Zacqary Mar 28, 2024
8973870
Fix jest
Zacqary Mar 28, 2024
2ee66fb
Merge remote-tracking branch 'upstream/main' into 179104-rule-type-se…
Zacqary Mar 28, 2024
64cfb3a
Fix typecheck
Zacqary Mar 28, 2024
55a2632
Fix discover tests
Zacqary Mar 28, 2024
417f430
Merge branch 'main' into 179104-rule-type-selection-modal
kibanamachine Apr 1, 2024
0aefba4
Add translations and optimizations
Zacqary Apr 2, 2024
3fb57cc
Update var and prop names
Zacqary Apr 2, 2024
b2d8f0d
Merge branch '179104-rule-type-selection-modal' of https://github.com…
Zacqary Apr 2, 2024
7ea00de
Use euiTheme constant in ruleTypeModal
Zacqary Apr 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/kbn-alerts-ui-shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ export { AlertsSearchBar } from './src/alerts_search_bar';
export type { AlertsSearchBarProps } from './src/alerts_search_bar/types';

export * from './src/alert_fields_table';

export * from './src/rule_type_modal';
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@
export * from './fetch_aad_fields';
export * from './fetch_alert_fields';
export * from './fetch_alert_index_names';
export * from './fetch_rule_types';
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,4 @@ import type { DataView, DataViewField } from '@kbn/data-views-plugin/common';

export const NO_INDEX_PATTERNS: DataView[] = [];
export const EMPTY_AAD_FIELDS: DataViewField[] = [];
export const ALERTS_FEATURE_ID = 'alerts';
export const BASE_ALERTING_API_PATH = '/api/alerting';
export const BASE_RAC_ALERTS_API_PATH = '/internal/rac/alerts';
export * from '../common/constants';
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@
*/

export * from './use_alert_data_view';
export * from './use_load_rule_types_query';
export * from './use_rule_aad_fields';

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { AlertConsumers } from '@kbn/rule-data-utils';
import { NO_INDEX_PATTERNS } from './constants';
import { SEARCH_BAR_PLACEHOLDER } from './translations';
import type { AlertsSearchBarProps, QueryLanguageType } from './types';
import { useLoadRuleTypesQuery } from '../common/hooks/use_load_rule_types_query';
import { useAlertDataView } from './hooks/use_alert_data_view';
import { useRuleAADFields } from './hooks/use_rule_aad_fields';
import { useLoadRuleTypesQuery } from './hooks/use_load_rule_types_query';

const SA_ALERTS = { type: 'alerts', fields: {} } as SuggestionsAbstraction;

Expand Down
11 changes: 11 additions & 0 deletions packages/kbn-alerts-ui-shared/src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export const ALERTS_FEATURE_ID = 'alerts';
export const BASE_ALERTING_API_PATH = '/api/alerting';
export const BASE_RAC_ALERTS_API_PATH = '/internal/rac/alerts';
9 changes: 9 additions & 0 deletions packages/kbn-alerts-ui-shared/src/common/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export * from './use_load_rule_types_query';
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { keyBy } from 'lodash';
import { i18n } from '@kbn/i18n';
import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import type { HttpStart } from '@kbn/core-http-browser';
import type { ToastsStart } from '@kbn/core-notifications-browser';
import type { RuleType } from '@kbn/triggers-actions-ui-types';
import { ALERTS_FEATURE_ID } from '../constants';
import { fetchRuleTypes } from '../apis/fetch_rule_types';
import { RuleTypeIndexWithDescriptions, RuleTypeWithDescription } from '../types';

export interface UseRuleTypesProps {
http: HttpStart;
toasts: ToastsStart;
filteredRuleTypes: string[];
registeredRuleTypes?: Array<{ id: string; description: string }>;
enabled?: boolean;
}

const getFilteredIndex = (
data: Array<RuleType<string, string>>,
filteredRuleTypes: string[],
registeredRuleTypes: UseRuleTypesProps['registeredRuleTypes']
) => {
const index: RuleTypeIndexWithDescriptions = new Map();
const registeredRuleTypesDictionary = registeredRuleTypes ? keyBy(registeredRuleTypes, 'id') : {};
for (const ruleType of data) {
const ruleTypeRecord: RuleType<string, string> & { description?: string } = { ...ruleType };
if (!registeredRuleTypes) {
// If rule type registry is not provided, don't use it for filtering
index.set(ruleType.id, ruleTypeRecord);
} else if (registeredRuleTypesDictionary[ruleType.id]) {
// Filter out unregistered rule types, and add descriptions to registered rule types
ruleTypeRecord.description = registeredRuleTypesDictionary[ruleType.id].description;
index.set(ruleType.id, ruleTypeRecord);
}
}
let filteredIndex = index;
if (filteredRuleTypes?.length) {
filteredIndex = new Map(
[...index].filter(([k, v]) => {
return filteredRuleTypes.includes(v.id);
})
);
}
return filteredIndex;
};

export const useLoadRuleTypesQuery = ({
http,
toasts,
filteredRuleTypes,
registeredRuleTypes,
enabled = true,
}: UseRuleTypesProps) => {
const queryFn = () => {
return fetchRuleTypes({ http });
};

const onErrorFn = (error: Error) => {
if (error) {
toasts.addDanger(
i18n.translate('alertsUIShared.hooks.useLoadRuleTypesQuery.unableToLoadRuleTypesMessage', {
defaultMessage: 'Unable to load rule types',
})
);
}
};
const { data, isSuccess, isFetching, isInitialLoading, isLoading, error } = useQuery({
queryKey: ['loadRuleTypes'],
queryFn,
onError: onErrorFn,
refetchOnWindowFocus: false,
// Leveraging TanStack Query's caching system to avoid duplicated requests as
// other state-sharing solutions turned out to be overly complex and less readable
staleTime: 60 * 1000,
enabled,
});

const filteredIndex = useMemo(
() =>
data
? getFilteredIndex(data, filteredRuleTypes, registeredRuleTypes)
: new Map<string, RuleTypeWithDescription>(),
[data, filteredRuleTypes, registeredRuleTypes]
);

const hasAnyAuthorizedRuleType = filteredIndex.size > 0;
const authorizedRuleTypes = useMemo(() => [...filteredIndex.values()], [filteredIndex]);
const authorizedToCreateAnyRules = authorizedRuleTypes.some(
(ruleType) => ruleType.authorizedConsumers[ALERTS_FEATURE_ID]?.all
);
const authorizedToReadAnyRules =
authorizedToCreateAnyRules ||
authorizedRuleTypes.some((ruleType) => ruleType.authorizedConsumers[ALERTS_FEATURE_ID]?.read);

return {
ruleTypesState: {
initialLoad: isLoading || isInitialLoading,
isLoading: isLoading || isFetching,
data: filteredIndex,
error,
},
hasAnyAuthorizedRuleType,
authorizedRuleTypes,
authorizedToReadAnyRules,
authorizedToCreateAnyRules,
isSuccess,
};
};
45 changes: 45 additions & 0 deletions packages/kbn-alerts-ui-shared/src/common/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { i18n } from '@kbn/i18n';

export const PRODUCER_DISPLAY_NAMES = {
apm: i18n.translate('alertsUIShared.producerDisplayNames.apm', {
defaultMessage: 'APM and User Experience',
}),
uptime: i18n.translate('alertsUIShared.producerDisplayNames.uptime', {
defaultMessage: 'Synthetics and Uptime',
}),
stackAlerts: i18n.translate('alertsUIShared.producerDisplayNames.stackAlerts', {
defaultMessage: 'Stack Alerts',
}),
metrics: i18n.translate('alertsUIShared.producerDisplayNames.metrics', {
defaultMessage: 'Metrics',
}),
logs: i18n.translate('alertsUIShared.producerDisplayNames.logs', {
defaultMessage: 'Logs',
}),
siem: i18n.translate('alertsUIShared.producerDisplayNames.siem', {
defaultMessage: 'Security',
}),
observability: i18n.translate('alertsUIShared.producerDisplayNames.observability', {
defaultMessage: 'Observability',
}),
ml: i18n.translate('alertsUIShared.producerDisplayNames.ml', {
defaultMessage: 'Machine Learning',
}),
slo: i18n.translate('alertsUIShared.producerDisplayNames.slo', {
defaultMessage: 'SLOs',
}),
infrastructure: i18n.translate('alertsUIShared.producerDisplayNames.infrastructure', {
defaultMessage: 'Infrastructure',
}),
monitoring: i18n.translate('alertsUIShared.producerDisplayNames.monitoring', {
defaultMessage: 'Stack Monitoring',
}),
};
13 changes: 13 additions & 0 deletions packages/kbn-alerts-ui-shared/src/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { RuleType } from '@kbn/triggers-actions-ui-types';

export type RuleTypeWithDescription = RuleType<string, string> & { description?: string };

export type RuleTypeIndexWithDescriptions = Map<string, RuleTypeWithDescription>;
Loading