-
Notifications
You must be signed in to change notification settings - Fork 8.3k
[ResponseOps][Alerts] Implement alerts filters form #214982
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
[ResponseOps][Alerts] Implement alerts filters form #214982
Conversation
03c52ed
to
1647136
Compare
0ba7dbc
to
9876eba
Compare
9876eba
to
9982fb6
Compare
Pinging @elastic/response-ops (Team:ResponseOps) |
isDisabled?: boolean; | ||
} | ||
|
||
const DEFAULT_VALUE: AlertsFiltersExpression = { |
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.
This ensures that the form is initialized with an initially empty "Filter by" selector
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: this comment here could be a comment in code for future us
2b3bc5c
to
1d8fca4
Compare
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.
Great work! looks really good 🎉
Could you please add an integration test or functional test to check different roles and users to verify solutions and rule types privileges?
I have a user with `security` and `stack rules` privileges. However the solution shows `observability`. Shouldn't it be security and stack like serverless?
security_and_stack.mov
security_and_stack_permissions.mov
...kages/shared/response-ops/alerts-filters-form/components/alerts_filter_by_rule_tags.test.tsx
Outdated
Show resolved
Hide resolved
Thanks for taking a look Janki! 😊
I was hoping to test the complete creation flow with the Dashboard panel as well 🙂
Yes, that's normal since in non-serverless envs when enabling the Stack rules privilege you also get access to multi-consumer rule types, one of which is categorized under |
745bcea
to
8786ed0
Compare
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.
Thanks for your patience and with addressing my comments!
export const getRuleTypeIdsForSolution = ( | ||
ruleTypes: InternalRuleType[], | ||
solution: RuleTypeSolution, | ||
includeStackInObservability = true |
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: Do not forget to remove this.
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.
Done ✅
}); | ||
|
||
it.each([null, undefined])('should return false for %s items', (filter) => { | ||
expect(isFilter(filter as Parameters<typeof isFilter>[0])).toBeFalsy(); |
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.
expect(isFilter(filter as Parameters<typeof isFilter>[0])).toBeFalsy(); | |
// @ts-expect-error: testing empty values | |
expect(isFilter(filter)).toBeFalsy(); |
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.
Done ✅
return null; | ||
} | ||
const FilterComponent = alertsFiltersMetadata[type].component as AlertsFilterComponentType<T>; | ||
return <FilterComponent value={value} onChange={onValueChange} isDisabled={isDisabled} />; |
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.
I was referring to const filter = useMemo(() => {
. Any idea on that?
if (options.length < 2) { | ||
if (options.length === 1) { | ||
// Select the only available solution and | ||
// don't show the selector | ||
onSolutionChange(options[0].value); | ||
} | ||
return null; | ||
} |
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.
A pseudo example of how it can be done without any useEffects
or call of onSolutionChange
.
// top-level component
const { data: ruleTypes, isLoading, isError } = useGetInternalRuleTypesQuery({ http });
if (isLoading) {
return null;
}
return <AlertsFilterFormWraper ruleTypes={ruleTypes}> // name tbd
// AlertsFilterFormWraper
// ruleTypes always available as the component will render after the fetch
const AlertsFilterFormWraper = ({ ruleTypes }) => {
const availableSolutions = useMemo(() => getAvailableSolutions(ruleTypes), [ruleTypes]);
const [selectedSolution, setSelectedSolution] = useState(availableSolutions.length === 1 ? availableSolutions[0].value : undefined) // or whatever default we want.
availableSolutions.length > 1 && <AlertsSolutionSelector availableSolutions={availableSolutions} selectedSolution={selectedSolution} onSolutionChange={setSolution}>
}
It is very similar to what you have in the sandbox with some tweaks. We can do it on the final PR.
…oolean-filters-ui
…ato/kibana into 213061-alerts-boolean-filters-ui
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.
Changes in package.json
LGTM
Starting backport for target branches: 8.19 |
💚 Build Succeeded
Metrics [docs]Async chunks
Unknown metric groupsESLint disabled line counts
Total ESLint disabled count
History
|
💔 All backports failed
Manual backportTo create the backport manually run:
Questions ?Please refer to the Backport tool documentation |
Friendly reminder: Looks like this PR hasn’t been backported yet. |
## Summary Implements the alerts filters form that will be used to pre-filter the alerts table embeddable. <img width="1004" alt="image" src="https://github.com/user-attachments/assets/b51ce051-40d2-42d0-a9c1-0fba3fd919af" /> > [!NOTE] > I'm using the terminology "form" to distinguish this from the alert filter _controls_ or other type of more KQL-bar-like filters. Other alternatives that came to mind were `alerts-boolean-filters-...` or `alerts-filters-builder`. <details> <summary> ## Implementation details </summary> ### Filters expression state I opted for a tree state representation of the form's boolean expression to accommodate potential future requirements such as more complex boolean expressions (negation, parenthesized subexpressions to manually control operators precedence): ```ts { operator: 'or', operands: [ { operator: 'or', operands: [ { type: 'ruleTags', value: ['tag-1'] }, { type: 'ruleTags', value: ['tag-2'] }, { operator: 'and', operands: [{ type: 'ruleTypes', value: ['type-1'] }, { type: 'ruleTypes', value: ['type-2'] }], }, ], }, { type: 'ruleTags', value: ['tag-3'] }, ], } ``` This state is saved in the embeddable panel state and represents the editor form. The embeddable alerts table wrapper component will then transform this to an actual ES query. To simplify interactions inside the form, an intermediate equivalent flattened state is used: ```ts [ { filter: { type: 'ruleTags', value: ['tag-1'] } }, { operator: 'or' }, { filter: { type: 'ruleTags', value: ['tag-2'] } }, { operator: 'or' }, { filter: { type: 'ruleTypes', value: ['type-1'] }}, { operator: 'and' }, { filter: { type: 'ruleTypes', value: ['type-2'] } }, { operator: 'or' }, { filter: { type: 'ruleTags', value: ['tag-3'] } }, ] ``` ### Filters model Each filter is described by an `AlertsFilterMetadata<T>` object, where `T` is the type of the filter value: ```tsx export const filterMetadata: AlertsFilterMetadata<string[]> = { id: 'ruleTags', displayName: RULE_TAGS_FILTER_LABEL, component: AlertsFilterByRuleTags, // Filter-specific empty check isEmpty: (value?: string[]) => !value?.length, // Conversion to ES query DSL toEsQuery: (value: string[]) => { return { terms: { [ALERT_RULE_TAGS]: value, }, }; }, }; ``` </details> ## Verification steps 1. Run Kibana with examples (`yarn start --run-examples`) 2. Create rules in different solutions with tags 3. Navigate to `/app/triggersActionsUiExample/alerts_filters_form` 4. Check that the solution selector options are coherent with the rule types the user can access 5. Select a solution 6. Build filters expressions, checking that the rule tags and rule types are coherent with the solution selection and the rules created previously 7. Repeat steps 3-6 with different roles: 7.1. having access to rule types from just one solution (in this case the solution selector shouldn't appear at all), 7.2. having access just to Observability and Stack but not Security (in this case the solution selector shouldn't appear at all), 8. Repeat steps 3-6 in the three serverless project types: ```shell $ yarn es serverless —ssl --projectType <es|oblt|security> $ yarn serverless-<es|oblt|security> --ssl --run-examples ``` (If the authentication fails when switching between project types, use a clean session) 8.1. ES project types should have access only to Stack rules (no selector) 8.2. Observability project types should have access only to Observability and Stack rules (no selector) 8.3. Security project types should have access only to Security and Stack rules (selector shows Stack instead of Observability) ## References Depends on elastic#214187 Closes elastic#213061 ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Christos Nasikas <xristosnasikas@gmail.com>
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
## Summary Implements the alerts filters form that will be used to pre-filter the alerts table embeddable. <img width="1004" alt="image" src="https://github.com/user-attachments/assets/b51ce051-40d2-42d0-a9c1-0fba3fd919af" /> > [!NOTE] > I'm using the terminology "form" to distinguish this from the alert filter _controls_ or other type of more KQL-bar-like filters. Other alternatives that came to mind were `alerts-boolean-filters-...` or `alerts-filters-builder`. <details> <summary> ## Implementation details </summary> ### Filters expression state I opted for a tree state representation of the form's boolean expression to accommodate potential future requirements such as more complex boolean expressions (negation, parenthesized subexpressions to manually control operators precedence): ```ts { operator: 'or', operands: [ { operator: 'or', operands: [ { type: 'ruleTags', value: ['tag-1'] }, { type: 'ruleTags', value: ['tag-2'] }, { operator: 'and', operands: [{ type: 'ruleTypes', value: ['type-1'] }, { type: 'ruleTypes', value: ['type-2'] }], }, ], }, { type: 'ruleTags', value: ['tag-3'] }, ], } ``` This state is saved in the embeddable panel state and represents the editor form. The embeddable alerts table wrapper component will then transform this to an actual ES query. To simplify interactions inside the form, an intermediate equivalent flattened state is used: ```ts [ { filter: { type: 'ruleTags', value: ['tag-1'] } }, { operator: 'or' }, { filter: { type: 'ruleTags', value: ['tag-2'] } }, { operator: 'or' }, { filter: { type: 'ruleTypes', value: ['type-1'] }}, { operator: 'and' }, { filter: { type: 'ruleTypes', value: ['type-2'] } }, { operator: 'or' }, { filter: { type: 'ruleTags', value: ['tag-3'] } }, ] ``` ### Filters model Each filter is described by an `AlertsFilterMetadata<T>` object, where `T` is the type of the filter value: ```tsx export const filterMetadata: AlertsFilterMetadata<string[]> = { id: 'ruleTags', displayName: RULE_TAGS_FILTER_LABEL, component: AlertsFilterByRuleTags, // Filter-specific empty check isEmpty: (value?: string[]) => !value?.length, // Conversion to ES query DSL toEsQuery: (value: string[]) => { return { terms: { [ALERT_RULE_TAGS]: value, }, }; }, }; ``` </details> ## Verification steps 1. Run Kibana with examples (`yarn start --run-examples`) 2. Create rules in different solutions with tags 3. Navigate to `/app/triggersActionsUiExample/alerts_filters_form` 4. Check that the solution selector options are coherent with the rule types the user can access 5. Select a solution 6. Build filters expressions, checking that the rule tags and rule types are coherent with the solution selection and the rules created previously 7. Repeat steps 3-6 with different roles: 7.1. having access to rule types from just one solution (in this case the solution selector shouldn't appear at all), 7.2. having access just to Observability and Stack but not Security (in this case the solution selector shouldn't appear at all), 8. Repeat steps 3-6 in the three serverless project types: ```shell $ yarn es serverless —ssl --projectType <es|oblt|security> $ yarn serverless-<es|oblt|security> --ssl --run-examples ``` (If the authentication fails when switching between project types, use a clean session) 8.1. ES project types should have access only to Stack rules (no selector) 8.2. Observability project types should have access only to Observability and Stack rules (no selector) 8.3. Security project types should have access only to Security and Stack rules (selector shows Stack instead of Observability) ## References Depends on elastic#214187 Closes elastic#213061 ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Christos Nasikas <xristosnasikas@gmail.com> (cherry picked from commit c44efc5) # Conflicts: # x-pack/examples/triggers_actions_ui_example/public/application.tsx
…218759) # Backport This will backport the following commits from `main` to `8.19`: - [[ResponseOps][Alerts] Implement alerts filters form (#214982)](#214982) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Umberto Pepato","email":"umbopepato@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-04-17T14:18:24Z","message":"[ResponseOps][Alerts] Implement alerts filters form (#214982)\n\n## Summary\n\nImplements the alerts filters form that will be used to pre-filter the\nalerts table embeddable.\n\n<img width=\"1004\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/b51ce051-40d2-42d0-a9c1-0fba3fd919af\"\n/>\n\n> [!NOTE]\n> I'm using the terminology \"form\" to distinguish this from the alert\nfilter _controls_ or other type of more KQL-bar-like filters. Other\nalternatives that came to mind were `alerts-boolean-filters-...` or\n`alerts-filters-builder`.\n\n<details>\n<summary>\n\n## Implementation details\n\n</summary>\n\n### Filters expression state\n\nI opted for a tree state representation of the form's boolean expression\nto accommodate potential future requirements such as more complex\nboolean expressions (negation, parenthesized subexpressions to manually\ncontrol operators precedence):\n\n```ts\n{\n operator: 'or',\n operands: [\n {\n operator: 'or',\n operands: [\n { type: 'ruleTags', value: ['tag-1'] },\n { type: 'ruleTags', value: ['tag-2'] },\n {\n operator: 'and',\n operands: [{ type: 'ruleTypes', value: ['type-1'] }, { type: 'ruleTypes', value: ['type-2'] }],\n },\n ],\n },\n { type: 'ruleTags', value: ['tag-3'] },\n ],\n}\n```\n\nThis state is saved in the embeddable panel state and represents the\neditor form. The embeddable alerts table wrapper component will then\ntransform this to an actual ES query.\n\nTo simplify interactions inside the form, an intermediate equivalent\nflattened state is used:\n\n```ts\n[\n { filter: { type: 'ruleTags', value: ['tag-1'] } },\n { operator: 'or' },\n { filter: { type: 'ruleTags', value: ['tag-2'] } },\n { operator: 'or' },\n { filter: { type: 'ruleTypes', value: ['type-1'] }},\n { operator: 'and' },\n { filter: { type: 'ruleTypes', value: ['type-2'] } },\n { operator: 'or' },\n { filter: { type: 'ruleTags', value: ['tag-3'] } },\n]\n```\n\n### Filters model\n\nEach filter is described by an `AlertsFilterMetadata<T>` object, where\n`T` is the type of the filter value:\n\n```tsx\nexport const filterMetadata: AlertsFilterMetadata<string[]> = {\n id: 'ruleTags',\n displayName: RULE_TAGS_FILTER_LABEL,\n component: AlertsFilterByRuleTags,\n // Filter-specific empty check\n isEmpty: (value?: string[]) => !value?.length,\n // Conversion to ES query DSL\n toEsQuery: (value: string[]) => {\n return {\n terms: {\n [ALERT_RULE_TAGS]: value,\n },\n };\n },\n};\n```\n\n</details>\n\n## Verification steps\n\n1. Run Kibana with examples (`yarn start --run-examples`)\n2. Create rules in different solutions with tags\n3. Navigate to `/app/triggersActionsUiExample/alerts_filters_form`\n4. Check that the solution selector options are coherent with the rule\ntypes the user can access\n5. Select a solution\n6. Build filters expressions, checking that the rule tags and rule types\nare coherent with the solution selection and the rules created\npreviously\n7. Repeat steps 3-6 with different roles:\n7.1. having access to rule types from just one solution (in this case\nthe solution selector shouldn't appear at all),\n7.2. having access just to Observability and Stack but not Security (in\nthis case the solution selector shouldn't appear at all),\n8. Repeat steps 3-6 in the three serverless project types:\n ```shell\n $ yarn es serverless —ssl --projectType <es|oblt|security>\n $ yarn serverless-<es|oblt|security> --ssl --run-examples\n ```\n(If the authentication fails when switching between project types, use a\nclean session)\n8.1. ES project types should have access only to Stack rules (no\nselector)\n8.2. Observability project types should have access only to\nObservability and Stack rules (no selector)\n8.3. Security project types should have access only to Security and\nStack rules (selector shows Stack instead of Observability)\n\n## References\n\nDepends on #214187\nCloses #213061\n\n### Checklist\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: Christos Nasikas <xristosnasikas@gmail.com>","sha":"c44efc52f62f2bb80c8cb8c288cfb40fc3164344","branchLabelMapping":{"^v9.1.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:ResponseOps","backport missing","backport:version","v9.1.0","v8.19.0"],"title":"[ResponseOps][Alerts] Implement alerts filters form","number":214982,"url":"https://github.com/elastic/kibana/pull/214982","mergeCommit":{"message":"[ResponseOps][Alerts] Implement alerts filters form (#214982)\n\n## Summary\n\nImplements the alerts filters form that will be used to pre-filter the\nalerts table embeddable.\n\n<img width=\"1004\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/b51ce051-40d2-42d0-a9c1-0fba3fd919af\"\n/>\n\n> [!NOTE]\n> I'm using the terminology \"form\" to distinguish this from the alert\nfilter _controls_ or other type of more KQL-bar-like filters. Other\nalternatives that came to mind were `alerts-boolean-filters-...` or\n`alerts-filters-builder`.\n\n<details>\n<summary>\n\n## Implementation details\n\n</summary>\n\n### Filters expression state\n\nI opted for a tree state representation of the form's boolean expression\nto accommodate potential future requirements such as more complex\nboolean expressions (negation, parenthesized subexpressions to manually\ncontrol operators precedence):\n\n```ts\n{\n operator: 'or',\n operands: [\n {\n operator: 'or',\n operands: [\n { type: 'ruleTags', value: ['tag-1'] },\n { type: 'ruleTags', value: ['tag-2'] },\n {\n operator: 'and',\n operands: [{ type: 'ruleTypes', value: ['type-1'] }, { type: 'ruleTypes', value: ['type-2'] }],\n },\n ],\n },\n { type: 'ruleTags', value: ['tag-3'] },\n ],\n}\n```\n\nThis state is saved in the embeddable panel state and represents the\neditor form. The embeddable alerts table wrapper component will then\ntransform this to an actual ES query.\n\nTo simplify interactions inside the form, an intermediate equivalent\nflattened state is used:\n\n```ts\n[\n { filter: { type: 'ruleTags', value: ['tag-1'] } },\n { operator: 'or' },\n { filter: { type: 'ruleTags', value: ['tag-2'] } },\n { operator: 'or' },\n { filter: { type: 'ruleTypes', value: ['type-1'] }},\n { operator: 'and' },\n { filter: { type: 'ruleTypes', value: ['type-2'] } },\n { operator: 'or' },\n { filter: { type: 'ruleTags', value: ['tag-3'] } },\n]\n```\n\n### Filters model\n\nEach filter is described by an `AlertsFilterMetadata<T>` object, where\n`T` is the type of the filter value:\n\n```tsx\nexport const filterMetadata: AlertsFilterMetadata<string[]> = {\n id: 'ruleTags',\n displayName: RULE_TAGS_FILTER_LABEL,\n component: AlertsFilterByRuleTags,\n // Filter-specific empty check\n isEmpty: (value?: string[]) => !value?.length,\n // Conversion to ES query DSL\n toEsQuery: (value: string[]) => {\n return {\n terms: {\n [ALERT_RULE_TAGS]: value,\n },\n };\n },\n};\n```\n\n</details>\n\n## Verification steps\n\n1. Run Kibana with examples (`yarn start --run-examples`)\n2. Create rules in different solutions with tags\n3. Navigate to `/app/triggersActionsUiExample/alerts_filters_form`\n4. Check that the solution selector options are coherent with the rule\ntypes the user can access\n5. Select a solution\n6. Build filters expressions, checking that the rule tags and rule types\nare coherent with the solution selection and the rules created\npreviously\n7. Repeat steps 3-6 with different roles:\n7.1. having access to rule types from just one solution (in this case\nthe solution selector shouldn't appear at all),\n7.2. having access just to Observability and Stack but not Security (in\nthis case the solution selector shouldn't appear at all),\n8. Repeat steps 3-6 in the three serverless project types:\n ```shell\n $ yarn es serverless —ssl --projectType <es|oblt|security>\n $ yarn serverless-<es|oblt|security> --ssl --run-examples\n ```\n(If the authentication fails when switching between project types, use a\nclean session)\n8.1. ES project types should have access only to Stack rules (no\nselector)\n8.2. Observability project types should have access only to\nObservability and Stack rules (no selector)\n8.3. Security project types should have access only to Security and\nStack rules (selector shows Stack instead of Observability)\n\n## References\n\nDepends on #214187\nCloses #213061\n\n### Checklist\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: Christos Nasikas <xristosnasikas@gmail.com>","sha":"c44efc52f62f2bb80c8cb8c288cfb40fc3164344"}},"sourceBranch":"main","suggestedTargetBranches":["8.19"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/214982","number":214982,"mergeCommit":{"message":"[ResponseOps][Alerts] Implement alerts filters form (#214982)\n\n## Summary\n\nImplements the alerts filters form that will be used to pre-filter the\nalerts table embeddable.\n\n<img width=\"1004\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/b51ce051-40d2-42d0-a9c1-0fba3fd919af\"\n/>\n\n> [!NOTE]\n> I'm using the terminology \"form\" to distinguish this from the alert\nfilter _controls_ or other type of more KQL-bar-like filters. Other\nalternatives that came to mind were `alerts-boolean-filters-...` or\n`alerts-filters-builder`.\n\n<details>\n<summary>\n\n## Implementation details\n\n</summary>\n\n### Filters expression state\n\nI opted for a tree state representation of the form's boolean expression\nto accommodate potential future requirements such as more complex\nboolean expressions (negation, parenthesized subexpressions to manually\ncontrol operators precedence):\n\n```ts\n{\n operator: 'or',\n operands: [\n {\n operator: 'or',\n operands: [\n { type: 'ruleTags', value: ['tag-1'] },\n { type: 'ruleTags', value: ['tag-2'] },\n {\n operator: 'and',\n operands: [{ type: 'ruleTypes', value: ['type-1'] }, { type: 'ruleTypes', value: ['type-2'] }],\n },\n ],\n },\n { type: 'ruleTags', value: ['tag-3'] },\n ],\n}\n```\n\nThis state is saved in the embeddable panel state and represents the\neditor form. The embeddable alerts table wrapper component will then\ntransform this to an actual ES query.\n\nTo simplify interactions inside the form, an intermediate equivalent\nflattened state is used:\n\n```ts\n[\n { filter: { type: 'ruleTags', value: ['tag-1'] } },\n { operator: 'or' },\n { filter: { type: 'ruleTags', value: ['tag-2'] } },\n { operator: 'or' },\n { filter: { type: 'ruleTypes', value: ['type-1'] }},\n { operator: 'and' },\n { filter: { type: 'ruleTypes', value: ['type-2'] } },\n { operator: 'or' },\n { filter: { type: 'ruleTags', value: ['tag-3'] } },\n]\n```\n\n### Filters model\n\nEach filter is described by an `AlertsFilterMetadata<T>` object, where\n`T` is the type of the filter value:\n\n```tsx\nexport const filterMetadata: AlertsFilterMetadata<string[]> = {\n id: 'ruleTags',\n displayName: RULE_TAGS_FILTER_LABEL,\n component: AlertsFilterByRuleTags,\n // Filter-specific empty check\n isEmpty: (value?: string[]) => !value?.length,\n // Conversion to ES query DSL\n toEsQuery: (value: string[]) => {\n return {\n terms: {\n [ALERT_RULE_TAGS]: value,\n },\n };\n },\n};\n```\n\n</details>\n\n## Verification steps\n\n1. Run Kibana with examples (`yarn start --run-examples`)\n2. Create rules in different solutions with tags\n3. Navigate to `/app/triggersActionsUiExample/alerts_filters_form`\n4. Check that the solution selector options are coherent with the rule\ntypes the user can access\n5. Select a solution\n6. Build filters expressions, checking that the rule tags and rule types\nare coherent with the solution selection and the rules created\npreviously\n7. Repeat steps 3-6 with different roles:\n7.1. having access to rule types from just one solution (in this case\nthe solution selector shouldn't appear at all),\n7.2. having access just to Observability and Stack but not Security (in\nthis case the solution selector shouldn't appear at all),\n8. Repeat steps 3-6 in the three serverless project types:\n ```shell\n $ yarn es serverless —ssl --projectType <es|oblt|security>\n $ yarn serverless-<es|oblt|security> --ssl --run-examples\n ```\n(If the authentication fails when switching between project types, use a\nclean session)\n8.1. ES project types should have access only to Stack rules (no\nselector)\n8.2. Observability project types should have access only to\nObservability and Stack rules (no selector)\n8.3. Security project types should have access only to Security and\nStack rules (selector shows Stack instead of Observability)\n\n## References\n\nDepends on #214187\nCloses #213061\n\n### Checklist\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: Christos Nasikas <xristosnasikas@gmail.com>","sha":"c44efc52f62f2bb80c8cb8c288cfb40fc3164344"}},{"branch":"8.19","label":"v8.19.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT-->
Summary
Implements the alerts filters form that will be used to pre-filter the alerts table embeddable.
Note
I'm using the terminology "form" to distinguish this from the alert filter controls or other type of more KQL-bar-like filters. Other alternatives that came to mind were
alerts-boolean-filters-...
oralerts-filters-builder
.Implementation details
Filters expression state
I opted for a tree state representation of the form's boolean expression to accommodate potential future requirements such as more complex boolean expressions (negation, parenthesized subexpressions to manually control operators precedence):
This state is saved in the embeddable panel state and represents the editor form. The embeddable alerts table wrapper component will then transform this to an actual ES query.
To simplify interactions inside the form, an intermediate equivalent flattened state is used:
Filters model
Each filter is described by an
AlertsFilterMetadata<T>
object, whereT
is the type of the filter value:Verification steps
yarn start --run-examples
)/app/triggersActionsUiExample/alerts_filters_form
7.1. having access to rule types from just one solution (in this case the solution selector shouldn't appear at all),
7.2. having access just to Observability and Stack but not Security (in this case the solution selector shouldn't appear at all),
8.1. ES project types should have access only to Stack rules (no selector)
8.2. Observability project types should have access only to Observability and Stack rules (no selector)
8.3. Security project types should have access only to Security and Stack rules (selector shows Stack instead of Observability)
References
Depends on #214187
Closes #213061
Checklist