[lint] Enable plugin vue recommended rules (#3403)

This commit is contained in:
Chenlei Hu
2025-04-11 12:53:20 -04:00
committed by GitHub
parent dc5d7ea1be
commit a03841cb1a
121 changed files with 691 additions and 668 deletions

View File

@@ -32,7 +32,7 @@ export default [
},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
...pluginVue.configs['flat/essential'],
...pluginVue.configs['flat/recommended'],
{
files: ['src/**/*.vue'],
languageOptions: {

View File

@@ -1,19 +1,19 @@
<template>
<Splitter
:key="activeSidebarTabId ?? undefined"
class="splitter-overlay-root splitter-overlay"
:pt:gutter="sidebarPanelVisible ? '' : 'hidden'"
:key="activeSidebarTabId ?? undefined"
:stateKey="activeSidebarTabId ?? undefined"
stateStorage="local"
:state-key="activeSidebarTabId ?? undefined"
state-storage="local"
>
<SplitterPanel
class="side-bar-panel"
:minSize="10"
:size="20"
v-show="sidebarPanelVisible"
v-if="sidebarLocation === 'left'"
class="side-bar-panel"
:min-size="10"
:size="20"
>
<slot name="side-bar-panel"></slot>
<slot name="side-bar-panel" />
</SplitterPanel>
<SplitterPanel :size="100">
@@ -21,26 +21,26 @@
class="splitter-overlay max-w-full"
layout="vertical"
:pt:gutter="bottomPanelVisible ? '' : 'hidden'"
stateKey="bottom-panel-splitter"
stateStorage="local"
state-key="bottom-panel-splitter"
state-storage="local"
>
<SplitterPanel class="graph-canvas-panel relative">
<slot name="graph-canvas-panel"></slot>
<slot name="graph-canvas-panel" />
</SplitterPanel>
<SplitterPanel class="bottom-panel" v-show="bottomPanelVisible">
<slot name="bottom-panel"></slot>
<SplitterPanel v-show="bottomPanelVisible" class="bottom-panel">
<slot name="bottom-panel" />
</SplitterPanel>
</Splitter>
</SplitterPanel>
<SplitterPanel
class="side-bar-panel"
:minSize="10"
:size="20"
v-show="sidebarPanelVisible"
v-if="sidebarLocation === 'right'"
class="side-bar-panel"
:min-size="10"
:size="20"
>
<slot name="side-bar-panel"></slot>
<slot name="side-bar-panel" />
</SplitterPanel>
</Splitter>
</template>

View File

@@ -5,11 +5,11 @@
:style="positionCSS"
>
<Button
v-tooltip="{ value: $t('menu.showMenu'), showDelay: 300 }"
icon="pi pi-bars"
severity="secondary"
text
size="large"
v-tooltip="{ value: $t('menu.showMenu'), showDelay: 300 }"
:aria-label="$t('menu.showMenu')"
aria-live="assertive"
@click="exitFocusMode"

View File

@@ -1,19 +1,19 @@
<template>
<div
class="batch-count"
v-tooltip.bottom="{
value: $t('menu.batchCount'),
showDelay: 600
}"
class="batch-count"
:aria-label="$t('menu.batchCount')"
>
<InputNumber
class="w-14"
v-model="batchCount"
class="w-14"
:min="minQueueCount"
:max="maxQueueCount"
fluid
showButtons
show-buttons
:pt="{
incrementButton: {
class: 'w-6',

View File

@@ -4,9 +4,8 @@
:style="style"
:class="{ 'is-dragging': isDragging, 'is-docked': isDocked }"
>
<div class="actionbar-content flex items-center select-none" ref="panelRef">
<span class="drag-handle cursor-move mr-2 p-0!" ref="dragHandleRef">
</span>
<div ref="panelRef" class="actionbar-content flex items-center select-none">
<span ref="dragHandleRef" class="drag-handle cursor-move mr-2 p-0!" />
<ComfyQueueButton />
</div>
</Panel>

View File

@@ -1,19 +1,19 @@
<template>
<div class="queue-button-group flex">
<SplitButton
class="comfyui-queue-button"
:label="activeQueueModeMenuItem.label"
severity="primary"
size="small"
@click="queuePrompt"
:model="queueModeMenuItems"
data-testid="queue-button"
v-tooltip.bottom="{
value: workspaceStore.shiftDown
? $t('menu.runWorkflowFront')
: $t('menu.runWorkflow'),
showDelay: 600
}"
class="comfyui-queue-button"
:label="activeQueueModeMenuItem.label"
severity="primary"
size="small"
:model="queueModeMenuItems"
data-testid="queue-button"
@click="queuePrompt"
>
<template #icon>
<i-lucide:list-start v-if="workspaceStore.shiftDown" />
@@ -23,15 +23,15 @@
</template>
<template #item="{ item }">
<Button
v-tooltip="{
value: item.tooltip,
showDelay: 600
}"
:label="String(item.label)"
:icon="item.icon"
:severity="item.key === queueMode ? 'primary' : 'secondary'"
size="small"
text
v-tooltip="{
value: item.tooltip,
showDelay: 600
}"
/>
</template>
</SplitButton>
@@ -48,8 +48,7 @@
text
:aria-label="$t('menu.interrupt')"
@click="() => commandStore.execute('Comfy.Interrupt')"
>
</Button>
/>
<Button
v-tooltip.bottom="{
value: $t('sideToolbar.queueTab.clearPendingTasks'),

View File

@@ -1,7 +1,7 @@
<template>
<div class="relative overflow-hidden h-full w-full bg-black" ref="rootEl">
<div ref="rootEl" class="relative overflow-hidden h-full w-full bg-black">
<div class="p-terminal rounded-none h-full w-full p-2">
<div class="h-full terminal-host" ref="terminalEl"></div>
<div ref="terminalEl" class="h-full terminal-host" />
</div>
</div>
</template>

View File

@@ -1,6 +1,8 @@
<template>
<div class="bg-black h-full w-full">
<p v-if="errorMessage" class="p-4 text-center">{{ errorMessage }}</p>
<p v-if="errorMessage" class="p-4 text-center">
{{ errorMessage }}
</p>
<ProgressSpinner
v-else-if="loading"
class="relative inset-0 flex justify-center items-center h-full z-10"

View File

@@ -5,8 +5,8 @@
<SelectButton
v-model="selectedColorOption"
:options="colorOptionsWithCustom"
optionLabel="name"
dataKey="value"
option-label="name"
data-key="value"
:allow-empty="false"
>
<template #option="slotProps">
@@ -18,8 +18,8 @@
backgroundColor: slotProps.option.value,
borderRadius: '50%'
}"
></div>
<i v-else class="pi pi-palette text-lg"></i>
/>
<i v-else class="pi pi-palette text-lg" />
</template>
</SelectButton>
<ColorPicker

View File

@@ -8,22 +8,22 @@
<img
v-if="contain"
:src="src"
@error="handleImageError"
:data-test="src"
class="comfy-image-blur"
:style="{ 'background-image': `url(${src})` }"
:alt="alt"
@error="handleImageError"
/>
<img
:src="src"
@error="handleImageError"
class="comfy-image-main"
:class="classProp"
:alt="alt"
@error="handleImageError"
/>
</span>
<div v-if="imageBroken" class="broken-image-placeholder">
<i class="pi pi-image"></i>
<i class="pi pi-image" />
<span>{{ $t('g.imageFailedToLoad') }}</span>
</div>
</template>

View File

@@ -1,5 +1,5 @@
<template>
<div ref="container"></div>
<div ref="container" />
</template>
<script setup lang="ts">

View File

@@ -6,14 +6,14 @@
<SelectButton
v-model="selectedIcon"
:options="iconOptions"
optionLabel="name"
dataKey="value"
option-label="name"
data-key="value"
>
<template #option="slotProps">
<i
:class="['pi', slotProps.option.value, 'mr-2']"
:style="{ color: finalColor }"
></i>
/>
</template>
</SelectButton>
</div>
@@ -30,14 +30,14 @@
<Button
:label="$t('g.reset')"
icon="pi pi-refresh"
@click="resetCustomization"
class="p-button-text"
@click="resetCustomization"
/>
<Button
:label="$t('g.confirm')"
icon="pi pi-check"
@click="confirmCustomization"
autofocus
@click="confirmCustomization"
/>
</template>
</Dialog>

View File

@@ -1,7 +1,9 @@
<template>
<div class="grid grid-cols-2 gap-2">
<template v-for="col in deviceColumns" :key="col.field">
<div class="font-medium">{{ col.header }}</div>
<div class="font-medium">
{{ col.header }}
</div>
<div>
{{ formatValue(props.device[col.field], col.field) }}
</div>

View File

@@ -6,19 +6,19 @@
<!-- Avoid double triggering finishEditing event when keyup.enter is triggered -->
<InputText
v-else
ref="inputRef"
v-model:modelValue="inputValue"
v-focus
type="text"
size="small"
fluid
v-model:modelValue="inputValue"
ref="inputRef"
@keyup.enter="blurInputElement"
@click.stop
:pt="{
root: {
onBlur: finishEditing
}
}"
v-focus
@keyup.enter="blurInputElement"
@click.stop
/>
</div>
</template>

View File

@@ -2,7 +2,7 @@
<template>
<div class="flex flex-col">
<div class="flex flex-row items-center gap-2">
<i class="pi pi-check text-green-500" v-if="status === 'completed'" />
<i v-if="status === 'completed'" class="pi pi-check text-green-500" />
<div class="file-info">
<div class="file-details">
<span class="file-type" :title="hint">{{ label }}</span>
@@ -14,20 +14,20 @@
<div class="file-action">
<Button
v-if="status === null || status === 'error'"
class="file-action-button"
:label="$t('g.download') + ' (' + fileSize + ')'"
size="small"
outlined
:disabled="!!props.error"
@click="triggerDownload"
v-if="status === null || status === 'error'"
icon="pi pi-download"
@click="triggerDownload"
/>
</div>
</div>
<div
class="flex flex-row items-center gap-2"
v-if="status === 'in_progress' || status === 'paused'"
class="flex flex-row items-center gap-2"
>
<!-- Temporary fix for issue when % only comes into view only if the progress bar is large enough
https://comfy-organization.slack.com/archives/C07H3GLKDPF/p1731551013385499
@@ -39,36 +39,36 @@
/>
<Button
class="file-action-button"
size="small"
outlined
:disabled="!!props.error"
@click="triggerPauseDownload"
v-if="status === 'in_progress'"
icon="pi pi-pause-circle"
v-tooltip.top="t('electronFileDownload.pause')"
/>
<Button
class="file-action-button"
size="small"
outlined
:disabled="!!props.error"
@click="triggerResumeDownload"
icon="pi pi-pause-circle"
@click="triggerPauseDownload"
/>
<Button
v-if="status === 'paused'"
icon="pi pi-play-circle"
v-tooltip.top="t('electronFileDownload.resume')"
/>
<Button
class="file-action-button"
size="small"
outlined
:disabled="!!props.error"
@click="triggerCancelDownload"
icon="pi pi-play-circle"
@click="triggerResumeDownload"
/>
<Button
v-tooltip.top="t('electronFileDownload.cancel')"
class="file-action-button"
size="small"
outlined
:disabled="!!props.error"
icon="pi pi-times-circle"
severity="danger"
v-tooltip.top="t('electronFileDownload.cancel')"
@click="triggerCancelDownload"
/>
</div>
</div>

View File

@@ -1,5 +1,5 @@
<template>
<component v-if="extension.type === 'vue'" :is="extension.component" />
<component :is="extension.component" v-if="extension.type === 'vue'" />
<div
v-else
:ref="
@@ -11,7 +11,7 @@
)
}
"
></div>
/>
</template>
<script setup lang="ts">

View File

@@ -10,7 +10,7 @@
:src="modelValue"
class="max-w-full max-h-full object-contain"
/>
<i v-else class="pi pi-image text-gray-400 text-xl"></i>
<i v-else class="pi pi-image text-gray-400 text-xl" />
</div>
<div class="flex flex-col gap-2">

View File

@@ -3,26 +3,26 @@
<div class="flex flex-row items-center gap-2">
<div class="form-label flex flex-grow items-center">
<span
:id="`${props.id}-label`"
class="text-muted"
:class="props.labelClass"
:id="`${props.id}-label`"
>
<slot name="name-prefix"></slot>
<slot name="name-prefix" />
{{ props.item.name }}
<i
v-if="props.item.tooltip"
class="pi pi-info-circle bg-transparent"
v-tooltip="props.item.tooltip"
class="pi pi-info-circle bg-transparent"
/>
<slot name="name-suffix"></slot>
<slot name="name-suffix" />
</span>
</div>
<div class="form-input flex justify-end">
<component
:is="markRaw(getFormComponent(props.item))"
:id="props.id"
:aria-labelledby="`${props.id}-label`"
v-model:modelValue="formValue"
:aria-labelledby="`${props.id}-label`"
v-bind="getFormAttrs(props.item)"
/>
</div>

View File

@@ -1,26 +1,26 @@
<template>
<div class="input-knob flex flex-row items-center gap-2">
<Knob
:modelValue="modelValue"
@update:modelValue="updateValue"
:valueTemplate="displayValue"
:model-value="modelValue"
:value-template="displayValue"
class="knob-part"
:class="knobClass"
:min="min"
:max="max"
:step="step"
v-bind="$attrs"
@update:model-value="updateValue"
/>
<InputNumber
:modelValue="modelValue"
@update:modelValue="updateValue"
:model-value="modelValue"
class="input-part"
:max-fraction-digits="3"
:class="inputClass"
:min="min"
:max="max"
:step="step"
:allowEmpty="false"
:allow-empty="false"
@update:model-value="updateValue"
/>
</div>
</template>

View File

@@ -1,25 +1,25 @@
<template>
<div class="input-slider flex flex-row items-center gap-2">
<Slider
:modelValue="modelValue"
@update:modelValue="(value) => updateValue(value as number)"
:model-value="modelValue"
class="slider-part"
:class="sliderClass"
:min="min"
:max="max"
:step="step"
v-bind="$attrs"
@update:model-value="(value) => updateValue(value as number)"
/>
<InputNumber
:modelValue="modelValue"
@update:modelValue="updateValue"
:model-value="modelValue"
class="input-part"
:max-fraction-digits="3"
:class="inputClass"
:min="min"
:max="max"
:step="step"
:allowEmpty="false"
:allow-empty="false"
@update:model-value="updateValue"
/>
</div>
</template>

View File

@@ -3,14 +3,16 @@
<Card>
<template #content>
<div class="flex flex-col items-center">
<i :class="icon" style="font-size: 3rem; margin-bottom: 1rem"></i>
<i :class="icon" style="font-size: 3rem; margin-bottom: 1rem" />
<h3>{{ title }}</h3>
<p class="whitespace-pre-line text-center">{{ message }}</p>
<p class="whitespace-pre-line text-center">
{{ message }}
</p>
<Button
v-if="buttonLabel"
:label="buttonLabel"
@click="$emit('action')"
class="p-button-text"
@click="$emit('action')"
/>
</div>
</template>

View File

@@ -22,7 +22,7 @@
class="p-button-icon pi pi-refresh transition-all"
:class="{ 'opacity-0': active }"
data-pc-section="icon"
></span>
/>
<span class="p-button-label" data-pc-section="label">&nbsp;</span>
<ProgressSpinner v-show="active" class="absolute w-1/2 h-1/2" />
</Button>

View File

@@ -11,9 +11,9 @@
/>
<InputText
class="search-box-input w-full"
@input="handleInput"
:modelValue="modelValue"
:model-value="modelValue"
:placeholder="placeholder"
@input="handleInput"
/>
<InputIcon v-if="!modelValue" :class="icon" />
<Button
@@ -26,8 +26,8 @@
/>
</IconField>
<div
class="search-filters pt-2 flex flex-wrap gap-2"
v-if="filters?.length"
class="search-filters pt-2 flex flex-wrap gap-2"
>
<SearchFilterChip
v-for="filter in filters"

View File

@@ -1,10 +1,14 @@
<template>
<div class="system-stats">
<div class="mb-6">
<h2 class="text-2xl font-semibold mb-4">{{ $t('g.systemInfo') }}</h2>
<h2 class="text-2xl font-semibold mb-4">
{{ $t('g.systemInfo') }}
</h2>
<div class="grid grid-cols-2 gap-2">
<template v-for="col in systemColumns" :key="col.field">
<div class="font-medium">{{ col.header }}</div>
<div class="font-medium">
{{ col.header }}
</div>
<div>{{ formatValue(systemInfo[col.field], col.field) }}</div>
</template>
</div>
@@ -13,7 +17,9 @@
<Divider />
<div>
<h2 class="text-2xl font-semibold mb-4">{{ $t('g.devices') }}</h2>
<h2 class="text-2xl font-semibold mb-4">
{{ $t('g.devices') }}
</h2>
<TabView v-if="props.stats.devices.length > 1">
<TabPanel
v-for="device in props.stats.devices"

View File

@@ -1,11 +1,11 @@
<template>
<Tree
class="tree-explorer py-0 px-2 2xl:px-4"
:class="props.class"
v-model:expandedKeys="expandedKeys"
v-model:selectionKeys="selectionKeys"
class="tree-explorer py-0 px-2 2xl:px-4"
:class="props.class"
:value="renderedRoot.children"
selectionMode="single"
selection-mode="single"
:pt="{
nodeLabel: 'tree-explorer-node-label',
nodeContent: ({ context }) => ({

View File

@@ -1,5 +1,6 @@
<template>
<div
ref="container"
:class="[
'tree-node',
{
@@ -8,17 +9,16 @@
'tree-leaf': props.node.leaf
}
]"
ref="container"
>
<div class="node-content">
<span class="node-label">
<slot name="before-label" :node="props.node"></slot>
<slot name="before-label" :node="props.node" />
<EditableText
:modelValue="node.label"
:isEditing="isEditing"
:model-value="node.label"
:is-editing="isEditing"
@edit="handleRename"
/>
<slot name="after-label" :node="props.node"></slot>
<slot name="after-label" :node="props.node" />
</span>
<Badge
v-if="showNodeBadgeText"
@@ -30,7 +30,7 @@
<div
class="node-actions motion-safe:opacity-0 motion-safe:group-hover/tree-node:opacity-100"
>
<slot name="actions" :node="props.node"></slot>
<slot name="actions" :node="props.node" />
</div>
</div>
</template>

View File

@@ -3,7 +3,7 @@
<div :style="{ height: `${(state.start / cols) * itemHeight}px` }" />
<div :style="gridStyle">
<div v-for="item in renderedItems" :key="item.key" data-virtual-grid-item>
<slot name="item" :item="item"> </slot>
<slot name="item" :item="item" />
</div>
</div>
<div

View File

@@ -13,11 +13,13 @@
>
<template #header>
<component
v-if="item.headerComponent"
:is="item.headerComponent"
v-if="item.headerComponent"
:id="item.key"
/>
<h3 v-else :id="item.key">{{ item.title || ' ' }}</h3>
<h3 v-else :id="item.key">
{{ item.title || ' ' }}
</h3>
</template>
<component
@@ -26,7 +28,7 @@
:maximized="item.dialogComponentProps.maximized"
/>
<template #footer v-if="item.footerComponent">
<template v-if="item.footerComponent" #footer>
<component :is="item.footerComponent" />
</template>
</Dialog>

View File

@@ -2,7 +2,9 @@
<section class="prompt-dialog-content flex flex-col gap-6 m-2 mt-4">
<span>{{ message }}</span>
<ul v-if="itemList?.length" class="pl-4 m-0 flex flex-col gap-2">
<li v-for="item of itemList" :key="item">{{ item }}</li>
<li v-for="item of itemList" :key="item">
{{ item }}
</li>
</ul>
<Message
v-if="hint"
@@ -18,53 +20,53 @@
:label="$t('g.cancel')"
icon="pi pi-undo"
severity="secondary"
@click="onCancel"
autofocus
@click="onCancel"
/>
<Button
v-if="type === 'default'"
:label="$t('g.confirm')"
severity="primary"
@click="onConfirm"
icon="pi pi-check"
@click="onConfirm"
/>
<Button
v-else-if="type === 'delete'"
:label="$t('g.delete')"
severity="danger"
@click="onConfirm"
icon="pi pi-trash"
@click="onConfirm"
/>
<Button
v-else-if="type === 'overwrite'"
:label="$t('g.overwrite')"
severity="warn"
@click="onConfirm"
icon="pi pi-save"
@click="onConfirm"
/>
<template v-else-if="type === 'dirtyClose'">
<Button
:label="$t('g.no')"
severity="secondary"
@click="onDeny"
icon="pi pi-times"
@click="onDeny"
/>
<Button :label="$t('g.save')" @click="onConfirm" icon="pi pi-save" />
<Button :label="$t('g.save')" icon="pi pi-save" @click="onConfirm" />
</template>
<Button
v-else-if="type === 'reinstall'"
:label="$t('desktopMenu.reinstall')"
severity="warn"
@click="onConfirm"
icon="pi pi-eraser"
@click="onConfirm"
/>
<!-- Invalid - just show a close button. -->
<Button
v-else
:label="$t('g.close')"
severity="primary"
@click="onCancel"
icon="pi pi-times"
@click="onCancel"
/>
</div>
</section>

View File

@@ -45,9 +45,9 @@
/>
<div class="flex gap-4 justify-end">
<FindIssueButton
:errorMessage="error.exceptionMessage"
:repoOwner="repoOwner"
:repoName="repoName"
:error-message="error.exceptionMessage"
:repo-owner="repoOwner"
:repo-name="repoName"
/>
<Button
v-if="reportOpen"

View File

@@ -8,7 +8,9 @@
>
<template #header>
<header class="flex flex-col items-center w-full">
<h2 id="issue-report-title" class="text-4xl">{{ title }}</h2>
<h2 id="issue-report-title" class="text-4xl">
{{ title }}
</h2>
<span v-if="subtitle" class="text-muted mt-0">{{ subtitle }}</span>
</header>
</template>

View File

@@ -7,8 +7,8 @@
/>
<ListBox
:options="uniqueNodes"
optionLabel="label"
scrollHeight="100%"
option-label="label"
scroll-height="100%"
class="comfy-missing-nodes"
:pt="{
list: { class: 'border-none' }
@@ -22,16 +22,16 @@
}}</span>
<Button
v-if="slotProps.option.action"
@click="slotProps.option.action.callback"
:label="slotProps.option.action.text"
size="small"
outlined
@click="slotProps.option.action.callback"
/>
</div>
</template>
</ListBox>
<div class="flex justify-end py-3">
<Button label="Open Manager" @click="openManager" size="small" outlined />
<Button label="Open Manager" size="small" outlined @click="openManager" />
</div>
</template>

View File

@@ -4,13 +4,15 @@
<InputText
ref="inputRef"
v-model="inputValue"
autofocus
@keyup.enter="onConfirm"
@focus="selectAllText"
autofocus
/>
<label>{{ message }}</label>
</FloatLabel>
<Button @click="onConfirm">{{ $t('g.confirm') }}</Button>
<Button @click="onConfirm">
{{ $t('g.confirm') }}
</Button>
</div>
</template>

View File

@@ -2,18 +2,18 @@
<div class="settings-container">
<ScrollPanel class="settings-sidebar flex-shrink-0 p-2 w-48 2xl:w-64">
<SearchBox
class="settings-search-box w-full mb-2"
v-model:modelValue="searchQuery"
@search="handleSearch"
class="settings-search-box w-full mb-2"
:placeholder="$t('g.searchSettings') + '...'"
:debounce-time="128"
@search="handleSearch"
/>
<Listbox
v-model="activeCategory"
:options="categories"
optionLabel="translatedLabel"
scrollHeight="100%"
:optionDisabled="
option-label="translatedLabel"
scroll-height="100%"
:option-disabled="
(option: SettingTreeNode) =>
!queryIsEmpty && !searchResultsCategories.has(option.label ?? '')
"
@@ -25,7 +25,7 @@
<Tabs :value="tabValue" :lazy="true" class="settings-content h-full w-full">
<TabPanels class="settings-tab-panels h-full w-full pr-0">
<PanelTemplate value="Search Results">
<SettingsPanel :settingGroups="searchResults" />
<SettingsPanel :setting-groups="searchResults" />
</PanelTemplate>
<PanelTemplate
@@ -38,7 +38,7 @@
<FirstTimeUIMessage v-if="tabValue === 'Comfy'" />
<ColorPaletteMessage v-if="tabValue === 'Appearance'" />
</template>
<SettingsPanel :settingGroups="sortedGroups(category)" />
<SettingsPanel :setting-groups="sortedGroups(category)" />
</PanelTemplate>
<AboutPanel />

View File

@@ -1,11 +1,10 @@
<template>
<Button
@click="openGitHubIssues"
:label="$t('g.findIssues')"
severity="secondary"
icon="pi pi-github"
>
</Button>
@click="openGitHubIssues"
/>
</template>
<script setup lang="ts">

View File

@@ -1,8 +1,8 @@
<template>
<Form
v-slot="$form"
@submit="submit"
:resolver="zodResolver(issueReportSchema)"
@submit="submit"
>
<Panel :pt="$attrs.pt as any">
<template #header>
@@ -33,15 +33,15 @@
>
<Checkbox
v-bind="$field"
:inputId="field.value"
:value="field.value"
v-model="selection"
:input-id="field.value"
:value="field.value"
/>
<label :for="field.value">{{ field.label }}</label>
</FormField>
</div>
</div>
<FormField class="mb-4" v-slot="$field" name="details">
<FormField v-slot="$field" class="mb-4" name="details">
<Textarea
v-bind="$field"
class="w-full"
@@ -83,9 +83,9 @@
>
<Checkbox
v-bind="$field"
:inputId="checkbox.value"
:value="checkbox.value"
v-model="contactPrefs"
:input-id="checkbox.value"
:value="checkbox.value"
:disabled="
$form.contactInfo?.error || !$form.contactInfo?.value
"

View File

@@ -14,8 +14,8 @@
<div class="flex flex-1 relative overflow-hidden">
<ManagerNavSidebar
v-if="isSideNavOpen"
:tabs="tabs"
v-model:selectedTab="selectedTab"
:tabs="tabs"
/>
<div
class="flex-1 overflow-auto pr-80"
@@ -29,7 +29,7 @@
<RegistrySearchBar
v-model:searchQuery="searchQuery"
v-model:searchMode="searchMode"
:searchResults="searchResults"
:search-results="searchResults"
:suggestions="suggestions"
/>
<div class="flex-1 overflow-auto">
@@ -56,16 +56,16 @@
<VirtualGrid
:items="resultsWithKeys"
:buffer-rows="3"
:gridStyle="GRID_STYLE"
:grid-style="GRID_STYLE"
@approach-end="onApproachEnd"
>
<template #item="{ item }">
<PackCard
@click.stop="(event) => selectNodePack(item, event)"
:node-pack="item"
:is-selected="
selectedNodePacks.some((pack) => pack.id === item.id)
"
@click.stop="(event) => selectNodePack(item, event)"
/>
</template>
</VirtualGrid>

View File

@@ -6,8 +6,8 @@
<Listbox
v-model="selectedTab"
:options="tabs"
optionLabel="label"
listStyle="max-height:unset"
option-label="label"
list-style="max-height:unset"
class="w-full border-0 bg-transparent shadow-none"
:pt="{
list: { class: 'p-5' },
@@ -17,7 +17,7 @@
>
<template #option="slotProps">
<div class="text-left flex items-center">
<i :class="['pi', slotProps.option.icon, 'mr-3']"></i>
<i :class="['pi', slotProps.option.icon, 'mr-3']" />
<span class="text-lg">{{ slotProps.option.label }}</span>
</div>
</template>

View File

@@ -10,7 +10,7 @@
<i
class="pi pi-circle-fill mr-1.5 text-[0.6rem] p-0"
:style="{ opacity: 0.8 }"
></i>
/>
{{ $t(`manager.status.${statusLabel}`) }}
</Message>
</template>

View File

@@ -2,8 +2,12 @@
<div class="overflow-hidden">
<Tabs :value="activeTab">
<TabList>
<Tab value="description">{{ $t('g.description') }}</Tab>
<Tab value="nodes">{{ $t('g.nodes') }}</Tab>
<Tab value="description">
{{ $t('g.description') }}
</Tab>
<Tab value="nodes">
{{ $t('g.nodes') }}
</Tab>
</TabList>
<TabPanels class="overflow-auto">
<TabPanel value="description">

View File

@@ -1,7 +1,9 @@
<template>
<div class="flex flex-col gap-4 text-sm">
<div v-for="(section, index) in sections" :key="index" class="mb-4">
<div class="mb-1">{{ section.title }}</div>
<div class="mb-1">
{{ section.title }}
</div>
<div class="text-muted break-words">
<a
v-if="section.isUrl"
@@ -10,10 +12,7 @@
rel="noopener noreferrer"
class="flex items-center gap-2"
>
<i
v-if="isGitHubLink(section.text)"
class="pi pi-github text-base"
></i>
<i v-if="isGitHubLink(section.text)" class="pi pi-github text-base" />
<span class="break-all">{{ section.text }}</span>
</a>
<MarkdownText v-else :text="section.text" class="text-muted" />

View File

@@ -1,6 +1,6 @@
<template>
<div>
<div v-if="!hasMarkdown" v-text="text" class="break-words"></div>
<div v-if="!hasMarkdown" class="break-words" v-text="text" />
<div v-else class="break-words">
<template v-for="(segment, index) in parsedSegments" :key="index">
<a

View File

@@ -4,8 +4,8 @@
<!-- TODO: when registry returns node defs, use them here -->
</div>
<div
v-else
v-for="i in 3"
v-else
:key="i"
class="border border-surface-border rounded-lg p-4"
>

View File

@@ -7,10 +7,8 @@
:placeholder="$t('manager.searchPlaceholder')"
:complete-on-focus="false"
:delay="8"
optionLabel="query"
option-label="query"
class="w-full"
@complete="stubTrue"
@option-select="onOptionSelect"
:pt="{
pcInputText: {
root: {
@@ -22,8 +20,9 @@
style: 'display: none'
}
}"
>
</AutoComplete>
@complete="stubTrue"
@option-select="onOptionSelect"
/>
</div>
<div class="flex mt-3 text-sm">
<div class="flex gap-6 ml-1">

View File

@@ -2,11 +2,10 @@
<div class="flex items-center gap-1">
<span class="text-muted">{{ label }}:</span>
<Dropdown
:modelValue="modelValue"
@update:modelValue="$emit('update:modelValue', $event)"
:model-value="modelValue"
:options="options"
optionLabel="label"
optionValue="id"
option-label="label"
option-value="id"
class="min-w-[6rem] border-none bg-transparent shadow-none"
:pt="{
input: { class: 'py-0 px-1 border-none' },
@@ -14,6 +13,7 @@
panel: { class: 'shadow-md' },
item: { class: 'py-2 px-3 text-sm' }
}"
@update:model-value="$emit('update:modelValue', $event)"
/>
</div>
</template>

View File

@@ -7,52 +7,44 @@
<div class="w-full px-4 py-3 flex justify-between items-center border-b">
<div class="flex items-center">
<div class="w-6 h-6 flex items-center justify-center">
<Skeleton shape="circle" width="1.5rem" height="1.5rem"></Skeleton>
<Skeleton shape="circle" width="1.5rem" height="1.5rem" />
</div>
<Skeleton width="5rem" height="1rem" class="ml-2"></Skeleton>
<Skeleton width="5rem" height="1rem" class="ml-2" />
</div>
<Skeleton width="4rem" height="1.75rem" borderRadius="0.75rem"></Skeleton>
<Skeleton width="4rem" height="1.75rem" border-radius="0.75rem" />
</div>
<!-- Card content with icon on left and text on right -->
<div class="flex-1 p-4 flex">
<!-- Left icon - 64x64 -->
<div class="flex-shrink-0 mr-4">
<Skeleton width="4rem" height="4rem" borderRadius="0.5rem"></Skeleton>
<Skeleton width="4rem" height="4rem" border-radius="0.5rem" />
</div>
<!-- Right content -->
<div class="flex-1 flex flex-col overflow-hidden">
<!-- Title -->
<Skeleton width="80%" height="1rem" class="mb-2"></Skeleton>
<Skeleton width="80%" height="1rem" class="mb-2" />
<!-- Description -->
<div class="mb-3">
<Skeleton width="100%" height="0.75rem" class="mb-1"></Skeleton>
<Skeleton width="95%" height="0.75rem" class="mb-1"></Skeleton>
<Skeleton width="90%" height="0.75rem"></Skeleton>
<Skeleton width="100%" height="0.75rem" class="mb-1" />
<Skeleton width="95%" height="0.75rem" class="mb-1" />
<Skeleton width="90%" height="0.75rem" />
</div>
<!-- Tags/Badges -->
<div class="flex gap-2">
<Skeleton
width="4rem"
height="1.5rem"
borderRadius="0.75rem"
></Skeleton>
<Skeleton
width="5rem"
height="1.5rem"
borderRadius="0.75rem"
></Skeleton>
<Skeleton width="4rem" height="1.5rem" border-radius="0.75rem" />
<Skeleton width="5rem" height="1.5rem" border-radius="0.75rem" />
</div>
</div>
</div>
<!-- Card footer - similar to header -->
<div class="w-full px-5 py-4 flex justify-between items-center border-t">
<Skeleton width="4rem" height="0.8rem"></Skeleton>
<Skeleton width="6rem" height="0.8rem"></Skeleton>
<Skeleton width="4rem" height="0.8rem" />
<Skeleton width="6rem" height="0.8rem" />
</div>
</div>
</template>

View File

@@ -1,6 +1,8 @@
<template>
<PanelTemplate value="About" class="about-container">
<h2 class="text-2xl font-bold mb-2">{{ $t('g.about') }}</h2>
<h2 class="text-2xl font-bold mb-2">
{{ $t('g.about') }}
</h2>
<div class="space-y-2">
<a
v-for="badge in aboutPanelStore.badges"
@@ -13,7 +15,7 @@
>
<Tag class="mr-2">
<template #icon>
<i :class="[badge.icon, 'mr-2 text-xl']"></i>
<i :class="[badge.icon, 'mr-2 text-xl']" />
</template>
{{ badge.label }}
</Tag>

View File

@@ -6,11 +6,11 @@
</div>
<div class="actions">
<Select
class="w-44"
v-model="activePaletteId"
class="w-44"
:options="palettes"
optionLabel="name"
optionValue="id"
option-label="name"
option-value="id"
/>
<Button
icon="pi pi-file-export"
@@ -29,8 +29,8 @@
severity="danger"
text
:title="$t('g.delete')"
@click="colorPaletteService.deleteCustomColorPalette(activePaletteId)"
:disabled="!colorPaletteStore.isCustomPalette(activePaletteId)"
@click="colorPaletteService.deleteCustomColorPalette(activePaletteId)"
/>
</div>
</div>

View File

@@ -10,7 +10,7 @@
<div>
{{ $t('g.currentUser') }}: {{ userStore.currentUser?.username }}
</div>
<Button icon="pi pi-sign-out" @click="logout" text />
<Button icon="pi pi-sign-out" text @click="logout" />
</div>
</Message>
</template>

View File

@@ -22,16 +22,16 @@
<div class="flex justify-end">
<Button
:label="$t('g.reloadToApplyChanges')"
@click="applyChanges"
outlined
severity="danger"
@click="applyChanges"
/>
</div>
</Message>
</template>
<DataTable
:value="extensionStore.extensions"
stripedRows
striped-rows
size="small"
:filters="filters"
>
@@ -61,8 +61,8 @@
</template>
<template #body="slotProps">
<ToggleSwitch
:disabled="extensionStore.isExtensionReadOnly(slotProps.data.name)"
v-model="editingEnabledExtensions[slotProps.data.name]"
:disabled="extensionStore.isExtensionReadOnly(slotProps.data.name)"
@change="updateExtensionStatus"
/>
</template>

View File

@@ -8,16 +8,16 @@
</template>
<DataTable
:value="commandsData"
v-model:selection="selectedCommandData"
:value="commandsData"
:global-filter-fields="['id', 'label']"
:filters="filters"
selectionMode="single"
stripedRows
selection-mode="single"
striped-rows
:pt="{
header: 'px-0'
}"
@rowDblclick="editKeybinding($event.data)"
@row-dblclick="editKeybinding($event.data)"
>
<Column field="actions" header="">
<template #body="slotProps">
@@ -30,8 +30,8 @@
<Button
icon="pi pi-trash"
class="p-button-text p-button-danger"
@click="removeKeybinding(slotProps.data)"
:disabled="!slotProps.data.keybinding"
@click="removeKeybinding(slotProps.data)"
/>
</div>
</template>
@@ -55,8 +55,8 @@
<template #body="slotProps">
<KeyComboDisplay
v-if="slotProps.data.keybinding"
:keyCombo="slotProps.data.keybinding.combo"
:isModified="
:key-combo="slotProps.data.keybinding.combo"
:is-modified="
keybindingStore.isCommandKeybindingModified(slotProps.data.id)
"
/>
@@ -66,22 +66,22 @@
</DataTable>
<Dialog
class="min-w-96"
v-model:visible="editDialogVisible"
class="min-w-96"
modal
:header="currentEditingCommand?.label"
@hide="cancelEdit"
>
<div>
<InputText
class="mb-2 text-center"
ref="keybindingInput"
:modelValue="newBindingKeyCombo?.toString() ?? ''"
class="mb-2 text-center"
:model-value="newBindingKeyCombo?.toString() ?? ''"
placeholder="Press keys for new binding"
@keydown.stop.prevent="captureKeybinding"
autocomplete="off"
fluid
:invalid="!!existingKeybindingOnCombo"
@keydown.stop.prevent="captureKeybinding"
/>
<Message v-if="existingKeybindingOnCombo" severity="error">
Keybinding already exists on
@@ -95,16 +95,16 @@
<Button
label="Save"
icon="pi pi-check"
@click="saveKeybinding"
:disabled="!!existingKeybindingOnCombo"
autofocus
@click="saveKeybinding"
/>
</template>
</Dialog>
<Button
v-tooltip="$t('g.resetKeybindingsTooltip')"
class="mt-4"
:label="$t('g.reset')"
v-tooltip="$t('g.resetKeybindingsTooltip')"
icon="pi pi-trash"
severity="danger"
fluid

View File

@@ -18,14 +18,14 @@
<div class="flex justify-end gap-2">
<Button
:label="$t('serverConfig.revertChanges')"
@click="revertChanges"
outlined
@click="revertChanges"
/>
<Button
:label="$t('serverConfig.restart')"
@click="restartApp"
outlined
severity="danger"
@click="restartApp"
/>
</div>
</Message>
@@ -37,9 +37,9 @@
<p>{{ commandLineArgs }}</p>
<Button
icon="pi pi-clipboard"
@click="copyCommandLineArgs"
severity="secondary"
text
@click="copyCommandLineArgs"
/>
</div>
</Message>
@@ -53,10 +53,10 @@
<h3>{{ $t(`serverConfigCategories.${label}`, label) }}</h3>
<div v-for="item in items" :key="item.name" class="mb-4">
<FormItem
:item="translateItem(item)"
v-model:formValue="item.value"
:id="item.id"
:labelClass="{
v-model:formValue="item.value"
:item="translateItem(item)"
:label-class="{
'text-highlight': item.initialValue !== item.value
}"
/>

View File

@@ -1,9 +1,9 @@
<template>
<FormItem
:item="formItem"
:id="setting.id"
:formValue="settingValue"
@update:formValue="updateSettingValue"
:item="formItem"
:form-value="settingValue"
@update:form-value="updateSettingValue"
>
<template #name-prefix>
<Tag v-if="setting.id === 'Comfy.Locale'" class="pi pi-language" />

View File

@@ -1,7 +1,7 @@
<template>
<div>
<h2 class="px-4">
<i class="pi pi-cog"></i>
<i class="pi pi-cog" />
<span>{{ $t('g.settings') }}</span>
</h2>
</div>

View File

@@ -22,8 +22,8 @@
<TitleEditor />
<GraphCanvasMenu v-if="!betaMenuEnabled && canvasMenuEnabled" />
<canvas
ref="canvasRef"
id="graph-canvas"
ref="canvasRef"
tabindex="1"
class="w-full h-full touch-none"
/>

View File

@@ -3,36 +3,36 @@
class="p-buttongroup-vertical absolute bottom-[10px] right-[10px] z-[1000]"
>
<Button
v-tooltip.left="t('graphCanvasMenu.zoomIn')"
severity="secondary"
icon="pi pi-plus"
v-tooltip.left="t('graphCanvasMenu.zoomIn')"
:aria-label="$t('graphCanvasMenu.zoomIn')"
@mousedown="repeat('Comfy.Canvas.ZoomIn')"
@mouseup="stopRepeat"
/>
<Button
v-tooltip.left="t('graphCanvasMenu.zoomOut')"
severity="secondary"
icon="pi pi-minus"
v-tooltip.left="t('graphCanvasMenu.zoomOut')"
:aria-label="$t('graphCanvasMenu.zoomOut')"
@mousedown="repeat('Comfy.Canvas.ZoomOut')"
@mouseup="stopRepeat"
/>
<Button
v-tooltip.left="t('graphCanvasMenu.fitView')"
severity="secondary"
icon="pi pi-expand"
v-tooltip.left="t('graphCanvasMenu.fitView')"
:aria-label="$t('graphCanvasMenu.fitView')"
@click="() => commandStore.execute('Comfy.Canvas.FitView')"
/>
<Button
severity="secondary"
v-tooltip.left="
t(
'graphCanvasMenu.' +
(canvasStore.canvas?.read_only ? 'panMode' : 'selectMode')
) + ' (Space)'
"
severity="secondary"
:aria-label="
t(
'graphCanvasMenu.' +
@@ -49,12 +49,12 @@
</template>
</Button>
<Button
v-tooltip.left="t('graphCanvasMenu.toggleLinkVisibility')"
severity="secondary"
:icon="linkHidden ? 'pi pi-eye-slash' : 'pi pi-eye'"
v-tooltip.left="t('graphCanvasMenu.toggleLinkVisibility')"
:aria-label="$t('graphCanvasMenu.toggleLinkVisibility')"
@click="() => commandStore.execute('Comfy.Canvas.ToggleLinkVisibility')"
data-testid="toggle-link-visibility-button"
@click="() => commandStore.execute('Comfy.Canvas.ToggleLinkVisibility')"
/>
</ButtonGroup>
</template>

View File

@@ -1,14 +1,14 @@
<!-- This component is used to bound the selected items on the canvas. -->
<template>
<div
v-show="visible"
class="selection-overlay-container pointer-events-none z-40"
:class="{
'show-border': showBorder
}"
:style="style"
v-show="visible"
>
<slot></slot>
<slot />
</div>
</template>

View File

@@ -9,16 +9,16 @@
<ColorPickerButton v-show="nodeSelected || groupSelected" />
<Button
v-show="nodeSelected"
severity="secondary"
text
@click="
() => commandStore.execute('Comfy.Canvas.ToggleSelectedNodes.Bypass')
"
data-testid="bypass-button"
v-tooltip.top="{
value: t('commands.Comfy_Canvas_ToggleSelectedNodes_Bypass.label'),
showDelay: 1000
}"
severity="secondary"
text
data-testid="bypass-button"
@click="
() => commandStore.execute('Comfy.Canvas.ToggleSelectedNodes.Bypass')
"
>
<template #icon>
<i-game-icons:detour />
@@ -26,24 +26,24 @@
</Button>
<Button
v-show="nodeSelected || groupSelected"
severity="secondary"
text
icon="pi pi-thumbtack"
@click="() => commandStore.execute('Comfy.Canvas.ToggleSelected.Pin')"
v-tooltip.top="{
value: t('commands.Comfy_Canvas_ToggleSelectedNodes_Pin.label'),
showDelay: 1000
}"
severity="secondary"
text
icon="pi pi-thumbtack"
@click="() => commandStore.execute('Comfy.Canvas.ToggleSelected.Pin')"
/>
<Button
severity="danger"
text
icon="pi pi-trash"
@click="() => commandStore.execute('Comfy.Canvas.DeleteSelectedItems')"
v-tooltip.top="{
value: t('commands.Comfy_Canvas_DeleteSelectedItems.label'),
showDelay: 1000
}"
severity="danger"
text
icon="pi pi-trash"
@click="() => commandStore.execute('Comfy.Canvas.DeleteSelectedItems')"
/>
<Button
v-show="isRefreshable"
@@ -55,15 +55,15 @@
<Button
v-for="command in extensionToolboxCommands"
:key="command.id"
severity="secondary"
text
:icon="typeof command.icon === 'function' ? command.icon() : command.icon"
@click="() => commandStore.execute(command.id)"
v-tooltip.top="{
value:
st(`commands.${normalizeI18nKey(command.id)}.label`, '') || undefined,
showDelay: 1000
}"
severity="secondary"
text
:icon="typeof command.icon === 'function' ? command.icon() : command.icon"
@click="() => commandStore.execute(command.id)"
/>
</Panel>
</template>

View File

@@ -5,8 +5,8 @@
:style="inputStyle"
>
<EditableText
:isEditing="showInput"
:modelValue="editedTitle"
:is-editing="showInput"
:model-value="editedTitle"
@edit="onEdit"
/>
</div>

View File

@@ -17,19 +17,19 @@
class="color-picker-container absolute -top-10 left-1/2"
>
<SelectButton
:modelValue="selectedColorOption"
@update:modelValue="applyColor"
:model-value="selectedColorOption"
:options="colorOptions"
optionLabel="name"
dataKey="value"
option-label="name"
data-key="value"
@update:model-value="applyColor"
>
<template #option="{ option }">
<i
v-tooltip.top="option.localizedName"
class="pi pi-circle-fill"
:style="{
color: isLightTheme ? option.value.light : option.value.dark
}"
v-tooltip.top="option.localizedName"
:data-testid="option.name"
/>
</template>

View File

@@ -1,17 +1,17 @@
<template>
<div
v-show="widgetState.visible"
ref="widgetElement"
class="dom-widget"
:title="tooltip"
ref="widgetElement"
:style="style"
v-show="widgetState.visible"
>
<component
v-if="isComponentWidget(widget)"
:is="widget.component"
:modelValue="widget.value"
@update:modelValue="emit('update:widgetValue', $event)"
v-if="isComponentWidget(widget)"
:model-value="widget.value"
:widget="widget"
@update:model-value="emit('update:widgetValue', $event)"
/>
</div>
</template>

View File

@@ -5,7 +5,7 @@
:options="options"
filter
:placeholder="placeholder"
:maxSelectedLabels="3"
:max-selected-labels="3"
:display="display"
class="w-full"
/>

View File

@@ -102,7 +102,7 @@
icon="pi pi-exclamation-triangle"
severity="warn"
:value="t('icon.exclamation-triangle')"
></Tag>
/>
{{ $t('install.gpuSelection.cpuModeDescription') }}
</p>
<p class="m-1">
@@ -119,7 +119,7 @@
>
<ToggleSwitch
v-model="cpuMode"
inputId="cpu-mode"
input-id="cpu-mode"
class="-translate-y-40"
/>
<label for="cpu-mode" class="select-none">

View File

@@ -16,15 +16,15 @@
v-model="installPath"
class="w-full"
:class="{ 'p-invalid': pathError }"
@update:modelValue="validatePath"
@update:model-value="validatePath"
@focus="onFocus"
/>
<InputIcon
class="pi pi-info-circle"
v-tooltip.top="$t('install.installLocationTooltip')"
class="pi pi-info-circle"
/>
</IconField>
<Button icon="pi pi-folder" @click="browsePath" class="w-12" />
<Button icon="pi pi-folder" class="w-12" @click="browsePath" />
</div>
<Message v-if="pathError" severity="error" class="whitespace-pre-line">
@@ -49,18 +49,18 @@
<span class="text-neutral-400">App Data:</span>
<span class="text-neutral-200">{{ appData }}</span>
<span
class="pi pi-info-circle"
v-tooltip="$t('install.appDataLocationTooltip')"
></span>
class="pi pi-info-circle"
/>
</div>
<div class="flex items-center gap-2">
<i class="pi pi-desktop text-neutral-400" />
<span class="text-neutral-400">App Path:</span>
<span class="text-neutral-200">{{ appPath }}</span>
<span
class="pi pi-info-circle"
v-tooltip="$t('install.appPathLocationTooltip')"
></span>
class="pi pi-info-circle"
/>
</div>
</div>
</div>

View File

@@ -16,9 +16,9 @@
placeholder="Select existing ComfyUI installation (optional)"
class="flex-1"
:class="{ 'p-invalid': pathError }"
@update:modelValue="validateSource"
@update:model-value="validateSource"
/>
<Button icon="pi pi-folder" @click="browsePath" class="w-12" />
<Button icon="pi pi-folder" class="w-12" @click="browsePath" />
</div>
<Message v-if="pathError" severity="error">
@@ -44,7 +44,7 @@
>
<Checkbox
v-model="item.selected"
:inputId="item.id"
:input-id="item.id"
:binary="true"
@click.stop
/>

View File

@@ -12,13 +12,14 @@
<Divider v-if="index > 0" />
<MirrorItem
:item="item"
v-model="modelValue.value"
:item="item"
@state-change="validationStates[index] = $event"
/>
</template>
<template #icons>
<i
v-tooltip="validationStateTooltip"
:class="{
'pi pi-spin pi-spinner text-neutral-400':
validationState === ValidationState.LOADING,
@@ -27,7 +28,6 @@
'pi pi-times text-red-500':
validationState === ValidationState.INVALID
}"
v-tooltip="validationStateTooltip"
/>
</template>
</Panel>

View File

@@ -7,55 +7,55 @@
<Load3DScene
ref="load3DSceneRef"
:node="node"
:inputSpec="inputSpec"
:backgroundColor="backgroundColor"
:showGrid="showGrid"
:lightIntensity="lightIntensity"
:input-spec="inputSpec"
:background-color="backgroundColor"
:show-grid="showGrid"
:light-intensity="lightIntensity"
:fov="fov"
:cameraType="cameraType"
:showPreview="showPreview"
:backgroundImage="backgroundImage"
:upDirection="upDirection"
:materialMode="materialMode"
:edgeThreshold="edgeThreshold"
@materialModeChange="listenMaterialModeChange"
@backgroundColorChange="listenBackgroundColorChange"
@lightIntensityChange="listenLightIntensityChange"
@fovChange="listenFOVChange"
@cameraTypeChange="listenCameraTypeChange"
@showGridChange="listenShowGridChange"
@showPreviewChange="listenShowPreviewChange"
@backgroundImageChange="listenBackgroundImageChange"
@upDirectionChange="listenUpDirectionChange"
@edgeThresholdChange="listenEdgeThresholdChange"
:camera-type="cameraType"
:show-preview="showPreview"
:background-image="backgroundImage"
:up-direction="upDirection"
:material-mode="materialMode"
:edge-threshold="edgeThreshold"
@material-mode-change="listenMaterialModeChange"
@background-color-change="listenBackgroundColorChange"
@light-intensity-change="listenLightIntensityChange"
@fov-change="listenFOVChange"
@camera-type-change="listenCameraTypeChange"
@show-grid-change="listenShowGridChange"
@show-preview-change="listenShowPreviewChange"
@background-image-change="listenBackgroundImageChange"
@up-direction-change="listenUpDirectionChange"
@edge-threshold-change="listenEdgeThresholdChange"
/>
<Load3DControls
:inputSpec="inputSpec"
:backgroundColor="backgroundColor"
:showGrid="showGrid"
:showPreview="showPreview"
:lightIntensity="lightIntensity"
:showLightIntensityButton="showLightIntensityButton"
:input-spec="inputSpec"
:background-color="backgroundColor"
:show-grid="showGrid"
:show-preview="showPreview"
:light-intensity="lightIntensity"
:show-light-intensity-button="showLightIntensityButton"
:fov="fov"
:showFOVButton="showFOVButton"
:showPreviewButton="showPreviewButton"
:cameraType="cameraType"
:hasBackgroundImage="hasBackgroundImage"
:upDirection="upDirection"
:materialMode="materialMode"
:edgeThreshold="edgeThreshold"
@updateBackgroundImage="handleBackgroundImageUpdate"
@switchCamera="switchCamera"
@toggleGrid="toggleGrid"
@updateBackgroundColor="handleBackgroundColorChange"
@updateLightIntensity="handleUpdateLightIntensity"
@togglePreview="togglePreview"
@updateFOV="handleUpdateFOV"
@updateUpDirection="handleUpdateUpDirection"
@updateMaterialMode="handleUpdateMaterialMode"
@updateEdgeThreshold="handleUpdateEdgeThreshold"
@uploadTexture="handleUploadTexture"
@exportModel="handleExportModel"
:show-f-o-v-button="showFOVButton"
:show-preview-button="showPreviewButton"
:camera-type="cameraType"
:has-background-image="hasBackgroundImage"
:up-direction="upDirection"
:material-mode="materialMode"
:edge-threshold="edgeThreshold"
@update-background-image="handleBackgroundImageUpdate"
@switch-camera="switchCamera"
@toggle-grid="toggleGrid"
@update-background-color="handleBackgroundColorChange"
@update-light-intensity="handleUpdateLightIntensity"
@toggle-preview="togglePreview"
@update-f-o-v="handleUpdateFOV"
@update-up-direction="handleUpdateUpDirection"
@update-material-mode="handleUpdateMaterialMode"
@update-edge-threshold="handleUpdateEdgeThreshold"
@upload-texture="handleUploadTexture"
@export-model="handleExportModel"
/>
</div>
</template>

View File

@@ -7,63 +7,63 @@
<Load3DAnimationScene
ref="load3DAnimationSceneRef"
:node="node"
:inputSpec="inputSpec"
:backgroundColor="backgroundColor"
:showGrid="showGrid"
:lightIntensity="lightIntensity"
:input-spec="inputSpec"
:background-color="backgroundColor"
:show-grid="showGrid"
:light-intensity="lightIntensity"
:fov="fov"
:cameraType="cameraType"
:showPreview="showPreview"
:showFOVButton="showFOVButton"
:showLightIntensityButton="showLightIntensityButton"
:camera-type="cameraType"
:show-preview="showPreview"
:show-f-o-v-button="showFOVButton"
:show-light-intensity-button="showLightIntensityButton"
:playing="playing"
:selectedSpeed="selectedSpeed"
:selectedAnimation="selectedAnimation"
:backgroundImage="backgroundImage"
:upDirection="upDirection"
:materialMode="materialMode"
@materialModeChange="listenMaterialModeChange"
@backgroundColorChange="listenBackgroundColorChange"
@lightIntensityChange="listenLightIntensityChange"
@fovChange="listenFOVChange"
@cameraTypeChange="listenCameraTypeChange"
@showGridChange="listenShowGridChange"
@showPreviewChange="listenShowPreviewChange"
@backgroundImageChange="listenBackgroundImageChange"
@animationListChange="animationListChange"
@upDirectionChange="listenUpDirectionChange"
:selected-speed="selectedSpeed"
:selected-animation="selectedAnimation"
:background-image="backgroundImage"
:up-direction="upDirection"
:material-mode="materialMode"
@material-mode-change="listenMaterialModeChange"
@background-color-change="listenBackgroundColorChange"
@light-intensity-change="listenLightIntensityChange"
@fov-change="listenFOVChange"
@camera-type-change="listenCameraTypeChange"
@show-grid-change="listenShowGridChange"
@show-preview-change="listenShowPreviewChange"
@background-image-change="listenBackgroundImageChange"
@animation-list-change="animationListChange"
@up-direction-change="listenUpDirectionChange"
/>
<div class="absolute top-0 left-0 w-full h-full pointer-events-none">
<Load3DControls
:inputSpec="inputSpec"
:backgroundColor="backgroundColor"
:showGrid="showGrid"
:showPreview="showPreview"
:lightIntensity="lightIntensity"
:showLightIntensityButton="showLightIntensityButton"
:input-spec="inputSpec"
:background-color="backgroundColor"
:show-grid="showGrid"
:show-preview="showPreview"
:light-intensity="lightIntensity"
:show-light-intensity-button="showLightIntensityButton"
:fov="fov"
:showFOVButton="showFOVButton"
:showPreviewButton="showPreviewButton"
:cameraType="cameraType"
:hasBackgroundImage="hasBackgroundImage"
:upDirection="upDirection"
:materialMode="materialMode"
@updateBackgroundImage="handleBackgroundImageUpdate"
@switchCamera="switchCamera"
@toggleGrid="toggleGrid"
@updateBackgroundColor="handleBackgroundColorChange"
@updateLightIntensity="handleUpdateLightIntensity"
@togglePreview="togglePreview"
@updateFOV="handleUpdateFOV"
@updateUpDirection="handleUpdateUpDirection"
@updateMaterialMode="handleUpdateMaterialMode"
:show-f-o-v-button="showFOVButton"
:show-preview-button="showPreviewButton"
:camera-type="cameraType"
:has-background-image="hasBackgroundImage"
:up-direction="upDirection"
:material-mode="materialMode"
@update-background-image="handleBackgroundImageUpdate"
@switch-camera="switchCamera"
@toggle-grid="toggleGrid"
@update-background-color="handleBackgroundColorChange"
@update-light-intensity="handleUpdateLightIntensity"
@toggle-preview="togglePreview"
@update-f-o-v="handleUpdateFOV"
@update-up-direction="handleUpdateUpDirection"
@update-material-mode="handleUpdateMaterialMode"
/>
<Load3DAnimationControls
:animations="animations"
:playing="playing"
@togglePlay="togglePlay"
@speedChange="speedChange"
@animationChange="animationChange"
@toggle-play="togglePlay"
@speed-change="speedChange"
@animation-change="animationChange"
/>
</div>
</div>

View File

@@ -6,25 +6,25 @@
<Button class="p-button-rounded p-button-text" @click="togglePlay">
<i
:class="['pi', playing ? 'pi-pause' : 'pi-play', 'text-white text-lg']"
></i>
/>
</Button>
<Select
v-model="selectedSpeed"
:options="speedOptions"
optionLabel="name"
optionValue="value"
@change="speedChange"
option-label="name"
option-value="value"
class="w-24"
@change="speedChange"
/>
<Select
v-model="selectedAnimation"
:options="animations"
optionLabel="name"
optionValue="index"
@change="animationChange"
option-label="name"
option-value="index"
class="w-32"
@change="animationChange"
/>
</div>
</template>

View File

@@ -1,25 +1,25 @@
<template>
<Load3DScene
:node="node"
:inputSpec="inputSpec"
:backgroundColor="backgroundColor"
:showGrid="showGrid"
:lightIntensity="lightIntensity"
:fov="fov"
:cameraType="cameraType"
:showPreview="showPreview"
:extraListeners="animationListeners"
:backgroundImage="backgroundImage"
:upDirection="upDirection"
:materialMode="materialMode"
@materialModeChange="listenMaterialModeChange"
@backgroundColorChange="listenBackgroundColorChange"
@lightIntensityChange="listenLightIntensityChange"
@fovChange="listenFOVChange"
@cameraTypeChange="listenCameraTypeChange"
@showGridChange="listenShowGridChange"
@showPreviewChange="listenShowPreviewChange"
ref="load3DSceneRef"
:node="node"
:input-spec="inputSpec"
:background-color="backgroundColor"
:show-grid="showGrid"
:light-intensity="lightIntensity"
:fov="fov"
:camera-type="cameraType"
:show-preview="showPreview"
:extra-listeners="animationListeners"
:background-image="backgroundImage"
:up-direction="upDirection"
:material-mode="materialMode"
@material-mode-change="listenMaterialModeChange"
@background-color-change="listenBackgroundColorChange"
@light-intensity-change="listenLightIntensityChange"
@fov-change="listenFOVChange"
@camera-type-change="listenCameraTypeChange"
@show-grid-change="listenShowGridChange"
@show-preview-change="listenShowPreviewChange"
/>
</template>
<script setup lang="ts">

View File

@@ -7,7 +7,7 @@
class="p-button-rounded p-button-text bg-opacity-30"
@click="toggleMenu"
>
<i class="pi pi-bars text-white text-lg"></i>
<i class="pi pi-bars text-white text-lg" />
</Button>
<div
@@ -22,7 +22,7 @@
:class="{ 'bg-gray-600': activeCategory === category }"
@click="selectCategory(category)"
>
<i :class="getCategoryIcon(category)"></i>
<i :class="getCategoryIcon(category)" />
<span class="text-white">{{ t(categoryLabels[category]) }}</span>
</Button>
</div>
@@ -32,62 +32,62 @@
<div v-show="activeCategory" class="bg-gray-700 bg-opacity-30 rounded-lg">
<SceneControls
v-if="activeCategory === 'scene'"
:backgroundColor="backgroundColor"
:showGrid="showGrid"
:hasBackgroundImage="hasBackgroundImage"
@toggleGrid="handleToggleGrid"
@updateBackgroundColor="handleBackgroundColorChange"
@updateBackgroundImage="handleBackgroundImageUpdate"
ref="sceneControlsRef"
:background-color="backgroundColor"
:show-grid="showGrid"
:has-background-image="hasBackgroundImage"
@toggle-grid="handleToggleGrid"
@update-background-color="handleBackgroundColorChange"
@update-background-image="handleBackgroundImageUpdate"
/>
<ModelControls
v-if="activeCategory === 'model'"
:inputSpec="inputSpec"
:upDirection="upDirection"
:materialMode="materialMode"
:edgeThreshold="edgeThreshold"
@updateUpDirection="handleUpdateUpDirection"
@updateMaterialMode="handleUpdateMaterialMode"
@updateEdgeThreshold="handleUpdateEdgeThreshold"
@uploadTexture="handleUploadTexture"
ref="modelControlsRef"
:input-spec="inputSpec"
:up-direction="upDirection"
:material-mode="materialMode"
:edge-threshold="edgeThreshold"
@update-up-direction="handleUpdateUpDirection"
@update-material-mode="handleUpdateMaterialMode"
@update-edge-threshold="handleUpdateEdgeThreshold"
@upload-texture="handleUploadTexture"
/>
<CameraControls
v-if="activeCategory === 'camera'"
:cameraType="cameraType"
:fov="fov"
:showFOVButton="showFOVButton"
@switchCamera="switchCamera"
@updateFOV="handleUpdateFOV"
ref="cameraControlsRef"
:camera-type="cameraType"
:fov="fov"
:show-f-o-v-button="showFOVButton"
@switch-camera="switchCamera"
@update-f-o-v="handleUpdateFOV"
/>
<LightControls
v-if="activeCategory === 'light'"
:lightIntensity="lightIntensity"
:showLightIntensityButton="showLightIntensityButton"
@updateLightIntensity="handleUpdateLightIntensity"
ref="lightControlsRef"
:light-intensity="lightIntensity"
:show-light-intensity-button="showLightIntensityButton"
@update-light-intensity="handleUpdateLightIntensity"
/>
<ExportControls
v-if="activeCategory === 'export'"
@exportModel="handleExportModel"
ref="exportControlsRef"
@export-model="handleExportModel"
/>
</div>
<div v-if="showPreviewButton">
<Button class="p-button-rounded p-button-text" @click="togglePreview">
<i
v-tooltip.right="{ value: t('load3d.previewOutput'), showDelay: 300 }"
:class="[
'pi',
showPreview ? 'pi-eye' : 'pi-eye-slash',
'text-white text-lg'
]"
v-tooltip.right="{ value: t('load3d.previewOutput'), showDelay: 300 }"
></i>
/>
</Button>
</div>
</div>

View File

@@ -5,7 +5,7 @@
class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
>
<div class="flex flex-col items-center">
<div class="spinner"></div>
<div class="spinner" />
<div class="text-white mt-4 text-lg">
{{ loadingMessage }}
</div>

View File

@@ -2,19 +2,19 @@
<div class="flex flex-col">
<Button class="p-button-rounded p-button-text" @click="switchCamera">
<i
:class="['pi', getCameraIcon, 'text-white text-lg']"
v-tooltip.right="{
value: t('load3d.switchCamera'),
showDelay: 300
}"
></i>
:class="['pi', getCameraIcon, 'text-white text-lg']"
/>
</Button>
<div class="relative show-fov" v-if="showFOVButton">
<div v-if="showFOVButton" class="relative show-fov">
<Button class="p-button-rounded p-button-text" @click="toggleFOV">
<i
class="pi pi-expand text-white text-lg"
v-tooltip.right="{ value: t('load3d.fov'), showDelay: 300 }"
></i>
class="pi pi-expand text-white text-lg"
/>
</Button>
<div
v-show="showFOV"
@@ -24,10 +24,10 @@
<Slider
v-model="fov"
class="w-full"
@change="updateFOV"
:min="10"
:max="150"
:step="1"
@change="updateFOV"
/>
</div>
</div>

View File

@@ -6,12 +6,12 @@
@click="toggleExportFormats"
>
<i
class="pi pi-download text-white text-lg"
v-tooltip.right="{
value: t('load3d.exportModel'),
showDelay: 300
}"
></i>
class="pi pi-download text-white text-lg"
/>
</Button>
<div
v-show="showExportFormats"

View File

@@ -1,17 +1,17 @@
<template>
<div class="flex flex-col">
<div class="relative show-light-intensity" v-if="showLightIntensityButton">
<div v-if="showLightIntensityButton" class="relative show-light-intensity">
<Button
class="p-button-rounded p-button-text"
@click="toggleLightIntensity"
>
<i
class="pi pi-sun text-white text-lg"
v-tooltip.right="{
value: t('load3d.lightIntensity'),
showDelay: 300
}"
></i>
class="pi pi-sun text-white text-lg"
/>
</Button>
<div
v-show="showLightIntensity"
@@ -21,10 +21,10 @@
<Slider
v-model="lightIntensity"
class="w-full"
@change="updateLightIntensity"
:min="1"
:max="20"
:step="1"
@change="updateLightIntensity"
/>
</div>
</div>

View File

@@ -3,12 +3,12 @@
<div class="relative show-up-direction">
<Button class="p-button-rounded p-button-text" @click="toggleUpDirection">
<i
class="pi pi-arrow-up text-white text-lg"
v-tooltip.right="{
value: t('load3d.upDirection'),
showDelay: 300
}"
></i>
class="pi pi-arrow-up text-white text-lg"
/>
</Button>
<div
v-show="showUpDirection"
@@ -34,12 +34,12 @@
@click="toggleMaterialMode"
>
<i
class="pi pi-box text-white text-lg"
v-tooltip.right="{
value: t('load3d.materialMode'),
showDelay: 300
}"
></i>
class="pi pi-box text-white text-lg"
/>
</Button>
<div
v-show="showMaterialMode"
@@ -69,18 +69,18 @@
>
<Button class="p-button-rounded p-button-text" @click="openTextureUpload">
<i
class="pi pi-image text-white text-lg"
v-tooltip.right="{
value: t('load3d.uploadTexture'),
showDelay: 300
}"
></i>
class="pi pi-image text-white text-lg"
/>
<input
type="file"
ref="texturePickerRef"
type="file"
accept="image/*"
@change="uploadTexture"
class="absolute opacity-0 w-0 h-0 p-0 m-0 pointer-events-none"
@change="uploadTexture"
/>
</Button>
</div>
@@ -91,12 +91,12 @@
@click="toggleEdgeThreshold"
>
<i
class="pi pi-sliders-h text-white text-lg"
v-tooltip.right="{
value: t('load3d.edgeThreshold'),
showDelay: 300
}"
></i>
class="pi pi-sliders-h text-white text-lg"
/>
</Button>
<div
v-show="showEdgeThreshold"
@@ -109,10 +109,10 @@
<Slider
v-model="edgeThreshold"
class="w-full"
@change="updateEdgeThreshold"
:min="0"
:max="120"
:step="1"
@change="updateEdgeThreshold"
/>
</div>
</div>

View File

@@ -6,28 +6,28 @@
@click="toggleGrid"
>
<i
class="pi pi-table text-white text-lg"
v-tooltip.right="{ value: t('load3d.showGrid'), showDelay: 300 }"
></i>
class="pi pi-table text-white text-lg"
/>
</Button>
<div v-if="!hasBackgroundImage">
<Button class="p-button-rounded p-button-text" @click="openColorPicker">
<i
class="pi pi-palette text-white text-lg"
v-tooltip.right="{
value: t('load3d.backgroundColor'),
showDelay: 300
}"
></i>
class="pi pi-palette text-white text-lg"
/>
<input
type="color"
ref="colorPickerRef"
type="color"
:value="backgroundColor"
class="absolute opacity-0 w-0 h-0 p-0 m-0 pointer-events-none"
@input="
updateBackgroundColor(($event.target as HTMLInputElement).value)
"
class="absolute opacity-0 w-0 h-0 p-0 m-0 pointer-events-none"
/>
</Button>
</div>
@@ -35,18 +35,18 @@
<div v-if="!hasBackgroundImage">
<Button class="p-button-rounded p-button-text" @click="openImagePicker">
<i
class="pi pi-image text-white text-lg"
v-tooltip.right="{
value: t('load3d.uploadBackgroundImage'),
showDelay: 300
}"
></i>
class="pi pi-image text-white text-lg"
/>
<input
type="file"
ref="imagePickerRef"
type="file"
accept="image/*"
@change="uploadBackgroundImage"
class="absolute opacity-0 w-0 h-0 p-0 m-0 pointer-events-none"
@change="uploadBackgroundImage"
/>
</Button>
</div>
@@ -57,12 +57,12 @@
@click="removeBackgroundImage"
>
<i
class="pi pi-times text-white text-lg"
v-tooltip.right="{
value: t('load3d.removeBackgroundImage'),
showDelay: 300
}"
></i>
class="pi pi-times text-white text-lg"
/>
</Button>
</div>
</div>

View File

@@ -20,8 +20,12 @@
class="object-contain w-full h-full opacity-25 pt-4 px-4"
/>
</template>
<template #title>{{ task.name }}</template>
<template #content>{{ description }}</template>
<template #title>
{{ task.name }}
</template>
<template #content>
{{ description }}
</template>
<template #footer>
<div class="flex gap-4 mt-1">
<Button
@@ -30,8 +34,8 @@
class="w-full"
raised
icon-pos="right"
@click="(event) => $emit('execute', event)"
:loading="isExecuting"
@click="(event) => $emit('execute', event)"
/>
</div>
</template>

View File

@@ -10,7 +10,9 @@
<TaskListStatusIcon :state="runner.state" :loading="isLoading" />
</td>
<td>
<p class="inline-block">{{ task.name }}</p>
<p class="inline-block">
{{ task.name }}
</p>
<Button
class="inline-block mx-2"
type="button"
@@ -30,8 +32,8 @@
:label="task.button?.text"
:severity
icon-pos="right"
@click="(event) => $emit('execute', event)"
:loading="isExecuting"
@click="(event) => $emit('execute', event)"
/>
</td>
</tr>

View File

@@ -1,7 +1,7 @@
<template>
<ProgressSpinner v-if="!state || loading" class="h-8 w-8" />
<template v-else>
<i :class="cssClasses" v-tooltip.top="{ value: tooltip, showDelay: 250 }" />
<i v-tooltip.top="{ value: tooltip, showDelay: 250 }" :class="cssClasses" />
</template>
</template>

View File

@@ -12,7 +12,7 @@ https://github.com/Nuked88/ComfyUI-N-Sidebar/blob/7ae7da4a9761009fb6629bc04c6830
color: litegraphColors.NODE_TITLE_COLOR
}"
>
<div class="_sb_dot headdot"></div>
<div class="_sb_dot headdot" />
{{ nodeDef.display_name }}
</div>
<div class="_sb_preview_badge">PREVIEW</div>
@@ -20,14 +20,16 @@ https://github.com/Nuked88/ComfyUI-N-Sidebar/blob/7ae7da4a9761009fb6629bc04c6830
<!-- Node slot I/O -->
<div
v-for="[slotInput, slotOutput] in _.zip(slotInputDefs, allOutputDefs)"
class="_sb_row slot_row"
:key="(slotInput?.name || '') + (slotOutput?.index.toString() || '')"
class="_sb_row slot_row"
>
<div class="_sb_col">
<div v-if="slotInput" :class="['_sb_dot', slotInput.type]"></div>
<div v-if="slotInput" :class="['_sb_dot', slotInput.type]" />
</div>
<div class="_sb_col">{{ slotInput ? slotInput.name : '' }}</div>
<div class="_sb_col middle-column"></div>
<div class="_sb_col">
{{ slotInput ? slotInput.name : '' }}
</div>
<div class="_sb_col middle-column" />
<div
class="_sb_col _sb_inherit"
:style="{
@@ -37,15 +39,15 @@ https://github.com/Nuked88/ComfyUI-N-Sidebar/blob/7ae7da4a9761009fb6629bc04c6830
{{ slotOutput ? slotOutput.name : '' }}
</div>
<div class="_sb_col">
<div v-if="slotOutput" :class="['_sb_dot', slotOutput.type]"></div>
<div v-if="slotOutput" :class="['_sb_dot', slotOutput.type]" />
</div>
</div>
<!-- Node widget inputs -->
<div
v-for="widgetInput in widgetInputDefs"
class="_sb_row _long_field"
:key="widgetInput.name"
class="_sb_row _long_field"
>
<div class="_sb_col _sb_arrow">&#x25C0;</div>
<div
@@ -56,7 +58,7 @@ https://github.com/Nuked88/ComfyUI-N-Sidebar/blob/7ae7da4a9761009fb6629bc04c6830
>
{{ widgetInput.name }}
</div>
<div class="_sb_col middle-column"></div>
<div class="_sb_col middle-column" />
<div
class="_sb_col _sb_inherit"
:style="{ color: litegraphColors.WIDGET_TEXT_COLOR }"
@@ -67,8 +69,8 @@ https://github.com/Nuked88/ComfyUI-N-Sidebar/blob/7ae7da4a9761009fb6629bc04c6830
</div>
</div>
<div
class="_sb_description"
v-if="nodeDef.description"
class="_sb_description"
:style="{
color: litegraphColors.WIDGET_SECONDARY_TEXT_COLOR,
backgroundColor: litegraphColors.WIDGET_BGCOLOR

View File

@@ -3,13 +3,13 @@
class="comfy-vue-node-search-container flex justify-center items-center w-full min-w-96"
>
<div
class="comfy-vue-node-preview-container absolute left-[-350px] top-[50px]"
v-if="enableNodePreview"
class="comfy-vue-node-preview-container absolute left-[-350px] top-[50px]"
>
<NodePreview
:nodeDef="hoveredSuggestion"
:key="hoveredSuggestion?.name || ''"
v-if="hoveredSuggestion"
:key="hoveredSuggestion?.name || ''"
:node-def="hoveredSuggestion"
/>
</div>
@@ -30,14 +30,14 @@
<h3>Add node filter condition</h3>
</template>
<div class="_dialog-body">
<NodeSearchFilter @addFilter="onAddFilter"></NodeSearchFilter>
<NodeSearchFilter @add-filter="onAddFilter" />
</div>
</Dialog>
<AutoCompletePlus
:model-value="filters"
class="comfy-vue-node-search-box z-10 flex-grow"
scrollHeight="40vh"
scroll-height="40vh"
:placeholder="placeholder"
:input-id="inputId"
append-to="self"
@@ -45,32 +45,32 @@
:min-length="0"
:delay="100"
:loading="!nodeFrequencyStore.isLoaded"
@complete="search($event.query)"
@option-select="emit('addNode', $event.value)"
@focused-option-changed="setHoverSuggestion($event)"
complete-on-focus
auto-option-focus
force-selection
multiple
:optionLabel="'display_name'"
:option-label="'display_name'"
@complete="search($event.query)"
@option-select="emit('addNode', $event.value)"
@focused-option-changed="setHoverSuggestion($event)"
>
<template v-slot:option="{ option }">
<NodeSearchItem :nodeDef="option" :currentQuery="currentQuery" />
<template #option="{ option }">
<NodeSearchItem :node-def="option" :current-query="currentQuery" />
</template>
<!-- FilterAndValue -->
<template v-slot:chip="{ value }">
<template #chip="{ value }">
<SearchFilterChip
v-if="value.filterDef && value.value"
:key="`${value.filterDef.id}-${value.value}`"
:text="value.value"
:badge="value.filterDef.invokeSequence.toUpperCase()"
:badge-class="value.filterDef.invokeSequence + '-badge'"
@remove="
onRemoveFilter(
$event,
value as FuseFilterWithValue<ComfyNodeDefImpl, string>
)
"
:text="value.value"
:badge="value.filterDef.invokeSequence.toUpperCase()"
:badge-class="value.filterDef.invokeSequence + '-badge'"
/>
</template>
</AutoCompletePlus>

View File

@@ -4,7 +4,6 @@
v-model:visible="visible"
modal
:dismissable-mask="dismissable"
@hide="clearFilters"
:pt="{
root: {
class: 'invisible-dialog-root',
@@ -19,6 +18,7 @@
leaveToClass: 'opacity-0 scale-75'
}
}"
@hide="clearFilters"
>
<template #container>
<NodeSearchBox

View File

@@ -1,23 +1,23 @@
<template>
<div class="_content">
<SelectButton
class="filter-type-select"
v-model="selectedFilter"
class="filter-type-select"
:options="filters"
:allowEmpty="false"
optionLabel="name"
:allow-empty="false"
option-label="name"
@change="updateSelectedFilterValue"
/>
<Select
class="filter-value-select"
v-model="selectedFilterValue"
class="filter-value-select"
:options="filterValues"
filter
autoFilterFocus
auto-filter-focus
/>
</div>
<div class="_footer">
<Button type="button" :label="$t('g.add')" @click="submit"></Button>
<Button type="button" :label="$t('g.add')" @click="submit" />
</div>
</template>

View File

@@ -5,14 +5,12 @@
<div class="option-display-name font-semibold flex flex-col">
<div>
<span v-if="isBookmarked">
<i class="pi pi-bookmark-fill text-sm mr-1"></i>
<i class="pi pi-bookmark-fill text-sm mr-1" />
</span>
<span
v-html="highlightQuery(nodeDef.display_name, currentQuery)"
></span>
<span v-html="highlightQuery(nodeDef.display_name, currentQuery)" />
<span>&nbsp;</span>
<Tag v-if="showIdName" severity="secondary">
<span v-html="highlightQuery(nodeDef.name, currentQuery)"></span>
<span v-html="highlightQuery(nodeDef.name, currentQuery)" />
</Tag>
</div>
<div

View File

@@ -5,7 +5,7 @@
v-for="tab in tabs"
:key="tab.id"
:icon="tab.icon"
:iconBadge="tab.iconBadge"
:icon-badge="tab.iconBadge"
:tooltip="tab.tooltip + getTabTooltipSuffix(tab)"
:selected="tab.id === selectedTab?.id"
:class="tab.id + '-tab-button'"

View File

@@ -1,5 +1,6 @@
<template>
<Button
v-tooltip="{ value: props.tooltip, showDelay: 300, hideDelay: 300 }"
:class="props.class"
text
:pt="{
@@ -13,7 +14,6 @@
}
}"
@click="emit('click', $event)"
v-tooltip="{ value: props.tooltip, showDelay: 300, hideDelay: 300 }"
>
<template #icon>
<OverlayBadge v-if="shouldShowBadge" :value="overlayValue">

View File

@@ -2,8 +2,8 @@
<SidebarIcon
icon="pi pi-cog"
class="comfy-settings-btn"
@click="showSetting"
:tooltip="$t('g.settings')"
@click="showSetting"
/>
</template>

View File

@@ -1,9 +1,9 @@
<template>
<SidebarIcon
:icon="icon"
@click="toggleTheme"
:tooltip="$t('sideToolbar.themeToggle')"
class="comfy-vue-theme-toggle"
@click="toggleTheme"
/>
</template>

View File

@@ -5,24 +5,24 @@
>
<template #tool-buttons>
<Button
v-tooltip.bottom="$t('g.refresh')"
icon="pi pi-refresh"
@click="modelStore.loadModelFolders"
severity="secondary"
text
v-tooltip.bottom="$t('g.refresh')"
@click="modelStore.loadModelFolders"
/>
<Button
v-tooltip.bottom="$t('g.loadAllFolders')"
icon="pi pi-cloud-download"
@click="modelStore.loadModels"
severity="secondary"
text
v-tooltip.bottom="$t('g.loadAllFolders')"
@click="modelStore.loadModels"
/>
</template>
<template #header>
<SearchBox
class="model-lib-search-box p-2 2xl:p-4"
v-model:modelValue="searchQuery"
class="model-lib-search-box p-2 2xl:p-4"
:placeholder="$t('g.searchModels') + '...'"
@search="handleSearch"
/>
@@ -31,9 +31,9 @@
<ElectronDownloadItems v-if="isElectron()" />
<TreeExplorer
v-model:expandedKeys="expandedKeys"
class="model-lib-tree-explorer"
:root="renderedRoot"
v-model:expandedKeys="expandedKeys"
>
<template #node="{ node }">
<ModelTreeLeaf :node="node" />

View File

@@ -5,36 +5,36 @@
>
<template #tool-buttons>
<Button
v-tooltip.bottom="$t('g.newFolder')"
class="new-folder-button"
icon="pi pi-folder-plus"
text
severity="secondary"
@click="nodeBookmarkTreeExplorerRef?.addNewBookmarkFolder()"
v-tooltip.bottom="$t('g.newFolder')"
/>
<Button
v-tooltip.bottom="$t('sideToolbar.nodeLibraryTab.sortOrder')"
class="sort-button"
:icon="alphabeticalSort ? 'pi pi-sort-alpha-down' : 'pi pi-sort-alt'"
text
severity="secondary"
@click="alphabeticalSort = !alphabeticalSort"
v-tooltip.bottom="$t('sideToolbar.nodeLibraryTab.sortOrder')"
/>
</template>
<template #header>
<SearchBox
class="node-lib-search-box p-2 2xl:p-4"
v-model:modelValue="searchQuery"
@search="handleSearch"
@show-filter="($event) => searchFilter?.toggle($event)"
@remove-filter="onRemoveFilter"
class="node-lib-search-box p-2 2xl:p-4"
:placeholder="$t('g.searchNodes') + '...'"
filter-icon="pi pi-filter"
:filters
@search="handleSearch"
@show-filter="($event) => searchFilter?.toggle($event)"
@remove-filter="onRemoveFilter"
/>
<Popover ref="searchFilter" class="ml-[-13px]">
<NodeSearchFilter @addFilter="onAddFilter" />
<NodeSearchFilter @add-filter="onAddFilter" />
</Popover>
</template>
<template #body>
@@ -48,9 +48,9 @@
class="m-2"
/>
<TreeExplorer
v-model:expandedKeys="expandedKeys"
class="node-lib-tree-explorer"
:root="renderedRoot"
v-model:expandedKeys="expandedKeys"
>
<template #node="{ node }">
<NodeTreeLeaf :node="node" />

View File

@@ -2,6 +2,7 @@
<SidebarTabTemplate :title="$t('sideToolbar.queue')">
<template #tool-buttons>
<Button
v-tooltip.bottom="$t(`sideToolbar.queueTab.${imageFit}ImagePreview`)"
:icon="
imageFit === 'cover'
? 'pi pi-arrow-down-left-and-arrow-up-right-to-center'
@@ -9,42 +10,41 @@
"
text
severity="secondary"
@click="toggleImageFit"
class="toggle-expanded-button"
v-tooltip.bottom="$t(`sideToolbar.queueTab.${imageFit}ImagePreview`)"
@click="toggleImageFit"
/>
<Button
v-if="isInFolderView"
v-tooltip.bottom="$t('sideToolbar.queueTab.backToAllTasks')"
icon="pi pi-arrow-left"
text
severity="secondary"
@click="exitFolderView"
class="back-button"
v-tooltip.bottom="$t('sideToolbar.queueTab.backToAllTasks')"
@click="exitFolderView"
/>
<template v-else>
<Button
v-tooltip="$t('sideToolbar.queueTab.showFlatList')"
:icon="isExpanded ? 'pi pi-images' : 'pi pi-image'"
text
severity="secondary"
@click="toggleExpanded"
class="toggle-expanded-button"
v-tooltip="$t('sideToolbar.queueTab.showFlatList')"
@click="toggleExpanded"
/>
<Button
v-if="queueStore.hasPendingTasks"
v-tooltip.bottom="$t('sideToolbar.queueTab.clearPendingTasks')"
icon="pi pi-stop"
severity="danger"
text
@click="() => commandStore.execute('Comfy.ClearPendingTasks')"
v-tooltip.bottom="$t('sideToolbar.queueTab.clearPendingTasks')"
/>
<Button
icon="pi pi-trash"
text
severity="primary"
@click="confirmRemoveAll($event)"
class="clear-all-button"
@click="confirmRemoveAll($event)"
/>
</template>
</template>
@@ -52,7 +52,7 @@
<VirtualGrid
v-if="allTasks?.length"
:items="allTasks"
:gridStyle="{
:grid-style="{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
padding: '0.5rem',
@@ -62,10 +62,10 @@
<template #item="{ item }">
<TaskItem
:task="item"
:isFlatTask="isExpanded || isInFolderView"
:is-flat-task="isExpanded || isInFolderView"
@contextmenu="handleContextMenu"
@preview="handlePreview"
@taskOutputLengthClicked="enterFolderView($event)"
@task-output-length-clicked="enterFolderView($event)"
/>
</template>
</VirtualGrid>
@@ -87,7 +87,7 @@
<ContextMenu ref="menu" :model="menuItems" />
<ResultGallery
v-model:activeIndex="galleryActiveIndex"
:allGalleryItems="allGalleryItems"
:all-gallery-items="allGalleryItems"
/>
</template>

View File

@@ -14,15 +14,15 @@
<div
class="flex flex-row motion-safe:w-0 motion-safe:opacity-0 motion-safe:group-hover/sidebar-tab:w-auto motion-safe:group-hover/sidebar-tab:opacity-100 motion-safe:group-focus-within/sidebar-tab:w-auto motion-safe:group-focus-within/sidebar-tab:opacity-100 touch:w-auto touch:opacity-100 transition-all duration-200"
>
<slot name="tool-buttons"></slot>
<slot name="tool-buttons" />
</div>
</template>
</Toolbar>
<slot name="header"></slot>
<slot name="header" />
</div>
<!-- h-0 to force scrollpanel to flex-grow -->
<ScrollPanel class="comfy-vue-side-bar-body flex-grow h-0">
<slot name="body"></slot>
<slot name="body" />
</ScrollPanel>
</div>
</template>

View File

@@ -5,26 +5,26 @@
>
<template #tool-buttons>
<Button
v-tooltip.bottom="$t('g.refresh')"
icon="pi pi-refresh"
@click="workflowStore.syncWorkflows()"
severity="secondary"
text
v-tooltip.bottom="$t('g.refresh')"
@click="workflowStore.syncWorkflows()"
/>
</template>
<template #header>
<SearchBox
class="workflows-search-box p-2 2xl:p-4"
v-model:modelValue="searchQuery"
@search="handleSearch"
class="workflows-search-box p-2 2xl:p-4"
:placeholder="$t('g.searchWorkflows') + '...'"
@search="handleSearch"
/>
</template>
<template #body>
<div class="comfyui-workflows-panel" v-if="!isSearching">
<div v-if="!isSearching" class="comfyui-workflows-panel">
<div
class="comfyui-workflows-open"
v-if="workflowTabsPosition === 'Sidebar'"
class="comfyui-workflows-open"
>
<TextDivider
:text="t('sideToolbar.workflowTab.workflowTreeType.open')"
@@ -32,9 +32,9 @@
class="ml-2"
/>
<TreeExplorer
:root="renderTreeNode(openWorkflowsTree, WorkflowTreeType.Open)"
:selectionKeys="selectionKeys"
v-model:expandedKeys="dummyExpandedKeys"
:root="renderTreeNode(openWorkflowsTree, WorkflowTreeType.Open)"
:selection-keys="selectionKeys"
>
<template #node="{ node }">
<TreeExplorerTreeNode :node="node">
@@ -60,8 +60,8 @@
</TreeExplorer>
</div>
<div
class="comfyui-workflows-bookmarks"
v-show="workflowStore.bookmarkedWorkflows.length > 0"
class="comfyui-workflows-bookmarks"
>
<TextDivider
:text="t('sideToolbar.workflowTab.workflowTreeType.bookmarks')"
@@ -69,14 +69,14 @@
class="ml-2"
/>
<TreeExplorer
v-model:expandedKeys="dummyExpandedKeys"
:root="
renderTreeNode(
bookmarkedWorkflowsTree,
WorkflowTreeType.Bookmarks
)
"
:selectionKeys="selectionKeys"
v-model:expandedKeys="dummyExpandedKeys"
:selection-keys="selectionKeys"
>
<template #node="{ node }">
<WorkflowTreeLeaf :node="node" />
@@ -90,10 +90,10 @@
class="ml-2"
/>
<TreeExplorer
:root="renderTreeNode(workflowsTree, WorkflowTreeType.Browse)"
v-model:expandedKeys="expandedKeys"
:selectionKeys="selectionKeys"
v-if="workflowStore.persistedWorkflows.length > 0"
v-model:expandedKeys="expandedKeys"
:root="renderTreeNode(workflowsTree, WorkflowTreeType.Browse)"
:selection-keys="selectionKeys"
>
<template #node="{ node }">
<WorkflowTreeLeaf :node="node" />
@@ -107,10 +107,10 @@
/>
</div>
</div>
<div class="comfyui-workflows-search-panel" v-else>
<div v-else class="comfyui-workflows-search-panel">
<TreeExplorer
:root="renderTreeNode(filteredRoot, WorkflowTreeType.Browse)"
v-model:expandedKeys="expandedKeys"
:root="renderTreeNode(filteredRoot, WorkflowTreeType.Browse)"
>
<template #node="{ node }">
<WorkflowTreeLeaf :node="node" />

View File

@@ -13,10 +13,10 @@
</Chip>
</div>
<div
class="mt-2 flex flex-row items-center gap-2"
v-if="
['in_progress', 'paused', 'completed'].includes(download.status ?? '')
"
class="mt-2 flex flex-row items-center gap-2"
>
<!-- Temporary fix for issue when % only comes into view only if the progress bar is large enough
https://comfy-organization.slack.com/archives/C07H3GLKDPF/p1731551013385499
@@ -28,34 +28,34 @@
/>
<Button
class="file-action-button w-[22px] h-[22px]"
size="small"
rounded
@click="triggerPauseDownload"
v-if="download.status === 'in_progress'"
icon="pi pi-pause"
v-tooltip.top="t('electronFileDownload.pause')"
/>
<Button
class="file-action-button w-[22px] h-[22px]"
size="small"
rounded
@click="triggerResumeDownload"
v-if="download.status === 'paused'"
icon="pi pi-play"
v-tooltip.top="t('electronFileDownload.resume')"
icon="pi pi-pause"
@click="triggerPauseDownload"
/>
<Button
v-if="download.status === 'paused'"
v-tooltip.top="t('electronFileDownload.resume')"
class="file-action-button w-[22px] h-[22px]"
size="small"
rounded
icon="pi pi-play"
@click="triggerResumeDownload"
/>
<Button
v-if="['in_progress', 'paused'].includes(download.status ?? '')"
v-tooltip.top="t('electronFileDownload.cancel')"
class="file-action-button w-[22px] h-[22px] p-red"
size="small"
rounded
severity="danger"
@click="triggerCancelDownload"
v-if="['in_progress', 'paused'].includes(download.status ?? '')"
icon="pi pi-times-circle"
v-tooltip.top="t('electronFileDownload.cancel')"
@click="triggerCancelDownload"
/>
</div>
</div>

View File

@@ -1,5 +1,5 @@
<template>
<div class="mx-6 mb-4" v-if="inProgressDownloads.length > 0">
<div v-if="inProgressDownloads.length > 0" class="mx-6 mb-4">
<div class="text-lg my-4">
{{ $t('electronFileDownload.inProgress') }}
</div>

View File

@@ -7,27 +7,27 @@
<div class="model_preview_filename">
{{ modelDef.file_name }}
</div>
<div class="model_preview_architecture" v-if="modelDef.architecture_id">
<div v-if="modelDef.architecture_id" class="model_preview_architecture">
<span class="model_preview_prefix">Architecture: </span>
{{ modelDef.architecture_id }}
</div>
<div class="model_preview_author" v-if="modelDef.author">
<div v-if="modelDef.author" class="model_preview_author">
<span class="model_preview_prefix">Author: </span>
{{ modelDef.author }}
</div>
</div>
<div class="model_preview_image" v-if="modelDef.image">
<div v-if="modelDef.image" class="model_preview_image">
<img :src="modelDef.image" />
</div>
<div class="model_preview_usage_hint" v-if="modelDef.usage_hint">
<div v-if="modelDef.usage_hint" class="model_preview_usage_hint">
<span class="model_preview_prefix">Usage hint: </span>
{{ modelDef.usage_hint }}
</div>
<div class="model_preview_trigger_phrase" v-if="modelDef.trigger_phrase">
<div v-if="modelDef.trigger_phrase" class="model_preview_trigger_phrase">
<span class="model_preview_prefix">Trigger phrase: </span>
{{ modelDef.trigger_phrase }}
</div>
<div class="model_preview_description" v-if="modelDef.description">
<div v-if="modelDef.description" class="model_preview_description">
<span class="model_preview_prefix">Description: </span>
{{ modelDef.description }}
</div>

View File

@@ -6,15 +6,14 @@
<span
class="model-lib-model-icon"
:style="{ backgroundImage: `url(${modelPreviewUrl})` }"
>
</span>
/>
</span>
</template>
</TreeExplorerTreeNode>
<teleport v-if="showPreview" to="#model-library-model-preview-container">
<div class="model-lib-model-preview" :style="modelPreviewStyle">
<ModelPreview ref="previewRef" :modelDef="modelDef"></ModelPreview>
<ModelPreview ref="previewRef" :model-def="modelDef" />
</div>
</teleport>
</div>

View File

@@ -1,9 +1,9 @@
<template>
<TreeExplorer
class="node-lib-bookmark-tree-explorer"
ref="treeExplorerRef"
class="node-lib-bookmark-tree-explorer"
:root="renderedBookmarkedRoot"
:expandedKeys="expandedKeys"
:expanded-keys="expandedKeys"
>
<template #folder="{ node }">
<NodeTreeFolder :node="node" />
@@ -15,9 +15,9 @@
<FolderCustomizationDialog
v-model="showCustomizationDialog"
:initial-icon="initialIcon"
:initial-color="initialColor"
@confirm="updateCustomization"
:initialIcon="initialIcon"
:initialColor="initialColor"
/>
</template>

View File

@@ -1,9 +1,6 @@
<template>
<div ref="container" class="node-lib-node-container">
<TreeExplorerTreeNode
:node="node"
@item-dropped="handleItemDrop"
></TreeExplorerTreeNode>
<TreeExplorerTreeNode :node="node" @item-dropped="handleItemDrop" />
</div>
</template>

Some files were not shown because too many files have changed in this diff Show More