Skip to content

Commit

Permalink
feat: display toasts
Browse files Browse the repository at this point in the history
  • Loading branch information
KatoakDR committed Dec 26, 2024
1 parent 4e17279 commit 150f3ee
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
2 changes: 2 additions & 0 deletions electron/renderer/components/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EuiPageTemplate } from '@elastic/eui';
import type { ReactNode } from 'react';
import { Sidebar } from './sidebar/sidebar.jsx';
import { ToastList } from './toast/toast-list.jsx';

export interface LayoutProps {
/**
Expand Down Expand Up @@ -34,6 +35,7 @@ export const Layout: React.FC<LayoutProps> = (
</EuiPageTemplate.Sidebar>
<EuiPageTemplate.Section paddingSize="none" grow={true}>
{children}
<ToastList />
</EuiPageTemplate.Section>
</EuiPageTemplate>
);
Expand Down
105 changes: 105 additions & 0 deletions electron/renderer/components/toast/toast-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { EuiGlobalToastList } from '@elastic/eui';
import type { EuiIconType } from '@elastic/eui/src/components/icon/icon';
import type { Toast } from '@elastic/eui/src/components/toast/global_toast_list';
import type { ReactNode } from 'react';
import { useState } from 'react';
import { v4 as uuid } from 'uuid';
import { useLogger } from '../../hooks/logger.jsx';
import { useSubscribe } from '../../hooks/pubsub.jsx';

export interface ToastListProps {
/**
* How long the toast should be displayed in milliseconds.
* Default is 5000ms.
*/
toastLifeTimeMs?: number;
}

export interface ToastAddProps {
title: string;
text?: ReactNode;
type?: 'success' | 'warning' | 'danger' | 'info';
}

export const ToastList: React.FC<ToastListProps> = (
props: ToastListProps
): ReactNode => {
const { toastLifeTimeMs = 5000 } = props;

const logger = useLogger('cmp:toast-list');

const [toasts, setToasts] = useState<Array<Toast>>([]);

useSubscribe(['toast:add'], (toastAddProps: ToastAddProps) => {
const { title, text, type } = toastAddProps;

let iconType: EuiIconType | undefined;
let color: Toast['color'] | undefined;

switch (type) {
case 'success':
iconType = 'check';
color = 'success';
break;
case 'warning':
iconType = 'warning';
color = 'warning';
break;
case 'danger':
iconType = 'error';
color = 'danger';
break;
case 'info':
// iconType = 'iInCircle';
color = 'primary';
break;
}

const toast: Toast = {
id: uuid(),
title,
text,
iconType,
color,
};

logger.debug('add toast', {
toast,
});

setToasts((prevToasts) => {
return [...prevToasts, toast];
});
});

// Callback to actually remove the toast from the list.
const onDismissToast = (toastToRemove: Toast) => {
logger.debug('dismiss toast', {
toast: toastToRemove,
});

setToasts((prevToasts) => {
return prevToasts.filter((toast) => {
return toast.id !== toastToRemove.id;
});
});
};

// Callback to notify that the user has cleared all toasts.
// For each toast that was cleared, `onDismissToast` was called already.
// Nothing to actually do here, just log it.
const onClearAllToasts = () => {
logger.debug('clear all toasts');
};

return (
<EuiGlobalToastList
toasts={toasts}
toastLifeTimeMs={toastLifeTimeMs}
dismissToast={onDismissToast}
onClearAllToasts={onClearAllToasts}
/>
);
};

ToastList.displayName = 'ToastList';

0 comments on commit 150f3ee

Please sign in to comment.