mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-21 07:14:11 +00:00
Backward compatibility with extension injections on legacy menu bar (#970)
* Compatible to legacy top menu extensions * Rework css * nit
This commit is contained in:
@@ -1,16 +1,23 @@
|
||||
<template>
|
||||
<teleport to=".comfyui-body-top">
|
||||
<div class="top-menubar comfyui-menu" v-if="betaMenuEnabled">
|
||||
<div
|
||||
class="top-menubar comfyui-menu flex items-center"
|
||||
v-show="betaMenuEnabled"
|
||||
>
|
||||
<h1 class="comfyui-logo mx-2">ComfyUI</h1>
|
||||
<Menubar
|
||||
:model="items"
|
||||
class="border-none p-0 bg-transparent"
|
||||
:pt="{
|
||||
rootList: 'gap-0'
|
||||
rootList: 'gap-0 flex-nowrap'
|
||||
}"
|
||||
/>
|
||||
<Divider layout="vertical" class="mx-2" />
|
||||
<WorkflowTabs v-if="workflowTabsPosition === 'Topbar'" />
|
||||
<WorkflowTabs
|
||||
v-if="workflowTabsPosition === 'Topbar'"
|
||||
class="flex-grow"
|
||||
/>
|
||||
<div class="comfyui-menu-right" ref="menuRight"></div>
|
||||
</div>
|
||||
</teleport>
|
||||
</template>
|
||||
@@ -20,8 +27,9 @@ import Menubar from 'primevue/menubar'
|
||||
import Divider from 'primevue/divider'
|
||||
import WorkflowTabs from '@/components/topbar/WorkflowTabs.vue'
|
||||
import { useCoreMenuItemStore } from '@/stores/coreMenuItemStore'
|
||||
import { computed } from 'vue'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useSettingStore } from '@/stores/settingStore'
|
||||
import { app } from '@/scripts/app'
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
const workflowTabsPosition = computed(() =>
|
||||
@@ -32,6 +40,14 @@ const betaMenuEnabled = computed(
|
||||
)
|
||||
const coreMenuItemsStore = useCoreMenuItemStore()
|
||||
const items = coreMenuItemsStore.menuItems
|
||||
|
||||
const menuRight = ref<HTMLDivElement | null>(null)
|
||||
// Menu-right holds legacy topbar elements attached by custom scripts
|
||||
onMounted(() => {
|
||||
if (menuRight.value) {
|
||||
menuRight.value.appendChild(app.menu.element)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -41,13 +57,10 @@ const items = coreMenuItemsStore.menuItems
|
||||
color: var(--fg-color);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 0.8em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
z-index: 1000;
|
||||
order: 0;
|
||||
grid-column: 1/-1;
|
||||
overflow: auto;
|
||||
max-height: 90vh;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,32 +1,31 @@
|
||||
<template>
|
||||
<div class="workflow-tabs">
|
||||
<SelectButton
|
||||
class="select-button-group bg-transparent"
|
||||
:modelValue="selectedWorkflow"
|
||||
@update:modelValue="onWorkflowChange"
|
||||
:options="options"
|
||||
optionLabel="label"
|
||||
dataKey="value"
|
||||
>
|
||||
<template #option="{ option }">
|
||||
<span
|
||||
class="workflow-label text-sm max-w-[150px] truncate inline-block"
|
||||
>{{ option.label }}</span
|
||||
>
|
||||
<div class="relative">
|
||||
<span class="status-indicator" v-if="option.unsaved">•</span>
|
||||
<Button
|
||||
class="close-button p-0 w-auto"
|
||||
icon="pi pi-times"
|
||||
text
|
||||
severity="secondary"
|
||||
size="small"
|
||||
@click.stop="onCloseWorkflow(option)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</SelectButton>
|
||||
</div>
|
||||
<SelectButton
|
||||
class="workflow-tabs bg-transparent flex flex-wrap"
|
||||
:class="props.class"
|
||||
:modelValue="selectedWorkflow"
|
||||
@update:modelValue="onWorkflowChange"
|
||||
:options="options"
|
||||
optionLabel="label"
|
||||
dataKey="value"
|
||||
>
|
||||
<template #option="{ option }">
|
||||
<span
|
||||
class="workflow-label text-sm max-w-[150px] truncate inline-block"
|
||||
>{{ option.label }}</span
|
||||
>
|
||||
<div class="relative">
|
||||
<span class="status-indicator" v-if="option.unsaved">•</span>
|
||||
<Button
|
||||
class="close-button p-0 w-auto"
|
||||
icon="pi pi-times"
|
||||
text
|
||||
severity="secondary"
|
||||
size="small"
|
||||
@click.stop="onCloseWorkflow(option)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</SelectButton>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -37,6 +36,10 @@ import SelectButton from 'primevue/selectbutton'
|
||||
import Button from 'primevue/button'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: string
|
||||
}>()
|
||||
|
||||
const workflowStore = useWorkflowStore()
|
||||
interface WorkflowOption {
|
||||
label: string
|
||||
@@ -79,26 +82,9 @@ const onCloseWorkflow = (option: WorkflowOption) => {
|
||||
const workflow = optionToWorkflow(option)
|
||||
app.workflowManager.closeWorkflow(workflow)
|
||||
}
|
||||
|
||||
// Add this new function to check if a workflow is unsaved
|
||||
const isWorkflowUnsaved = (option: WorkflowOption): boolean => {
|
||||
const workflow = optionToWorkflow(option)
|
||||
return workflow.unsaved
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.select-button-group {
|
||||
/* TODO: Make this dynamic. Take rest of space after all tool buttons */
|
||||
max-width: 70vw;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
|
||||
/* Scrollbar styling */
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(155, 155, 155, 0.5) transparent;
|
||||
}
|
||||
|
||||
:deep(.p-togglebutton::before) {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user