Skip to content

Commit

Permalink
Adds toast ID to toast api (#3752)
Browse files Browse the repository at this point in the history
* 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:
#2643

Signed-off-by: Ashwin P Chandran <[email protected]>

Co-authored-by: Josh Romero <[email protected]>

---------

Signed-off-by: Ashwin P Chandran <[email protected]>
Co-authored-by: Sean Neumann <[email protected]>
Co-authored-by: Josh Romero <[email protected]>
(cherry picked from commit 14bde2b)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md
  • Loading branch information
github-actions[bot] committed Apr 17, 2023
1 parent 9eb8eb9 commit 9dfdf44
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 7 deletions.
23 changes: 23 additions & 0 deletions src/core/public/notifications/toasts/toasts_api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()', () => {
Expand Down Expand Up @@ -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()', () => {
Expand Down
14 changes: 11 additions & 3 deletions src/core/public/notifications/toasts/toasts_api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,10 @@ import { I18nStart } from '../../i18n';
/**
* Allowed fields for {@link ToastInput}.
*
* @remarks
* `id` cannot be specified.
*
* @public
*/
export type ToastInputFields = Pick<EuiToast, Exclude<keyof EuiToast, 'id' | 'text' | 'title'>> & {
id?: string;
title?: string | MountPoint;
text?: string | MountPoint;
};
Expand Down Expand Up @@ -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'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/vis_builder/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,15 @@ 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
return () => {
unlistenParentHistory();
unmount();
appUnMounted();
unsubscribeStore();
};
},
});
Expand Down

0 comments on commit 9dfdf44

Please sign in to comment.