feat: add HoneyToast component for persistent progress notifications (#7902)

## Summary

Add HoneyToast, a persistent bottom-anchored notification component for
long-running task progress, and migrate existing progress dialogs to use
it.

## Changes

- **What**: 
- New `HoneyToast` component with slot-based API, Teleport, transitions,
and accessibility
  - Migrated `ModelImportProgressDialog` to use HoneyToast
- Created `ManagerProgressToast` combining the old Header/Content/Footer
components
- Deleted deprecated `ManagerProgressDialogContent`,
`ManagerProgressHeader`, `ManagerProgressFooter`, and
`useManagerProgressDialogStore`
- Removed no-op
`showManagerProgressDialog`/`toggleManagerProgressDialog` functions
  - Added Storybook stories for HoneyToast and ProgressToastItem

## Review Focus

- HoneyToast component design and slot API
- ManagerProgressToast self-contained state management (auto-shows when
`comfyManagerStore.taskLogs.length > 0`)
- Accessibility attributes on the toast component

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7902-feat-add-HoneyToast-component-for-persistent-progress-notifications-2e26d73d365081c78ae6edc5accb326e)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: sno <snomiao@gmail.com>
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Alexander Brown
2026-01-08 16:49:56 -08:00
committed by GitHub
parent af094ebefc
commit e26e1f0c9e
25 changed files with 1220 additions and 1393 deletions

View File

@@ -25,9 +25,7 @@ import type {
DialogComponentProps,
ShowDialogOptions
} from '@/stores/dialogStore'
import ManagerProgressDialogContent from '@/workbench/extensions/manager/components/ManagerProgressDialogContent.vue'
import ManagerProgressFooter from '@/workbench/extensions/manager/components/ManagerProgressFooter.vue'
import ManagerProgressHeader from '@/workbench/extensions/manager/components/ManagerProgressHeader.vue'
import ManagerDialogContent from '@/workbench/extensions/manager/components/manager/ManagerDialogContent.vue'
import ManagerHeader from '@/workbench/extensions/manager/components/manager/ManagerHeader.vue'
import ImportFailedNodeContent from '@/workbench/extensions/manager/components/manager/ImportFailedNodeContent.vue'
@@ -232,30 +230,6 @@ export const useDialogService = () => {
})
}
function showManagerProgressDialog(options?: {
props?: InstanceType<typeof ManagerProgressDialogContent>['$props']
}) {
return dialogStore.showDialog({
key: 'global-manager-progress-dialog',
component: ManagerProgressDialogContent,
headerComponent: ManagerProgressHeader,
footerComponent: ManagerProgressFooter,
props: options?.props,
priority: 2,
dialogComponentProps: {
closable: false,
modal: false,
position: 'bottom',
pt: {
root: { class: 'w-[80%] max-w-2xl mx-auto border-none' },
content: { class: 'p-0!' },
header: { class: 'p-0! border-none' },
footer: { class: 'p-0! border-none' }
}
}
})
}
/**
* Shows a dialog requiring sign in for API nodes
* @returns Promise that resolves to true if user clicks login, false if cancelled
@@ -443,16 +417,6 @@ export const useDialogService = () => {
}
}
function toggleManagerProgressDialog(
props?: ComponentAttrs<typeof ManagerProgressDialogContent>
) {
if (dialogStore.isDialogOpen('global-manager-progress-dialog')) {
dialogStore.closeDialog({ key: 'global-manager-progress-dialog' })
} else {
showManagerProgressDialog({ props })
}
}
function showLayoutDialog(options: {
key: string
component: Component
@@ -588,7 +552,6 @@ export const useDialogService = () => {
showAboutDialog,
showExecutionErrorDialog,
showManagerDialog,
showManagerProgressDialog,
showApiNodesSignInDialog,
showSignInDialog,
showSubscriptionRequiredDialog,
@@ -599,7 +562,6 @@ export const useDialogService = () => {
showErrorDialog,
confirm,
toggleManagerDialog,
toggleManagerProgressDialog,
showLayoutDialog,
showImportFailedNodeDialog,
showNodeConflictDialog