-
Notifications
You must be signed in to change notification settings - Fork 8.6k
[Dashboards as code] Add conversion functions from/to API filters interface and stored filters #242043
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
[Dashboards as code] Add conversion functions from/to API filters interface and stored filters #242043
Changes from all commits
d264710
5989e98
f900770
5037bbe
fb0f138
b49449a
ab20892
48689fc
f13c024
539a159
565848a
7f85963
01553d3
51c30b1
a2979a9
1d27d0b
54960ce
b9bc071
883b3b6
3cbf28b
00bd945
8aa68b4
e72bb46
6b5e025
f94f926
d1c1ea2
27870ca
36da619
7702432
6f3a0a2
be5747f
899ba8a
672a077
df7b5dc
bd9b5d6
fb5dc8c
13f1a62
d64b421
25316a0
0a930b4
f16f979
dee2b0d
01687a6
7fc89e4
f51ad53
cc08ab2
24c5e35
6cb4c93
ff77dbd
da409a6
50cff02
f350dca
50678b2
8c7f02b
6672d63
d2ab0dd
0c10777
53a4487
0cd3070
265270c
e6ef2e1
ff8c7d0
8472989
75d4c5d
c7dc9f8
69099df
6b224f7
6338af3
6c999d4
473bdc3
8405542
37a85a2
af431eb
8d7df32
21eaa18
00a4a21
ae140e0
70f89dd
cf78b9d
e6f73bc
4afaeda
5bdb619
22bff4b
e655e01
8cc0a78
756471f
3b29891
135a81e
dd93a49
288bbf8
b3fd494
b73ca8b
586817d
00a7d2a
9117b66
1aef0e7
2f3dc0f
6c80f36
a76ca59
9799f1d
6bc35e1
6521fe9
f59453b
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 |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # @kbn/as-code-filters-constants | ||
|
|
||
| Constants that can be used by both `@kbn/as-code-filters-schema` and `@kbn/as-code-filters-transforms` packages to avoid circular references. |
| 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| export { ASCODE_FILTER_OPERATOR } from './src/constants'; | ||
| export { ASCODE_GROUPED_CONDITION_TYPE } from './src/constants'; | ||
| export { ASCODE_FILTER_TYPE } from './src/constants'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /* | ||
| * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| module.exports = { | ||
| preset: '@kbn/test/jest_node', | ||
| rootDir: '../../../../../..', | ||
| roots: ['<rootDir>/src/platform/packages/shared/as-code/filters-constants'], | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "type": "shared-common", | ||
| "id": "@kbn/as-code-filters-constants", | ||
| "owner": "@elastic/kibana-presentation", | ||
| "group": "platform", | ||
| "visibility": "shared" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # This file is generated by the @kbn/moon package. Any manual edits will be erased! | ||
| # To extend this, write your extensions/overrides to 'moon.extend.yml' | ||
| # then regenerate this file with: 'node scripts/regenerate_moon_projects.js --update --filter @kbn/as-code-filters-constants' | ||
|
|
||
| $schema: https://moonrepo.dev/schemas/project.json | ||
| id: '@kbn/as-code-filters-constants' | ||
| type: unknown | ||
| owners: | ||
| defaultOwner: '@elastic/kibana-presentation' | ||
| toolchain: | ||
| default: node | ||
| language: typescript | ||
| project: | ||
| name: '@kbn/as-code-filters-constants' | ||
| description: Moon project for @kbn/as-code-filters-constants | ||
| channel: '' | ||
| owner: '@elastic/kibana-presentation' | ||
| metadata: | ||
| sourceRoot: src/platform/packages/shared/as-code/filters-constants | ||
| dependsOn: [] | ||
| tags: | ||
| - shared-common | ||
| - package | ||
| - prod | ||
| - group-platform | ||
| - shared | ||
| - jest-unit-tests | ||
| fileGroups: | ||
| src: | ||
| - '**/*.ts' | ||
| - '!target/**/*' | ||
| tasks: | ||
| jest: | ||
| args: | ||
| - '--config' | ||
| - $projectRoot/jest.config.js | ||
| inputs: | ||
| - '@group(src)' | ||
| jestCI: | ||
| args: | ||
| - '--config' | ||
| - $projectRoot/jest.config.js | ||
| inputs: | ||
| - '@group(src)' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "name": "@kbn/as-code-filters-constants", | ||
| "private": true, | ||
| "version": "1.0.0", | ||
| "license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0", | ||
| "sideEffects": false | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| /* | ||
| * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| /** | ||
| * As Code Filter operator constants | ||
| * These operators are used in SimpleFilterCondition to specify how to match field values | ||
| */ | ||
| export const ASCODE_FILTER_OPERATOR = { | ||
| IS: 'is', | ||
| IS_ONE_OF: 'is_one_of', | ||
| EXISTS: 'exists', | ||
| RANGE: 'range', | ||
| } as const; | ||
|
|
||
| export const ASCODE_GROUPED_CONDITION_TYPE = { | ||
| AND: 'and', | ||
| OR: 'or', | ||
| } as const; | ||
|
|
||
| export const ASCODE_FILTER_TYPE = { | ||
| CONDITION: 'condition', | ||
| GROUP: 'group', | ||
| DSL: 'dsl', | ||
| SPATIAL: 'spatial', | ||
| } as const; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "extends": "@kbn/tsconfig-base/tsconfig.json", | ||
| "compilerOptions": { | ||
| "outDir": "target/types", | ||
| }, | ||
| "include": [ | ||
| "**/*.ts", | ||
| ], | ||
| "exclude": [ | ||
| "target/**/*" | ||
| ], | ||
| "kbn_references": [] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| # @kbn/as-code-filters-schema | ||
|
|
||
| Validation schemas and TypeScript types for the **Kibana As Code Filter Interface**. | ||
|
|
||
| ## Overview | ||
|
|
||
| This package provides runtime validation schemas and corresponding TypeScript types for filters in the Kibana As Code API. It uses `@kbn/config-schema` for validation and is designed for server-side use in API route handlers. | ||
|
|
||
| ## Filter Structure | ||
|
|
||
| The As Code filter interface supports three main filter types: | ||
|
|
||
| ### 1. Condition Filters | ||
|
|
||
| Single field-value comparisons with type-safe operators: | ||
|
|
||
| ```typescript | ||
| import { | ||
| asCodeConditionFilterSchema, | ||
| type AsCodeConditionFilter, | ||
| } from '@kbn/as-code-filters-schema'; | ||
|
|
||
| // Examples of condition filters: | ||
| const isFilter: AsCodeConditionFilter = { | ||
| condition: { field: 'status', operator: 'is', value: 'active' }, | ||
| }; | ||
|
|
||
| const isOneOfFilter: AsCodeConditionFilter = { | ||
| condition: { field: 'category', operator: 'is_one_of', value: ['A', 'B', 'C'] }, | ||
| }; | ||
|
|
||
| const rangeFilter: AsCodeConditionFilter = { | ||
| condition: { field: 'price', operator: 'range', value: { gte: 10, lte: 100 } }, | ||
| negate: false, // Only range filters have negate property | ||
| }; | ||
|
|
||
| const existsFilter: AsCodeConditionFilter = { | ||
| condition: { field: 'description', operator: 'exists' }, | ||
| }; | ||
| ``` | ||
|
|
||
| **Operators:** | ||
|
|
||
| - `is` / `is_not` - Single value comparison | ||
| - `is_one_of` / `is_not_one_of` - Array value comparison | ||
| - `range` - Numeric/date range (has `negate` property) | ||
| - `exists` / `not_exists` - Field existence check | ||
|
|
||
| ### 2. Group Filters | ||
|
|
||
| Logical combinations of conditions with AND/OR: | ||
|
|
||
| ```typescript | ||
| import { asCodeGroupFilterSchema, type AsCodeGroupFilter } from '@kbn/as-code-filters-schema'; | ||
|
|
||
| const groupFilter: AsCodeGroupFilter = { | ||
| group: { | ||
| operator: 'and', | ||
| conditions: [ | ||
| { field: 'status', operator: 'is', value: 'active' }, | ||
| { field: 'priority', operator: 'range', value: { gte: 5 } }, | ||
| ], | ||
| }, | ||
| negate: false, // Can negate entire group | ||
| }; | ||
| ``` | ||
|
|
||
| Groups support nesting for complex logic: | ||
|
|
||
| ```typescript | ||
| const nestedGroup: AsCodeGroupFilter = { | ||
| group: { | ||
| operator: 'or', | ||
| conditions: [ | ||
| { field: 'region', operator: 'is', value: 'US' }, | ||
| { | ||
| group: { | ||
| operator: 'and', | ||
| conditions: [ | ||
| { field: 'region', operator: 'is', value: 'EU' }, | ||
|
Contributor
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. I wonder if we could compress the number of operators and allow for more flexibility by using a
Contributor
Author
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. Yeah, I rather like this idea. We could get rid of
Contributor
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. Let me know when I can re-review!
Contributor
Author
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. 4afaeda removes the |
||
| { field: 'vip', operator: 'is', value: true }, | ||
| ], | ||
| }, | ||
| }, | ||
| ], | ||
| }, | ||
| }; | ||
| ``` | ||
|
|
||
| ### 3. DSL Filters | ||
|
|
||
| Raw Elasticsearch Query DSL for advanced queries: | ||
|
|
||
| ```typescript | ||
| import { asCodeDSLFilterSchema, type AsCodeDSLFilter } from '@kbn/as-code-filters-schema'; | ||
|
|
||
| const dslFilter: AsCodeDSLFilter = { | ||
| dsl: { | ||
| match_phrase: { | ||
| message: 'quick brown fox', | ||
| }, | ||
| }, | ||
| negate: false, | ||
| }; | ||
| ``` | ||
|
|
||
| ## Common Properties | ||
|
|
||
| All filters support these optional metadata properties: | ||
|
|
||
| ```typescript | ||
| interface CommonProperties { | ||
| disabled?: boolean; // Filter is disabled | ||
| controlledBy?: string; // Component managing this filter | ||
| dataViewId?: string; // Associated data view | ||
| label?: string; // Human-readable label | ||
| isMultiIndex?: boolean; // Applies to multiple indices | ||
|
|
||
| // Legacy compatibility (deprecated): | ||
| filterType?: string; // Legacy filter type | ||
| key?: string; // Legacy field name | ||
| value?: string; // Legacy value | ||
| } | ||
| ``` | ||
|
|
||
| ## Usage in API Routes | ||
|
|
||
| ```typescript | ||
| import { asCodeFilterSchema, type AsCodeFilter } from '@kbn/as-code-filters-schema'; | ||
|
|
||
| router.post( | ||
| { | ||
| path: '/api/dashboards/{id}/filters', | ||
| validate: { | ||
| body: schema.object({ | ||
| filters: schema.arrayOf(asCodeFilterSchema), | ||
| }), | ||
| }, | ||
| }, | ||
| async (context, request, response) => { | ||
| const { filters } = request.body; | ||
| // filters is typed as AsCodeFilter[] | ||
| // ... process filters | ||
| } | ||
| ); | ||
| ``` | ||
|
|
||
| ## Exported Schemas | ||
|
|
||
| - `asCodeFilterSchema` - Main discriminated union schema | ||
| - `asCodeConditionFilterSchema` - Condition filter schema | ||
| - `asCodeGroupFilterSchema` - Group filter schema | ||
| - `asCodeDSLFilterSchema` - DSL filter schema | ||
|
|
||
| ## Exported Types Inferred from Schemas | ||
|
|
||
| - `AsCodeFilter` - Main discriminated union type | ||
| - `AsCodeConditionFilter` - Condition filter type | ||
| - `AsCodeGroupFilter` - Group filter type | ||
| - `AsCodeDSLFilter` - DSL filter type | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| /* | ||
| * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| export { | ||
| asCodeFilterSchema, | ||
| asCodeConditionFilterSchema, | ||
| asCodeGroupFilterSchema, | ||
| asCodeDSLFilterSchema, | ||
| asCodeSpatialFilterSchema, | ||
| } from './src/schemas/filter'; | ||
|
|
||
| export type { | ||
| AsCodeFilter, | ||
| AsCodeConditionFilter, | ||
| AsCodeGroupFilter, | ||
| AsCodeDSLFilter, | ||
| AsCodeSpatialFilter, | ||
| } from './src/types'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /* | ||
| * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| module.exports = { | ||
| preset: '@kbn/test/jest_node', | ||
| rootDir: '../../../../../..', | ||
| roots: ['<rootDir>/src/platform/packages/shared/as-code/filters-schema'], | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "type": "shared-common", | ||
|
Contributor
Author
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. Ideally, this would be |
||
| "id": "@kbn/as-code-filters-schema", | ||
| "owner": "@elastic/kibana-presentation", | ||
| "group": "platform", | ||
| "visibility": "shared" | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.