mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
## Summary Add asset browser dialog integration for combo widgets with full animation support and proper state management. (Thank you Claude from saving me me from merge conflict hell on this one.) ## Changes - Widget integration: combo widgets now use AssetBrowserModal for eligible asset types - Dialog animations: added animateHide() for smooth close transitions - Async operations: proper sequencing of widget updates and dialog animations - Service layer: added getAssetsForNodeType() and getAssetDetails() methods - Type safety: comprehensive TypeScript types and error handling - Test coverage: unit tests for all new functionality - Bonus: fixed the hardcoded labels in AssetFilterBar Widget behavior: - Shows asset browser button for eligible widgets when asset API enabled - Handles asset selection with proper callback sequencing - Maintains widget value updates and litegraph notification ## Review Focus I will call out some stuff inline. ## Screenshots https://github.com/user-attachments/assets/9d3a72cf-d2b0-445f-8022-4c49daa04637 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5629-feat-integrate-asset-browser-with-widget-system-2726d73d365081a9a98be9a2307aee0b) by [Unito](https://www.unito.io) --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: GitHub Action <action@github.com>
97 lines
2.8 KiB
TypeScript
97 lines
2.8 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
|
|
import { useAssetBrowserDialog } from '@/platform/assets/composables/useAssetBrowserDialog'
|
|
import { useDialogStore } from '@/stores/dialogStore'
|
|
|
|
// Mock the dialog store
|
|
vi.mock('@/stores/dialogStore')
|
|
|
|
// Mock the asset service
|
|
vi.mock('@/platform/assets/services/assetService', () => ({
|
|
assetService: {
|
|
getAssetsForNodeType: vi.fn().mockResolvedValue([])
|
|
}
|
|
}))
|
|
|
|
// Test factory functions
|
|
interface AssetBrowserProps {
|
|
nodeType: string
|
|
inputName: string
|
|
onAssetSelected?: (filename: string) => void
|
|
}
|
|
|
|
function createAssetBrowserProps(
|
|
overrides: Partial<AssetBrowserProps> = {}
|
|
): AssetBrowserProps {
|
|
return {
|
|
nodeType: 'CheckpointLoaderSimple',
|
|
inputName: 'ckpt_name',
|
|
...overrides
|
|
}
|
|
}
|
|
|
|
describe('useAssetBrowserDialog', () => {
|
|
describe('Asset Selection Flow', () => {
|
|
it('auto-closes dialog when asset is selected', async () => {
|
|
// Create fresh mocks for this test
|
|
const mockShowDialog = vi.fn()
|
|
const mockCloseDialog = vi.fn()
|
|
|
|
vi.mocked(useDialogStore).mockReturnValue({
|
|
showDialog: mockShowDialog,
|
|
closeDialog: mockCloseDialog
|
|
} as Partial<ReturnType<typeof useDialogStore>> as ReturnType<
|
|
typeof useDialogStore
|
|
>)
|
|
|
|
const assetBrowserDialog = useAssetBrowserDialog()
|
|
const onAssetSelected = vi.fn()
|
|
const props = createAssetBrowserProps({ onAssetSelected })
|
|
|
|
await assetBrowserDialog.show(props)
|
|
|
|
// Get the onSelect handler that was passed to the dialog
|
|
const dialogCall = mockShowDialog.mock.calls[0][0]
|
|
const onSelectHandler = dialogCall.props.onSelect
|
|
|
|
// Simulate asset selection
|
|
onSelectHandler('selected-asset-path')
|
|
|
|
// Should call the original callback and trigger hide animation
|
|
expect(onAssetSelected).toHaveBeenCalledWith('selected-asset-path')
|
|
expect(mockCloseDialog).toHaveBeenCalledWith({
|
|
key: 'global-asset-browser'
|
|
})
|
|
})
|
|
|
|
it('closes dialog when close handler is called', async () => {
|
|
// Create fresh mocks for this test
|
|
const mockShowDialog = vi.fn()
|
|
const mockCloseDialog = vi.fn()
|
|
|
|
vi.mocked(useDialogStore).mockReturnValue({
|
|
showDialog: mockShowDialog,
|
|
closeDialog: mockCloseDialog
|
|
} as Partial<ReturnType<typeof useDialogStore>> as ReturnType<
|
|
typeof useDialogStore
|
|
>)
|
|
|
|
const assetBrowserDialog = useAssetBrowserDialog()
|
|
const props = createAssetBrowserProps()
|
|
|
|
await assetBrowserDialog.show(props)
|
|
|
|
// Get the onClose handler that was passed to the dialog
|
|
const dialogCall = mockShowDialog.mock.calls[0][0]
|
|
const onCloseHandler = dialogCall.props.onClose
|
|
|
|
// Simulate dialog close
|
|
onCloseHandler()
|
|
|
|
expect(mockCloseDialog).toHaveBeenCalledWith({
|
|
key: 'global-asset-browser'
|
|
})
|
|
})
|
|
})
|
|
})
|