mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-23 08:14:06 +00:00
linting
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, computed } from 'vue';
|
||||
import { watchDebounced } from '@vueuse/core'
|
||||
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import draggable from 'vuedraggable'
|
||||
|
||||
import SearchBox from '@/components/common/SearchBox.vue'
|
||||
import SidebarTabTemplate from '@/components/sidebar/tabs/SidebarTabTemplate.vue'
|
||||
import SubgraphNodeWidget from '@/components/selectionbar/SubgraphNodeWidget.vue'
|
||||
import SidebarTabTemplate from '@/components/sidebar/tabs/SidebarTabTemplate.vue'
|
||||
import { useDomWidgetStore } from '@/stores/domWidgetStore'
|
||||
import { useCanvasStore } from '@/stores/graphStore'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const canvasStore = useCanvasStore()
|
||||
@@ -24,7 +23,7 @@ const activeNode = computed(() => {
|
||||
})
|
||||
|
||||
function keyfn(item) {
|
||||
return `${item[0].title}(${item[0].id}): ${item[1].name}`
|
||||
return `${item[0].title}(${item[0].id}): ${item[1].name}`
|
||||
}
|
||||
const activeWidgets = computed({
|
||||
get() {
|
||||
@@ -60,9 +59,12 @@ function toggleVisibility(nodeId, widgetName, isShown) {
|
||||
} else {
|
||||
const { properties } = node
|
||||
properties.proxyWidgets = properties.proxyWidgets.filter((p) => {
|
||||
return p[1] !== widgetName
|
||||
//NOTE: intentional loose as nodeId is often string/int
|
||||
|| p[0] != nodeId})
|
||||
return (
|
||||
p[1] !== widgetName ||
|
||||
//NOTE: intentional loose as nodeId is often string/int
|
||||
p[0] != nodeId
|
||||
)
|
||||
})
|
||||
}
|
||||
triggerUpdate.value++
|
||||
useCanvasStore().canvas.setDirty(true, true)
|
||||
@@ -70,34 +72,36 @@ function toggleVisibility(nodeId, widgetName, isShown) {
|
||||
|
||||
const candidateWidgets = computed(() => {
|
||||
const node = canvasStore.selectedItems[0]
|
||||
if(!node) return []
|
||||
triggerUpdate.value//mark dependent
|
||||
if (!node) return []
|
||||
triggerUpdate.value //mark dependent
|
||||
const pw = node.properties.proxyWidgets ?? []
|
||||
const interiorNodes = node?.subgraph?.nodes ?? []
|
||||
//node.widgets ??= []
|
||||
const intn = interiorNodes.flatMap((n) =>
|
||||
n.widgets?.map((w) => {
|
||||
return [n,w] ?? []
|
||||
}))
|
||||
const intn = interiorNodes
|
||||
.flatMap((n) =>
|
||||
n.widgets?.map((w) => {
|
||||
return [n, w] ?? []
|
||||
})
|
||||
)
|
||||
//widget has connected link. Should not be displayed
|
||||
.filter(([_, w]) => !w.computedDisabled)
|
||||
.filter(([n,w]) => !pw.some(([pn,pw]) => n.id == pn && w.name == pw))
|
||||
.filter(([n, w]) => !pw.some(([pn, pw]) => n.id == pn && w.name == pw))
|
||||
//TODO: filter enabled/disabled items while keeping order
|
||||
return intn
|
||||
})
|
||||
const filteredCandidates = computed(() => {
|
||||
const query = searchQuery.value.toLowerCase()
|
||||
if (!query) return candidateWidgets.value
|
||||
return candidateWidgets.value.filter(([n,w]) =>
|
||||
n.title.toLowerCase().includes(query)
|
||||
|| w.name.toLowerCase().includes(query)
|
||||
return candidateWidgets.value.filter(
|
||||
([n, w]) =>
|
||||
n.title.toLowerCase().includes(query) ||
|
||||
w.name.toLowerCase().includes(query)
|
||||
)
|
||||
})
|
||||
function showAll() {
|
||||
const node = activeNode.value
|
||||
const pw = node.properties.proxyWidgets ?? []
|
||||
const toAdd = candidateWidgets.value
|
||||
.map(([n,w]) => [n.id, w.name])
|
||||
const toAdd = candidateWidgets.value.map(([n, w]) => [n.id, w.name])
|
||||
pw.push(...toAdd)
|
||||
node.properties.proxyWidgets = pw
|
||||
useCanvasStore().canvas.setDirty(true, true)
|
||||
@@ -113,65 +117,81 @@ function hideAll() {
|
||||
const filteredActive = computed(() => {
|
||||
const query = searchQuery.value.toLowerCase()
|
||||
if (!query) {
|
||||
console.error("displaying filtered widgets with no search query")
|
||||
console.error('displaying filtered widgets with no search query')
|
||||
return activeWidgets.value
|
||||
}
|
||||
return activeWidgets.value.filter(([n,w]) =>
|
||||
n.title.toLowerCase().includes(query)
|
||||
|| w.name.toLowerCase().includes(query)
|
||||
return activeWidgets.value.filter(
|
||||
([n, w]) =>
|
||||
n.title.toLowerCase().includes(query) ||
|
||||
w.name.toLowerCase().includes(query)
|
||||
)
|
||||
})
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<SidebarTabTemplate
|
||||
:title="'Parameters'"
|
||||
class="workflows-sidebar-tab bg-[var(--p-tree-background)]"
|
||||
>
|
||||
>
|
||||
<template #header>
|
||||
<SearchBox
|
||||
v-model:modelValue="searchQuery"
|
||||
class="model-lib-search-box p-2 2xl:p-4"
|
||||
:placeholder="$t('g.search') + '...'"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
v-model:modelValue="searchQuery"
|
||||
class="model-lib-search-box p-2 2xl:p-4"
|
||||
:placeholder="$t('g.search') + '...'"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="widgets-section">
|
||||
<div class="widgets-section-header">
|
||||
<div> {{t('subgraphStore.shown')}}</div>
|
||||
<a @click.stop="hideAll" > {{t('subgraphStore.hideAll')}}</a>
|
||||
<div>{{ t('subgraphStore.shown') }}</div>
|
||||
<a @click.stop="hideAll"> {{ t('subgraphStore.hideAll') }}</a>
|
||||
</div>
|
||||
<div v-if="searchQuery"
|
||||
v-for="element in filteredActive" class="widget-container">
|
||||
<SubgraphNodeWidget :item="element" :node="activeNode"
|
||||
:toggleVisibility="toggleVisibility" :isShown="true"/>
|
||||
<div
|
||||
v-for="element in filteredActive"
|
||||
v-if="searchQuery"
|
||||
class="widget-container"
|
||||
>
|
||||
<SubgraphNodeWidget
|
||||
:item="element"
|
||||
:node="activeNode"
|
||||
:toggle-visibility="toggleVisibility"
|
||||
:is-shown="true"
|
||||
/>
|
||||
</div>
|
||||
<draggable
|
||||
<draggable
|
||||
v-else
|
||||
v-model="activeWidgets"
|
||||
group="enabledWidgets"
|
||||
class="widget-container draggable-item"
|
||||
chosenClass="dragged-item"
|
||||
dragClass="dragged-item"
|
||||
chosen-class="dragged-item"
|
||||
drag-class="dragged-item"
|
||||
:animation="100"
|
||||
@start="drag=true"
|
||||
@end="drag=false"
|
||||
item-key="id"
|
||||
v-else>
|
||||
<template #item="{element}">
|
||||
<SubgraphNodeWidget :item="element" :node="activeNode" :isShown="true"
|
||||
:toggleVisibility="toggleVisibility" :isDraggable="true"/>
|
||||
</template>
|
||||
</draggable>
|
||||
@start="drag = true"
|
||||
@end="drag = false"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<SubgraphNodeWidget
|
||||
:item="element"
|
||||
:node="activeNode"
|
||||
:is-shown="true"
|
||||
:toggle-visibility="toggleVisibility"
|
||||
:is-draggable="true"
|
||||
/>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
<div class="widgets-section">
|
||||
<div class="widgets-section-header">
|
||||
<div> {{t('subgraphStore.hidden')}}</div>
|
||||
<a @click.stop="showAll"> {{t('subgraphStore.showAll')}}</a>
|
||||
<div>{{ t('subgraphStore.hidden') }}</div>
|
||||
<a @click.stop="showAll"> {{ t('subgraphStore.showAll') }}</a>
|
||||
</div>
|
||||
<div v-for="element in filteredCandidates" class="widget-container">
|
||||
<SubgraphNodeWidget :item="element" :node="activeNode"
|
||||
:toggleVisibility="toggleVisibility"/>
|
||||
<SubgraphNodeWidget
|
||||
:item="element"
|
||||
:node="activeNode"
|
||||
:toggle-visibility="toggleVisibility"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -179,7 +199,7 @@ const filteredActive = computed(() => {
|
||||
</template>
|
||||
<style scoped>
|
||||
.widget-container {
|
||||
width: 100%
|
||||
width: 100%;
|
||||
}
|
||||
.widgets-section-header {
|
||||
display: flex;
|
||||
@@ -189,7 +209,7 @@ const filteredActive = computed(() => {
|
||||
align-self: stretch;
|
||||
}
|
||||
.widgets-section-header div {
|
||||
color: var(--color-text-secondary, #9C9EAB);
|
||||
color: var(--color-text-secondary, #9c9eab);
|
||||
/* body-text-badge */
|
||||
font-family: Inter;
|
||||
font-size: 9px;
|
||||
@@ -200,7 +220,7 @@ const filteredActive = computed(() => {
|
||||
}
|
||||
.widgets-section-header a {
|
||||
cursor: pointer;
|
||||
color: var(--color-base-blue-primary, #0B8CE9);
|
||||
color: var(--color-base-blue-primary, #0b8ce9);
|
||||
text-align: right;
|
||||
|
||||
/* body-text-caption */
|
||||
@@ -218,7 +238,7 @@ const filteredActive = computed(() => {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
align-self: stretch;
|
||||
border-bottom: 1px solid var(--color-node-divider, #2E3037);
|
||||
border-bottom: 1px solid var(--color-node-divider, #2e3037);
|
||||
}
|
||||
.dragged-item {
|
||||
cursor: grabbing;
|
||||
@@ -226,5 +246,4 @@ const filteredActive = computed(() => {
|
||||
.draggable-item {
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,40 +1,34 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import Button from 'primevue/button'
|
||||
import { useCanvasStore } from '@/stores/graphStore'
|
||||
|
||||
import TreeExplorerTreeNode from '@/components/common/TreeExplorerTreeNode.vue'
|
||||
import { RenderedTreeExplorerNode } from '@/types/treeExplorerTypes'
|
||||
|
||||
const props = defineProps<{
|
||||
item: [unknown, unknown],
|
||||
node: unknown,
|
||||
isShown?: boolean,
|
||||
isDraggable?: boolean,
|
||||
item: [unknown, unknown]
|
||||
node: unknown
|
||||
isShown?: boolean
|
||||
isDraggable?: boolean
|
||||
toggleVisibility
|
||||
}>()
|
||||
|
||||
function onClick(e) {
|
||||
props.toggleVisibility(`${props.item[0].id}`, props.item[1].name, props.isShown)
|
||||
props.toggleVisibility(
|
||||
`${props.item[0].id}`,
|
||||
props.item[1].name,
|
||||
props.isShown
|
||||
)
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="widget-item">
|
||||
<div class="icon">
|
||||
<i-lucide:grip-vertical v-if="isDraggable"/>
|
||||
<i-lucide:grip-vertical v-if="isDraggable" />
|
||||
</div>
|
||||
<div class="widget-title">
|
||||
<div class="widget-node">{{item[0].title}}</div>
|
||||
<div class="widget-name">{{item[1].name}}</div>
|
||||
<div class="widget-node">{{ item[0].title }}</div>
|
||||
<div class="widget-name">{{ item[1].name }}</div>
|
||||
</div>
|
||||
<Button
|
||||
size="small"
|
||||
text
|
||||
severity="secondary"
|
||||
@click.stop="onClick"
|
||||
>
|
||||
<i-lucide:eye v-if="isShown"/>
|
||||
<i-lucide:eye-off v-else/>
|
||||
<Button size="small" text severity="secondary" @click.stop="onClick">
|
||||
<i-lucide:eye v-if="isShown" />
|
||||
<i-lucide:eye-off v-else />
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -65,7 +59,7 @@ function onClick(e) {
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
align-self: stretch;
|
||||
color: var(--color-text-secondary, #9C9EAB);
|
||||
color: var(--color-text-secondary, #9c9eab);
|
||||
|
||||
/* heading-text-nav */
|
||||
font-family: Inter;
|
||||
@@ -75,7 +69,7 @@ function onClick(e) {
|
||||
line-height: normal;
|
||||
}
|
||||
.widget-name {
|
||||
color: var(--color-text-primary, #FFF);
|
||||
color: var(--color-text-primary, #fff);
|
||||
|
||||
/* body-text-small */
|
||||
font-family: Inter;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { markRaw } from 'vue'
|
||||
|
||||
import SubgraphNode from '@/components/selectionbar/SubgraphNode.vue'
|
||||
|
||||
@@ -23,6 +23,7 @@ import type {
|
||||
import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets'
|
||||
import type { UUID } from '@/lib/litegraph/src/utils/uuid'
|
||||
import { toConcreteWidget } from '@/lib/litegraph/src/widgets/widgetMap'
|
||||
import { useDomWidgetStore } from '@/stores/domWidgetStore'
|
||||
|
||||
import {
|
||||
type ExecutableLGraphNode,
|
||||
@@ -31,8 +32,6 @@ import {
|
||||
} from './ExecutableNodeDTO'
|
||||
import type { SubgraphInput } from './SubgraphInput'
|
||||
|
||||
import { useDomWidgetStore } from '@/stores/domWidgetStore'
|
||||
|
||||
/**
|
||||
* An instance of a {@link Subgraph}, displayed as a node on the containing (parent) graph.
|
||||
*/
|
||||
@@ -313,7 +312,8 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph {
|
||||
const proxyWidgets = this.properties.proxyWidgets
|
||||
Object.defineProperty(this.properties, 'proxyWidgets', {
|
||||
get: () => {
|
||||
return this.widgets.filter((w) => !!w._overlay)
|
||||
return this.widgets
|
||||
.filter((w) => !!w._overlay)
|
||||
.map((w) => [w._overlay.nodeId, w._overlay.widgetName])
|
||||
},
|
||||
set: (property) => {
|
||||
@@ -325,7 +325,7 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph {
|
||||
//NOTE: This does not apply to pushed entries, only initial load
|
||||
this.widgets = this.widgets.filter((w) => !w._overlay)
|
||||
for (const [nodeId, widgetName] of property) {
|
||||
const w = this.addProxyWidget(`${nodeId}`, widgetName)
|
||||
const w = this.addProxyWidget(`${nodeId}`, widgetName)
|
||||
if (w.id && widgetStates.has(w.id)) {
|
||||
const widgetState = widgetStates.get(w.id)
|
||||
widgetState.active = true
|
||||
@@ -608,10 +608,10 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph {
|
||||
return super.serialize()
|
||||
}
|
||||
addProxyWidget(nodeId: string, widgetName: string) {
|
||||
const overlay = {nodeId, widgetName}
|
||||
return this.addProxyFromOverlay({__proto__:overlay})
|
||||
const overlay = { nodeId, widgetName }
|
||||
return this.addProxyFromOverlay({ __proto__: overlay })
|
||||
}
|
||||
addProxyFromOverlay(overlay: Object) {
|
||||
addProxyFromOverlay(overlay: object) {
|
||||
overlay.label = `${overlay.nodeId}: ${overlay.widgetName}`
|
||||
overlay.graph = this.subgraph
|
||||
overlay.isProxyWidget = true
|
||||
@@ -619,47 +619,59 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph {
|
||||
//use a weakref and only trigger recalc on calls when undefined?
|
||||
//TODO: call toConcrete when resolved and hold reference?
|
||||
const subgraphNode = this
|
||||
function linkedWidget(graph, nodeId="", widgetName) {
|
||||
let g = graph
|
||||
function linkedWidget(graph, nodeId = '', widgetName) {
|
||||
const g = graph
|
||||
let n = undefined
|
||||
for (let id of nodeId.split(':')) {
|
||||
for (const id of nodeId.split(':')) {
|
||||
n = g?._nodes_by_id?.[id]
|
||||
graph = n?.subgraph
|
||||
}
|
||||
if (!n) return
|
||||
return n.widgets.find((w) => w.name === widgetName)
|
||||
return n.widgets.find((w) => w.name === widgetName)
|
||||
}
|
||||
let lw = undefined
|
||||
const handler = Object.fromEntries(['get', 'set', 'getPrototypeOf', 'ownKeys', 'has'].map((s) => {
|
||||
const func = function(t,p,...rest) {
|
||||
if (s == 'get' && p == '_overlay')
|
||||
return overlay
|
||||
if (!lw) {
|
||||
lw = linkedWidget(overlay.graph, overlay.nodeId, overlay.widgetName)
|
||||
const handler = Object.fromEntries(
|
||||
['get', 'set', 'getPrototypeOf', 'ownKeys', 'has'].map((s) => {
|
||||
const func = function (t, p, ...rest) {
|
||||
if (s == 'get' && p == '_overlay') return overlay
|
||||
if (!lw) {
|
||||
lw = linkedWidget(overlay.graph, overlay.nodeId, overlay.widgetName)
|
||||
}
|
||||
if (s == 'get' && p == 'node') {
|
||||
return subgraphNode
|
||||
}
|
||||
if (s == 'set' && p == 'computedDisabled') {
|
||||
//ignore setting, calc actual
|
||||
lw.computedDisabled =
|
||||
lw.disabled || lw.node.getSlotFromWidget(lw)?.link != null
|
||||
return true
|
||||
}
|
||||
//NOTE: p may be undefined
|
||||
let r = rest.at(-1)
|
||||
if (
|
||||
[
|
||||
'y',
|
||||
'last_y',
|
||||
'width',
|
||||
'computedHeight',
|
||||
'afterQueued',
|
||||
'beforeQueued',
|
||||
'onRemove',
|
||||
'isProxyWidget',
|
||||
'label'
|
||||
].includes(p)
|
||||
)
|
||||
t = overlay
|
||||
else {
|
||||
t = lw
|
||||
if (!t) t = { __proto__: overlay, draw: drawDisconnected }
|
||||
if (p == 'value') r = t
|
||||
}
|
||||
return Reflect[s](t, p, ...rest.slice(0, -1), r)
|
||||
}
|
||||
if (s == 'get' && p == 'node') {
|
||||
return subgraphNode
|
||||
}
|
||||
if (s == 'set' && p == 'computedDisabled') {
|
||||
//ignore setting, calc actual
|
||||
lw.computedDisabled = lw.disabled || lw.node.getSlotFromWidget(lw)?.link != null
|
||||
return true
|
||||
}
|
||||
//NOTE: p may be undefined
|
||||
let r = rest.at(-1)
|
||||
if (['y', 'last_y', 'width', 'computedHeight', 'afterQueued', 'beforeQueued', 'onRemove', 'isProxyWidget', 'label'].includes(p))
|
||||
t = overlay
|
||||
else {
|
||||
t = lw
|
||||
if (!t)
|
||||
t = {__proto__: overlay, draw: drawDisconnected}
|
||||
if (p == "value")
|
||||
r = t
|
||||
}
|
||||
return Reflect[s](t,p,...rest.slice(0,-1),r)
|
||||
}
|
||||
return [s, func]
|
||||
}))
|
||||
return [s, func]
|
||||
})
|
||||
)
|
||||
const w = new Proxy(overlay, handler)
|
||||
this.widgets.push(w)
|
||||
return w
|
||||
|
||||
@@ -4,8 +4,8 @@ import { computed, ref } from 'vue'
|
||||
import { useModelLibrarySidebarTab } from '@/composables/sidebarTabs/useModelLibrarySidebarTab'
|
||||
import { useNodeLibrarySidebarTab } from '@/composables/sidebarTabs/useNodeLibrarySidebarTab'
|
||||
import { useQueueSidebarTab } from '@/composables/sidebarTabs/useQueueSidebarTab'
|
||||
import { useWorkflowsSidebarTab } from '@/composables/sidebarTabs/useWorkflowsSidebarTab'
|
||||
import { useSubgraphNodeTab } from '@/composables/sidebarTabs/useSubgraphNodeTab'
|
||||
import { useWorkflowsSidebarTab } from '@/composables/sidebarTabs/useWorkflowsSidebarTab'
|
||||
import { t, te } from '@/i18n'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useMenuItemStore } from '@/stores/menuItemStore'
|
||||
|
||||
Reference in New Issue
Block a user