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 full-page create/edit form behind feature flag to Stack Management #180539

Closed
wants to merge 73 commits into from
Closed
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
5c43b99
Initial rule form commit
Zacqary Apr 1, 2024
537b12e
Hook up plugins and referrer
Zacqary Apr 2, 2024
f770508
Add doc links and refinition panel section
Zacqary Apr 2, 2024
2a785e8
Schedule field wip
Zacqary Apr 3, 2024
30a5765
Finish implementing rule definition
Zacqary Apr 3, 2024
b545970
Add validation
Zacqary Apr 4, 2024
1354f91
Add save rule functionality
Zacqary Apr 8, 2024
b35b9f6
Merge remote-tracking branch 'upstream/main' into 179105-rule-form-fu…
Zacqary Apr 8, 2024
e13f0a0
Make context providers reusable
Zacqary Apr 8, 2024
4d59f5f
Move loading screen into alertsUiShared
Zacqary Apr 8, 2024
fb63b51
Add edit rule route
Zacqary Apr 9, 2024
6a38327
Add edit link route
Zacqary Apr 9, 2024
ca583df
Fix edit page query key bug
Zacqary Apr 9, 2024
ce7bc57
Fix types
Zacqary Apr 10, 2024
bfcb91b
Improve expression error handling
Zacqary Apr 10, 2024
fd3ccde
Improve error validation and display
Zacqary Apr 10, 2024
2c16f50
Add validation states to index threshold rule, display error list
Zacqary Apr 10, 2024
43f22a6
Extend string for rule form errors
Zacqary Apr 10, 2024
72c6a5b
Use new validation types in stack alerts
Zacqary Apr 10, 2024
e26fbb6
Add integration tests
Zacqary Apr 10, 2024
c277d4a
Add test for editing rule and showing consumer selector
Zacqary Apr 10, 2024
4559bbc
Merge remote-tracking branch 'upstream/main' into 179105-rule-form-fu…
Zacqary Apr 10, 2024
c1f130c
Move changes out of rule-data-utils
Zacqary Apr 10, 2024
e7af676
Revert gis changes
Zacqary Apr 10, 2024
1360a3a
Commit missing untracked file
Zacqary Apr 10, 2024
73d522e
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Apr 10, 2024
44e3efd
Fix rule route imports
Zacqary Apr 10, 2024
498b2e5
Merge branch '179105-rule-form-fullpage' of https://github.com/Zacqar…
Zacqary Apr 10, 2024
e2eb1ae
Increase bundle limit
Zacqary Apr 11, 2024
ca154a4
Fix i18n
Zacqary Apr 11, 2024
1a8a02f
Fix i18n
Zacqary Apr 11, 2024
f1a445b
Merge remote-tracking branch 'upstream/main' into 179105-rule-form-fu…
Zacqary Apr 11, 2024
095e38e
Fix kbn dependencies in package
Zacqary Apr 12, 2024
2e6c0db
Revert message variable change
Zacqary Apr 12, 2024
c593e98
Merge remote-tracking branch 'upstream/main' into 179105-rule-form-fu…
Zacqary Apr 12, 2024
38f0658
Fix circular typescript references
Zacqary Apr 12, 2024
654a1e0
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Apr 12, 2024
3be6977
Fix typecheck
Zacqary Apr 12, 2024
1499e26
Merge branch '179105-rule-form-fullpage' of https://github.com/Zacqar…
Zacqary Apr 12, 2024
4799969
Restore triggers actions changes
Zacqary Apr 12, 2024
170bb62
Fix bad merge
Zacqary Apr 12, 2024
c3a0bfd
Fix bad merge
Zacqary Apr 12, 2024
43bd686
Deprectate RuleEdit
Zacqary Apr 12, 2024
0f76637
Fix bad merge
Zacqary Apr 12, 2024
ba82b31
Fix another bad merge
Zacqary Apr 12, 2024
d4e1216
Fix bad merge of app route
Zacqary Apr 12, 2024
c21fc21
Fix bad merge of app route
Zacqary Apr 12, 2024
31155be
Fix typeerrors in bad merge
Zacqary Apr 15, 2024
91e0777
Fix api rule transforms
Zacqary Apr 15, 2024
d0ded77
Fix jest
Zacqary Apr 15, 2024
e460850
Bump limits.yml
Zacqary Apr 15, 2024
063f4b6
Fix connectors merge
Zacqary Apr 15, 2024
c6bc59d
Merge remote-tracking branch 'upstream/main' into 179105-rule-form-fu…
Zacqary Apr 15, 2024
383531d
Fix bad merge of types.ts
Zacqary Apr 15, 2024
1b3afec
Fix stale state when editing
Zacqary Apr 17, 2024
9433444
Merge remote-tracking branch 'upstream/main' into 179105-rule-form-fu…
Zacqary Apr 17, 2024
8d23121
Fix parsing negative duration
Zacqary Apr 17, 2024
b6ac3c6
Add incomplete error typing to es query rule
Zacqary Apr 17, 2024
0764544
Remove console.log
Zacqary Apr 17, 2024
3e4e4b0
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Apr 17, 2024
8645e6a
Fix alertDelay UX, infinite resolve bug
Zacqary Apr 17, 2024
9512318
Fix jest
Zacqary Apr 17, 2024
66a7da5
Merge branch '179105-rule-form-fullpage' of https://github.com/Zacqar…
Zacqary Apr 17, 2024
708928e
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Apr 17, 2024
2bd2eee
Port show api request button
Zacqary Apr 17, 2024
171196f
Update limits
Zacqary Apr 17, 2024
7882630
Merge branch '179105-rule-form-fullpage' of https://github.com/Zacqar…
Zacqary Apr 17, 2024
bdd7865
Fix jest
Zacqary Apr 17, 2024
2e4fc7b
Up limits
Zacqary Apr 17, 2024
d7585a6
Display only params error 0 in callout
Zacqary Apr 18, 2024
d76cc7f
Slice periods off tooltip error list
Zacqary Apr 18, 2024
110334d
Merge branch 'main' into 179105-rule-form-fullpage
kibanamachine Apr 18, 2024
bd9d4cd
Merge branch 'main' into 179105-rule-form-fullpage
kibanamachine Apr 23, 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
4 changes: 4 additions & 0 deletions packages/kbn-alerts-ui-shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ export type { AlertsSearchBarProps } from './src/alerts_search_bar/types';
export * from './src/alert_fields_table';

export * from './src/rule_type_modal';
export * from './src/rule_form';

export * from './src/common/helpers/parse_duration';
export * from './src/common/helpers/rule_circuit_breaker_error_message';
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
EuiSelectableOption,
} from '@elastic/eui';
import type { ActionVariable } from '@kbn/alerting-types';
import './add_message_variables.scss';
// import './add_message_variables.scss';
import { TruncatedText } from './truncated_text';
import * as i18n from './translations';

Expand Down
7 changes: 7 additions & 0 deletions packages/kbn-alerts-ui-shared/src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@
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 enum TIME_UNITS {
SECOND = 's',
MINUTE = 'm',
HOUR = 'h',
DAY = 'd',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copypasted from x-pack/plugins/triggers_actions_ui/public/common/lib/get_time_options.test.ts

* 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 { getTimeOptions, getTimeFieldOptions } from './get_time_options';

describe('get_time_options', () => {
test('if getTimeOptions return single unit time options', () => {
const timeUnitValue = getTimeOptions(1);
expect(timeUnitValue).toMatchObject([
{ text: 'second', value: 's' },
{ text: 'minute', value: 'm' },
{ text: 'hour', value: 'h' },
{ text: 'day', value: 'd' },
]);
});

test('if getTimeOptions return multiple unit time options', () => {
const timeUnitValue = getTimeOptions(10);
expect(timeUnitValue).toMatchObject([
{ text: 'seconds', value: 's' },
{ text: 'minutes', value: 'm' },
{ text: 'hours', value: 'h' },
{ text: 'days', value: 'd' },
]);
});

test('if getTimeFieldOptions return only date type fields', () => {
const timeOnlyTypeFields = getTimeFieldOptions([
{ type: 'date', name: 'order_date' },
{ type: 'date_nanos', name: 'order_date_nanos' },
{ type: 'number', name: 'sum' },
]);
expect(timeOnlyTypeFields).toMatchObject([
{ text: 'order_date', value: 'order_date' },
{ text: 'order_date_nanos', value: 'order_date_nanos' },
]);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copypasted from x-pack/plugins/triggers_actions_ui/public/common/lib/get_time_options.ts

* 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 { getTimeUnitLabel } from './get_time_unit_label';
import { TIME_UNITS } from '../constants';

export const getTimeOptions = (unitSize: number) =>
Object.entries(TIME_UNITS).map(([_key, value]) => {
return {
text: getTimeUnitLabel(value, unitSize.toString()),
value,
};
});

interface TimeFieldOptions {
text: string;
value: string;
}

export const getTimeFieldOptions = (
fields: Array<{ type: string; name: string }>
): TimeFieldOptions[] => {
const options: TimeFieldOptions[] = [];

fields.forEach((field: { type: string; name: string }) => {
if (field.type === 'date' || field.type === 'date_nanos') {
options.push({
text: field.name,
value: field.name,
});
}
});
return options;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copypasted from x-pack/plugins/triggers_actions_ui/public/common/lib/get_time_unit_label.ts

* 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';
import { TIME_UNITS } from '../constants';

export function getTimeUnitLabel(timeUnit = TIME_UNITS.SECOND, timeValue = '0') {
switch (timeUnit) {
case TIME_UNITS.SECOND:
return i18n.translate('alertsUIShared.timeUnits.secondLabel', {
defaultMessage: '{timeValue, plural, one {second} other {seconds}}',
values: { timeValue },
});
case TIME_UNITS.MINUTE:
return i18n.translate('alertsUIShared.timeUnits.minuteLabel', {
defaultMessage: '{timeValue, plural, one {minute} other {minutes}}',
values: { timeValue },
});
case TIME_UNITS.HOUR:
return i18n.translate('alertsUIShared.timeUnits.hourLabel', {
defaultMessage: '{timeValue, plural, one {hour} other {hours}}',
values: { timeValue },
});
case TIME_UNITS.DAY:
return i18n.translate('alertsUIShared.timeUnits.dayLabel', {
defaultMessage: '{timeValue, plural, one {day} other {days}}',
values: { timeValue },
});
}
}
12 changes: 12 additions & 0 deletions packages/kbn-alerts-ui-shared/src/common/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* 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 './parse_duration';
export * from './get_time_options';
export * from './get_time_unit_label';
export * from './rule_circuit_breaker_error_message';
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copypasted from x-pack/plugins/alerting/common/parse_duration.test.ts

* 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 {
parseDuration,
formatDuration,
getDurationNumberInItsUnit,
getDurationUnitValue,
convertDurationToFrequency,
} from './parse_duration';

test('parses seconds', () => {
const result = parseDuration('10s');
expect(result).toEqual(10000);
});

test('parses minutes', () => {
const result = parseDuration('10m');
expect(result).toEqual(600000);
});

test('parses hours', () => {
const result = parseDuration('10h');
expect(result).toEqual(36000000);
});

test('parses days', () => {
const result = parseDuration('10d');
expect(result).toEqual(864000000);
});

test('throws error when the format is invalid', () => {
expect(() => parseDuration('10x')).toThrowErrorMatchingInlineSnapshot(
`"Invalid duration \\"10x\\". Durations must be of the form {number}x. Example: 5s, 5m, 5h or 5d\\""`
);
});

test('throws error when suffix is missing', () => {
expect(() => parseDuration('1000')).toThrowErrorMatchingInlineSnapshot(
`"Invalid duration \\"1000\\". Durations must be of the form {number}x. Example: 5s, 5m, 5h or 5d\\""`
);
});

test('formats single second', () => {
const result = formatDuration('1s');
expect(result).toEqual('1 sec');
});

test('formats single second with full unit', () => {
const result = formatDuration('1s', true);
expect(result).toEqual('1 second');
});

test('formats seconds', () => {
const result = formatDuration('10s');
expect(result).toEqual('10 sec');
});

test('formats seconds with full unit', () => {
const result = formatDuration('10s', true);
expect(result).toEqual('10 seconds');
});

test('formats single minute', () => {
const result = formatDuration('1m');
expect(result).toEqual('1 min');
});

test('formats single minute with full unit', () => {
const result = formatDuration('1m', true);
expect(result).toEqual('1 minute');
});

test('formats minutes', () => {
const result = formatDuration('10m');
expect(result).toEqual('10 min');
});

test('formats minutes with full unit', () => {
const result = formatDuration('10m', true);
expect(result).toEqual('10 minutes');
});

test('formats single hour', () => {
const result = formatDuration('1h');
expect(result).toEqual('1 hr');
});

test('formats single hour with full unit', () => {
const result = formatDuration('1h', true);
expect(result).toEqual('1 hour');
});

test('formats hours', () => {
const result = formatDuration('10h');
expect(result).toEqual('10 hr');
});

test('formats hours with full unit', () => {
const result = formatDuration('10h', true);
expect(result).toEqual('10 hours');
});

test('formats single day', () => {
const result = formatDuration('1d');
expect(result).toEqual('1 day');
});

test('formats single day with full unit', () => {
const result = formatDuration('1d', true);
expect(result).toEqual('1 day');
});

test('formats days', () => {
const result = formatDuration('10d');
expect(result).toEqual('10 days');
});

test('formats days with full unit', () => {
const result = formatDuration('10d', true);
expect(result).toEqual('10 days');
});

test('format throws error when the format is invalid', () => {
expect(() => formatDuration('10x')).toThrowErrorMatchingInlineSnapshot(
`"Invalid duration \\"10x\\". Durations must be of the form {number}x. Example: 5s, 5m, 5h or 5d\\""`
);
});

test('format throws error when suffix is missing', () => {
expect(() => formatDuration('1000')).toThrowErrorMatchingInlineSnapshot(
`"Invalid duration \\"1000\\". Durations must be of the form {number}x. Example: 5s, 5m, 5h or 5d\\""`
);
});

test('throws error when 0 based', () => {
expect(() => parseDuration('0s')).toThrowErrorMatchingInlineSnapshot(
`"Invalid duration \\"0s\\". Durations must be of the form {number}x. Example: 5s, 5m, 5h or 5d\\""`
);
expect(() => parseDuration('0m')).toThrowErrorMatchingInlineSnapshot(
`"Invalid duration \\"0m\\". Durations must be of the form {number}x. Example: 5s, 5m, 5h or 5d\\""`
);
expect(() => parseDuration('0h')).toThrowErrorMatchingInlineSnapshot(
`"Invalid duration \\"0h\\". Durations must be of the form {number}x. Example: 5s, 5m, 5h or 5d\\""`
);
expect(() => parseDuration('0d')).toThrowErrorMatchingInlineSnapshot(
`"Invalid duration \\"0d\\". Durations must be of the form {number}x. Example: 5s, 5m, 5h or 5d\\""`
);
});

test('getDurationNumberInItsUnit days', () => {
const result = getDurationNumberInItsUnit('10d');
expect(result).toEqual(10);
});

test('getDurationNumberInItsUnit minutes', () => {
const result = getDurationNumberInItsUnit('1m');
expect(result).toEqual(1);
});

test('getDurationNumberInItsUnit seconds', () => {
const result = getDurationNumberInItsUnit('123s');
expect(result).toEqual(123);
});

test('getDurationUnitValue minutes', () => {
const result = getDurationUnitValue('1m');
expect(result).toEqual('m');
});

test('getDurationUnitValue days', () => {
const result = getDurationUnitValue('23d');
expect(result).toEqual('d');
});

test('getDurationUnitValue hours', () => {
const result = getDurationUnitValue('100h');
expect(result).toEqual('h');
});

test('convertDurationToFrequency converts duration', () => {
let result = convertDurationToFrequency('1m');
expect(result).toEqual(1);
result = convertDurationToFrequency('5m');
expect(result).toEqual(0.2);
result = convertDurationToFrequency('10s');
expect(result).toEqual(6);
result = convertDurationToFrequency('1s');
expect(result).toEqual(60);
});

test('convertDurationToFrequency throws when duration is invalid', () => {
expect(() => convertDurationToFrequency('0d')).toThrowErrorMatchingInlineSnapshot(
`"Invalid duration \\"0d\\". Durations must be of the form {number}x. Example: 5s, 5m, 5h or 5d\\""`
);
});

test('convertDurationToFrequency throws when denomination is 0', () => {
expect(() => convertDurationToFrequency('1s', 0)).toThrowErrorMatchingInlineSnapshot(
`"Invalid denomination value: value cannot be 0"`
);
});
Loading