From 9dfdf447895a07835759e3d2c6d08863f11f29a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 17 Apr 2023 23:03:37 +0000 Subject: [PATCH 1/2] Adds toast ID to toast api (#3752) * Currently sending the same toast multiple times results in multiple toasts being rendered on the screen. This change allows the toast api to additionally accept an id parameter that * Update changelog * Update src/core/public/notifications/toasts/toasts_api.tsx Issue Resolved: https://github.com/opensearch-project/OpenSearch-Dashboards/issues/2643 Signed-off-by: Ashwin P Chandran Co-authored-by: Josh Romero --------- Signed-off-by: Ashwin P Chandran Co-authored-by: Sean Neumann <1413295+seanneumann@users.noreply.github.com> Co-authored-by: Josh Romero (cherry picked from commit 14bde2bba9b338183f117a8e852cbd4ce02c0694) Signed-off-by: github-actions[bot] # Conflicts: # CHANGELOG.md --- .../notifications/toasts/toasts_api.test.ts | 23 +++++++++++++++++++ .../notifications/toasts/toasts_api.tsx | 14 ++++++++--- .../application/components/workspace.tsx | 6 ++++- .../utils/state_management/store.ts | 4 ++-- src/plugins/vis_builder/public/plugin.ts | 3 ++- 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/core/public/notifications/toasts/toasts_api.test.ts b/src/core/public/notifications/toasts/toasts_api.test.ts index ef4f469194d7..dacfa98b623a 100644 --- a/src/core/public/notifications/toasts/toasts_api.test.ts +++ b/src/core/public/notifications/toasts/toasts_api.test.ts @@ -105,6 +105,24 @@ describe('#get$()', () => { toasts.remove('bar'); expect(onToasts).not.toHaveBeenCalled(); }); + + it('does not emit a new toast list when a toast with the same id is passed to add()', () => { + const toasts = new ToastsApi(toastDeps()); + const onToasts = jest.fn(); + + toasts.get$().subscribe(onToasts); + toasts.add({ + id: 'foo', + title: 'foo', + }); + onToasts.mockClear(); + + toasts.add({ + id: 'foo', + title: 'bar', + }); + expect(onToasts).not.toHaveBeenCalled(); + }); }); describe('#add()', () => { @@ -135,6 +153,11 @@ describe('#add()', () => { const toasts = new ToastsApi(toastDeps()); expect(toasts.add('foo')).toHaveProperty('title', 'foo'); }); + + it('accepts an id and does not auto increment', async () => { + const toasts = new ToastsApi(toastDeps()); + expect(toasts.add({ id: 'foo', title: 'not foo' })).toHaveProperty('id', 'foo'); + }); }); describe('#remove()', () => { diff --git a/src/core/public/notifications/toasts/toasts_api.tsx b/src/core/public/notifications/toasts/toasts_api.tsx index 008c4fb3c507..76d0bf9cf9b2 100644 --- a/src/core/public/notifications/toasts/toasts_api.tsx +++ b/src/core/public/notifications/toasts/toasts_api.tsx @@ -42,12 +42,10 @@ import { I18nStart } from '../../i18n'; /** * Allowed fields for {@link ToastInput}. * - * @remarks - * `id` cannot be specified. - * * @public */ export type ToastInputFields = Pick> & { + id?: string; title?: string | MountPoint; text?: string | MountPoint; }; @@ -143,6 +141,16 @@ export class ToastsApi implements IToasts { * @returns a {@link Toast} */ public add(toastOrTitle: ToastInput) { + if (typeof toastOrTitle !== 'string') { + const toastObject = toastOrTitle; + const list = this.toasts$.getValue(); + const existingToast = list.find((toast) => toast.id === toastObject.id); + + if (existingToast) { + return existingToast; + } + } + const toast: Toast = { id: String(this.idCounter++), toastLifeTimeMs: this.uiSettings.get('notifications:lifetime:info'), diff --git a/src/plugins/vis_builder/public/application/components/workspace.tsx b/src/plugins/vis_builder/public/application/components/workspace.tsx index 214a735f6ba8..baccd4faf342 100644 --- a/src/plugins/vis_builder/public/application/components/workspace.tsx +++ b/src/plugins/vis_builder/public/application/components/workspace.tsx @@ -56,7 +56,11 @@ export const WorkspaceUI = () => { const err = schemaValidation.errorMsg || aggValidation.errorMsg; - if (err) toasts.addWarning(err); + if (err) + toasts.addWarning({ + id: 'vb_expression_validation', + title: err, + }); return; } diff --git a/src/plugins/vis_builder/public/application/utils/state_management/store.ts b/src/plugins/vis_builder/public/application/utils/state_management/store.ts index f1b1c0eeae2a..588c221a50fd 100644 --- a/src/plugins/vis_builder/public/application/utils/state_management/store.ts +++ b/src/plugins/vis_builder/public/application/utils/state_management/store.ts @@ -47,9 +47,9 @@ export const getPreloadedStore = async (services: VisBuilderServices) => { }; // the store subscriber will automatically detect changes and call handleChange function - store.subscribe(handleChange); + const unsubscribe = store.subscribe(handleChange); - return store; + return { store, unsubscribe }; }; // Infer the `RootState` and `AppDispatch` types from the store itself diff --git a/src/plugins/vis_builder/public/plugin.ts b/src/plugins/vis_builder/public/plugin.ts index 0c1d569f6bed..5744341ab3cf 100644 --- a/src/plugins/vis_builder/public/plugin.ts +++ b/src/plugins/vis_builder/public/plugin.ts @@ -163,7 +163,7 @@ export class VisBuilderPlugin }; // Instantiate the store - const store = await getPreloadedStore(services); + const { store, unsubscribe: unsubscribeStore } = await getPreloadedStore(services); const unmount = renderApp(params, services, store); // Render the application @@ -171,6 +171,7 @@ export class VisBuilderPlugin unlistenParentHistory(); unmount(); appUnMounted(); + unsubscribeStore(); }; }, }); From 51ae18ce43ca3a851ac4abb2620d4b04b58c13b2 Mon Sep 17 00:00:00 2001 From: Josh Romero Date: Mon, 17 Apr 2023 23:10:19 +0000 Subject: [PATCH 2/2] add changelog Signed-off-by: Josh Romero --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f315e0307624..0d1f11d1d0f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [Monaco editor] Add json worker support ([#3424](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3424)) - [Dashboard] Indicate that IE is no longer supported ([#3641](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3641)) - [Data] Add geo shape filter field ([#3605](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3605)) +- [Notifications] Adds id to toast api for deduplication ([#3752](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3752)) - [UI] Add support for comma delimiters in the global filter bar ([#3686](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3686)) - [VisBuilder] Add UI actions handler ([#3732](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3732))