mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-20 14:54:12 +00:00
Add Popover component,with extra options
Extra options are implemented through commands that seem to not function. Further investigation is needed
This commit is contained in:
69
src/components/ui/Popover.vue
Normal file
69
src/components/ui/Popover.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
PopoverArrow,
|
||||
PopoverContent,
|
||||
PopoverPortal,
|
||||
PopoverRoot,
|
||||
PopoverTrigger
|
||||
} from 'reka-ui'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
|
||||
defineProps<{
|
||||
entries: { label: string; action?: () => void; icon?: string }[][]
|
||||
icon?: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PopoverRoot v-slot="{ close }">
|
||||
<PopoverTrigger as-child>
|
||||
<slot name="button">
|
||||
<Button size="icon">
|
||||
<i :class="icon" />
|
||||
</Button>
|
||||
</slot>
|
||||
</PopoverTrigger>
|
||||
<PopoverPortal>
|
||||
<PopoverContent
|
||||
side="bottom"
|
||||
:side-offset="5"
|
||||
class="rounded-lg p-2 bg-base-background shadow-sm border border-border-subtle will-change-[transform,opacity] data-[state=open]:data-[side=top]:animate-slideDownAndFade data-[state=open]:data-[side=right]:animate-slideLeftAndFade data-[state=open]:data-[side=bottom]:animate-slideUpAndFade data-[state=open]:data-[side=left]:animate-slideRightAndFade"
|
||||
>
|
||||
<slot>
|
||||
<div class="flex flex-col p-1">
|
||||
<entry-group
|
||||
v-for="(entryGroup, index) in entries"
|
||||
:key="index"
|
||||
class="flex flex-col border-b-2 last:border-none border-border-subtle"
|
||||
>
|
||||
<entry-item
|
||||
v-for="{ label, action, icon } in entryGroup"
|
||||
:key="label"
|
||||
:class="
|
||||
cn(
|
||||
'flex flex-row gap-4 p-2 rounded-sm my-1',
|
||||
action &&
|
||||
'cursor-pointer hover:bg-secondary-background-hover'
|
||||
)
|
||||
"
|
||||
@click="
|
||||
() => {
|
||||
if (!action) return
|
||||
action()
|
||||
close()
|
||||
}
|
||||
"
|
||||
>
|
||||
<i v-if="icon" :class="icon" />
|
||||
{{ label }}
|
||||
</entry-item>
|
||||
</entry-group>
|
||||
</div>
|
||||
</slot>
|
||||
<PopoverArrow class="fill-base-background stroke-border-subtle" />
|
||||
</PopoverContent>
|
||||
</PopoverPortal>
|
||||
</PopoverRoot>
|
||||
</template>
|
||||
@@ -13,14 +13,17 @@ import Splitter from 'primevue/splitter'
|
||||
import SplitterPanel from 'primevue/splitterpanel'
|
||||
import { computed, ref, shallowRef, useTemplateRef, watch } from 'vue'
|
||||
|
||||
import { downloadFile } from '@/base/common/downloadUtil'
|
||||
import TopbarBadges from '@/components/topbar/TopbarBadges.vue'
|
||||
import WorkflowTabs from '@/components/topbar/WorkflowTabs.vue'
|
||||
import Popover from '@/components/ui/Popover.vue'
|
||||
import ZoomPane from '@/components/ui/ZoomPane.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { safeWidgetMapper } from '@/composables/graph/useGraphNodeManager'
|
||||
import { d, t } from '@/i18n'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||
import { useMediaAssets } from '@/platform/assets/composables/media/useMediaAssets'
|
||||
import { useMediaAssetActions } from '@/platform/assets/composables/useMediaAssetActions'
|
||||
import { getOutputAssetMetadata } from '@/platform/assets/schemas/assetMetadataSchema'
|
||||
import type { AssetItem } from '@/platform/assets/schemas/assetSchema'
|
||||
import SubscribeToRunButton from '@/platform/cloud/subscription/components/SubscribeToRun.vue'
|
||||
@@ -44,6 +47,7 @@ const commandStore = useCommandStore()
|
||||
const executionStore = useExecutionStore()
|
||||
const outputs = useMediaAssets('output')
|
||||
const nodeOutputStore = useNodeOutputStore()
|
||||
const mediaActions = useMediaAssetActions()
|
||||
const queueStore = useQueueStore()
|
||||
const { isActiveSubscription } = useSubscription()
|
||||
const workflowStore = useWorkflowStore()
|
||||
@@ -398,7 +402,8 @@ function handleCenterWheel(e: WheelEvent) {
|
||||
@wheel.capture="handleCenterWheel"
|
||||
>
|
||||
<linear-output-info
|
||||
class="flex gap-4 text-muted-foreground h-14 w-full items-center"
|
||||
v-if="activeItem"
|
||||
class="flex gap-2 p-1 text-muted-foreground w-full items-center"
|
||||
>
|
||||
<div
|
||||
v-for="({ content, iconClass }, index) in itemStats"
|
||||
@@ -409,24 +414,37 @@ function handleCenterWheel(e: WheelEvent) {
|
||||
{{ content }}
|
||||
</div>
|
||||
<div class="grow" />
|
||||
<Button class="px-4 py-2" @click="rerun">
|
||||
<span>{{ t('Rerun') }}</span
|
||||
><i class="icon-[lucide--refresh-cw]" />
|
||||
<Button size="md" @click="rerun">
|
||||
{{ t('Rerun') }}
|
||||
<i class="icon-[lucide--refresh-cw]" />
|
||||
</Button>
|
||||
<Button
|
||||
class="px-4 py-2"
|
||||
@click="() => loadWorkflow(activeItem, activeLoad)"
|
||||
>
|
||||
<span>{{ t('ReuseParameters') }}</span
|
||||
><i class="icon-[lucide--list-restart]" />
|
||||
<Button size="md" @click="() => loadWorkflow(activeItem, activeLoad)">
|
||||
{{ t('ReuseParameters') }}
|
||||
<i class="icon-[lucide--list-restart]" />
|
||||
</Button>
|
||||
<Divider layout="vertical" />
|
||||
<Button class="px-3 py-2">
|
||||
<Divider layout="vertical" class="mx-1" />
|
||||
<Button size="icon" @click="downloadFile(preview.url)">
|
||||
<i class="icon-[lucide--download]" />
|
||||
</Button>
|
||||
<Button class="px-3 py-2">
|
||||
<i class="icon-[lucide--ellipsis]" />
|
||||
</Button>
|
||||
<Popover
|
||||
:entries="[
|
||||
[
|
||||
{
|
||||
icon: 'icon-[lucide--download]',
|
||||
label: t('DownloadAll'),
|
||||
action: () => mediaActions.downloadAsset(activeItem)
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
icon: 'icon-[lucide--trash-2]',
|
||||
label: t('DeleteAsset'),
|
||||
action: () => mediaActions.confirmDelete(activeItem)
|
||||
}
|
||||
]
|
||||
]"
|
||||
icon="icon-[lucide--ellipsis]"
|
||||
/>
|
||||
</linear-output-info>
|
||||
<ZoomPane
|
||||
v-if="preview?.mediaType === 'images'"
|
||||
|
||||
Reference in New Issue
Block a user