refactor: actionable toasts (#27203)

This commit is contained in:
Daniel Dietzler
2026-03-26 18:18:06 +01:00
committed by GitHub
parent 4812a2e2d8
commit 389356149a
6 changed files with 24 additions and 91 deletions
-33
View File
@@ -1,33 +0,0 @@
<script lang="ts">
import { Button, ToastContainer, ToastContent, type Color, type IconLike } from '@immich/ui';
type Props = {
onClose?: () => void;
color?: Color;
title: string;
icon?: IconLike | false;
description: string;
button?: {
text: string;
color?: Color;
onClick: () => void;
};
};
const { onClose, title, description, color, icon, button }: Props = $props();
const onClick = () => {
button?.onClick();
onClose?.();
};
</script>
<ToastContainer {color}>
<ToastContent {color} {title} {description} {onClose} {icon}>
{#if button}
<div class="flex justify-end gap-2 px-2 pb-2 me-3 mt-2">
<Button color={button.color ?? 'secondary'} size="small" onclick={onClick}>{button.text}</Button>
</div>
{/if}
</ToastContent>
</ToastContainer>
+5 -23
View File
@@ -1,5 +1,4 @@
import { goto } from '$app/navigation';
import ToastAction from '$lib/components/ToastAction.svelte';
import { authManager } from '$lib/managers/auth-manager.svelte';
import { eventManager } from '$lib/managers/event-manager.svelte';
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
@@ -138,16 +137,8 @@ const notifyAddToAlbum = ($t: MessageFormatter, albumId: string, assetIds: strin
description = $t('assets_were_part_of_album_count', { values: { count: duplicateCount } });
}
toastManager.custom(
{
component: ToastAction,
props: {
title: $t('info'),
color: 'primary',
description,
button: { text: $t('view_album'), color: 'primary', onClick: () => goto(Route.viewAlbum({ id: albumId })) },
},
},
toastManager.primary(
{ description, button: { label: $t('view_album'), onclick: () => goto(Route.viewAlbum({ id: albumId })) } },
{ timeout: 5000 },
);
};
@@ -229,18 +220,9 @@ export const handleUpdateAlbum = async ({ id }: { id: string }, dto: UpdateAlbum
try {
const response = await updateAlbumInfo({ id, updateAlbumDto: dto });
eventManager.emit('AlbumUpdate', response);
toastManager.custom({
component: ToastAction,
props: {
color: 'primary',
title: $t('success'),
description: $t('album_info_updated'),
button: {
text: $t('view_album'),
color: 'primary',
onClick: () => goto(Route.viewAlbum({ id })),
},
},
toastManager.primary({
description: $t('album_info_updated'),
button: { label: $t('view_album'), onclick: () => goto(Route.viewAlbum({ id })) },
});
return true;
+8 -18
View File
@@ -1,4 +1,3 @@
import ToastAction from '$lib/components/ToastAction.svelte';
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
import type { StackResponse } from '$lib/utils/asset-utils';
@@ -32,24 +31,15 @@ export const deleteAssets = async (
await deleteBulk({ assetBulkDeleteDto: { ids, force } });
onAssetDelete(ids);
toastManager.custom(
toastManager.primary(
{
component: ToastAction,
props: {
title: $t('success'),
description: force
? $t('assets_permanently_deleted_count', { values: { count: ids.length } })
: $t('assets_trashed_count', { values: { count: ids.length } }),
color: 'success',
button:
onUndoDelete && !force
? {
color: 'secondary',
text: $t('undo'),
onClick: () => undoDeleteAssets(onUndoDelete, assets),
}
: undefined,
},
description: force
? $t('assets_permanently_deleted_count', { values: { count: ids.length } })
: $t('assets_trashed_count', { values: { count: ids.length } }),
button:
onUndoDelete && !force
? { label: $t('undo'), color: 'secondary', onclick: () => undoDeleteAssets(onUndoDelete, assets) }
: undefined,
},
{ timeout: 5000 },
);
+5 -11
View File
@@ -1,4 +1,3 @@
import ToastAction from '$lib/components/ToastAction.svelte';
import { authManager } from '$lib/managers/auth-manager.svelte';
import { downloadManager } from '$lib/managers/download-manager.svelte';
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
@@ -326,16 +325,11 @@ export const stackAssets = async (assets: { id: string }[], showNotification = t
try {
const stack = await createStack({ stackCreateDto: { assetIds: assets.map(({ id }) => id) } });
if (showNotification) {
toastManager.custom({
component: ToastAction,
props: {
title: $t('success'),
description: $t('stacked_assets_count', { values: { count: stack.assets.length } }),
color: 'success',
button: {
text: $t('view_stack'),
onClick: () => navigate({ targetRoute: 'current', assetId: stack.primaryAssetId }),
},
toastManager.primary({
description: $t('stacked_assets_count', { values: { count: stack.assets.length } }),
button: {
label: $t('view_stack'),
onclick: () => navigate({ targetRoute: 'current', assetId: stack.primaryAssetId }),
},
});
}