mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-21 07:14:11 +00:00
### Motivation - Prevent context-menu actions from operating on stale or non-existent assets when a completed job has no `previewOutput`, since `Inspect asset`, `Add to current workflow`, and `Download` should be inactive in that case. - Also ensure the `Inspect asset` entry is disabled when the optional inspect callback is not provided to avoid unexpected behavior. ### Description - Added an optional `disabled?: boolean` field to the `MenuEntry` type returned by `useJobMenu` and computed `hasPreviewAsset` to detect when `taskRef.previewOutput` is present. - Mark `inspect-asset`, `add-to-current`, and `download` entries as `disabled` when the preview is missing (and also when the inspect callback is missing for `inspect-asset`), and keep `delete` omitted when no preview exists. - Updated `JobContextMenu.vue` to pass `:disabled="entry.disabled"` to the rendered `Button` and to short-circuit the action emit when an entry is disabled. - Expanded `useJobMenu` unit tests to assert enabled states when a preview exists and disabled states when preview or inspect handler is missing. ### Testing - Ran `pnpm vitest src/composables/queue/useJobMenu.test.ts` and all tests passed (36 tests). - Ran `pnpm lint` and the linter reported no warnings or errors. - Ran `pnpm typecheck` (`vue-tsc --noEmit`) and type checking completed without errors. ------ [Codex Task](https://chatgpt.com/codex/tasks/task_e_69864ed56e408330b88c3e9def1b5fb5) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8700-fix-disable-job-asset-actions-when-preview-output-is-missing-2ff6d73d365081b8b72ccadf0ae43e9d) by [Unito](https://www.unito.io)
78 lines
1.9 KiB
Vue
78 lines
1.9 KiB
Vue
<template>
|
|
<Popover
|
|
ref="jobItemPopoverRef"
|
|
:dismissable="true"
|
|
:close-on-escape="true"
|
|
unstyled
|
|
:pt="{
|
|
root: { class: 'absolute z-50' },
|
|
content: {
|
|
class: [
|
|
'bg-transparent border-none p-0 pt-2 rounded-lg shadow-lg font-inter'
|
|
]
|
|
}
|
|
}"
|
|
>
|
|
<div
|
|
class="flex min-w-[14rem] flex-col items-stretch rounded-lg border border-interface-stroke bg-interface-panel-surface px-2 py-3 font-inter"
|
|
>
|
|
<template v-for="entry in entries" :key="entry.key">
|
|
<div v-if="entry.kind === 'divider'" class="px-2 py-1">
|
|
<div class="h-px bg-interface-stroke" />
|
|
</div>
|
|
<Button
|
|
v-else
|
|
class="w-full justify-start bg-transparent"
|
|
variant="textonly"
|
|
size="sm"
|
|
:aria-label="entry.label"
|
|
:disabled="entry.disabled"
|
|
@click="onEntry(entry)"
|
|
>
|
|
<i
|
|
v-if="entry.icon"
|
|
:class="[
|
|
entry.icon,
|
|
'block size-4 shrink-0 leading-none text-text-secondary'
|
|
]"
|
|
/>
|
|
<span>{{ entry.label }}</span>
|
|
</Button>
|
|
</template>
|
|
</div>
|
|
</Popover>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import Popover from 'primevue/popover'
|
|
import { ref } from 'vue'
|
|
|
|
import Button from '@/components/ui/button/Button.vue'
|
|
import type { MenuEntry } from '@/composables/queue/useJobMenu'
|
|
|
|
defineProps<{ entries: MenuEntry[] }>()
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'action', entry: MenuEntry): void
|
|
}>()
|
|
|
|
const jobItemPopoverRef = ref<InstanceType<typeof Popover> | null>(null)
|
|
|
|
function open(event: Event) {
|
|
if (jobItemPopoverRef.value) {
|
|
jobItemPopoverRef.value.toggle(event)
|
|
}
|
|
}
|
|
|
|
function hide() {
|
|
jobItemPopoverRef.value?.hide()
|
|
}
|
|
|
|
function onEntry(entry: MenuEntry) {
|
|
if (entry.kind === 'divider' || entry.disabled) return
|
|
emit('action', entry)
|
|
}
|
|
|
|
defineExpose({ open, hide })
|
|
</script>
|