From abf00ee777a40b9487b87927e8fc1baa49ab7d02 Mon Sep 17 00:00:00 2001 From: Marco Antonio Ghiani Date: Fri, 10 Jan 2025 12:01:55 +0100 Subject: [PATCH] =?UTF-8?q?[Streams=20=F0=9F=8C=8A]=20Stream=20enrichment?= =?UTF-8?q?=20processors=20management=20(#204793)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 📓 Summary Part of #https://github.com/elastic/streams-program/issues/32 This work implements a UI for basic stream enrichment, supporting grok and dissect processor + detected fields mapping. The main features implemented in this PR consist of: - **Sortable processors list** - **Add new processor - Grok, Dissect** - Ad-hoc forms for each processor - Simulated document outcome with extracted fields - Filter matching documents with parsed fields - Mapping detected fields (only available for wired streams) - **Edit processor** - Change configuration only - Delete processor CTA As a side quest, I added a small package for object utils as @simianhacker suggested. `@kbn/object-utils` exposes `calculateObjectDiff` and `flattenObject` to detect the changed fields in a simulation. ## 🔜 Follow-up work I'll work on minor updates on top of this MVP to make this available for further testing from the team. The next steps will be: - **Tests** for features that consolidate on the functional pov. - Better field mapping detection and UI feedback (infer the type of the detected field, currently always unmapped) - Add better form validation and feedback for processor configuration. As discussed offline, state management is purely based on the built-in react APIs + react-hook-form. It could be improved with different approaches, including a more solid state management library to make it easier to maintain and bulletproof to race conditions. No state syncs with the URL currently. ## 🎥 Demo https://github.com/user-attachments/assets/a48fade9-f5aa-4270-bb19-d91d1eed822b --------- Co-authored-by: Marco Antonio Ghiani Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 1 + package.json | 1 + .../shared/kbn-object-utils/README.md | 76 +++ .../packages/shared/kbn-object-utils/index.ts | 11 + .../shared/kbn-object-utils/jest.config.js | 14 + .../shared/kbn-object-utils/kibana.jsonc | 10 + .../shared/kbn-object-utils/package.json | 8 + .../src/calculate_object_diff.test.ts | 34 ++ .../src/calculate_object_diff.ts | 75 +++ .../src/flatten_object.test.ts | 32 ++ .../kbn-object-utils/src/flatten_object.ts | 33 ++ .../shared/kbn-object-utils/tsconfig.json | 10 + tsconfig.base.json | 2 + .../src/apis/list_streams_response.ts | 4 +- .../kbn-streams-schema/src/helpers/index.ts | 1 + .../src/helpers/processing.ts | 38 ++ .../src/helpers/type_guards.ts | 8 +- .../kbn-streams-schema/src/models/common.ts | 25 +- .../src/models/streams/stream.ts | 4 +- .../lib/streams/errors/simulation_failed.ts | 20 + .../lib/streams/helpers/condition_fields.ts | 13 - .../server/lib/streams/helpers/processing.ts | 26 + .../generate_ingest_pipeline.ts | 37 +- .../plugins/streams/server/routes/index.ts | 2 + .../routes/streams/processing/simulate.ts | 153 ++++++ .../streams/server/routes/streams/sample.ts | 6 +- .../plugins/streams/tsconfig.json | 1 + .../get_mock_streams_app_context.tsx | 2 + .../public/components/app_root/index.tsx | 1 + .../public/components/asset_image/index.tsx | 47 ++ .../asset_image/no_results_dark.png | Bin 0 -> 37719 bytes .../asset_image/no_results_light.png | Bin 0 -> 37158 bytes .../components/asset_image/welcome_dark.png | Bin 0 -> 48993 bytes .../components/asset_image/welcome_light.png | Bin 0 -> 50657 bytes .../public/components/assets/illustration.png | Bin 58425 -> 0 bytes .../components/condition_editor/index.tsx | 7 +- .../management_bottom_bar/index.tsx | 58 +++ .../public/components/preview_table/index.tsx | 10 +- .../stream_detail_enriching/index.tsx | 18 - .../add_processor_button.tsx | 22 + .../enrichment_empty_prompt.tsx | 44 ++ .../flyout/danger_zone.tsx | 89 ++++ .../dissect/dissect_append_separator.tsx | 36 ++ .../dissect/dissect_pattern_definition.tsx | 79 +++ .../flyout/dissect/index.tsx | 50 ++ .../flyout/grok/grok_pattern_definition.tsx | 92 ++++ .../flyout/grok/grok_patterns_editor.tsx | 128 +++++ .../flyout/grok/index.tsx | 50 ++ .../stream_detail_enrichment/flyout/index.tsx | 169 +++++++ .../flyout/optional_fields_accordion.tsx | 38 ++ .../flyout/processor_condition_editor.tsx | 16 + .../flyout/processor_field_selector.tsx | 31 ++ .../flyout/processor_flyout_template.tsx | 62 +++ .../flyout/processor_outcome_preview.tsx | 459 ++++++++++++++++++ .../flyout/processor_type_selector.tsx | 108 +++++ .../flyout/toggle_field.tsx | 40 ++ .../hooks/use_definition.ts | 162 +++++++ .../stream_detail_enrichment/index.tsx | 31 ++ .../stream_detail_enrichment/page_content.tsx | 157 ++++++ .../processors_list.tsx | 114 +++++ .../root_stream_empty_prompt.tsx | 39 ++ .../sortable_list.tsx | 38 ++ .../stream_detail_enrichment/types.ts | 45 ++ .../stream_detail_enrichment/utils.ts | 137 ++++++ .../stream_detail_management/classic.tsx | 6 +- .../stream_detail_management/wired.tsx | 6 +- .../stream_detail_management/wrapper.tsx | 2 +- .../stream_detail_routing/index.tsx | 11 +- .../streams_app_search_bar/index.tsx | 4 +- .../public/hooks/use_discard_confirm.ts | 35 ++ .../streams_app/public/hooks/use_kibana.tsx | 6 +- .../plugins/streams_app/tsconfig.json | 6 + yarn.lock | 4 + 73 files changed, 2998 insertions(+), 106 deletions(-) create mode 100644 src/platform/packages/shared/kbn-object-utils/README.md create mode 100644 src/platform/packages/shared/kbn-object-utils/index.ts create mode 100644 src/platform/packages/shared/kbn-object-utils/jest.config.js create mode 100644 src/platform/packages/shared/kbn-object-utils/kibana.jsonc create mode 100644 src/platform/packages/shared/kbn-object-utils/package.json create mode 100644 src/platform/packages/shared/kbn-object-utils/src/calculate_object_diff.test.ts create mode 100644 src/platform/packages/shared/kbn-object-utils/src/calculate_object_diff.ts create mode 100644 src/platform/packages/shared/kbn-object-utils/src/flatten_object.test.ts create mode 100644 src/platform/packages/shared/kbn-object-utils/src/flatten_object.ts create mode 100644 src/platform/packages/shared/kbn-object-utils/tsconfig.json create mode 100644 x-pack/packages/kbn-streams-schema/src/helpers/processing.ts create mode 100644 x-pack/solutions/observability/plugins/streams/server/lib/streams/errors/simulation_failed.ts create mode 100644 x-pack/solutions/observability/plugins/streams/server/lib/streams/helpers/processing.ts create mode 100644 x-pack/solutions/observability/plugins/streams/server/routes/streams/processing/simulate.ts create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/index.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/no_results_dark.png create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/no_results_light.png create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/welcome_dark.png create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/welcome_light.png delete mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/assets/illustration.png create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/management_bottom_bar/index.tsx delete mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enriching/index.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/add_processor_button.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/enrichment_empty_prompt.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/danger_zone.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/dissect_append_separator.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/dissect_pattern_definition.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/index.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/grok_pattern_definition.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/grok_patterns_editor.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/index.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/index.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/optional_fields_accordion.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_condition_editor.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_field_selector.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_flyout_template.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_outcome_preview.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_type_selector.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/toggle_field.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/hooks/use_definition.ts create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/index.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/page_content.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/processors_list.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/root_stream_empty_prompt.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/sortable_list.tsx create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/types.ts create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/utils.ts create mode 100644 x-pack/solutions/observability/plugins/streams_app/public/hooks/use_discard_confirm.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c9af0fd8d5c1b..3cc282ab49b50 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -497,6 +497,7 @@ src/platform/packages/shared/kbn-management/settings/field_definition @elastic/k src/platform/packages/shared/kbn-management/settings/types @elastic/kibana-management src/platform/packages/shared/kbn-management/settings/utilities @elastic/kibana-management src/platform/packages/shared/kbn-monaco @elastic/appex-sharedux +src/platform/packages/shared/kbn-object-utils @elastic/kibana-core src/platform/packages/shared/kbn-object-versioning @elastic/appex-sharedux src/platform/packages/shared/kbn-object-versioning-utils @elastic/appex-sharedux src/platform/packages/shared/kbn-openapi-common @elastic/security-detection-rule-management diff --git a/package.json b/package.json index 44730ac027fe9..9d592efff0187 100644 --- a/package.json +++ b/package.json @@ -686,6 +686,7 @@ "@kbn/newsfeed-test-plugin": "link:test/common/plugins/newsfeed", "@kbn/no-data-page-plugin": "link:src/platform/plugins/private/no_data_page", "@kbn/notifications-plugin": "link:x-pack/platform/plugins/shared/notifications", + "@kbn/object-utils": "link:src/platform/packages/shared/kbn-object-utils", "@kbn/object-versioning": "link:src/platform/packages/shared/kbn-object-versioning", "@kbn/object-versioning-utils": "link:src/platform/packages/shared/kbn-object-versioning-utils", "@kbn/observability-ai-assistant-app-plugin": "link:x-pack/solutions/observability/plugins/observability_ai_assistant_app", diff --git a/src/platform/packages/shared/kbn-object-utils/README.md b/src/platform/packages/shared/kbn-object-utils/README.md new file mode 100644 index 0000000000000..c3a94576d727f --- /dev/null +++ b/src/platform/packages/shared/kbn-object-utils/README.md @@ -0,0 +1,76 @@ +# @kbn/object-utils + +Utilities for objects manipulation and parsing. + +## Utilities + +### calculateObjectDiff + +This utils compares two JSON objects and calculates the added and removed properties, including nested properties. + +```ts +const oldObject = { + alpha: 1, + beta: { + gamma: 2, + delta: { + sigma: 7, + }, + }, +}; + +const newObject = { + alpha: 1, + beta: { + gamma: 2, + eta: 4, + }, +}; + +const diff = calculateObjectDiff(oldObject, newObject); + +/* +Result: +{ + added: { + beta: { + eta: 4, + }, + }, + removed: { + beta: { + delta: { + sigma: 7, + }, + }, + }, +} +*/ +``` + +### flattenObject + +This utils returns a flattened version of the input object also accounting for nested properties. + +```ts +const flattened = flattenObject({ + alpha: { + gamma: { + sigma: 1, + }, + delta: { + sigma: 2, + }, + }, + beta: 3, +}); + +/* +Result: +{ + 'alpha.gamma.sigma': 1, + 'alpha.delta.sigma': 2, + beta: 3, +} +*/ +``` diff --git a/src/platform/packages/shared/kbn-object-utils/index.ts b/src/platform/packages/shared/kbn-object-utils/index.ts new file mode 100644 index 0000000000000..f5051ab8b042c --- /dev/null +++ b/src/platform/packages/shared/kbn-object-utils/index.ts @@ -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", 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 * from './src/calculate_object_diff'; +export * from './src/flatten_object'; diff --git a/src/platform/packages/shared/kbn-object-utils/jest.config.js b/src/platform/packages/shared/kbn-object-utils/jest.config.js new file mode 100644 index 0000000000000..cd6727b073b79 --- /dev/null +++ b/src/platform/packages/shared/kbn-object-utils/jest.config.js @@ -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', + rootDir: '../../../../..', + roots: ['/src/platform/packages/shared/kbn-object-utils'], +}; diff --git a/src/platform/packages/shared/kbn-object-utils/kibana.jsonc b/src/platform/packages/shared/kbn-object-utils/kibana.jsonc new file mode 100644 index 0000000000000..ce6365156b592 --- /dev/null +++ b/src/platform/packages/shared/kbn-object-utils/kibana.jsonc @@ -0,0 +1,10 @@ +{ + "type": "shared-common", + "id": "@kbn/object-utils", + "owner": [ + "@elastic/kibana-core" + ], + "group": "platform", + "visibility": "shared", + "devOnly": false +} \ No newline at end of file diff --git a/src/platform/packages/shared/kbn-object-utils/package.json b/src/platform/packages/shared/kbn-object-utils/package.json new file mode 100644 index 0000000000000..86111f76bb09d --- /dev/null +++ b/src/platform/packages/shared/kbn-object-utils/package.json @@ -0,0 +1,8 @@ +{ + "description": "Object utils for Kibana", + "license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0", + "name": "@kbn/object-utils", + "private": true, + "version": "1.0.0", + "sideEffects": false +} \ No newline at end of file diff --git a/src/platform/packages/shared/kbn-object-utils/src/calculate_object_diff.test.ts b/src/platform/packages/shared/kbn-object-utils/src/calculate_object_diff.test.ts new file mode 100644 index 0000000000000..340be7783aef3 --- /dev/null +++ b/src/platform/packages/shared/kbn-object-utils/src/calculate_object_diff.test.ts @@ -0,0 +1,34 @@ +/* + * 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". + */ + +import { calculateObjectDiff } from './calculate_object_diff'; + +describe('calculateObjectDiff', () => { + it('should return the added and removed parts between 2 objects', () => { + const { added, removed } = calculateObjectDiff({ alpha: 1, beta: 2 }, { alpha: 1, gamma: 3 }); + expect(added).toEqual({ gamma: 3 }); + expect(removed).toEqual({ beta: 2 }); + }); + + it('should work on nested objects', () => { + const { added, removed } = calculateObjectDiff( + { alpha: 1, beta: { gamma: 2, delta: { sigma: 7 } } }, + { alpha: 1, beta: { gamma: 2, eta: 4 } } + ); + + expect(added).toEqual({ beta: { eta: 4 } }); + expect(removed).toEqual({ beta: { delta: { sigma: 7 } } }); + }); + + it('should return empty added/removed when the objects are the same', () => { + const { added, removed } = calculateObjectDiff({ alpha: 1, beta: 2 }, { alpha: 1, beta: 2 }); + expect(added).toEqual({}); + expect(removed).toEqual({}); + }); +}); diff --git a/src/platform/packages/shared/kbn-object-utils/src/calculate_object_diff.ts b/src/platform/packages/shared/kbn-object-utils/src/calculate_object_diff.ts new file mode 100644 index 0000000000000..33fe441de5ac6 --- /dev/null +++ b/src/platform/packages/shared/kbn-object-utils/src/calculate_object_diff.ts @@ -0,0 +1,75 @@ +/* + * 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". + */ + +import { isEmpty, isPlainObject } from 'lodash'; + +interface Obj { + [key: PropertyKey]: Obj | unknown; +} + +type DeepPartial = { + [Prop in keyof TInputObj]?: TInputObj[Prop] extends Obj + ? DeepPartial + : TInputObj[Prop]; +}; + +interface ObjectDiffResult { + added: DeepPartial; + removed: DeepPartial; +} + +/** + * Compares two JSON objects and calculates the added and removed properties, including nested properties. + * @param oldObj - The base object. + * @param newObj - The comparison object. + * @returns An object containing added and removed properties. + */ +export function calculateObjectDiff( + oldObj: TBase, + newObj?: TCompare +): ObjectDiffResult { + const added: DeepPartial = {}; + const removed: DeepPartial = {}; + + if (!newObj) return { added, removed }; + + function diffRecursive( + base: Obj, + compare: Obj, + addedMap: DeepPartial, + removedMap: DeepPartial + ): void { + for (const key in compare) { + if (!(key in base)) { + addedMap[key] = compare[key]; + } else if (isPlainObject(base[key]) && isPlainObject(compare[key])) { + addedMap[key] = {}; + removedMap[key] = {}; + diffRecursive( + base[key] as Obj, + compare[key] as Obj, + addedMap[key] as Obj, + removedMap[key] as Obj + ); + if (isEmpty(addedMap[key])) delete addedMap[key]; + if (isEmpty(removedMap[key])) delete removedMap[key]; + } + } + + for (const key in base) { + if (!(key in compare)) { + removedMap[key] = base[key]; + } + } + } + + diffRecursive(oldObj, newObj, added, removed); + + return { added, removed }; +} diff --git a/src/platform/packages/shared/kbn-object-utils/src/flatten_object.test.ts b/src/platform/packages/shared/kbn-object-utils/src/flatten_object.test.ts new file mode 100644 index 0000000000000..80bb6b4503020 --- /dev/null +++ b/src/platform/packages/shared/kbn-object-utils/src/flatten_object.test.ts @@ -0,0 +1,32 @@ +/* + * 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". + */ + +import { flattenObject } from './flatten_object'; + +describe('flattenObject', () => { + it('should flat gamma object properties', () => { + const flattened = flattenObject({ + alpha: { + gamma: { + sigma: 1, + }, + delta: { + sigma: 2, + }, + }, + beta: 3, + }); + + expect(flattened).toEqual({ + 'alpha.gamma.sigma': 1, + 'alpha.delta.sigma': 2, + beta: 3, + }); + }); +}); diff --git a/src/platform/packages/shared/kbn-object-utils/src/flatten_object.ts b/src/platform/packages/shared/kbn-object-utils/src/flatten_object.ts new file mode 100644 index 0000000000000..0690012ca2640 --- /dev/null +++ b/src/platform/packages/shared/kbn-object-utils/src/flatten_object.ts @@ -0,0 +1,33 @@ +/* + * 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". + */ + +import { isPlainObject } from 'lodash'; + +/** + * Returns a flattened version of the input object also accounting for nested properties. + * @param obj - The input object. + * @param parentKey - The initial key used for recursive flattening. + * @returns An object containing all the flattened properties. + */ +export function flattenObject(obj: Record, parentKey: string = '') { + const result: Record = {}; + + for (const key in obj) { + if (Object.hasOwn(obj, key)) { + const value = obj[key]; + const newKey = parentKey ? `${parentKey}.${key}` : key; + if (isPlainObject(value)) { + Object.assign(result, flattenObject(value as Record, newKey)); + } else { + result[newKey] = value; + } + } + } + return result; +} diff --git a/src/platform/packages/shared/kbn-object-utils/tsconfig.json b/src/platform/packages/shared/kbn-object-utils/tsconfig.json new file mode 100644 index 0000000000000..2e04c4a6f5733 --- /dev/null +++ b/src/platform/packages/shared/kbn-object-utils/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "outDir": "target/types", + "types": ["jest", "node"] + }, + "exclude": ["target/**/*"], + "extends": "../../../../../tsconfig.base.json", + "include": ["**/*.ts"], + "kbn_references": [] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 2a439e72882bb..75784f7dad582 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1308,6 +1308,8 @@ "@kbn/no-data-page-plugin/*": ["src/platform/plugins/private/no_data_page/*"], "@kbn/notifications-plugin": ["x-pack/platform/plugins/shared/notifications"], "@kbn/notifications-plugin/*": ["x-pack/platform/plugins/shared/notifications/*"], + "@kbn/object-utils": ["src/platform/packages/shared/kbn-object-utils"], + "@kbn/object-utils/*": ["src/platform/packages/shared/kbn-object-utils/*"], "@kbn/object-versioning": ["src/platform/packages/shared/kbn-object-versioning"], "@kbn/object-versioning/*": ["src/platform/packages/shared/kbn-object-versioning/*"], "@kbn/object-versioning-utils": ["src/platform/packages/shared/kbn-object-versioning-utils"], diff --git a/x-pack/packages/kbn-streams-schema/src/apis/list_streams_response.ts b/x-pack/packages/kbn-streams-schema/src/apis/list_streams_response.ts index f1f42f7e90ae2..57077c98c1ad3 100644 --- a/x-pack/packages/kbn-streams-schema/src/apis/list_streams_response.ts +++ b/x-pack/packages/kbn-streams-schema/src/apis/list_streams_response.ts @@ -5,10 +5,10 @@ * 2.0. */ import { z } from '@kbn/zod'; -import { streamDefintionSchema } from '../models'; +import { streamDefinitionSchema } from '../models'; export const listStreamsResponseSchema = z.object({ - streams: z.array(streamDefintionSchema), + streams: z.array(streamDefinitionSchema), }); export type ListStreamsResponse = z.infer; diff --git a/x-pack/packages/kbn-streams-schema/src/helpers/index.ts b/x-pack/packages/kbn-streams-schema/src/helpers/index.ts index d1f9a8ff0c50a..d9cb94d020d13 100644 --- a/x-pack/packages/kbn-streams-schema/src/helpers/index.ts +++ b/x-pack/packages/kbn-streams-schema/src/helpers/index.ts @@ -5,4 +5,5 @@ * 2.0. */ +export * from './processing'; export * from './type_guards'; diff --git a/x-pack/packages/kbn-streams-schema/src/helpers/processing.ts b/x-pack/packages/kbn-streams-schema/src/helpers/processing.ts new file mode 100644 index 0000000000000..95d7aa0b23aac --- /dev/null +++ b/x-pack/packages/kbn-streams-schema/src/helpers/processing.ts @@ -0,0 +1,38 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Condition, ProcessingDefinition } from '../models'; +import { + isGrokProcessor, + isDissectProcessor, + isFilterCondition, + isAndCondition, + isOrCondition, +} from './type_guards'; + +export function getProcessorType(processor: ProcessingDefinition) { + if (isGrokProcessor(processor.config)) { + return 'grok'; + } + if (isDissectProcessor(processor.config)) { + return 'dissect'; + } + throw new Error('Unknown processor type'); +} + +export function isCompleteCondition(condition: Condition): boolean { + if (isFilterCondition(condition)) { + return condition.field !== undefined && condition.field !== ''; + } + if (isAndCondition(condition)) { + return condition.and.every(isCompleteCondition); + } + if (isOrCondition(condition)) { + return condition.or.every(isCompleteCondition); + } + return false; +} diff --git a/x-pack/packages/kbn-streams-schema/src/helpers/type_guards.ts b/x-pack/packages/kbn-streams-schema/src/helpers/type_guards.ts index 6e3fb3418b853..3c3be21f794d0 100644 --- a/x-pack/packages/kbn-streams-schema/src/helpers/type_guards.ts +++ b/x-pack/packages/kbn-streams-schema/src/helpers/type_guards.ts @@ -10,7 +10,7 @@ import { AndCondition, conditionSchema, dissectProcessingDefinitionSchema, - DissectProcssingDefinition, + DissectProcessingDefinition, FilterCondition, filterConditionSchema, GrokProcessingDefinition, @@ -23,7 +23,7 @@ import { ReadStreamDefinition, readStreamDefinitonSchema, StreamDefinition, - streamDefintionSchema, + streamDefinitionSchema, WiredReadStreamDefinition, wiredReadStreamDefinitonSchema, WiredStreamDefinition, @@ -60,7 +60,7 @@ export function isIngestReadStream(subject: any): subject is IngestReadStreamDef } export function isStream(subject: any): subject is StreamDefinition { - return isSchema(streamDefintionSchema, subject); + return isSchema(streamDefinitionSchema, subject); } export function isIngestStream(subject: StreamDefinition): subject is IngestStreamDefinition { @@ -97,7 +97,7 @@ export function isGrokProcessor(subject: any): subject is GrokProcessingDefiniti return isSchema(grokProcessingDefinitionSchema, subject); } -export function isDissectProcessor(subject: any): subject is DissectProcssingDefinition { +export function isDissectProcessor(subject: any): subject is DissectProcessingDefinition { return isSchema(dissectProcessingDefinitionSchema, subject); } diff --git a/x-pack/packages/kbn-streams-schema/src/models/common.ts b/x-pack/packages/kbn-streams-schema/src/models/common.ts index f3c967e52605a..4b3a8628a38ec 100644 --- a/x-pack/packages/kbn-streams-schema/src/models/common.ts +++ b/x-pack/packages/kbn-streams-schema/src/models/common.ts @@ -52,6 +52,8 @@ export const grokProcessingDefinitionSchema = z.object({ field: z.string(), patterns: z.array(z.string()), pattern_definitions: z.optional(z.record(z.string())), + ignore_failure: z.optional(z.boolean()), + ignore_missing: z.optional(z.boolean()), }), }); @@ -61,10 +63,13 @@ export const dissectProcessingDefinitionSchema = z.object({ dissect: z.object({ field: z.string(), pattern: z.string(), + append_separator: z.optional(z.string()), + ignore_failure: z.optional(z.boolean()), + ignore_missing: z.optional(z.boolean()), }), }); -export type DissectProcssingDefinition = z.infer; +export type DissectProcessingDefinition = z.infer; export const processingConfigSchema = z.union([ grokProcessingDefinitionSchema, @@ -78,8 +83,24 @@ export const processingDefinitionSchema = z.object({ export type ProcessingDefinition = z.infer; +export type ProcessorType = ProcessingDefinition['config'] extends infer U + ? U extends { [key: string]: any } + ? keyof U + : never + : never; + +export const FIELD_DEFINITION_TYPES = [ + 'keyword', + 'match_only_text', + 'long', + 'double', + 'date', + 'boolean', + 'ip', +] as const; + export const fieldDefinitionConfigSchema = z.object({ - type: z.enum(['keyword', 'match_only_text', 'long', 'double', 'date', 'boolean', 'ip']), + type: z.enum(FIELD_DEFINITION_TYPES), format: z.optional(z.string()), }); diff --git a/x-pack/packages/kbn-streams-schema/src/models/streams/stream.ts b/x-pack/packages/kbn-streams-schema/src/models/streams/stream.ts index 152397060e51b..a5e411f1674c6 100644 --- a/x-pack/packages/kbn-streams-schema/src/models/streams/stream.ts +++ b/x-pack/packages/kbn-streams-schema/src/models/streams/stream.ts @@ -9,9 +9,9 @@ import { z } from '@kbn/zod'; import { wiredStreamDefinitonSchema } from './wired_stream'; import { ingestStreamDefinitonSchema } from './ingest_stream'; -export const streamDefintionSchema = z.union([ +export const streamDefinitionSchema = z.union([ wiredStreamDefinitonSchema, ingestStreamDefinitonSchema, ]); -export type StreamDefinition = z.infer; +export type StreamDefinition = z.infer; diff --git a/x-pack/solutions/observability/plugins/streams/server/lib/streams/errors/simulation_failed.ts b/x-pack/solutions/observability/plugins/streams/server/lib/streams/errors/simulation_failed.ts new file mode 100644 index 0000000000000..28140b377403f --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams/server/lib/streams/errors/simulation_failed.ts @@ -0,0 +1,20 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { errors } from '@elastic/elasticsearch'; + +export class SimulationFailed extends Error { + constructor(error: errors.ResponseError) { + super( + error.body?.error?.reason || + error.body?.error?.caused_by?.reason || + error.message || + 'Unknown error' + ); + this.name = 'SimulationFailed'; + } +} diff --git a/x-pack/solutions/observability/plugins/streams/server/lib/streams/helpers/condition_fields.ts b/x-pack/solutions/observability/plugins/streams/server/lib/streams/helpers/condition_fields.ts index b9b1bbfd1948b..5a7a5dd345fdf 100644 --- a/x-pack/solutions/observability/plugins/streams/server/lib/streams/helpers/condition_fields.ts +++ b/x-pack/solutions/observability/plugins/streams/server/lib/streams/helpers/condition_fields.ts @@ -13,19 +13,6 @@ import { isOrCondition, } from '@kbn/streams-schema'; -export function isComplete(condition: Condition): boolean { - if (isFilterCondition(condition)) { - return condition.field !== undefined && condition.field !== ''; - } - if (isAndCondition(condition)) { - return condition.and.every(isComplete); - } - if (isOrCondition(condition)) { - return condition.or.every(isComplete); - } - return false; -} - export function getFields( condition: Condition ): Array<{ name: string; type: 'number' | 'string' }> { diff --git a/x-pack/solutions/observability/plugins/streams/server/lib/streams/helpers/processing.ts b/x-pack/solutions/observability/plugins/streams/server/lib/streams/helpers/processing.ts new file mode 100644 index 0000000000000..111e1f22bdf56 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams/server/lib/streams/helpers/processing.ts @@ -0,0 +1,26 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ProcessingDefinition, getProcessorType } from '@kbn/streams-schema'; +import { get } from 'lodash'; +import { IngestProcessorContainer } from '@elastic/elasticsearch/lib/api/types'; +import { conditionToPainless } from './condition_to_painless'; + +export function formatToIngestProcessors( + processing: ProcessingDefinition[] +): IngestProcessorContainer[] { + return processing.map((processor) => { + const type = getProcessorType(processor); + const config = get(processor.config, type); + return { + [type]: { + ...config, + if: processor.condition ? conditionToPainless(processor.condition) : undefined, + }, + }; + }); +} diff --git a/x-pack/solutions/observability/plugins/streams/server/lib/streams/ingest_pipelines/generate_ingest_pipeline.ts b/x-pack/solutions/observability/plugins/streams/server/lib/streams/ingest_pipelines/generate_ingest_pipeline.ts index fb03868ed7482..ceeee0bab6866 100644 --- a/x-pack/solutions/observability/plugins/streams/server/lib/streams/ingest_pipelines/generate_ingest_pipeline.ts +++ b/x-pack/solutions/observability/plugins/streams/server/lib/streams/ingest_pipelines/generate_ingest_pipeline.ts @@ -5,48 +5,19 @@ * 2.0. */ -import { - isDissectProcessor, - isGrokProcessor, - ProcessingDefinition, - StreamDefinition, -} from '@kbn/streams-schema'; -import { get } from 'lodash'; +import { StreamDefinition } from '@kbn/streams-schema'; import { ASSET_VERSION } from '../../../../common/constants'; -import { conditionToPainless } from '../helpers/condition_to_painless'; import { logsDefaultPipelineProcessors } from './logs_default_pipeline'; import { isRoot } from '../helpers/hierarchy'; import { getProcessingPipelineName } from './name'; - -function getProcessorType(processor: ProcessingDefinition) { - if (isGrokProcessor(processor.config)) { - return 'grok'; - } - if (isDissectProcessor(processor.config)) { - return 'dissect'; - } - throw new Error('Unknown processor type'); -} - -function generateProcessingSteps(definition: StreamDefinition) { - return definition.stream.ingest.processing.map((processor) => { - const type = getProcessorType(processor); - const config = get(processor.config, type); - return { - [type]: { - ...config, - if: processor.condition ? conditionToPainless(processor.condition) : undefined, - }, - }; - }); -} +import { formatToIngestProcessors } from '../helpers/processing'; export function generateIngestPipeline(id: string, definition: StreamDefinition) { return { id: getProcessingPipelineName(id), processors: [ ...(isRoot(definition.name) ? logsDefaultPipelineProcessors : []), - ...generateProcessingSteps(definition), + ...formatToIngestProcessors(definition.stream.ingest.processing), { pipeline: { name: `${id}@stream.reroutes`, @@ -64,7 +35,7 @@ export function generateIngestPipeline(id: string, definition: StreamDefinition) export function generateClassicIngestPipelineBody(definition: StreamDefinition) { return { - processors: generateProcessingSteps(definition), + processors: formatToIngestProcessors(definition.stream.ingest.processing), _meta: { description: `Stream-managed pipeline for the ${definition.name} stream`, managed: true, diff --git a/x-pack/solutions/observability/plugins/streams/server/routes/index.ts b/x-pack/solutions/observability/plugins/streams/server/routes/index.ts index 3e80d57dfff3c..340900050d1c9 100644 --- a/x-pack/solutions/observability/plugins/streams/server/routes/index.ts +++ b/x-pack/solutions/observability/plugins/streams/server/routes/index.ts @@ -19,6 +19,7 @@ import { resyncStreamsRoute } from './streams/resync'; import { sampleStreamRoute } from './streams/sample'; import { schemaFieldsSimulationRoute } from './streams/schema/fields_simulation'; import { unmappedFieldsRoute } from './streams/schema/unmapped_fields'; +import { simulateProcessorRoute } from './streams/processing/simulate'; import { streamsStatusRoutes } from './streams/settings'; export const streamsRouteRepository = { @@ -36,6 +37,7 @@ export const streamsRouteRepository = { ...sampleStreamRoute, ...streamDetailRoute, ...unmappedFieldsRoute, + ...simulateProcessorRoute, ...schemaFieldsSimulationRoute, }; diff --git a/x-pack/solutions/observability/plugins/streams/server/routes/streams/processing/simulate.ts b/x-pack/solutions/observability/plugins/streams/server/routes/streams/processing/simulate.ts new file mode 100644 index 0000000000000..4b0c7a14ed861 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams/server/routes/streams/processing/simulate.ts @@ -0,0 +1,153 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { z } from '@kbn/zod'; +import { notFound, internal, badRequest } from '@hapi/boom'; +import { FieldDefinitionConfig, processingDefinitionSchema } from '@kbn/streams-schema'; +import { calculateObjectDiff, flattenObject } from '@kbn/object-utils'; +import { + IngestSimulateResponse, + IngestSimulateSimulateDocumentResult, +} from '@elastic/elasticsearch/lib/api/types'; +import { SimulationFailed } from '../../../lib/streams/errors/simulation_failed'; +import { formatToIngestProcessors } from '../../../lib/streams/helpers/processing'; +import { createServerRoute } from '../../create_server_route'; +import { DefinitionNotFound } from '../../../lib/streams/errors'; +import { checkAccess } from '../../../lib/streams/stream_crud'; + +export const simulateProcessorRoute = createServerRoute({ + endpoint: 'POST /api/streams/{id}/processing/_simulate', + options: { + access: 'internal', + }, + security: { + authz: { + enabled: false, + reason: + 'This API delegates security to the currently logged in user and their Elasticsearch permissions.', + }, + }, + params: z.object({ + path: z.object({ id: z.string() }), + body: z.object({ + processing: z.array(processingDefinitionSchema), + documents: z.array(z.record(z.unknown())), + }), + }), + handler: async ({ params, request, response, getScopedClients }) => { + try { + const { scopedClusterClient } = await getScopedClients({ request }); + + const hasAccess = await checkAccess({ id: params.path.id, scopedClusterClient }); + if (!hasAccess) { + throw new DefinitionNotFound(`Stream definition for ${params.path.id} not found.`); + } + // Normalize processing definition to pipeline processors + const processors = formatToIngestProcessors(params.body.processing); + // Convert input documents to ingest simulation format + const docs = params.body.documents.map((doc) => ({ _source: doc })); + + let simulationResult: IngestSimulateResponse; + try { + simulationResult = await scopedClusterClient.asCurrentUser.ingest.simulate({ + verbose: true, + pipeline: { processors }, + docs, + }); + } catch (error) { + throw new SimulationFailed(error); + } + + const documents = computeSimulationDocuments(simulationResult, docs); + const detectedFields = computeDetectedFields(simulationResult, docs); + const successRate = computeSuccessRate(simulationResult); + const failureRate = 1 - successRate; + + return { + documents, + success_rate: parseFloat(successRate.toFixed(2)), + failure_rate: parseFloat(failureRate.toFixed(2)), + detected_fields: detectedFields, + }; + } catch (error) { + if (error instanceof DefinitionNotFound) { + throw notFound(error); + } + + if (error instanceof SimulationFailed) { + throw badRequest(error); + } + + throw internal(error); + } + }, +}); + +const computeSimulationDocuments = ( + simulation: IngestSimulateResponse, + sampleDocs: Array<{ _source: Record }> +) => { + return simulation.docs.map((doc, id) => { + // If every processor was successful, return and flatten the simulation doc from the last processor + if (isSuccessfulDocument(doc)) { + return { + value: flattenObject(doc.processor_results.at(-1)?.doc?._source ?? sampleDocs[id]._source), + isMatch: true, + }; + } + + return { + value: flattenObject(sampleDocs[id]._source), + isMatch: false, + }; + }); +}; + +const computeDetectedFields = ( + simulation: IngestSimulateResponse, + sampleDocs: Array<{ _source: Record }> +): Array<{ + name: string; + type: FieldDefinitionConfig['type'] | 'unmapped'; +}> => { + // Since we filter out failed documents, we need to map the simulation docs to the sample docs for later retrieval + const samplesToSimulationMap = new Map(simulation.docs.map((doc, id) => [doc, sampleDocs[id]])); + + const diffs = simulation.docs + .filter(isSuccessfulDocument) + .map((doc) => { + const sample = samplesToSimulationMap.get(doc); + if (sample) { + const { added } = calculateObjectDiff( + sample._source, + doc.processor_results.at(-1)?.doc?._source + ); + return flattenObject(added); + } + + return {}; + }) + .map(Object.keys) + .flat(); + + const uniqueFields = [...new Set(diffs)]; + + return uniqueFields.map((name) => ({ name, type: 'unmapped' })); +}; + +const computeSuccessRate = (simulation: IngestSimulateResponse) => { + const successfulCount = simulation.docs.reduce((rate, doc) => { + return (rate += isSuccessfulDocument(doc) ? 1 : 0); + }, 0); + return successfulCount / simulation.docs.length; +}; + +const isSuccessfulDocument = ( + doc: IngestSimulateSimulateDocumentResult +): doc is Required => + doc.processor_results?.every((processorSimulation) => processorSimulation.status === 'success') || + false; diff --git a/x-pack/solutions/observability/plugins/streams/server/routes/streams/sample.ts b/x-pack/solutions/observability/plugins/streams/server/routes/streams/sample.ts index 1e4508149f4e7..7716865d73bb9 100644 --- a/x-pack/solutions/observability/plugins/streams/server/routes/streams/sample.ts +++ b/x-pack/solutions/observability/plugins/streams/server/routes/streams/sample.ts @@ -8,12 +8,12 @@ import { z } from '@kbn/zod'; import { notFound, internal } from '@hapi/boom'; import { errors } from '@elastic/elasticsearch'; -import { conditionSchema } from '@kbn/streams-schema'; +import { conditionSchema, isCompleteCondition } from '@kbn/streams-schema'; import { createServerRoute } from '../create_server_route'; import { DefinitionNotFound } from '../../lib/streams/errors'; import { checkAccess } from '../../lib/streams/stream_crud'; import { conditionToQueryDsl } from '../../lib/streams/helpers/condition_to_query_dsl'; -import { getFields, isComplete } from '../../lib/streams/helpers/condition_fields'; +import { getFields } from '../../lib/streams/helpers/condition_fields'; export const sampleStreamRoute = createServerRoute({ endpoint: 'POST /api/streams/{id}/_sample', @@ -48,7 +48,7 @@ export const sampleStreamRoute = createServerRoute({ query: { bool: { must: [ - isComplete(params.body.condition) + isCompleteCondition(params.body.condition) ? conditionToQueryDsl(params.body.condition) : { match_all: {} }, { diff --git a/x-pack/solutions/observability/plugins/streams/tsconfig.json b/x-pack/solutions/observability/plugins/streams/tsconfig.json index 27743fbd9f70c..f7fb1f0a2d1b2 100644 --- a/x-pack/solutions/observability/plugins/streams/tsconfig.json +++ b/x-pack/solutions/observability/plugins/streams/tsconfig.json @@ -28,6 +28,7 @@ "@kbn/encrypted-saved-objects-plugin", "@kbn/licensing-plugin", "@kbn/server-route-repository-client", + "@kbn/object-utils", "@kbn/observability-utils-server", "@kbn/observability-utils-common", "@kbn/alerting-plugin", diff --git a/x-pack/solutions/observability/plugins/streams_app/.storybook/get_mock_streams_app_context.tsx b/x-pack/solutions/observability/plugins/streams_app/.storybook/get_mock_streams_app_context.tsx index 8e5dad100fc31..c684e65b567f4 100644 --- a/x-pack/solutions/observability/plugins/streams_app/.storybook/get_mock_streams_app_context.tsx +++ b/x-pack/solutions/observability/plugins/streams_app/.storybook/get_mock_streams_app_context.tsx @@ -17,9 +17,11 @@ import type { SavedObjectTaggingPluginStart } from '@kbn/saved-objects-tagging-p import type { StreamsAppKibanaContext } from '../public/hooks/use_kibana'; export function getMockStreamsAppContext(): StreamsAppKibanaContext { + const appParams = coreMock.createAppMountParameters(); const core = coreMock.createStart(); return { + appParams, core, dependencies: { start: { diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/app_root/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/app_root/index.tsx index c5e8b78ae2155..bbe3e50cf1710 100644 --- a/x-pack/solutions/observability/plugins/streams_app/public/components/app_root/index.tsx +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/app_root/index.tsx @@ -33,6 +33,7 @@ export function AppRoot({ const { history } = appMountParameters; const context = { + appParams: appMountParameters, core: coreStart, dependencies: { start: pluginsStart, diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/index.tsx new file mode 100644 index 0000000000000..cc9ee24e7ef95 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/index.tsx @@ -0,0 +1,47 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiImage, EuiImageProps, useEuiTheme } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React, { useEffect } from 'react'; +import { useState } from 'react'; + +const imageSets = { + welcome: { + light: import('./welcome_light.png'), + dark: import('./welcome_dark.png'), + alt: i18n.translate('xpack.streams.streamDetailView.welcomeImage', { + defaultMessage: 'Welcome image for the streams app', + }), + }, + noResults: { + light: import('./no_results_light.png'), + dark: import('./no_results_dark.png'), + alt: i18n.translate('xpack.streams.streamDetailView.noResultsImage', { + defaultMessage: 'No results image for the streams app', + }), + }, +}; + +interface AssetImageProps extends Omit { + type?: keyof typeof imageSets; +} + +export function AssetImage({ type = 'welcome', ...props }: AssetImageProps) { + const { colorMode } = useEuiTheme(); + const { alt, dark, light } = imageSets[type]; + + const [imageSrc, setImageSrc] = useState(); + + useEffect(() => { + const dynamicImageImport = colorMode === 'LIGHT' ? light : dark; + + dynamicImageImport.then((module) => setImageSrc(module.default)); + }, [colorMode, dark, light]); + + return imageSrc ? : null; +} diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/no_results_dark.png b/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/no_results_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..4ee7c1645aeb3591081e9b3a70ba381999a49ced GIT binary patch literal 37719 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 literal 0 HcmV?d00001 diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/no_results_light.png b/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/no_results_light.png new file mode 100644 index 0000000000000000000000000000000000000000..d53e0dfde35a6d16ae2919af4774f8f0aa0b9c6f GIT binary patch literal 37158 zcmd42g;!Kx)ILskNvGt%&_j0(9m>$4w4_LPNHe4~G9Wcbr*tC?Qi32zcjthBNPWl8 z`@ZYy z4Dt)tP0hp;1qGk%-ybSUb`CZ2M^sN;RWM4;B>e&M9}Ihi7YZmSbxHX5R+uO#$sOuS z3i^JiClC03udlMs;=g`v`pDP3qZxA|-i$se+=!bgI$mV|L+0S?BuR-Cmd{4I=C7#I z4VnPF5FE#s8{|G?5fbU>?+b`Cd$5Rphdqa>w|Yerd8u(&4a?Yw9 zE~&p$|LARUbR%`v!6s49`Yn}rL38fT|GCMJcJ*dJb#3<CL?zFZ(=eLr^ef|vG3D9~#Bo^=8pz8^K`EMD!00vdLvb5}L z8Nm9IUyF0xM6}lw---BL-$PG229G6jr7(X?3BI{HOtB5lQ-#jgnZq?J?eoUd(|*Au z)We@q`#}W#<7ATUA@gq;q>h})`Lz{;H=`Uf-t02`ez51Iylh>o8{`3uJs3QDJE@K+it5vh0EEDK|3*Pbr?kSTUVyZpk zAFw6|WxTr9qlrpOjATtF&L(N<5vQd@E*+GxRafN4X;w>x$5dVRTg$}Vi^Z;2o+m$u zdINK4`hV1benKYy!9}rtUQ@DjzlW#xT+1IUMVq)wuaT-jSyaidC*7KW+?kR{gv&CRi2Th92gKpr2t(^H1<%G%KM)bkcvub*(2^J z2i0*gr0Mo6Y@3QZn&XD}0#R!Rt=*10HJhLJjZHxM3LtkbvP(vVpj%yoC|3s z+$ZWT1C5p#xs_Ewfi5Dy@v7c`BiKe{H||g6+7;Y$wV@+j zc}fcIE>BWUtTw*cerP*oBnrGkL`svX_CS8TizZdXX`;7N6M?217RET{ZVzc4^Z{X+ z>eH9F|EYlTX8ehEV~ugk)eFF^X8PyUdb}0#TULUT<&-h^vOb)fkY{$`k*S{K!c&xB z)B;EJy#l&RWpcrvoZmVYOsUJ)$t>v!|CuX{<;&(~wGj*}D8^!kf2{EX`CFmw5tu=j zI?#`yMAf(<;U!R@D0LVf3fXxU3;S;5*TWlm(uXnA4myl+F>u8mn#TF(Q}FO4xo@~2 z3~lc!vjVPEb6a+g6N5HVt1G=i4faW9H^io10j3soLgAEB%N{D1B6u>Ku|mhKRszP1lS8ni7WqStXimQ!r4nHyf(r#UXG_yoq?X%;xU)=GEFMs zSD-w4Lry7o<70hj+s^qUuNep%>G>W!G>tl#Cg_X8;g(|$dqD?v<)WW$-c7BWlS@hH zd&R!Y)La2EX5&gyOosh)S}4tzsnLGV(98)wi4ccH7g(c25IV>PxmmCj8c(5pCW!pq~Y~EgV zAWKO}b_z#h2hmCU2?r?Jiy&xQsDDn9+|+^!Z!rU=o|xc=cx?FU_oiKh%{;RBOrduH zOQ>gRAddLScE-vQ4-cQ(&fN3xqErlz*&)?gluj(+ERw^C%J1|UzXv92n%th*#ekDW zuYrkZ?>ubL%OSIYJIt^ukOjq&E9-~bclb)n6E!_}c$)Z73*8V;(-bB98naRMBQD7p zIdJsTx8+{rn3pS6-HmS!eh97Jqz{-{VNCgl;afu2J^lB$Rz96#l@y!{zqMNxykN|K zFFbrJV15tv9v&$lsR*mgZ|_7jy>5#VPh-@0pw!mO!q74XdhZN(h@D|XM{HEj>%=&Z zTg}{k@31+V8txF4K_^0rS9!b4hn)J4Xxl*y%zCRi}D?2~C; z13dET6(><_4qo|o7X(7CDiwz!1sd$k8*bi!oZ7D9nxAW&cfi0%lsOF7M`zA zc^<~tI(`PGVjm%4-~gdGWi=s%=YOl-`{m>4Hw3-;xTe^ z1{T18#;!EI)ev?!B7!Yr4Ta94J_&)#Op2ps*$?*7pBmm>WW3`5l}I0m|5eDf-M@*b zw~)eW7e0@!0||GSL8^}+Y+7a!#XFF?0oHCBRY5WYODCV31wt7{wCmc@BN>2Jq8LZk z&tmsDo$g$0cWBll?@{(<4y2JK52tthv!;lsmu^d-N6#qqr6|GVZnQ<9j+_*wsFO`u0zC;J87Bx9&}R-A9_iGU*;x675v-^r}VNB z))8lBEqWIv80u+Bt*Vp!B?X{xTY7^DA^gy%wUGn6jV@sOHcp^Gqqws(TEAKxSCziX zSqU)inEbk3o&l-BxhnRGCnV>ZIQ^5azPZz&Mi3mGI3DAu&^y&w|L0-=4eCx1HSV9n zQNp3L?S_Mg8V|dTB28|qSClu2){HE7h5lw1t<}E>1{y_vM09Z>jc@1x^Q-DRu#YB{nq6Gfu~u z4f|pq|4?Z|1WQUlizZp;>T@QT?lsW}-Bt#uM9_AlPnzhu(4g54@ zbwHvqMq88Y(m=Qi+c|1pt^ARI1<`P!7oKdV*+n7c-}5tdoY!#~{~G=I{J{8;8Gw0V z0whCvN>3GmyG||cNUuV1v>{p1co?Z_mWkmoOJsTj85pPO{xhE4NNch3PcL!QDRp{Cc&s(3;Omwj ze@4R-dgreY?~ZoJ;px_b8Gh;@d%!Tc{42wa$#%k>fgt+P7XxazH}W({h@Rzb_qqSn zt0HzAg6JPYjzMNdB^M^#_I&o0c^I%VZOBF#)ufc^D7!3Lf=LwtrjOiAp7GkJHH%g; z@*(@~YT||zNfoI|%p_y}W$`>b!4kE9oU1|PxuxWT>Fhc6I2Llur2pW>{jeFI?g}My zVyJE=<7!tq*(f!q@*G){?%O%fNJG^>~yI2ZK^+=1UCuP|oF9ImNYBs?Mb1-02w zS!u_SN{VmSJ>1u2?Sm1w!$sq>pW{((n`-v zVfy`TFX@URS9dbZ#lXy00K?QO>CF=}hM`>vDfu|ec!aMerVx`*T6GfDV zl|NDKm%un)b5boQ+TRP$TdGUd2a4{@l@J{W2ygLYz>_zH8Dy6yF;^U9nd5ETo0XQC!rWrpoiP)JhkjM`&A9nP@4%hx zYS-;B2!Fp_TyW(~NfRAwk&vVAe zV6>CNVObC7(=^`|%Fc3If47xVc0c4gzW4m({BFANgE=wyjy-v-FcQ8SZTSt$V799N z%Z#L18u4e?0!RAa;_}}oJ6v|al-s_q3jxK&vwXt8bOS3e5U!s6VUxTKl;QnGYjW~I zT0Jyu1De?5lmh2~2!tmGGn!Lww9V&#zdSK|)*zlZdn4?bb#aLcwcX@~1=82Lx? zF$jZxDD@-^KfNS`s$X$_>sx`#BOULIwMh4=(QqL=T4&u^Rr6#ak1%8Klg}|o_OLN+ zDnD9+O=m86CC*!0ImsTsoB{)~5Y}=rMuA^pfukd*n!~aK#U>6M!kAhgAAr;{T})NDwQU(-$JZ01Q`2)sDpHH) zgp&uBigrHJD+07t;xj=R%;fx;K0Iw@WH8)++ZJ!aojZ;-q4a~cvUGKllbH?TiS+3n zV&e|`ff`Yw5ux>CTQDLv!_KD%88?PUo1m7bz&*xh9zq}64A@oz?t{NL5smK zTea3?DUx_-;%4kejW(0c?U=i@$2|-LIA)4k|2P=Cak{aVlfRqmYczNlh?k|hkdpPZ z-&bg&c?%_W5A;rI-rhDc?zDk2P?rF42v@-rm%!ERnR#jn?!V+qWz%Yt@DgiQ`A1Sa ze5qkT<1@3&J2E2FG-BQGJIG&IYZh9}v(=EOsre`NnN@XWPtVKd>HOCI3}W}h@vQ%H zfg@~wbogSVZnUD|3wtAbN0Go|;|nU)(}TY&?2Y(&V^*FXmMuqp_nar#T87B-OVTRFxH#40#M}=0P&8wq-$Ix#qXD?n%nD=GqWf`L6ew`&diUe99WcN7 zf{Qz!r{^!CD=9x?Q)Sui;K4rRfRd8GEoH3$3;HdB?CHp}y4~?Tjwf~MxhVp0zS=5z zB)a<~jrIBFL1vL@0#scK&E)*@91}AWRY+(mtUUODu|AG^%A30DUhoU; zA+svcI_}+2o>LHZLBj2Qd+FT1Wfzv?fJoeF|A)FXs*i_k=R{4zp*8I`{a>vPsnEw8 zkywJ9f|et6?fif)ooW|lKID&3*?lj-q$T!LlHiT@Bi1e{=3zJHlb0qoIc{Kqwe3FN zy~RDs?tX{>BjWKoB=qiv(QZY>z@T?uj1N0@UgC4F5SQJ`%w7Il`V<1WPdUB_y`zjT z^}%*PlK)96wM_nHa+02$){S$L=l8V>bZDRMz`U58gJ2&Fx-cgwQ!F%roA_B92B_PihUKYeB40kr5^R0{Uzrxj{E4zvq?3# zTwlc8Q3fQPJN2pojN{&qtW$Im{P)%@irvLncdkKl{^p}ix(*BVKw5E*V=COwPvZKI zherAVnch;K>f8xt^+f5i2Cr^y27EG;U*{P6ykE6&?J{wUvm*vr+iVir!d?@dE&ssu zueV;AW89QtDOHHqjp6^7hE^FJ3rvP1Q+uZ`FH|+5Fn6#D@VyfP^A; zG?W5^Wc;(_)&8L0B`64x+lYhDv@lL}2er)=c^VUFoNdU1Q7~Zl(ap0;@VBf%S}(oF zBS2fn+GO`45Oq(Hh+a%qX`|4iBBuZQhg_ifTwy~$LjnyQC1|`#Z<3|Nc(eHSXPt-u zV3i7Q4qb=?*g^*m2`rb1N&f!IGA;8<{UCsMW%M_vx7Y2s>;La;`xV+b^gBnyubH-qLP#o z-(3G$ZBsX80IUxR8Us#s=Q(%jZ(1;8EAhz`lHYG5x7O(6D{S+UKgjj(CYVqNxG*e- zJouNj?o>kD13OmMU-G~ZVjDS}P(Qe7%ts@Yd_%A^=F0>h0=pR&9G#|VHV*ddHo1rq zBSS@I9o?1bI4i|$CZdLc+Y{}LH{~KGqPRyN_ajXqU-<9dy5Asy?^k?kc0yz|Wn5yg z=A|H?12pdGp;qCwcwGuC?iI;xNHBhim|Uc_E;*uJ@#kP6^Pzq_5w$8ft>S7`wnMMB zsuI&_0}On=83PyuJj@$-DWsSLBhoT)nb*cUl}`=8!hAjHhv?#$U5rC+`-F^NJ@0ao zSgmsKkwvW>JuMC>?SjF|U5kAT6}W(VtLs26^e%Oi;)q)c=jwR z;A`@wt|`J=Zc)%I?M#=CoSa75F-T}B;9l^;X(Z*poP%%{pl_C54>Qeb;xUJnBa=mU zfN5KHI1PiM`bIN1 zFf~SPpr*ax+uH*YR#wDS8aE#rYU8Y)-4}n;Ya`K}EBWd%%#fSm^YibIw>D|>* zU2D~`N;q9WO*v0%guAI+B}08I6{gt?vW}=VOaj^&4mzWlCK?|v&jx~(Kscf9@1GGx zR8-4!^$DLmrxNZYBFKHq`&~Sp=^2|Ytv`VMHqMxQHXQT3^1J`W-!ZDbG1t7%tT<|^ zcSU=Y0E!PkA;35mb92HPBMlF#Eq|h&3H{Uird+ACNXh$b=e>bXJ3H()Wk~dJR0;oh z>cqtujm8rBr#*c9OcQ_+{T^l#;b}QaLr%@6GO+J(dbi%vU$l>M|0S16*MY&CX3)tX zial)jjg)}3pLjPt)5aoObE${!3#s=~8@tCYm%mup-;MM1Wf`dfb3%M)88N>6h(`=W>cIYAGW~~nu>y~ImnrR>ksSzB_fUXb;1fJ_U7+Ek%n?%vE`gBdmrzdM zsavK!Hlq=5iTA1l{J@tZ{>)UEWnQx}bb&s@I;0XnhaqLs>dLZ4S6xMZ13mQ7J#>TI z&CmiMEtSCSWS6Ew9yR8|-gn2>m%cI}J>yQ0P?QRx4XeQjwPWO@4IZy`BqZPFRVjv7 zNMqooxh2db98)V6ECDo8Z{=PfW;rIA!ayYNij$qDMxrr=`qDfNJx!V&m%-!R%iQ|fHOI#FzfE~Gv9R;za_qUG)d$v*FqCl&O8#*z z_<2gq?k;U=a{2vFIV5aHJ&j;oxU&ma(i-FbET)L+_UXbu$ilbyb!k`t3bHe2g{oHw z6j1hy8c^rs9TR!*qQ>6rQ~UF<-K^~o`Zodyk`2uzf}2CN=)p-u3pSN%VoOdr6qrY%q<-ZcaVgC;z_(2 zI;iQdfZH+4&(8RpjHCB%RkkcBa8F;6rG?V^H;Mrc=gO=2eA%s+_^Txqa9+l<#d`wK zIFI1hv9g;^iA&v&{&6@_?+^+bpKL~=mC$1;!#~CY+oc6&h%So^nO>kMV=;`qTrPG# zW?LB;i=(G_ijnDYK?8ccLlwG}(1CGAGiBuMS;Pf0Nqk1YDTIL?XPERs5i>mEK4iz3*N@ZG3 zkLDyvR25|Z7Ym-Eeshe5Y;9;r__~hBPxsd{^kMPX-hQ_hDsU3OTvUPai$kv$y0;;8 zAlulZ8P@d&#wYYO#@iRwB@$Y_PPKV&8<@HQ^VeoZBHr&ZtmuiNlQjq>zv;PXigv&* zEYxsp7NLF8eEpPkvmv%O8Gxvs}g^w^D3WhKDCN;P@GDI4aW}bX{LK z2L<8@>BMM=y`zfpvrh>>dTMqV`l*hbNW%w6C*)TdA*>$Yb1I1A(mLm(KU)NH5{=B# z1LP8~rAny*(fiZIc`P*u6etwEesI(!1Khv+$O`7}Ia3v}Z$wfb+)Ny)1D=m$z^h53 z5`qvUX%|D69>>IXwZ8X=A>;&Jdqp09p}?c=sOP*5-1PCWc16{wvIpywXq@RlO(<9p z^`x-+=nE?#J$WaeFY_DTR~QmM;=ulf*z$r}0+y(H)uB4LFw)82@N$o%5?#e!#!e$jg?)HF{tyURCiLd%J7+hR0 zm^bpN^94jmnt=BM<8Th!54VR?&t;(XWVVj?4=>I*KLupQbhBC8@tm3+la#MH`Bs~b z=|1BpS$|h~@_HMP|0FPs4!jgPikzh`bPROO&XzxHB@h?fK5?5jWm!G74~=9^nQ3Mfi&>4*kLoO zLNPsn5T@Ub@G!=4r?#MyA#LO%@lZ3WuxS5nm1+1a(hA3S1-KbU%TU#9bw0Qa(^l5X zw`x6nQT_^ZgdOgf-~VJr_lV9PN=p1)r>)Vwiq15ec=)boJup5e^ZcnEuWCqTgeu5> zbw1G902`!*+lN*%8>2FntHw6In^p;C2~|>tzAbdOQaYN6DgkCjfi=@Vfj4sBC8sGS zsSdLYvu}+2x+^x6*0JV~%1GT=E&n!%fm;(d>L;sxA*b#y1x!x;?pyLxy-k+~@#8)z zWd|%K7ka^$`MgiN@ckdvN8ZQWn=kY!tp`)m)O^d@Z^+A1+owTc~x(wAz3<* z%^_V@h+7xO+p!KRhZH@sEHuFE4(^Mphyms(ZL-ktu}sUm5K9QVyuFnZxPTGdlqrdi zOn%SGk=L@SPWL$0=ZH;I2M^Y0X?)aO@|W!PqfUqpr>iOPQOgy=nq4dz&YMug2HowX3$T0pC)}nrWC2Sb%%@@Vi zzm1O%)3x{b6_pc@iSMyAPl>C3)^sqxrTeZ9am91E7!+X;QfG z9Acnb;zr}FdMl-j!$D!t*-5*MqtS_SnQujo{ypMH-bwdRAcjUvvr)v0lE@DlF=t?! z^yaOngOt-s?lY}bi-kuAvw>o>D63|}Y|o;>gcC;ZRay+FI}XxWgl&%(Xh9~`K_tGK zg1E3qrUKDN9{@=k9UF_$?gUVRarMY7guF&CR8RxF=~1F3`v!p_HF z3;foUeA=_nd$tlf2S^L!csdQ6@l3!2SjTailTI8G^-2>NtcM&Fq#l;ayfEPZ9_@Oi zX-?Ax#;c>Th&Ta-2xLsnU7PFG`3|;o7;e4iI%51z+}C2>g7R>YzPK+UA>H+Ge-@_-;j+5~MGcTbAl6a_Gb?m5~T!_7_(I#~nQCwV7=5IF3 z>t!+?J$z?c?QFku96!ybpaG53&E~3yI9@FcdvaVe_mU=ZJpOpIa8zzjFkx2s9!kba zq^nBuYeVSC(OsEJdh)LbWmkx+<;VH#!d3lL=yN%&jwwVU4%uFg)K!8NwZRMeR@LWqm?qU2#1U3i4-u z{L_thQ~Gk%j|&9Y9jv>Ez?6Bbjmy8In9Ay8>{bJYeo5AFH|oCj228U;1O)0Ad{p^N>YK3aEqAh9-mIS$yRvi zOZcqOQLz7*B1Fl{tZTjI+P|wwHU>kHL|hib(9625O;?CaWFv)XV5kp-55d`>$&?Ck zxq(*fjWq@QOITf7!5LI|xHk&T^TwQEc(%t*78AzrV>F(aKndvUB&2$j7`4F_oRo8O zPT)IINnURtS)Xosl6>@JgU_<=Z{qDaqwsld5`Ms$=2$o|j#}HBB1Xx>%S#x;>Ivuo zB{IOLlJB-+2LLdzUxp4FVY*lV$O${7_?CY)z&#j2TaDe4^;%&^ZMUgw+bd75>yMTm z-8H{L9BxYZ(fh?wko+S(o3gt~)hOBAiY+I%^&;MPF{2G{d(XFJW5r{O;`m=gTkrgW zlvh8iYPIi-lJmskU5Z#!Ou1o7_sgL1zO4>;_!_Pfd!e4*dNC#SX%z+Pj)Lr|!C1Bo z-`u46!E-YA_kXpjWhImhuO&j4Y%NM6?5L4`L$P4p78`f*vy;SYxoJKnH7H}J8M1#obMdh z6BD@We1}%Fgnq--xcCq^ijNtSD!VbfIEm_nu)Y(GJGT$BqQ^iIq&Qh-g)m6rkv8Ej zL(*pCyzMfgs5ue(a=uYq^VdN$S=CRuaMRN}ZBhN(G!j8bdNN1Yv#4TM2>p5lHCSLVL8pNvnRYaNNk z%1T$S(d=lI2i*2<-}aB=9c{XUdBXI{6M1w6(fBzhd}W;r`qN)!Dqx2T_$0wXa$6vsvAMW4pEBjZkT zBD}Ahkj$-#)Et0KQ?se|%*_9-8ckRVJ8EEb8m=c#&niA-(@1eQ7#ars3b$P^dJw;U_fm@7_7`r~3=>aed;P!aktLqSSyT5)Hjz^p zX`v>823U++(HFH}9Os`JVX*ad{YY3y#4{^|x4s55f1cg-K24`FlEfqORle8c6KU79 zR^ey|tuDSTGuLPQp2_U6UYveiH!V?z#A_tS73cDKzc!0=Bo8M=hifVpYrT#t|L`A1 zlcFn+?=~}35K#{?BTEi2G{sYV^Xgdws(qJ!A1&$FA&>2{I>J!kM&mJMzk@HXy@}c;*83d^^+w|UIhJ2j!)6WtbkU72;p4!+o32x@kthtU# zE{NBx7B5JxwbjgVP&26M%cbpcXC{V^M{US#_x3k-O8$oL_VcsHfO-5)&teU<(J03Q z#;)f`|Nr0e!#Ro=r$ly&lpt!!OJJ+dZqQwC{it-krm3P;f$jA_v_}HJ^*sa9l)!F+ z&%}>5iqO=FlESeAYN|IMpL;5S#a+U6!85@)NQWmLIRL^ebX+q2RP*h#*QZpUvXW11;8A!U@4Umkx56 zMCne()aO5pJX!aoawhr$c|jY$-}e_Y_-D5wSO7IkscveLMN zV_Fnfb`n;56*y+tne)z>T1!7wk=)nC9fIfae@7hBF04kJadTw`||!!fXVtP9eJ$O>uZy;}is#@9SRPZ`WCud+rjcD<9*8+#sBno4Fii zrKb{c9I|1D>L;mm_3M7;iICn#(n-V#-42`Gd|@unY=;!+%$ z#d>L)_x_WR1>=3TI}cPUz@F!@8?R^ji8Y@BSC=}rG*hSnnZHuoVU;n3AZ+3k=QHr3 z(=Hvv^ogXB(J3&AFeJNs9EFA!70OAu$5##adtl6bgon_Hy}8o7I`1bKS9#|t6kF_;ScD&aX2L>(pR`}Htg^O{&| zRRwlPQQXV0E}tHr(F1Du7oopV`B=ix8tNaW+smw$i9dP^t%{HrMCwrH_h0r`Fw7%2ukXJ;6E;P%T7^9f=R@uv;GZ+|x4!uoA>3C7U)LtJ|0bp=TbeE6&(J9U zg#Dqx<)s8CAM96L9hA!0eVTvzq>zFjQ8?-JskiFg{0 zF7Er%mrY@g(q-xQ{+@5DKX*IMJ*`D#W?iL-sY75XKz-h-hFbL;Kc^sjoJ_XH4-_B5 zPdya&XS0OTy)sb^uJGMHQN#S){g;2A(5Yw>M3h#LE*nsg(BVgfjfoiDJJUVKl^6Ds z%mG9$Zm)IDmamOxVeGZY{bch#3TA#oXF!zS3v_$+-Pq0{*OJSPMHd^76>*fzDT!1R z)hQ|Q&Wbj;i`>e`k1Fa3bn-L%R|jRpU~YPs22xfG>7NG8pGa|`$9HUe1hsn!@5kNP zlpAx1T;olUajz-QESiLO)(gz!t!kU&~lSvAFAflKb+Xb3V+u8-$D5^NX$XZA_W9s$&-0x4)rq&g<{K&BDI zj+s^d(~+UtTziAJ8AKK+G+$4^b>KvGQh2F0r>3_$4k_Cy-WiQGhh5%kB3SWb(Rqqp zho~SWBfWZf6j-$xKf*;@*^JPy5+EUu{kNu;0c)s^exA5H)M$S1=o3zcBWaU-Z^dGd z6^?2gmz^xqK(a(vIKb7}!ug8$8}goAXD%?*4{M~I9_Gj7v|hH--5Rftr)YYkTnHJK zWb*_N&YIt`^M}nX>Bo@G`l=x+HFF8>Kdy{J^GmsmPc0J%QJtw@2j{1;+~^Alku_6f zM^cMU(b(HTrD|Bng=}>KXqoujz}(k%T@(;0CVCiXbD%5WBC`H%ZJ+k}HLuy10^wzJ z=EVxi*~LBp?oKHL=-{=V{$5T}5-Y?0XLz34D1bTj7nO8tHLrPkeU$cF4?c#pYdSij zUqlJK$zJd8slTyVOnC1u8EX8&pdJoqo)*!k&Aq%vGgr-R-??#horI-VW6+O3#58=% zl8_?MBS41dEYTPC23y!=#!f(Y$L15RiU>J!TIniWZ@HD1X7gg?%R2&B-KSxe>cTzX zo6nA>on?L=HNw^I(SznWshQS_eZ}oud^V($__5@q(xdh4&(}^=Q~{@l2|B9@8fJU6 zRLW`7>EbvEZ+dUkT_z$T#lx9DYs#&9-~Id=a(7)tVe3K;TG#4ClA7p$eTHVa{_}AI zo6y6_Ar*@`T~lGQA0K^*2?*9b0>i7RBE9Zgny+O>P1?0^TmB(rdTEL0tLiL` z1Uo-*$ANf^nt3UVY3;eWdTFQJqBV(FipUUqa`CQjs=B{NoU-^x3Sp7u9{Q1i56%6i z@K-Da(&buY{Cj9*6elsm7e#iGX^?b?!Qs!(L(3@V?^Hn?z1c|6jFhDp#1dGdNkcdhb7lsP znFe}0KWxg{W5BwN7LqKz(}+DKH=^lz|ma^{PFS8pd zuM2GPGxOOYd4{jr<2*#_FOYE^AVku1X$FkV9HHc5(M_OV3hR9%wRxsTl(Y7ju1!0K zN!@_|9LX8;&n+N6>3$gAGrRv2jJepN<0ZVIxeany)Fy_vhB+1r@Au8;Y+)oMzhVGs zr67xNNUc&UQ9?|x^72v{p2M_zgUV)f|JWBcPNj6WLkuc_YXuzOWjd7uE9R#>> z?XdmF3sp~l(&A>8w!F%f+sZ7;_edVkxX$GW^`3DpypL_~Q7ZNv(z}R`L-K$}|7+^y z7CrTUeN#Iv&G#p1Aj0FrBCe+we&Ix_5kL9$ymh}bts0%L46v7=apMpvvV&kN~ZJ)tdYY`6LQgW5arW7tj_5r-D8WB%xuO6m zU;{-qW9gq6f9~`b3fW}2)x$PqPnMMw?TI41{I`zOzu-vSvkjk>MpR_{9uN>9*r84_ zI-Jtqj~Vl(cx3$wU}_$6xytu``D`{zz@6L1krkqqPBQsUjwzCgx?}`tsc~o$oWPga zujnd6avbTT7c4${WMcKC0D?JcZaW4)G|6E_!v_Y^vWiyuIiSwN$|eYiDm4%x$`D5uSm^4Vwnw@?X|4b)SJjFXvB}y0*;!MfZXzYJRpzMEaN*AzPmxAKE zp3Cff!tclZyJxN}^g|i#$@f81bRjOpVlMulg%{93@xHTIGRNh;>b*Qh%x$BR{p7v#A1fWJ_Qe!1u`pzof(_&YJxrM#oY z=+E(jN_wlN^)Qh(#?~Z38y|EyzHoPZPae+E-pc(VFgW$WkBPNsJO+>T53RYGC<7*{L?r|1=UDj6jSHMlYuCB~V=cR^0@%y=Y zGZFzwa|)$I9Pb@(Bf~`*Yhaa9qK05})WsVWZ0&_RLovR_N|b;#*LK;QH4)$%{VhMNB&FUCn$Pot;9=))zO@*6QXZS{SwL*%ZT|AA4UMk`7h(Fwv>h&=j{P1n=E{9`svm(PQ zv4sJA1>F8_bwwt^{*mf2?lel~0gd8|8}qVg{I_Skj3E|4HJRIF$=xO;?tabaP>DjXe0eA6UH zz4(8ff)G?m?F@1*0JoV->@5FHkm!Yjv%Dll?f1sL>+Ep$0Vq~dfk*I~`X^yvu3&k4 zeY0p8=^Br^JY-9f%fG~lcGSUlraHkW$&jZEl|Msit9{>rWkPV+wfGIIf|T#jYds3& zSsykV;6WxmgQTd)VE-P3QbtU6?eSd~Jlbeu&Akcjq&BfXnp+|6ukeTEkLsCCkMWtZ zh@Yl^8|e3!1%p-xlPsb`Mi}Hh+t}-gpStCIhsRGE8F<}(OmU8d$s8k3J^bTuMeYVz zn7;>|H|9GSmez;|ORL$IZ8wTnn(^Vgb-&a=~>sFiptM;1^Rv7@X1X%0*6N-si;hK{V%TtR1gAS$ck`XIj4bu z0e_(_3v-+j#kgKsXWNeg45O1*#VljmHyc@-^BP=`pWs&%A@X2WRWBQ`$Gb;XKZY`;(DmEK4 z1IO9OY!@0=w)r}@ilm>*_H}w&a((C_BIiA_dZpf6A(MYX##|a*5J{aF#_I0$j!$?vqjnh=024G9`alyg?QfLxUOzoQg~F^os+P##I!%%+zxxwW;sJOHi|Ii6%%m>0eTSeg@fD z*`Wq!2`Ix`<}Daw^|8}73Rc5Xt~6q*{lJSq79p30B@gfRY=P%FYTGOY(HrQ|1x3`& zN7oR2hy##2oi0r`PQis>LOzaBwGSqTLeYd+P;;?}k~vQSL$-UARJ4<5)d)3h`w~Q+lj7c(&)LhW8c$FoB8z~;kgWV%rD?$@=zhVNz%_Q44WSi=@c*V zs0GH*>}>Dwy#;XmGq8ie;o4$Va2uAg9}`xPg*8F_m(JS7l!&F->P(NV4H_^45wpM(Na=yQk!Cn+51AQARHlWL|F!S&K4-sw-%WV^ zBn+voiiF#!{!G;){@MBn(J+q^<9}Uu8r#(N($%n_WNl4FK9k1t31e3Ro#>?3^l0i) zc>Eqo!P9f|BI)(BjiIeYadatrUxfsC4gOYFDYMQU+L5nB0Ip3%R}FvL&I3x|E8f)WR?eJGd7A*T&RnEbtr)!_FoL6zKBEvH6M|0~?G z1K<7w&L7uB2X!$gHEJ_Tb=Hfgak*RdUncW_C#Q#KH{ZzCdv|n)6+gG805!11p1WUp1rwvDs6_&$Aq?>|uI!F@m1=hEFieZq@gjm2n$9=$b= zNpz>C=IIo`x;C_%8Gbe`AhaV0gbc3WcjUXCH>2(d)`K4@Q*P*uIul0*?}XNS_Wx1+ zf;GiQir`&gzobJD=n_2tB6S_ZKOIzN4q!Oo7kAgYbWs8q0K?ip5$J{eldBpN*${F zb}&FR!GOs4!v+uTm$o6L^1sA(pcR~P~^Pr7tuQB=0h&|L1@mHUil2{Y$u#f1up={;~6Dn?U;??46dyc@SsBW-B(e z{%owMQ5G;As!RJZ{Q|AEwa$vw=u~;F#KM>%G=X{2Ljagia3iU0WiD0J+Oy(BA<#!V z6apVdDj+$Pao-Z(lJ}>j(8?g!7iL;Iv~NS?5lO1k)AVo9P=eJ*qk(r&EAPn-0<9_Y z&(jWwA3|3U`H=}SJJ2{KPDW=>exzV|XMkM?iZ&qV*Fm@4fpC8l15hU|fvI@bfGAW7zH~ zj&Jv~{ppa$v|r8lyTb;9D|gO#pThTM0}w?&h)Kbsi5tRatsgyhT^) zM)$DiOWMKck$z)B0@P-1?TFC_(c-c0u&sU| z17bMLA6FA1e&7C4?8>AJ!pRw}wwl&rD?KlS4*!6Tp&5*zc!yimf9ma}ZV}otIu3b$ zfZpBN3^;>t)!Rwn1piIjEA2IYnWJ~}8x8f)X%fxU#A*J-x5#QWH_2Oxbj&Q|^}_yO z1;semJstHP8O|j79yX}fEk*G@HkP%-H~n{*+s!CVrl<1!lnxrFML;#Nh7mGyX`0Jw z&hy@Z0cp2ij#KN#2>HwX991`NDBwb)R%8U&R5*Zm%%2e4F^+XAs9+;;rQjx+;oJxy z3q7*8DLoBj`#8jz^>k`XzhDh^fj*ymZ_K}(W8KX^<#u4MQ;jt9!`Z1zQt6by76&@h zs9~-mKpE40#fK2=|5?wc!dCJ6?Za3y;NoH7Vyq#NIw2jMN{k&;zFefe5%lM;nuwKX zrtv;&-GH`;-%9luvO5W3X!9R7mc-;O?2p6oh9&H{LS};*#CN#iw}6neJ>Pla&<6zXXFdo{BatN{U<1X%aIGW zzC=;;u%X#K{{g(54|`i)9yqaXgq-8|AVxmAnwMy;nbm&4`fYVjhEfuJL`!X8YGM94 zKn?nGHm1sk#ev{B3D(t3B$IS^HGdyDqZ_;JYCzXkfw4lv9~?xbLPd)}U^HZ^u#_%;eI z(B?CGz6YiLEwh;HOF>A9#MdoqdZME*`&2Ob7D;FDo8G%Uy!AI&5y9VO#PT+RbWv-V z)e;axRbv9JGTdhqqiFSXw8ShXKj@RRYWsgFS*W)(;bvYl{^|FiY280#`inMtvziTA z2nPeN(6*s9xIqcWTQ}~rWY_shvgR}9w$Sr_tqW7U2(N=|6o*R4>(`fvs2u$!8<9k+ zPNKsQlA>`VRIqoyl=c7*yNX=7u>}$kJm0d_v1`-h{Xk4HsZSFyBN$H?!I<91h6b_6 z-P}7ZFl4DIiGl3Uf(=sYOuMp8j(aDtTRB_M)~erx!Gy7VsilvG5+e~oxFPe|9L*vS%5D#V z#@KJ$&v=eo9hkqtt6qELz{en1a_k7;9F6B}Lq;mG))RJwsLdoW2=d??CV>tWXz>13 zHsw$6xjur-K-k{XuZo7n*kIyv^!y!tM(q3q7;2MJRn!Q~@=y8o$JErWQyk*$q3Q$! zeP6kiufOc9DCJl0dRqI9;}#GR>`xjPyGT|q^8miKpvtl=I@Wo~>4q&kxx7;ILQ zKn8w*y^yA))I(Qk%zj5WN8urum8gQ}W`uXN4|q_F&raI?=2qcnXmQUoCo~63F9Jcm z(uiaBEMLH|lEY2ZMlz~d&(5+RKoT;Aj=_>8c}JBHB%BI5^YAoa5*1Z1_w1n)M>{?E zVZR$pMBowf?vb=MFk}88_@0oTE0nswAxjyQ0W=Dw^B46dKIDT$gc!B`U+n+G&+Cn!`MiS&>AnnWhEOYIKPILNlU&YEAD=u5i9#)_8vU>$wYx6K~{>2)5~ zJKo@iF4*aI!A0>j@1DHr3$iueKzJ_N=F>Cs&oK$9+PzFobU!w-1BMHjQf7FWD3?l0 z5IflduIHlG%P+lGm_e1^CV#&bwH90Y9AHLP@3wwZ+zNviI%3h$OW>s1`t+wT%*Gw8t*= zAc^}}&~h-eK{2Z9T2pL0(#WL}EgU02q>Sn_vt=JqA~$_HMSERd0Yv@uA=S7mQuaAP z=d}(Y=2!@T-TEgIkW&aKgs3vkVx)ejPac=g zMWEe7U7dcXp?*~LXm)!RrN7Xb)wkOw)!C*)Gk;~5&4bcKEgN7Dr=*CQPx$l zS3KyiHH?w!BTeE=EDj5XT5Jfhn@vvGZLm!ajYiYdL>p1QUFrtYzs&};G{o@ubizqs zIBzIfU%v_v>HM;qP@Qz0^eKtrvky?OgR`}@N+C?i zvgOG<*&3TlRN}p$BB+M!(8S-r5p&j3WG)Z1=>C+GW;zJqz%o5ugt87Z4)KVN?x=b+H;^r#8D{9P@?_Hg#~ zkY9kL?8^$H`M05+$ROhUCq{Q`s3G__+{^(M zuu3*;W=0!;j+&CW5ZrT1Act`D4W~f=$JbkFgE=#NE#t&pf{k**it}T^S$GwRZWYLf z<^c|Kh7r0*d}m#2p*O7`4=-l47VTq3IP0ca+}5s5zcc>u1e=3YVi(L&|A+y03Lo6? zi2b(`NF}sqw2LEKVHtM7RZefUN9DFCAlU+4VY@%c`5F8|g6ukAp9}m#p2N%XBYGt@ zwFw(pDo@bEkMDcrOYaC^kMmD@2=TAg0F6HH_Arm(daCP5ff4JlV0C#n{A2BM z;6w9f_+L^#SpUorDVlkmD|DcUZU9Z; z>GHDN=(Z1iGhf|J6>_j0jl~q6+<@Q!P??m3-{h%&#GWDvryn*S7&YJUMD3Q5%2AXV zPi-*~*5mSk;u&cip7!J7c;&&pwXyH80mowC&$s1;Y**WgQ)+|EkmSj-4CKr@+}H)l z4|L`_43@4AGxc-Z;F#`YYQ?6QYG=qpFv&qzbv`g;rvjY*&S+$p|069nYwNe=DJ`^@ z-Jp@p@aDz<7$qie5lHwyRyC# z6D`T5NUdeI=iA{B5F>RjFo;H@5A>;fQEogpk^Zimj>;I7L(75PzeEAHaDZ@0!g&=+ z-(@ajjx+`MZ<^h)iguFxv9B(&iK)<-XSS&nHVbUhLOM+xxSqw=m^V5)V0yQbPGIAZ zFXtWTY-H`@Z01TSA{DY}3f^HUi6B@tS0R-7jfYL|&aFvQDzw~L9J<-?k0ql=_=l3q zNqBcM?%1-dLvKaOhGXbNGr$qP1->OKY?T!hX<7JSfB%=;m;0k5##<~Qr!DDKey=1z zzzR_8aPT;y58k`aYIXitAXef5&-DZN0npmmR%Q=hBMqPu|rgWi)QC&tCThKcY~zsYnSCuhY7b zzPMd>AKZGsC3`zq*DniSszD#Xi-u5CXmkTm12H+K9=TI(G()-A`I>Myigx5c1~FTjwntIOx2O}x$tV<|A`UvChvE?jZ#()<^O+qw+Zx`5zc$rPD9j)T-zj4_W$0! zv0{1cKR|O;84T=%G9k*!RN(JS$)~O0yBey9XGYQ?IeLxO-gqlL5g->ZGox{jhlG6J zXX!?#$4g$A`U&PJ=@e0Nvhm|?F`87H!5&t`{m&+Oi^(=h(hIbX$;2lGOIXT|JH3!5 z&4YjC)nbN4o&ES|bPo@sbB%sCUnp!1a*V9*pBGM5xe*8xCDB$<_N}f2Pj}(?y-j~AypILM)}+;<-bcv=kP!`z zn#A(tzc8q8&15f+|0qPV(9zrI%DpL;P#FP*kA8w1r0r1%x`1#{%#Lfy* zAsVrK%9NV2Z<2q0-skYa5zCe{Muh`IgY$=aOosKp$=+`Q?zk`m!jFnj(g>>4&sqrC z?H!_f_23Ri1r_f?i@KCq-mv{t0O~G?VSVVo5+`FK?~DVrMQ`@I+2Df8Lp21CtwMTL zifNm-qH44=|K_9?Lsns7f8&R3+%J@#S7}X73u77_!ZR%_==v0Tuw8J8Xb3_C@V&|( zPc^##&VlrXb{zpn)l!hzC=@4@?n7)#=p$pm&m2;@_H=D9sX~u8J>`Y)gUoHCwvLsa z>QlC>4RZ(#m}&iaPzEdXgG8?3lVlIK8pQd0` zD{)Rf#I+p+J%Aa*19-Ic-`ad*@9hLtfb`~BftrNrTVfjYHm=rGX(cBHZKxU5jI{9l z9lC`cDF#xMELcpg$Z%#U{T~#$hXGYOF5{koo?xqP4|K$=X5kHbWJQD{28(g=&Ln4% z0qPDa+SjYkpmyaz2*JAVfq$vT;ONnpV#cH#J8TKd$7S8i{7l~Npb1}US5q=petenI zUG}n58z1gpAByFY>pkmM(`+M|Xo12tK7``Yf4&btuczY4^E|=NILB)32B7)4Peeha zfM%#9+|Dlh>#UFsYqfZ1Ij5%^^!$8?hJQke+&<^xTS#S?W>jL*Qh>X}SY(jSM{Snu z8Rue#jKPf&tqofHD8CPPBGmW*Jjiz_=^V1WA4L1(iaE{Z4#+BN*kFLL+yU8@F$h7( zLSmz@vq!9LXiA>VE(vl^Vb0)&oFt1N$KaD(eC_i!ShSFY(2-)NcY}9s2+Us;NS>F6S;;w7I|xtf=Og zY8cG~&y3XVgEze}4S-Rf1Rl5;8KOB13gw~YX}{`) zT0M??nt`{IXnK1$a7H26AqE7#&$nWSTiOcktABqV#06%&A6tec=0aN=_)(=+|NRT3 z2AZl8B2)Ygh*}k^`J+H!iGSKriMayhn2Egu*WAVcf!$dOfLRT-NS0fSJ|7u-< zNp$Vy^sRbMD?X(3 zBSek2U#0@R#J(cq44=}7`O87(P1TIs41Tf4L;yX1*;0g>hY{s2ExjAA0j=xP)0|z9 zyGi|j8Kk=36Fzs4b~FW&$LN-tTTy;nYsNlmAQ@Rq4;PSYCk$a7518>fuH1D{yM(;* z19To|vu@{@{@518Y(>~T5=c@E}HXH+DGEZF$5rZ{ zwgsw5eQ!pkZs-gCrEHJ_v8QgIOUk$RV&je4<8S)-aNo08{=#QjgdnRvSJc~4g?_$p z-+V=`!;7-563WL03i^~v#|B3W!~xFE#Ei8S7pbdZQ&Sd#d?b>?f?(W{@@dLVD^~*a zI${?hXG0*OcAkF`K%l^9ksKTmdk_QItwC@~g!xQ&R!!Fjo+pn0MHZ}cOCLmj@;iq* z`~4A4Qgt)R?(j#W_B>nPAT?EGAvQh{-adO&I<3hzmp>nzc=u8!c!=Z>Eftp0wde2k z4oqDQMf%%l(h5?LDEm1Lc*gihfr~&K+~c*-XHBO6Ew#IMf5gOaOS1~;?5t}_M((k(wWb8y>q zk?DY88<49!`FIEp3=&PdbfI4)>KCAgf)XJy_T`9wKSa;4JSE1+Fg&nrc z&D65lDxyYC*^g$k^6FT^PdL~7DqCQ7&aZc|XwDFbzJmv}@3rM^)RL2^`wQqTVyC3e z{^9E7t6}l8FvEf+2~hmr;*Tjpv4w6H6V6m`PGLbnw@Y_2acX8c-7piIEEl&n`8Pvd zfYJru)B&JZG4t5=&%v{Nhe@d`#H0IVb7#=QN{KUhhJ<{uR#F~jE!YbgiIB)b9$b{F zBWrBENXEFh51OM+Q8;!A+oS zRl<_-5HCA?t<~?73zxUg)Adbd;qW-Mh?h4BHp?n(5V;NH>C}TCIS_@5u#M4;_-nc> zWl2zwiRO6T3%VoQ?}pOe0^&X1Le*<$T66BF}$_ULV3;emiB=`jJnF5*r76i z_>7c9q@ca6B*2ptIqjAUe5RUFV4*-GI8CalpdClvcbgdhHe6z?Cp4M&O-e;70uxXf z6s$;U>qT?L5|IJ;cw-OOC40+f-!m6D$bbBMkX{5r_el{K_f)amG-Rf$F1aN z@LXQ{XR42v;*U>l6UxW^mR(pTC)rgQf_BS;OJ)$gu$qb*2K~}fl;o$Gyc0wW1d4_0 za}zk(lZWcCn3-SLq02wXge0lWszdSToi$ju`QEWbhk)1EiV;z_lxwUaP~@|y)8b-- zGfq~B*IDkYTqLjcAgbBk(EbLMK!14`$yt9#wyUaKy=z!W)Pg+WKyoDn8r@v$_ayID zXYHcBA(z$B;7D+ix$=jv%t;dZ#Wq_mcbR#N%_vg&NM@}#{M@K?{fK4I{;9Hk4Qh=I_Q>dhZ`5^o<$is^;L$xJ2F&3>Ke9V$SrQ=7ili?m>`G!8W=^_ zUuw#12r&sVZ`_%fGq2OYoWM(}S2in{RP3d_$ z_hN$|Otj_~%|MA>@;eiMp{o-qbuubv(Vv=ja8=CG&HA+Eq6_#Vp*DQGkW5`!#is-mDeN31km&RD?g zzilm4+?k?Knxt8Y&#UFZsNA+l#US4#h9|tC)=_T-# zb@9@u+lYXTosa0KMN#?q!s?5Q9uPBMqp`%g~w7ZO@LsB42dz9fqiH%rkg{ z2;3LnFoSUCEZWktcDp;Q{5K0o8f}fMP7%%~mF&aI)-Vo3B8!l#@aZgQhTEfY;b$HfFU+E zhy({2kCd2zkQMElU8z5OcA8?+7M%2O0U%{AIrHae?PBkdbpTrp&UlA|A)6u7-Ju!!W zGRY5&K)=donkF_5+N5^c!dR(G%fML(VxR){*K&Enzuq)6_@UUjh?+kC3jXMmYGz3G zO5<-$TTsy-F;KcKM6*r>1!G2J6x=W(YMY4GN77eZ` zUk-v67eIl1VT{Y0W^$*%^I}k|2>-o27K&JAScs{d3IVq-!}gB zU4i{(@(?>L6}^G?mIpS?{LDe@N@iWP=)_buX4PhF2axdqKL0@9JKY>ZpFp9QaJ0&W zva9lKTFvqjI(pFG&lBvQZARN$gkCZ^SL|Xf4`4#V(vM(xfhWnjO%n7 z+P|<$AlTaQ^Jkw^L>0A?tBvqS=HoBS%5FEw->~UrQo6Xgz0zt0FTeIifs1)*$q@{R zkE*8ZOC3Xya?UqdmA3|xQ}4gpYMzSFzvZI?4Tq~aV1%l`Pf$hx?-6dPE?3TUuvv(} zY0le7Y-g)NLfC@xrDv18ML7=ax;|O=Qu%B$T~Tm$EW>}8LTK1%4+9K2Phw$v+6ew;c7X{o!vZlUM6-H?TH_(I7iwXdaP zVm=_!NE|cugyViEf753{u`mlq6(EE?ZYuvB9c-gk=W2F@PxE)_1Ka>wMA}Z%O#7eJ zgl(5;^nQQSBzMt9pc{t?~(Bkxri$q1?e-HOajA+@ej*1Qs zE7+Mx^CIQJF@CVmF=`U7#yYFuY3p3{-ZuvCIWOb) zp5Z5bY#iK<|54z@2rNZW1WxHI$De}#r5Q%~afyxuvF;iiDB{_>s7S6>zbhOolo8^T zN8g7Bvu?@)*o(4j5ip_xo>$?JAheE<=i9P>z~1Oz85gjWPxZ4ASD`}la8<2?G{(m{ z5wJkpeuFw!;*XX#ND3zJZ`td9qdTVsV`6bv7Id=6^MdxsTK{})U`k4yc%HNF7Af`^ z-anBtc2FeNYIr7$%oljblu!ro&GrL9;}>xn`+dC@>nR*_tUg?PprtEo`x;KCApbz4 z_vm*6T8fZnFiRLvC%Y~0yLw0Z)>yH*hIXUo;%f>F`#aP_c6gU4^LdC^b*Dfdo9{Je+Mso*zG(X|M|N6F6hVVL}b? zkLneHa4;JQ2EwGjXGEGR3a<26nHNhEx^r=mg1u_X!@<3RN2oNaCN6;6-)cl|emjQt zi9~h6YSCk~6e7*emV>t{#IE=4dUmSD{**x>bjYAKFUor`?;&yJ z3qNuheqR3pq&j~Dul$iC$Jz*?xbk}p$PS7vSrS$(yF8+Twp8^($3#(*33lTWxSRZbgUhP9E5EZa_InW( zl|GlY|3RaSeAD5nbO?VT)kYr~e-q)lk4?NCb89mPydgj@?#**Y21{eTVTsRniEX2Y zc|ab#QD@#HCMUr9E=Agwp*N&g7MF+UVY;O0m;9&q(yHiUCp&q}VjAF!L}6N!Qu5}; zdJ&ATk+MUz`;0X2lKj4{@J>C@9U++0-4@e6IIEy)TE9Nb)KuZnP`Xp^bo}W1iwBF< z!-p-`=C$X9SuRju^`XdhlKNqVCo1J`lfgbSe+*Cn`oLD$0MjMeg*y5u@%vB0xc9@D z9Ij9dbJK|FOqLr&iwF*uW=G?1Rraqo$AoN@q)MrLewiD0E<1rDSyb^YT8;^GK>_Me z3s0_NO?f7Tk+v%3uhKX%^VbM9Iwpr2v!%L6OE&t(fpkzZ|Rk9S3J$) zmdp4jJFC=_+rmHz$MD0!LLo#j3G7#fx*QdkK_oH7Q~};P8DBIEKtiTWsF0+rbkYSf z&pbT`3Ig&x{lR^^vo46rR_$I3MB=gWpUSCvNY<#V+mcU ztX}o=pmfLlJy}p=Z}hY4sVSEpz0!gzI&zrfho{^{bcJ#ziQ8ePgu3s{j*Mkj|0<_< zr@rt}mzl#{@Zka}9#mGXSt*)@na0~I8T#+-+Ie7<?|=2^xupLnzzOg#=Ix7Zg^{t&metXjdAta&?l8=a zHkcw5D|L^PeH9HD41b5_f?Iq8)WIFOdiE#3-{DGDZ|R4-L-NNz^W!`iyrrutVN2H9 zE}C^OS$hUgr5j|UEyo~fvkXiuCUukglA;S(fm$Y1ejEMpKhxQWWhIG)mzm2?;voB= zg@hkg9+6Q$tk6)jD3bv8$Hk@l!$-C|9Z%pi&pXg|O1naWM=02lkY7gyt?uAb z2<(;Ce5PedTh(%qD8d#yDh<9q8%P00qhdIK?A)9j%wWxiOC3@eLN~ojU%3wiFQt)?B1`Boipe)%8 z%SIM~m7XJF8LEwKz}td(O4zWd?Gms9ey7A1$)~ViH}bhYmqHGp}Lf2eF@^Y0d-y#|IfD ziJ=aztouWw0)2NL0V|HOZ&lY`=(Chb+y(0P&5XIMIT2tfIm zIIXN&i(E{-GU1PJ+}*ZJ+xRIdk)(DGp0qhB3MY%5-sA4VRFV2?z_=;@+trcNL|nsO=MkJ%JoM$qvY5eoaBL%PJImnOya0|?uWj<-@# zVk=BaiLrtCRB{2SZ4Eh{1$YOu@`jQ6G3Se=mg>b%{E@6qG2# zFp1w4=J57xPajpTWo6%4HqG5we^y-%DxqdpQ$5nifqkY5VM!L#ce<%>h}k^>xg_Nw zQ~h?Sdl;hjY35lD|A8aB~;^EFo=JOX8N%x`t^~?0*@><^!E>a z{8`~7J7Udd!vt=a{zli_eh{rx8-s=MdRbl5j{6L2u>;#(t)YZ4(xdfLEGE?E5AqD` zSWM#=KBj_dT>{Y`nyNgP8vU5^l#;8y(7sKDz?Jg0^h%PR`Eid62S^J6@JO)PH_r-e z`&I)^R8^8`#S<&Z6r`oM;ll|@2y2k@X+5buSE9E5pk4}{S-xEd(Xp!-b1SQeVLwRDRQGo+@5P-=%`J=mM$?tVCr(r)u{C-trExVn%hLOx; zRl27ebU33vjDBvcKD~q$mXx!e?lGd$l0#ZKsMuxx5mIlNM|T(eI>ULf7xE=X7FPz% zvW$*Asl9Yq^IK0fi|X{d%*C=~?{u&r;_)LCy;lO|CJ5i z^VnPyUDOtLr(4JUH2@~bq#oXk-=1iv7N(5;Wtjm|i$K3w0@EVv6s_h0hgiIST_a@3 z4AR|yU%d+0T{XUdTmA9aVthjm!C$q5*UR{4f0(lJY!ed>Ywjlz%6{XmHcL_?(Ga?# z7)NhJ3j$F{jlEr|7s?+0f9l+a>X^Ic`&8^&gyy z)BNl+LM&6abZsNmU!aT7wU1Nv6){(ta82Jc-b9iLA`wW+g^JZ}8P<<>vfxezk+}vw zsyY2>#Zl;@>jqwDK%yEzdV9X zXB^#e_Dl>fgD-aM=(3|;|Afge{lr<--R}QyM@JbTY2~m}TSEn(_>rpKiI$jVZcxzD z-6U2>D4)_sZf)txobTo)5U&--{5hgNUYq_@MeXB?RZNe%z7|z``a1?x7_d z&67lZzFc=CV6y0g)+Rl_1<7Sz^j(zzZ>4DFU%oGq1VqCVbuHj~5qi$oMrIVWPB68> zTM6cHXEBo&^@#bf_^vbi(k0=lXXc+$#n{J4CW!Pi*AdLL^cWyoJv#7jY8Ow$0o9cV zd3}FjI4*+3`w5`-&kka_2;eMvU~~D6ylkhwB~Ap!Z$KQmEW*#K-p`%qH}QO=gEuqzbU43^RqTLK`;xbfO6GafAZio+~!s z*lw9IE`*Ms-%T|D?QKv^b`6o zrj;{PXy23|-7ZKH%c}H$VJKR3IQgk6o>AOUQvxQu5+cn)0$3*OSK0GZvDCzS*MQbi{Lv3XL`DBM<&EN4OTC*ZI;Y+5?>w&7 zuk`s#a~EbFOLrGx47+tmYuK}_HP-hKik)+=vKw;!9l?{G+6h;1|5|shNY8vZkq*(? zo{N|woh~xsbs{*?wofM}v-XXA_eV1V;NCX@L)7pHoBxZ|QVI;@{eVi&^5Wv=0mg-e zNR*bNdHF;Ipx(d`O~F^Qr7L3Ah}v^`A#qiVAT=o zd~Zf7mI(kzsbKE`E!M<8P{n3bXIAl|Iofwdu-F_7YR(RPx_+vQ`vYvTl$vI&+NkOthUEmm zQ!5p{xDvL9#BOJUeKtR&b1pRWLpijZPLG{cajBsS(Pw^K{qv z3~1uf>Jm>}$KG)BxwqFPsXan6)>}q6JINgiK>WA41e9zIk0Zd`yeasL1*O=^a|Rz2 zI(Anl4cSqfWlZ*M3!rxlIBG)W)KPlR&SllTx`3LK+EnII9Qk1rlPXtQX%Uz-qbJP< z-5(EzKLwcvHuxi6rvIn(+m&b6KM96~K@ftOl5VLAxU(}cMPm>CGV6Wu_=|T@J%s<* zP;;(DY)2(-fs988jPhOp^cuD!v|^FRW5*T9ubtS*kj3SQ%qB=@!<=%WpEXi9t$tVh z@pXUmo$<28T!+SeSuQ3qNMECT!RrVK+UKYe1Kyi(e%Hb?!yb-~ z6DY`f+qPO2mIv-~j68ZBq+QvxbXZ;Be&nl#tX<}n+Mm-yR)d%n~s?-VcNjhPo7%WaB@Y>#Zu9H)ew8bIo&h(g7GbDUf`0r z=FcG0y?CV$gR$6?810CCaOnN-Sqol<{$_V4zxJzldmWRVt5KYd)yuyCM|g}oWr#y5 zHZi4x603hW+ydcPT&HfjuR8hM`FhAWv6vVmVA^xy8i5uR9S(k2^h z+wWPt^NIx|h05J=dB`1$usPE#Mk0U;P@~_#$tTguzbd_eL#{Zp;olmvq*lU(yPJL%RmUoz1w3 z2`pe{+c3fE+X{Ovg*`lKXD8vPVC_kQW;;<*-JoD%d}bd{3wXIXwOr;;m4Pj^{lpuK z-JBm%AFWWX9_Xt*J)?8+%sf1+7>1}A$OLt0HI(NU5oNH_^$B}Zp6W@pm8japHRCQ< z+nJB6RGz0+btk$w$GH>0+8F)A)CvV5lHfgSG#VY0L+L#r4SH<0?I4Vy9S&V<*hiHO z&u)M^hA*_%O)g9ofBH{C*!%)AUin_4g8T+j?fA{y&G(v76qE&vU!zSY04eCcR1cqlXDh|D;-Mh{v zs-#H#+jc?^5h+r?Hr1@faG(@$_#^F2y{9P$a1v(UPK5A+)5LnJK(;p|zHjRqPNYzQ zHvR}S5W~G3hH2I0H!t zWq^>X?*Am`uJ2RK^PzCmcFs`Wb&!Tigit6ePD4ttS#LxX+OTTYy3fg1iM|g}JT-4< zE0oR)b#_m#fj2@T2E9-<)gpnofv0J4C{T8`6VWh}%VxkCdb7*adX_|h<|u6Bn;Cdc zn|7S}d}|UO*gYY3DmU-d{2*1D!ZQ4T8=1cu4*++?Orr8;so+_~N&I{=&O?D9SC#a{9{drKRlZ0Z`2Yzc zKkH=~c%L_@SdaJ1>DZ9|qF6AMc1#uO{4r_UT(twpD@TW-f?}%QL(3KpbyY7jS31SW zNuyjW(_viqLAaTDlv&bKSg6Kh@Cf8lCZsGj+BE zz3xcq?SNr`4Gv_0lU7z^Q&zKdNyvE89aYssJiMGQ#lT2q6=F$t#LHZKH<)? zE90d^w!>fs#8jqV?>1j(j`$1d9mrRg@igB+2LIJ1RIKzQna9$B+^et=L9vFjXa74w zz8Qn&!dvKVu5%9_Q8$K`?}wWidM8X#X7>=Su85YZKSe0-QDKv?h~5D9Z2dX99g^2y zY_$X|L4t4-9YzM|s@#Oftpz@f=641Wr71nS*)hwYXqw-2C3ISFY~&>`HLMU&Q^fZ zHuWEgI8{mgBQ*n0V#6&Os|)R=H@mJw2c%cip21K;MT$*@qqQH9nA6U?;AOR5gJL9T zeA$eHIjC_SZ@NZ|{V%;g!OS8tBY^@U5%~_f@c9!(1FS}Qz%;Y@%hmue+G0@j%)6{~ zDcGlG!^du>R<%OD>`KA^w|lX}12udl^xz{kuF8hq$anoMfrq4s)d(~m8}FSw zq;QP;a&6$E!3{o2%GG__4Fk<#v<-_mAU#-2vuv$n`^%3yAj>muQESN#bCLV zQ=Y39?;Cl3bbp6kM|}J5vm($8>k}X-&)0(D&{%R-B4$`3RxvFWbDM#sVARo4XD>v8 zP40zhP?cP`zFBk8QZYpO!zQmZs#arFp&QH94wBN~ec>(lxjrfj9b@JSUw=m}mrN6G zPM(rwBJ>^xw0b6w@BUM9F~y5%?U5gCH~F_QTWA}uW!uf;6!^$t4h5r^BgI_9H#6WGIe!CrBME$ z(I*?>I8k6-^eDis6`H?qm5gvJ+1^%zaqDO6BssQ=b5nud8T!@AH!DbMPMRIx)k_Ii zbf=L100yUXWkrZRi+i&bEqVncVfC|k<1I~p+68ce?-t6N#H})lQ1t^;aGSUUC`VB( zkRVkejGG~t-d_pMnc5BE(eHG}3|H6fcW`#^gkN4IH%x=HCkfH=MCjR648Y1D$X~Q7 zKUqtB&(PpZO}q>;Z9{;*A&A96C@Nl$A4WR_N^9Uu?A|Lpa$E;2aS|*9#xIIjyirMl9=L{J2VB@cEG24HOQhfc+ZA4Ewguv#L1|-RFeBwd?++YaP#~DRz z%aYZeBZ1{v{|uiK7$ETPozfpkrFZs&yf3^LXJ2tS)69P%g++M|uZeX_9&oL!`m6+m zacPNiw?v`Pik=ma{+bC|@IM0-VyGlNIYbG6dyL5>Hc!K`h!7uH9!6&J4&<(vlUXtq zz~LBFKhq2)T=sL_Vj*nzxu^f1d;1H?vir|plm+qM1twP1eAJx{0dBddxDsV*muYgn zGr9K*>b3>nYnv`AQha)snYHs>pfg=JO;b>^=y-DUkA8`_@e87-yw`hSjoE%7Jw6jb z3+tS?QtVXZ$*D`p-(1r$39}Dxl(WRh#Y;93BU7smEKJfBj#!9aaL8bFW zwJti;y5h=*n--lI+Mg|bG2fbcQxwrY=i&^h{`dt%$V`zDUXc--M8<7fIfy)5o{qi9 zhDn{e5=WvS>HnI$@_(qiFJ2P~H3?4?Mq`~p8e|(YGDBsV8Dnd+JPI-DF|udhrPN?X zC>djkQG_;I2pL;hOQo^Qc!WVnwk+Sz^!yXw&+GHs=e|DoyzV{sea|`f-1qS~vzzLR zbHO?5tv?J?NSb5?JbaAjepHj(!&^jtzp-noia13=Z4RP+XA~GUGmbM)kP?$Jh;3hP?(o?(9(}yovB9Q%r}Y9>|!o!S^cY2CYz2F z(~(1OweWm@yDf(Vxezu(fg@vnX2DO;2wRd_DGR zzsZ_&xWT)x?nF7O5Bnx5hjwOrU|cgGw!7+{R$iYX)_Ia=eVFJBzC%N&UJ z4p4`5{W6%~>?8RU4tFA8#S`fh$l#0}70E-6TDYo{cEv7XZRzTh_yf>GwBd9d%!j!; z*Y@2WA3Gt9G(9>aBhiB8MtGULoYeL)c~C0fVlaJf9k})OF=BV!s>tz$tPMSn)=yk+ znRB{wn!#eVKEZ|1^K$6NPF2d0k+y`4mFubj*Bas&`SXLs`+^G^w@)dq8}S}|#x!OM z-0-|+%BNmWQ5;hPYN!hl2aJ@Te&i=I1|@VSH(hi6o>oFXIYcK&KVC4m7x?NZ<2_;- zCA;Ii#xyb14N;KdVxcyiaq$Gva(h2z(KNh13P|p+WS6*KH2n9S5 z#(rooj-#zk1J#;Z-2mMQ>yVWhW(wzKzivTve{13^j8J^IMRdszBi$8++_gI2j*MwN zD3%qVUsa`N!s(~jf z4v7GeBh4oXhU96?A$!X1Ny&F&=asT`_HXSx)e8AlnweHk!3Tiow zz`p%^{I3juI{DdOzWT?hwYOp^A707HQA_Vmk+W)Z zB3UDhG~V2ZkznGs57WWQ4igbt5(|LwW$CL8u9@Zs*I2d*n2k9QD_yw>cGNf_8#S34 zWtef0dduQ%SMx*3{iLDUk z%N?)HMG)(;cyJB&CTbC=RpY7Q+Jy5+yQYbYX13{vNZ3h!SuykAcijUS-s8eDAZ9er9C<*qw{afEj#FaeiukaQ(fM+Dp+PiGKKa)N`{CwGtMtN?0zDU}lcy)S_~YbgE*S)!A{|UB}M$z7K(q%d&S1Hi7F7qz&jSu1?D= zG-mqxfYt+)=OG3!)0_RWw~Zyi&+7z#i_)$6Kjm}BPYlw0`z|2$6^AN@;@z&mZhhVM z9KL6E=&oFr+6{e)wQ#zXNLG06sC}zMiRwKWSNYO6j3DJnaJc8ot*`|X@cY*id}PR>}RUz*7|U+@y}5!aR85QOT4tTt=j)e3>m zKdKxdXcLTgng*D>^p2Knvy0jm)ndR&comx3p!0$Z{YeG_L;LwPEkHmJFHe2A0_$#yd6ixH9T^>E0jR#M;G3Gm zD-49CzIV*6q>kIXt6IQFbk{fM_QicLF?J5RgUR>*k?Zv8(freVCRTS#b&u3?k+6eD zI3$_C%5GD~eb$4N52qnD|C2#H$^W7evJ%`h9o8lw1f(}FO> z6o@W8y7d0fROuWK6*^1uTe0c1+6~~ueqVV&Z)Foe{zvwCwR8nu&oDvj5f-M{c zthf{7V&VWugYhJl#7yv&ycx)!g~b=<|K-i9;_U2kmwoFvC!Gx41w0m~31;P3*Vz97 D&efKy literal 0 HcmV?d00001 diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/welcome_dark.png b/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/welcome_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..d324a8bb4c5718d152f113b674fd5c2d925f267c GIT binary patch literal 48993 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%0DfQKmKB6yQbhVH6po8a( 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 F{{c-&&&dD) literal 0 HcmV?d00001 diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/welcome_light.png b/x-pack/solutions/observability/plugins/streams_app/public/components/asset_image/welcome_light.png new file mode 100644 index 0000000000000000000000000000000000000000..06f4a7154655096f90f4b76a01998d445ec45c91 GIT binary patch literal 50657 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 JM(J(j{{WPBV(|a~ diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/condition_editor/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/condition_editor/index.tsx index e53c9f9069797..0b08ca68dc6f7 100644 --- a/x-pack/solutions/observability/plugins/streams_app/public/components/condition_editor/index.tsx +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/condition_editor/index.tsx @@ -175,11 +175,8 @@ function FilterForm(props: { }; const newOperator = e.target.value as FilterCondition['operator']; - if ( - 'value' in newCondition && - (newOperator === 'exists' || newOperator === 'notExists') - ) { - delete newCondition.value; + if (newOperator === 'exists' || newOperator === 'notExists') { + if ('value' in newCondition) delete newCondition.value; } else if (!('value' in newCondition)) { (newCondition as BinaryFilterCondition).value = ''; } diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/management_bottom_bar/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/management_bottom_bar/index.tsx new file mode 100644 index 0000000000000..6e5086ee026c4 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/management_bottom_bar/index.tsx @@ -0,0 +1,58 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiBottomBar, EuiButton, EuiButtonEmpty, EuiFlexGroup } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useDiscardConfirm } from '../../hooks/use_discard_confirm'; + +interface ManagementBottomBarProps { + confirmButtonText?: string; + disabled?: boolean; + isLoading?: boolean; + onCancel: () => void; + onConfirm: () => void; +} + +export function ManagementBottomBar({ + confirmButtonText = defaultConfirmButtonText, + disabled = false, + isLoading = false, + onCancel, + onConfirm, +}: ManagementBottomBarProps) { + const handleCancel = useDiscardConfirm(onCancel); + + return ( + + + + {i18n.translate('xpack.streams.streamDetailView.managementTab.bottomBar.cancel', { + defaultMessage: 'Cancel changes', + })} + + + + {confirmButtonText} + + + + ); +} + +const defaultConfirmButtonText = i18n.translate( + 'xpack.streams.streamDetailView.managementTab.bottomBar.confirm', + { defaultMessage: 'Save changes' } +); diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/preview_table/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/preview_table/index.tsx index d200e6b3b40be..e98134c42935b 100644 --- a/x-pack/solutions/observability/plugins/streams_app/public/components/preview_table/index.tsx +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/preview_table/index.tsx @@ -6,21 +6,23 @@ */ import { EuiDataGrid } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, { CSSProperties, useEffect, useMemo, useState } from 'react'; export function PreviewTable({ documents, displayColumns, + height, }: { documents: unknown[]; displayColumns?: string[]; + height?: CSSProperties['height']; }) { - const [height, setHeight] = useState('100px'); + const [computedHeight, setComputedHeight] = useState('100px'); useEffect(() => { // set height to 100% after a short delay otherwise it doesn't calculate correctly // TODO: figure out a better way to do this setTimeout(() => { - setHeight(`100%`); + setComputedHeight(`100%`); }, 50); }, []); @@ -59,7 +61,7 @@ export function PreviewTable({ }} toolbarVisibility={false} rowCount={documents.length} - height={height} + height={height ?? computedHeight} renderCellValue={({ rowIndex, columnId }) => { const doc = documents[rowIndex]; if (!doc || typeof doc !== 'object') { diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enriching/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enriching/index.tsx deleted file mode 100644 index fe532825d970a..0000000000000 --- a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enriching/index.tsx +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { StreamDefinition } from '@kbn/streams-schema'; -import React from 'react'; - -export function StreamDetailEnriching({ - definition: _definition, - refreshDefinition: _refreshDefinition, -}: { - definition?: StreamDefinition; - refreshDefinition: () => void; -}) { - return <>{'TODO'}; -} diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/add_processor_button.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/add_processor_button.tsx new file mode 100644 index 0000000000000..34219c9b83781 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/add_processor_button.tsx @@ -0,0 +1,22 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiButton } from '@elastic/eui'; +import { EuiButtonPropsForButton } from '@elastic/eui/src/components/button/button'; +import { i18n } from '@kbn/i18n'; + +export function AddProcessorButton(props: EuiButtonPropsForButton) { + return ( + + {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichmentEmptyPrompt.addProcessorAction', + { defaultMessage: 'Add a processor' } + )} + + ); +} diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/enrichment_empty_prompt.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/enrichment_empty_prompt.tsx new file mode 100644 index 0000000000000..96c8bddb2c822 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/enrichment_empty_prompt.tsx @@ -0,0 +1,44 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiEmptyPrompt } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { AssetImage } from '../asset_image'; +import { AddProcessorButton } from './add_processor_button'; + +interface EnrichmentEmptyPromptProps { + onAddProcessor: () => void; +} + +export const EnrichmentEmptyPrompt = ({ onAddProcessor }: EnrichmentEmptyPromptProps) => { + return ( + } + title={title} + body={body} + actions={[]} + /> + ); +}; + +const title = ( +

+ {i18n.translate('xpack.streams.streamDetailView.managementTab.enrichmentEmptyPrompt.title', { + defaultMessage: 'Start extracting useful fields from your data', + })} +

+); + +const body = ( +

+ {i18n.translate('xpack.streams.streamDetailView.managementTab.enrichmentEmptyPrompt.body', { + defaultMessage: 'Use processors to transform data before indexing', + })} +

+); diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/danger_zone.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/danger_zone.tsx new file mode 100644 index 0000000000000..5f8d44d0d8962 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/danger_zone.tsx @@ -0,0 +1,89 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { + EuiPanel, + EuiTitle, + EuiSpacer, + useGeneratedHtmlId, + EuiButton, + EuiConfirmModal, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useBoolean } from '@kbn/react-hooks'; + +export const DangerZone = ({ + onDeleteProcessor, +}: Pick) => { + return ( + + +

+ {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.dangerAreaTitle', + { defaultMessage: 'Danger area' } + )} +

+
+ + +
+ ); +}; + +interface DeleteProcessorButtonProps { + onDeleteProcessor: () => void; +} + +const DeleteProcessorButton = ({ onDeleteProcessor }: DeleteProcessorButtonProps) => { + const [isConfirmModalOpen, { on: openConfirmModal, off: closeConfirmModal }] = useBoolean(); + const confirmModalId = useGeneratedHtmlId(); + + return ( + <> + + {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.dangerAreaTitle', + { defaultMessage: 'Delete processor' } + )} + + {isConfirmModalOpen && ( + +

+ {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.deleteProcessorModalBody', + { + defaultMessage: + 'You can still reset this until the changes are confirmed on the processors list.', + } + )} +

+
+ )} + + ); +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/dissect_append_separator.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/dissect_append_separator.tsx new file mode 100644 index 0000000000000..dc6bf2dbb39cb --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/dissect_append_separator.tsx @@ -0,0 +1,36 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { useFormContext } from 'react-hook-form'; +import { EuiCode, EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +export const DissectAppendSeparator = () => { + const { register } = useFormContext(); + const { ref, ...inputProps } = register(`append_separator`); + + return ( + "" }} + /> + } + fullWidth + > + + + ); +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/dissect_pattern_definition.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/dissect_pattern_definition.tsx new file mode 100644 index 0000000000000..751a522c0610b --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/dissect_pattern_definition.tsx @@ -0,0 +1,79 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { useController } from 'react-hook-form'; +import { EuiFormRow, EuiLink } from '@elastic/eui'; +import { CodeEditor } from '@kbn/code-editor'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useKibana } from '../../../../hooks/use_kibana'; + +export const DissectPatternDefinition = () => { + const { core } = useKibana(); + const esDocUrl = core.docLinks.links.ingest.dissectKeyModifiers; + + const { field, fieldState } = useController({ name: 'pattern' }); + + return ( + + {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.dissectPatternDefinitionsLink', + { defaultMessage: 'key modifier' } + )} + + ), + }} + /> + } + isInvalid={fieldState.invalid} + fullWidth + > + field.onChange(deserialize(value))} + languageId="text" + height={75} + options={{ minimap: { enabled: false } }} + aria-label={i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.dissectPatternDefinitionsAriaLabel', + { defaultMessage: 'Pattern editor' } + )} + /> + + ); +}; + +const serialize = (input: string) => { + if (typeof input === 'string') { + const s = JSON.stringify(input); + return s.slice(1, s.length - 1); + } + + return input; +}; + +const deserialize = (input: string) => { + if (typeof input === 'string') { + try { + return JSON.parse(`"${input}"`); + } catch (e) { + return input; + } + } +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/index.tsx new file mode 100644 index 0000000000000..b88ac46d65789 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/dissect/index.tsx @@ -0,0 +1,50 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiSpacer } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { DissectAppendSeparator } from './dissect_append_separator'; +import { DissectPatternDefinition } from './dissect_pattern_definition'; +import { ProcessorFieldSelector } from '../processor_field_selector'; +import { ToggleField } from '../toggle_field'; +import { OptionalFieldsAccordion } from '../optional_fields_accordion'; +import { ProcessorConditionEditor } from '../processor_condition_editor'; + +export const DissectProcessorForm = () => { + return ( + <> + + + + + + + + + + + + + ); +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/grok_pattern_definition.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/grok_pattern_definition.tsx new file mode 100644 index 0000000000000..1cfa43a904867 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/grok_pattern_definition.tsx @@ -0,0 +1,92 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { useController } from 'react-hook-form'; +import { EuiFormRow } from '@elastic/eui'; +import { CodeEditor } from '@kbn/code-editor'; +import { i18n } from '@kbn/i18n'; + +export const GrokPatternDefinition = () => { + const { field, fieldState } = useController({ name: 'pattern_definitions' }); + + return ( + + field.onChange(deserialize(value))} + languageId="xjson" + height={200} + aria-label={i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.grokPatternDefinitionsAriaLabel', + { defaultMessage: 'Pattern definitions editor' } + )} + /> + + ); +}; + +const serialize = (v: unknown) => { + if (!v) { + return '{}'; + } + if (typeof v === 'string') { + return formatXJsonString(v); + } + return JSON.stringify(v, null, 2); +}; + +const deserialize = (input: string) => { + try { + return JSON.parse(input); + } catch (e) { + return input; + } +}; + +/** + * Format a XJson string input as parsed JSON. Replaces the invalid characters + * with a placeholder, parses the new string in a JSON format with the expected + * indentantion and then replaces the placeholders with the original values. + */ +const formatXJsonString = (input: string) => { + let placeholder = 'PLACEHOLDER'; + const INVALID_STRING_REGEX = /"""(.*?)"""/gs; + while (input.includes(placeholder)) { + placeholder += '_'; + } + const modifiedInput = input.replace(INVALID_STRING_REGEX, () => `"${placeholder}"`); + + let jsonObject; + try { + jsonObject = JSON.parse(modifiedInput); + } catch (error) { + return input; + } + let formattedJsonString = JSON.stringify(jsonObject, null, 2); + const invalidStrings = input.match(INVALID_STRING_REGEX); + if (invalidStrings) { + invalidStrings.forEach((invalidString) => { + formattedJsonString = formattedJsonString.replace(`"${placeholder}"`, invalidString); + }); + } + return formattedJsonString; +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/grok_patterns_editor.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/grok_patterns_editor.tsx new file mode 100644 index 0000000000000..efefc6870d5b4 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/grok_patterns_editor.tsx @@ -0,0 +1,128 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { useFormContext, useFieldArray, UseFormRegisterReturn } from 'react-hook-form'; +import { + DragDropContextProps, + EuiFormRow, + EuiPanel, + EuiSpacer, + EuiButtonEmpty, + EuiDraggable, + EuiFlexGroup, + EuiIcon, + EuiFieldText, + EuiButtonIcon, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { SortableList } from '../../sortable_list'; +import { GrokFormState } from '../../types'; + +export const GrokPatternsEditor = () => { + const { register } = useFormContext(); + const { fields, append, remove, move } = useFieldArray>({ + name: 'patterns', + }); + + const handlerPatternDrag: DragDropContextProps['onDragEnd'] = ({ source, destination }) => { + if (source && destination) { + move(source.index, destination.index); + } + }; + + const handleAddPattern = () => { + append({ value: '' }); + }; + + const getRemovePatternHandler = (id: number) => (fields.length > 1 ? () => remove(id) : null); + + return ( + + + + {fields.map((field, idx) => ( + + ))} + + + + {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.grokEditor.addPattern', + { defaultMessage: 'Add pattern' } + )} + + + + ); +}; + +interface DraggablePatternInputProps { + idx: number; + inputProps: UseFormRegisterReturn<`patterns.${number}.value`>; + onRemove: ((idx: number) => void) | null; + pattern: GrokFormState['patterns'][number] & { id: string }; +} + +const DraggablePatternInput = ({ + idx, + inputProps, + onRemove, + pattern, +}: DraggablePatternInputProps) => { + const { ref, ...inputPropsWithoutRef } = inputProps; + + return ( + + {(provided) => ( + + + + + + {onRemove && ( + onRemove(idx)} + aria-label={i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.grokEditor.removePattern', + { defaultMessage: 'Remove grok pattern' } + )} + /> + )} + + )} + + ); +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/index.tsx new file mode 100644 index 0000000000000..0adfe8faa4dfc --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/grok/index.tsx @@ -0,0 +1,50 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiSpacer } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { GrokPatternDefinition } from './grok_pattern_definition'; +import { GrokPatternsEditor } from './grok_patterns_editor'; +import { ProcessorFieldSelector } from '../processor_field_selector'; +import { ToggleField } from '../toggle_field'; +import { OptionalFieldsAccordion } from '../optional_fields_accordion'; +import { ProcessorConditionEditor } from '../processor_condition_editor'; + +export const GrokProcessorForm = () => { + return ( + <> + + + + + + + + + + + + + ); +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/index.tsx new file mode 100644 index 0000000000000..d8f0d2f0c5ffa --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/index.tsx @@ -0,0 +1,169 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import { FormProvider, SubmitHandler, useForm } from 'react-hook-form'; +import { EuiCallOut, EuiForm, EuiButton, EuiSpacer, EuiHorizontalRule } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { ProcessingDefinition, ReadStreamDefinition, getProcessorType } from '@kbn/streams-schema'; +import { isEqual } from 'lodash'; +import { dynamic } from '@kbn/shared-ux-utility'; +import { ProcessorTypeSelector } from './processor_type_selector'; +import { ProcessorFlyoutTemplate } from './processor_flyout_template'; +import { DetectedField, ProcessorDefinition, ProcessorFormState } from '../types'; +import { DangerZone } from './danger_zone'; +import { DissectProcessorForm } from './dissect'; +import { GrokProcessorForm } from './grok'; +import { convertFormStateToProcessing, getDefaultFormState } from '../utils'; + +const ProcessorOutcomePreview = dynamic(() => + import(/* webpackChunkName: "management_processor_outcome" */ './processor_outcome_preview').then( + (mod) => ({ + default: mod.ProcessorOutcomePreview, + }) + ) +); + +export interface ProcessorFlyoutProps { + onClose: () => void; +} + +export interface AddProcessorFlyoutProps extends ProcessorFlyoutProps { + definition: ReadStreamDefinition; + onAddProcessor: (newProcessing: ProcessingDefinition, newFields?: DetectedField[]) => void; +} +export interface EditProcessorFlyoutProps extends ProcessorFlyoutProps { + processor: ProcessorDefinition; + onDeleteProcessor: (id: string) => void; + onUpdateProcessor: (id: string, processor: ProcessorDefinition) => void; +} + +export function AddProcessorFlyout({ + definition, + onAddProcessor, + onClose, +}: AddProcessorFlyoutProps) { + const defaultValues = useMemo(() => getDefaultFormState('grok'), []); + + const methods = useForm({ defaultValues }); + + const formFields = methods.watch(); + + const hasChanges = useMemo( + () => !isEqual(defaultValues, formFields), + [defaultValues, formFields] + ); + + const handleSubmit: SubmitHandler = (data) => { + const processingDefinition = convertFormStateToProcessing(data); + + onAddProcessor(processingDefinition, data.detected_fields); + onClose(); + }; + + return ( + + {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.confirmAddProcessor', + { defaultMessage: 'Add processor' } + )} + + } + > + + + + + {formFields.type === 'grok' && } + {formFields.type === 'dissect' && } + + + + + + ); +} + +export function EditProcessorFlyout({ + onClose, + onDeleteProcessor, + onUpdateProcessor, + processor, +}: EditProcessorFlyoutProps) { + const defaultValues = useMemo( + () => getDefaultFormState(getProcessorType(processor), processor), + [processor] + ); + + const methods = useForm({ defaultValues }); + + const formFields = methods.watch(); + + const hasChanges = useMemo( + () => !isEqual(defaultValues, formFields), + [defaultValues, formFields] + ); + + const handleSubmit: SubmitHandler = (data) => { + const processingDefinition = convertFormStateToProcessing(data); + + onUpdateProcessor(processor.id, { id: processor.id, ...processingDefinition }); + onClose(); + }; + + const handleProcessorDelete = () => { + onDeleteProcessor(processor.id); + onClose(); + }; + + return ( + + } + confirmButton={ + + {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.confirmEditProcessor', + { defaultMessage: 'Update processor' } + )} + + } + > + + + + + {formFields.type === 'grok' && } + {formFields.type === 'dissect' && } + + + + + + ); +} diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/optional_fields_accordion.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/optional_fields_accordion.tsx new file mode 100644 index 0000000000000..ddba021d10106 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/optional_fields_accordion.tsx @@ -0,0 +1,38 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { PropsWithChildren } from 'react'; +import { EuiAccordion, useEuiTheme } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { css } from '@emotion/react'; + +export const OptionalFieldsAccordion = ({ children }: PropsWithChildren) => { + const { euiTheme } = useEuiTheme(); + + return ( + +
+ {children} +
+
+ ); +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_condition_editor.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_condition_editor.tsx new file mode 100644 index 0000000000000..51a57bf6b14df --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_condition_editor.tsx @@ -0,0 +1,16 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { useController } from 'react-hook-form'; +import { ConditionEditor } from '../../condition_editor'; + +export const ProcessorConditionEditor = () => { + const { field } = useController({ name: 'condition' }); + + return ; +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_field_selector.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_field_selector.tsx new file mode 100644 index 0000000000000..da4a455f894ba --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_field_selector.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFormRow, EuiFieldText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { useFormContext } from 'react-hook-form'; + +export const ProcessorFieldSelector = () => { + const { register } = useFormContext(); + const { ref, ...inputProps } = register(`field`); + + return ( + + + + ); +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_flyout_template.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_flyout_template.tsx new file mode 100644 index 0000000000000..b20df887fd223 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_flyout_template.tsx @@ -0,0 +1,62 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { PropsWithChildren } from 'react'; +import { + EuiFlyoutResizable, + EuiFlyoutHeader, + EuiTitle, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlexGroup, + EuiButtonEmpty, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useDiscardConfirm } from '../../../hooks/use_discard_confirm'; + +interface ProcessorFlyoutTemplateProps { + banner?: React.ReactNode; + confirmButton?: React.ReactNode; + onClose: () => void; + shouldConfirm?: boolean; + title: string; +} + +export function ProcessorFlyoutTemplate({ + banner, + children, + confirmButton, + onClose, + shouldConfirm = false, + title, +}: PropsWithChildren) { + const handleClose = useDiscardConfirm(onClose); + + const closeHandler = shouldConfirm ? handleClose : onClose; + + return ( + + + +

{title}

+
+
+ {children} + + + + {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.cancel', + { defaultMessage: 'Cancel' } + )} + + {confirmButton} + + +
+ ); +} diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_outcome_preview.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_outcome_preview.tsx new file mode 100644 index 0000000000000..45e47157dd69a --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_outcome_preview.tsx @@ -0,0 +1,459 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect, useMemo, useState } from 'react'; +import { useDateRange } from '@kbn/observability-utils-browser/hooks/use_date_range'; +import { + EuiPanel, + EuiTitle, + EuiSpacer, + EuiFlexGroup, + EuiFilterButton, + EuiFilterGroup, + EuiEmptyPrompt, + EuiLoadingLogo, + EuiButton, + EuiFormRow, + EuiSuperSelectOption, + EuiSuperSelect, + useEuiTheme, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { TimeRange } from '@kbn/es-query'; +import { isEmpty } from 'lodash'; +import { FieldIcon } from '@kbn/react-field'; +import { + FIELD_DEFINITION_TYPES, + ReadStreamDefinition, + isWiredReadStream, +} from '@kbn/streams-schema'; +import { useController, useFieldArray } from 'react-hook-form'; +import { css } from '@emotion/react'; +import { flattenObject } from '@kbn/object-utils'; +import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; +import { useStreamsAppFetch } from '../../../hooks/use_streams_app_fetch'; +import { useKibana } from '../../../hooks/use_kibana'; +import { StreamsAppSearchBar, StreamsAppSearchBarProps } from '../../streams_app_search_bar'; +import { PreviewTable } from '../../preview_table'; +import { convertFormStateToProcessing, isCompleteProcessingDefinition } from '../utils'; +import { DetectedField, ProcessorFormState } from '../types'; + +interface ProcessorOutcomePreviewProps { + definition: ReadStreamDefinition; + formFields: ProcessorFormState; +} + +export const ProcessorOutcomePreview = ({ + definition, + formFields, +}: ProcessorOutcomePreviewProps) => { + const { dependencies } = useKibana(); + const { + data, + streams: { streamsRepositoryClient }, + } = dependencies.start; + + const { + timeRange, + absoluteTimeRange: { start, end }, + setTimeRange, + } = useDateRange({ data }); + + const [selectedDocsFilter, setSelectedDocsFilter] = + useState('outcome_filter_all'); + + const { + value: samples, + loading: isLoadingSamples, + refresh: refreshSamples, + } = useStreamsAppFetch( + ({ signal }) => { + if (!definition || !formFields.field) { + return { documents: [] }; + } + + return streamsRepositoryClient.fetch('POST /api/streams/{id}/_sample', { + signal, + params: { + path: { id: definition.name }, + body: { + condition: { field: formFields.field, operator: 'exists' }, + start: start?.valueOf(), + end: end?.valueOf(), + number: 100, + }, + }, + }); + }, + [definition, formFields.field, streamsRepositoryClient, start, end], + { disableToastOnError: true } + ); + + const { + value: simulation, + loading: isLoadingSimulation, + error, + refresh: refreshSimulation, + } = useStreamsAppFetch( + async ({ signal }) => { + if (!definition || !samples || isEmpty(samples.documents)) { + return Promise.resolve(null); + } + + const processingDefinition = convertFormStateToProcessing(formFields); + + if (!isCompleteProcessingDefinition(processingDefinition)) { + return Promise.resolve(null); + } + + const simulationResult = await streamsRepositoryClient.fetch( + 'POST /api/streams/{id}/processing/_simulate', + { + signal, + params: { + path: { id: definition.name }, + body: { + documents: samples.documents as Array>, + processing: [processingDefinition], + }, + }, + } + ); + + return simulationResult; + }, + [definition, samples, streamsRepositoryClient], + { disableToastOnError: true } + ); + + const simulationError = error as IHttpFetchError | undefined; + + const simulationDocuments = useMemo(() => { + if (!simulation?.documents) { + const docs = (samples?.documents ?? []) as Array>; + return docs.map((doc) => flattenObject(doc)); + } + + const filterDocuments = (filter: DocsFilterOption) => { + switch (filter) { + case 'outcome_filter_matched': + return simulation.documents.filter((doc) => doc.isMatch); + case 'outcome_filter_unmatched': + return simulation.documents.filter((doc) => !doc.isMatch); + case 'outcome_filter_all': + default: + return simulation.documents; + } + }; + + return filterDocuments(selectedDocsFilter).map((doc) => doc.value); + }, [samples?.documents, simulation?.documents, selectedDocsFilter]); + + const detectedFieldsColumns = simulation?.detected_fields + ? simulation.detected_fields.map((field) => field.name) + : []; + + const detectedFieldsEnabled = + isWiredReadStream(definition) && simulation && !isEmpty(simulation.detected_fields); + + return ( + + + +

+ {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.outcomeTitle', + { defaultMessage: 'Outcome' } + )} +

+
+ + {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.runSimulation', + { defaultMessage: 'Run simulation' } + )} + +
+ + {detectedFieldsEnabled && } + + + +
+ ); +}; + +const docsFilterOptions = { + outcome_filter_all: { + id: 'outcome_filter_all', + label: i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.outcomeControls.all', + { defaultMessage: 'All samples' } + ), + }, + outcome_filter_matched: { + id: 'outcome_filter_matched', + label: i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.outcomeControls.matched', + { defaultMessage: 'Matched' } + ), + }, + outcome_filter_unmatched: { + id: 'outcome_filter_unmatched', + label: i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.outcomeControls.unmatched', + { defaultMessage: 'Unmatched' } + ), + }, +} as const; + +type DocsFilterOption = keyof typeof docsFilterOptions; + +interface OutcomeControlsProps { + docsFilter: DocsFilterOption; + timeRange: TimeRange; + onDocsFilterChange: (filter: DocsFilterOption) => void; + onTimeRangeChange: (timeRange: TimeRange) => void; + onTimeRangeRefresh: () => void; + simulationFailureRate?: number; + simulationSuccessRate?: number; +} + +const OutcomeControls = ({ + docsFilter, + timeRange, + onDocsFilterChange, + onTimeRangeChange, + onTimeRangeRefresh, + simulationFailureRate, + simulationSuccessRate, +}: OutcomeControlsProps) => { + const handleQuerySubmit: StreamsAppSearchBarProps['onQuerySubmit'] = ( + { dateRange }, + isUpdate + ) => { + if (!isUpdate) { + return onTimeRangeRefresh(); + } + + if (dateRange) { + onTimeRangeChange({ + from: dateRange.from, + to: dateRange?.to, + mode: dateRange.mode, + }); + } + }; + + return ( + + + onDocsFilterChange(docsFilterOptions.outcome_filter_all.id)} + > + {docsFilterOptions.outcome_filter_all.label} + + onDocsFilterChange(docsFilterOptions.outcome_filter_matched.id)} + badgeColor="success" + numActiveFilters={ + simulationSuccessRate ? parseFloat((simulationSuccessRate * 100).toFixed(2)) : undefined + } + > + {docsFilterOptions.outcome_filter_matched.label} + + onDocsFilterChange(docsFilterOptions.outcome_filter_unmatched.id)} + badgeColor="accent" + numActiveFilters={ + simulationFailureRate ? parseFloat((simulationFailureRate * 100).toFixed(2)) : undefined + } + > + {docsFilterOptions.outcome_filter_unmatched.label} + + + + + ); +}; + +const DetectedFields = ({ detectedFields }: { detectedFields: DetectedField[] }) => { + const { euiTheme } = useEuiTheme(); + const { fields, replace } = useFieldArray<{ detected_fields: DetectedField[] }>({ + name: 'detected_fields', + }); + + useEffect(() => { + replace(detectedFields); + }, [detectedFields, replace]); + + return ( + + + {fields.map((field, id) => ( + + ))} + + + ); +}; + +const DetectedFieldSelector = ({ selectorId }: { selectorId: string }) => { + const { field } = useController({ name: selectorId }); + + const options = useMemo(() => getDetectedFieldSelectOptions(field.value), [field]); + + return ( + field.onChange({ ...field.value, type })} + css={css` + min-inline-size: 180px; + `} + /> + ); +}; + +const getDetectedFieldSelectOptions = ( + fieldValue: DetectedField +): Array> => + [...FIELD_DEFINITION_TYPES, 'unmapped'].map((type) => ({ + value: type, + inputDisplay: ( + + + {fieldValue.name} + + ), + dropdownDisplay: ( + + + {type} + + ), + })); + +interface OutcomePreviewTableProps { + documents?: Array>; + columns: string[]; + error?: IHttpFetchError; + isLoading?: boolean; +} + +const OutcomePreviewTable = ({ + documents = [], + columns, + error, + isLoading, +}: OutcomePreviewTableProps) => { + if (error) { + return ( + + {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.outcomePreviewTable.errorTitle', + { defaultMessage: 'Unable to display the simulation outcome for this processor.' } + )} + + } + body={ + <> +

+ {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.outcomePreviewTable.errorBody', + { defaultMessage: 'The processor did not run correctly.' } + )} +

+ {error.body?.message ?

{error.body.message}

: null} + + } + /> + ); + } + + if (isLoading) { + return ( + } + title={ +

+ {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.outcomePreviewTable.loadingTitle', + { defaultMessage: 'Running processor simulation' } + )} +

+ } + /> + ); + } + + if (documents?.length === 0) { + return ( + + {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.outcomePreviewTable.noDataTitle', + { + defaultMessage: + 'There are no simulation outcome documents for the current selection.', + } + )} +

+ } + /> + ); + } + + return ; +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_type_selector.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_type_selector.tsx new file mode 100644 index 0000000000000..9f464c3f33319 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/processor_type_selector.tsx @@ -0,0 +1,108 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiLink, EuiFormRow, EuiSuperSelect, EuiSuperSelectProps } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useController, useFormContext, useWatch } from 'react-hook-form'; +import { ProcessorType } from '@kbn/streams-schema'; +import { useKibana } from '../../../hooks/use_kibana'; +import { getDefaultFormState } from '../utils'; + +interface TAvailableProcessor { + value: ProcessorType; + inputDisplay: string; + getDocUrl: (esDocUrl: string) => React.ReactNode; +} + +type TAvailableProcessors = Record; + +export const ProcessorTypeSelector = ({ + disabled = false, +}: Pick) => { + const { core } = useKibana(); + const esDocUrl = core.docLinks.links.elasticsearch.docsBase; + + const { control, reset } = useFormContext(); + const { field, fieldState } = useController({ name: 'type', control, rules: { required: true } }); + + const processorType = useWatch<{ type: ProcessorType }>({ name: 'type' }); + + const handleChange = (type: ProcessorType) => { + const formState = getDefaultFormState(type); + reset(formState); + }; + + return ( + + + + ); +}; + +const availableProcessors: TAvailableProcessors = { + dissect: { + value: 'dissect', + inputDisplay: 'Dissect', + getDocUrl: (esDocUrl: string) => ( + + dissect + + ), + }} + /> + ), + }, + grok: { + value: 'grok', + inputDisplay: 'Grok', + getDocUrl: (esDocUrl: string) => ( + + grok + + ), + }} + /> + ), + }, +}; + +const getProcessorDescription = (esDocUrl: string) => (type: ProcessorType) => + availableProcessors[type].getDocUrl(esDocUrl); + +const processorTypeSelectorOptions = Object.values(availableProcessors).map( + ({ value, inputDisplay }) => ({ value, inputDisplay }) +); diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/toggle_field.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/toggle_field.tsx new file mode 100644 index 0000000000000..885934dc48933 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/flyout/toggle_field.tsx @@ -0,0 +1,40 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { useController } from 'react-hook-form'; +import { EuiFormRow, EuiSwitch, htmlIdGenerator } from '@elastic/eui'; + +interface ToggleFieldProps { + helpText?: string; + id?: string; + label: string; + name: string; +} + +export const ToggleField = ({ + helpText, + id = createId(), + label, + name, + ...rest +}: ToggleFieldProps) => { + const { field } = useController({ name }); + + return ( + + field.onChange(e.target.checked)} + /> + + ); +}; + +const createId = htmlIdGenerator(); diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/hooks/use_definition.ts b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/hooks/use_definition.ts new file mode 100644 index 0000000000000..d5ca191bfb16a --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/hooks/use_definition.ts @@ -0,0 +1,162 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useState, useMemo, useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; +import { useAbortController } from '@kbn/observability-utils-browser/hooks/use_abort_controller'; +import { useBoolean } from '@kbn/react-hooks'; +import { + ReadStreamDefinition, + ProcessingDefinition, + isWiredReadStream, + FieldDefinition, + WiredReadStreamDefinition, +} from '@kbn/streams-schema'; +import { htmlIdGenerator } from '@elastic/eui'; +import { isEqual } from 'lodash'; +import { DetectedField, ProcessorDefinition } from '../types'; +import { useKibana } from '../../../hooks/use_kibana'; + +export const useDefinition = (definition: ReadStreamDefinition, refreshDefinition: () => void) => { + const { core, dependencies } = useKibana(); + + const { toasts } = core.notifications; + const { processing } = definition.stream.ingest; + const { streamsRepositoryClient } = dependencies.start.streams; + + const abortController = useAbortController(); + const [isSavingChanges, { on: startsSaving, off: endsSaving }] = useBoolean(); + + const [processors, setProcessors] = useState(() => createProcessorsList(processing)); + const [fields, setFields] = useState(() => + isWiredReadStream(definition) ? definition.stream.ingest.wired.fields : {} + ); + + const httpProcessing = useMemo(() => processors.map(removeIdFromProcessor), [processors]); + + useEffect(() => { + // Reset processors when definition refreshes + setProcessors(createProcessorsList(definition.stream.ingest.processing)); + }, [definition]); + + const hasChanges = useMemo( + () => !isEqual(processing, httpProcessing), + [processing, httpProcessing] + ); + + const addProcessor = (newProcessing: ProcessingDefinition, newFields?: DetectedField[]) => { + setProcessors((prevProcs) => prevProcs.concat(createProcessorWithId(newProcessing))); + + if (isWiredReadStream(definition) && newFields) { + setFields((currentFields) => mergeFields(definition, currentFields, newFields)); + } + }; + + const updateProcessor = (id: string, processorUpdate: ProcessorDefinition) => { + setProcessors((prevProcs) => + prevProcs.map((proc) => (proc.id === id ? processorUpdate : proc)) + ); + }; + + const deleteProcessor = (id: string) => { + setProcessors((prevProcs) => prevProcs.filter((proc) => proc.id !== id)); + }; + + const resetChanges = () => { + setProcessors(createProcessorsList(processing)); + setFields(isWiredReadStream(definition) ? definition.stream.ingest.wired.fields : {}); + }; + + const saveChanges = async () => { + startsSaving(); + try { + await streamsRepositoryClient.fetch(`PUT /api/streams/{id}`, { + signal: abortController.signal, + params: { + path: { + id: definition.name, + }, + body: { + ingest: { + ...definition.stream.ingest, + processing: httpProcessing, + ...(isWiredReadStream(definition) && { wired: { fields } }), + }, + }, + }, + }); + + toasts.addSuccess( + i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.saveChangesSuccess', + { defaultMessage: "Stream's processors updated" } + ) + ); + } catch (error) { + toasts.addError(error, { + title: i18n.translate( + 'xpack.streams.streamDetailView.managementTab.enrichment.saveChangesError', + { defaultMessage: "An issue occurred saving processors' changes." } + ), + toastMessage: error.body.message, + }); + } finally { + await refreshDefinition(); + endsSaving(); + } + }; + + return { + // Values + processors, + // Actions + addProcessor, + updateProcessor, + deleteProcessor, + resetChanges, + saveChanges, + setProcessors, + // Flags + hasChanges, + isSavingChanges, + }; +}; + +const createId = htmlIdGenerator(); +const createProcessorsList = (processors: ProcessingDefinition[]): ProcessorDefinition[] => + processors.map(createProcessorWithId); + +const createProcessorWithId = (processor: ProcessingDefinition): ProcessorDefinition => ({ + ...processor, + id: createId(), +}); + +const removeIdFromProcessor = (processor: ProcessorDefinition): ProcessingDefinition => { + const { id, ...rest } = processor; + return rest; +}; + +const mergeFields = ( + definition: WiredReadStreamDefinition, + currentFields: FieldDefinition, + newFields: DetectedField[] +) => { + return { + ...definition.stream.ingest.wired.fields, + ...newFields.reduce((acc, field) => { + // Add only new fields and ignore unmapped ones + if ( + !(field.name in currentFields) && + !(field.name in definition.inherited_fields) && + field.type !== 'unmapped' + ) { + acc[field.name] = { type: field.type }; + } + return acc; + }, {} as FieldDefinition), + }; +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/index.tsx new file mode 100644 index 0000000000000..c0f5644eb1320 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/index.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { dynamic } from '@kbn/shared-ux-utility'; +import { ReadStreamDefinition } from '@kbn/streams-schema'; + +const StreamDetailEnrichmentContent = dynamic(() => + import(/* webpackChunkName: "management_enrichment" */ './page_content').then((mod) => ({ + default: mod.StreamDetailEnrichmentContent, + })) +); + +interface StreamDetailEnrichmentProps { + definition?: ReadStreamDefinition; + refreshDefinition: () => void; +} + +export function StreamDetailEnrichment({ + definition, + refreshDefinition, +}: StreamDetailEnrichmentProps) { + if (!definition) return null; + + return ( + + ); +} diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/page_content.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/page_content.tsx new file mode 100644 index 0000000000000..6ded439d24385 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/page_content.tsx @@ -0,0 +1,157 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect } from 'react'; +import { + DragDropContextProps, + EuiPanel, + EuiSpacer, + EuiText, + EuiTitle, + euiDragDropReorder, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { ReadStreamDefinition, isRootStream } from '@kbn/streams-schema'; +import { useBoolean } from '@kbn/react-hooks'; +import { useUnsavedChangesPrompt } from '@kbn/unsaved-changes-prompt'; +import { EnrichmentEmptyPrompt } from './enrichment_empty_prompt'; +import { AddProcessorButton } from './add_processor_button'; +import { AddProcessorFlyout } from './flyout'; +import { DraggableProcessorListItem } from './processors_list'; +import { ManagementBottomBar } from '../management_bottom_bar'; +import { SortableList } from './sortable_list'; +import { useDefinition } from './hooks/use_definition'; +import { useKibana } from '../../hooks/use_kibana'; +import { RootStreamEmptyPrompt } from './root_stream_empty_prompt'; + +interface StreamDetailEnrichmentContentProps { + definition: ReadStreamDefinition; + refreshDefinition: () => void; +} + +export function StreamDetailEnrichmentContent({ + definition, + refreshDefinition, +}: StreamDetailEnrichmentContentProps) { + const { appParams, core } = useKibana(); + + const [isBottomBarOpen, { on: openBottomBar, off: closeBottomBar }] = useBoolean(); + const [isAddProcessorOpen, { on: openAddProcessor, off: closeAddProcessor }] = useBoolean(); + + const { + processors, + addProcessor, + updateProcessor, + deleteProcessor, + resetChanges, + saveChanges, + setProcessors, + hasChanges, + isSavingChanges, + } = useDefinition(definition, refreshDefinition); + + const handlerItemDrag: DragDropContextProps['onDragEnd'] = ({ source, destination }) => { + if (source && destination) { + const items = euiDragDropReorder(processors, source.index, destination.index); + setProcessors(items); + } + }; + + useEffect(() => { + if (hasChanges) openBottomBar(); + else closeBottomBar(); + }, [closeBottomBar, hasChanges, openBottomBar]); + + useUnsavedChangesPrompt({ + hasUnsavedChanges: hasChanges, + history: appParams.history, + http: core.http, + navigateToUrl: core.application.navigateToUrl, + openConfirm: core.overlays.openConfirm, + }); + + const handleSaveChanges = async () => { + await saveChanges(); + closeBottomBar(); + }; + + const handleDiscardChanges = async () => { + await resetChanges(); + closeBottomBar(); + }; + + const bottomBar = isBottomBarOpen && ( + + ); + + const addProcessorFlyout = isAddProcessorOpen && ( + + ); + + const hasProcessors = processors.length > 0; + + if (isRootStream(definition)) { + return ; + } + + return ( + <> + {hasProcessors ? ( + + + + + {processors.map((processor, idx) => ( + + ))} + + + + + ) : ( + + )} + {addProcessorFlyout} + {bottomBar} + + ); +} + +const ProcessorsHeader = () => { + return ( + <> + +

+ {i18n.translate('xpack.streams.streamDetailView.managementTab.enrichment.headingTitle', { + defaultMessage: 'Processors for field extraction', + })} +

+
+ + {i18n.translate('xpack.streams.streamDetailView.managementTab.enrichment.headingSubtitle', { + defaultMessage: + 'Use processors to transform data before indexing. Drag and drop existing processors to update their execution order.', + })} + + + ); +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/processors_list.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/processors_list.tsx new file mode 100644 index 0000000000000..946a78a80f041 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/processors_list.tsx @@ -0,0 +1,114 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { + EuiDraggable, + EuiPanelProps, + EuiPanel, + EuiFlexGroup, + EuiIcon, + EuiText, + EuiFlexItem, + EuiButtonIcon, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { getProcessorType, isDissectProcessor, isGrokProcessor } from '@kbn/streams-schema'; +import { useBoolean } from '@kbn/react-hooks'; +import { css } from '@emotion/react'; +import { EditProcessorFlyout, EditProcessorFlyoutProps } from './flyout'; +import { ProcessorDefinition } from './types'; + +export const DraggableProcessorListItem = ({ + processor, + idx, + ...props +}: Omit & { idx: number }) => ( + + {(_provided, state) => ( + + )} + +); + +interface ProcessorListItemProps { + processor: ProcessorDefinition; + hasShadow: EuiPanelProps['hasShadow']; + onUpdateProcessor: EditProcessorFlyoutProps['onUpdateProcessor']; + onDeleteProcessor: EditProcessorFlyoutProps['onDeleteProcessor']; +} + +const ProcessorListItem = ({ + processor, + hasShadow = false, + onUpdateProcessor, + onDeleteProcessor, +}: ProcessorListItemProps) => { + const [isEditProcessorOpen, { on: openEditProcessor, off: closeEditProcessor }] = useBoolean(); + + const type = getProcessorType(processor); + const description = getProcessorDescription(processor); + + return ( + + + + + {type.toUpperCase()} + + + + {description} + + + + + {isEditProcessorOpen && ( + + )} + + ); +}; + +const getProcessorDescription = (processor: ProcessorDefinition) => { + if (isGrokProcessor(processor.config)) { + return processor.config.grok.patterns.join(' • '); + } else if (isDissectProcessor(processor.config)) { + return processor.config.dissect.pattern; + } + + return ''; +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/root_stream_empty_prompt.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/root_stream_empty_prompt.tsx new file mode 100644 index 0000000000000..6feb38a0e736c --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/root_stream_empty_prompt.tsx @@ -0,0 +1,39 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiEmptyPrompt } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { AssetImage } from '../asset_image'; + +export const RootStreamEmptyPrompt = () => { + return ( + } + title={ +

+ {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.rootStreamEmptyPrompt.title', + { defaultMessage: 'Processing data is not allowed for root streams.' } + )} +

+ } + body={ +

+ {i18n.translate( + 'xpack.streams.streamDetailView.managementTab.rootStreamEmptyPrompt.body', + { + defaultMessage: + 'Root streams are selectively immutable and cannot be enriched with processors. To enrich data, reroute a new child stream and add processors to it.', + } + )} +

+ } + /> + ); +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/sortable_list.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/sortable_list.tsx new file mode 100644 index 0000000000000..4847359cec734 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/sortable_list.tsx @@ -0,0 +1,38 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { + DragDropContextProps, + EuiDroppableProps, + EuiDragDropContext, + EuiDroppable, + useEuiTheme, +} from '@elastic/eui'; +import { css } from '@emotion/react'; + +interface SortableListProps { + onDragItem: DragDropContextProps['onDragEnd']; + children: EuiDroppableProps['children']; +} + +export const SortableList = ({ onDragItem, children }: SortableListProps) => { + const { euiTheme } = useEuiTheme(); + + return ( + + + {children} + + + ); +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/types.ts b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/types.ts new file mode 100644 index 0000000000000..6e97f585ed35d --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/types.ts @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + DissectProcessingDefinition, + FieldDefinitionConfig, + GrokProcessingDefinition, + ProcessingDefinition, +} from '@kbn/streams-schema'; + +export interface ProcessorDefinition extends ProcessingDefinition { + id: string; +} + +export interface ProcessingDefinitionGrok extends Pick { + config: GrokProcessingDefinition; +} + +export interface ProcessingDefinitionDissect extends Pick { + config: DissectProcessingDefinition; +} + +interface BaseFormState extends Pick { + detected_fields?: DetectedField[]; +} + +export type GrokFormState = BaseFormState & + Omit & { + type: 'grok'; + patterns: Array<{ value: string }>; + }; + +export type DissectFormState = DissectProcessingDefinition['dissect'] & + BaseFormState & { type: 'dissect' }; + +export type ProcessorFormState = GrokFormState | DissectFormState; + +export interface DetectedField { + name: string; + type: FieldDefinitionConfig['type'] | 'unmapped'; +} diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/utils.ts b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/utils.ts new file mode 100644 index 0000000000000..52e995a8619d2 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_enrichment/utils.ts @@ -0,0 +1,137 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + DissectProcessingDefinition, + GrokProcessingDefinition, + ProcessingDefinition, + ProcessorType, + isCompleteCondition, + isDissectProcessor, + isGrokProcessor, +} from '@kbn/streams-schema'; +import { isEmpty } from 'lodash'; +import { DissectFormState, GrokFormState, ProcessorDefinition, ProcessorFormState } from './types'; + +const defaultCondition: ProcessingDefinition['condition'] = { + field: '', + operator: 'eq', + value: '', +}; + +const defaultGrokProcessorFormState: GrokFormState = { + type: 'grok', + field: 'message', + patterns: [{ value: '' }], + pattern_definitions: {}, + ignore_failure: true, + ignore_missing: true, + condition: defaultCondition, +}; + +const defaultDissectProcessorFormState: DissectFormState = { + type: 'dissect', + field: 'message', + pattern: '', + ignore_failure: true, + ignore_missing: true, + condition: defaultCondition, +}; + +const defaultProcessorFormStateByType: Record = { + dissect: defaultDissectProcessorFormState, + grok: defaultGrokProcessorFormState, +}; + +export const getDefaultFormState = ( + type: ProcessorType, + processor?: ProcessorDefinition +): ProcessorFormState => { + if (!processor) return defaultProcessorFormStateByType[type]; + + let configValues: ProcessorFormState = defaultProcessorFormStateByType[type]; + + if (isGrokProcessor(processor.config)) { + const { grok } = processor.config; + + configValues = structuredClone({ + ...grok, + type: 'grok', + patterns: grok.patterns.map((pattern) => ({ value: pattern })), + }); + } + + if (isDissectProcessor(processor.config)) { + const { dissect } = processor.config; + + configValues = structuredClone({ + ...dissect, + type: 'dissect', + }); + } + + return { + condition: processor.condition || defaultCondition, + ...configValues, + }; +}; + +export const convertFormStateToProcessing = ( + formState: ProcessorFormState +): ProcessingDefinition => { + if (formState.type === 'grok') { + const { condition, patterns, ...grokConfig } = formState; + + return { + condition: isCompleteCondition(condition) ? condition : undefined, + config: { + grok: { + patterns: patterns + .filter(({ value }) => value.trim().length > 0) + .map(({ value }) => value), + ...grokConfig, + }, + }, + }; + } + + if (formState.type === 'dissect') { + const { condition, ...dissectConfig } = formState; + + return { + condition: isCompleteCondition(condition) ? condition : undefined, + config: { + dissect: dissectConfig, + }, + }; + } + + throw new Error('Cannot convert form state to processing: unknown type.'); +}; + +export const isCompleteGrokDefinition = (processing: GrokProcessingDefinition) => { + const { patterns } = processing.grok; + + return !isEmpty(patterns); +}; + +export const isCompleteDissectDefinition = (processing: DissectProcessingDefinition) => { + const { pattern } = processing.dissect; + + return !isEmpty(pattern); +}; + +export const isCompleteProcessingDefinition = (processing: ProcessingDefinition) => { + if (isGrokProcessor(processing.config)) { + return isCompleteGrokDefinition(processing.config); + } + if (isDissectProcessor(processing.config)) { + return isCompleteDissectDefinition(processing.config); + } + + return false; +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/classic.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/classic.tsx index 9a7b0869b62f1..9d66083db849a 100644 --- a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/classic.tsx +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/classic.tsx @@ -10,7 +10,7 @@ import { ReadStreamDefinition } from '@kbn/streams-schema'; import { EuiFlexGroup, EuiListGroup, EuiText } from '@elastic/eui'; import { useStreamsAppParams } from '../../hooks/use_streams_app_params'; import { RedirectTo } from '../redirect_to'; -import { StreamDetailEnriching } from '../stream_detail_enriching'; +import { StreamDetailEnrichment } from '../stream_detail_enrichment'; import { useKibana } from '../../hooks/use_kibana'; import { Wrapper } from './wrapper'; @@ -40,9 +40,9 @@ export function ClassicStreamDetailManagement({ }, enrich: { content: ( - + ), - label: i18n.translate('xpack.streams.streamDetailView.enrichingTab', { + label: i18n.translate('xpack.streams.streamDetailView.enrichmentTab', { defaultMessage: 'Extract field', }), }, diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/wired.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/wired.tsx index 8f4586a1d4207..7abf05797cde4 100644 --- a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/wired.tsx +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/wired.tsx @@ -10,7 +10,7 @@ import { WiredReadStreamDefinition } from '@kbn/streams-schema'; import { useStreamsAppParams } from '../../hooks/use_streams_app_params'; import { RedirectTo } from '../redirect_to'; import { StreamDetailRouting } from '../stream_detail_routing'; -import { StreamDetailEnriching } from '../stream_detail_enriching'; +import { StreamDetailEnrichment } from '../stream_detail_enrichment'; import { StreamDetailSchemaEditor } from '../stream_detail_schema_editor'; import { Wrapper } from './wrapper'; @@ -44,9 +44,9 @@ export function WiredStreamDetailManagement({ }, enrich: { content: ( - + ), - label: i18n.translate('xpack.streams.streamDetailView.enrichingTab', { + label: i18n.translate('xpack.streams.streamDetailView.enrichmentTab', { defaultMessage: 'Extract field', }), }, diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/wrapper.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/wrapper.tsx index 92d80924298fc..e6e9d3a6de19c 100644 --- a/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/wrapper.tsx +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/stream_detail_management/wrapper.tsx @@ -23,7 +23,7 @@ export function Wrapper({ return ( - + {previewSampleFetch.loading ? ( diff --git a/x-pack/solutions/observability/plugins/streams_app/public/components/streams_app_search_bar/index.tsx b/x-pack/solutions/observability/plugins/streams_app/public/components/streams_app_search_bar/index.tsx index cd07f540f3ba1..bcb3a9b43e15e 100644 --- a/x-pack/solutions/observability/plugins/streams_app/public/components/streams_app_search_bar/index.tsx +++ b/x-pack/solutions/observability/plugins/streams_app/public/components/streams_app_search_bar/index.tsx @@ -10,7 +10,7 @@ import React, { useMemo } from 'react'; import type { DataView } from '@kbn/data-views-plugin/common'; import { useKibana } from '../../hooks/use_kibana'; -interface Props { +export interface StreamsAppSearchBarProps { query?: string; dateRangeFrom?: string; dateRangeTo?: string; @@ -30,7 +30,7 @@ export function StreamsAppSearchBar({ query, placeholder, dataViews, -}: Props) { +}: StreamsAppSearchBarProps) { const { dependencies: { start: { unifiedSearch }, diff --git a/x-pack/solutions/observability/plugins/streams_app/public/hooks/use_discard_confirm.ts b/x-pack/solutions/observability/plugins/streams_app/public/hooks/use_discard_confirm.ts new file mode 100644 index 0000000000000..8e26e5620a0a9 --- /dev/null +++ b/x-pack/solutions/observability/plugins/streams_app/public/hooks/use_discard_confirm.ts @@ -0,0 +1,35 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { useKibana } from './use_kibana'; + +export const useDiscardConfirm = (handler: () => void) => { + const { core } = useKibana(); + + return async () => { + const hasCancelled = await core.overlays.openConfirm( + i18n.translate('xpack.streams.cancelModal.message', { + defaultMessage: 'Are you sure you want to discard your changes?', + }), + { + buttonColor: 'danger', + title: i18n.translate('xpack.streams.cancelModal.title', { + defaultMessage: 'Discard changes?', + }), + confirmButtonText: i18n.translate('xpack.streams.cancelModal.confirm', { + defaultMessage: 'Discard', + }), + cancelButtonText: i18n.translate('xpack.streams.cancelModal.cancel', { + defaultMessage: 'Keep editing', + }), + } + ); + + if (hasCancelled) handler(); + }; +}; diff --git a/x-pack/solutions/observability/plugins/streams_app/public/hooks/use_kibana.tsx b/x-pack/solutions/observability/plugins/streams_app/public/hooks/use_kibana.tsx index 9c6b23465fb11..7503e6b0f74d0 100644 --- a/x-pack/solutions/observability/plugins/streams_app/public/hooks/use_kibana.tsx +++ b/x-pack/solutions/observability/plugins/streams_app/public/hooks/use_kibana.tsx @@ -5,13 +5,14 @@ * 2.0. */ -import type { CoreStart } from '@kbn/core/public'; +import type { AppMountParameters, CoreStart } from '@kbn/core/public'; import { useMemo } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import type { StreamsAppStartDependencies } from '../types'; import type { StreamsAppServices } from '../services/types'; export interface StreamsAppKibanaContext { + appParams: AppMountParameters; core: CoreStart; dependencies: { start: StreamsAppStartDependencies; @@ -23,9 +24,10 @@ const useTypedKibana = (): StreamsAppKibanaContext => { const context = useKibana>(); return useMemo(() => { - const { dependencies, services, ...core } = context.services; + const { appParams, dependencies, services, ...core } = context.services; return { + appParams, core, dependencies, services, diff --git a/x-pack/solutions/observability/plugins/streams_app/tsconfig.json b/x-pack/solutions/observability/plugins/streams_app/tsconfig.json index ef9abc3a21b51..b1de53dff4ddb 100644 --- a/x-pack/solutions/observability/plugins/streams_app/tsconfig.json +++ b/x-pack/solutions/observability/plugins/streams_app/tsconfig.json @@ -48,5 +48,11 @@ "@kbn/core-notifications-browser", "@kbn/index-lifecycle-management-common-shared", "@kbn/streams-schema", + "@kbn/react-hooks", + "@kbn/i18n-react", + "@kbn/react-field", + "@kbn/shared-ux-utility", + "@kbn/unsaved-changes-prompt", + "@kbn/object-utils" ] } diff --git a/yarn.lock b/yarn.lock index 3bdf5c9e68c2e..072f8db4c9f67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6469,6 +6469,10 @@ version "0.0.0" uid "" +"@kbn/object-utils@link:src/platform/packages/shared/kbn-object-utils": + version "0.0.0" + uid "" + "@kbn/object-versioning-utils@link:src/platform/packages/shared/kbn-object-versioning-utils": version "0.0.0" uid ""