mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-11 08:00:21 +00:00
feat/fix: App mode further updates (#9545)
## Summary Additional updates ## Changes - **What**: - Share widget rename functionality with properties panel implementation - Add hammer icon to builder mode tabs - Change (!) to (i) on app builder info sections ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9545-feat-fix-App-mode-further-updates-31c6d73d36508104aaa9c5f1e6205a0b) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -10,7 +10,6 @@ import PropertiesAccordionItem from '@/components/rightSidePanel/layout/Properti
|
||||
import WidgetItem from '@/components/rightSidePanel/parameters/WidgetItem.vue'
|
||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import type { LGraphNode, NodeId } from '@/lib/litegraph/src/LGraphNode'
|
||||
import type { INodeInputSlot } from '@/lib/litegraph/src/interfaces'
|
||||
import type { LGraphCanvas } from '@/lib/litegraph/src/LGraphCanvas'
|
||||
import {
|
||||
LGraphEventMode,
|
||||
@@ -25,7 +24,7 @@ import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteracti
|
||||
import TransformPane from '@/renderer/core/layout/transform/TransformPane.vue'
|
||||
import { app } from '@/scripts/app'
|
||||
import { DOMWidgetImpl } from '@/scripts/domWidget'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { promptRenameWidget } from '@/utils/widgetUtil'
|
||||
import { useAppMode } from '@/composables/useAppMode'
|
||||
import { nodeTypeValidForApp, useAppModeStore } from '@/stores/appModeStore'
|
||||
import { resolveNode } from '@/utils/litegraphUtil'
|
||||
@@ -73,15 +72,12 @@ const inputsWithState = computed(() =>
|
||||
}
|
||||
}
|
||||
|
||||
const input = node.inputs.find((i) => i.widget?.name === widget.name)
|
||||
const rename = input && (() => renameWidget(widget, input))
|
||||
|
||||
return {
|
||||
nodeId,
|
||||
widgetName,
|
||||
label: widget.label,
|
||||
subLabel: node.title,
|
||||
rename
|
||||
rename: () => promptRenameWidget(widget, node, t)
|
||||
}
|
||||
})
|
||||
)
|
||||
@@ -92,20 +88,6 @@ const outputsWithState = computed<[NodeId, string][]>(() =>
|
||||
])
|
||||
)
|
||||
|
||||
async function renameWidget(widget: IBaseWidget, input: INodeInputSlot) {
|
||||
const newLabel = await useDialogService().prompt({
|
||||
title: t('g.rename'),
|
||||
message: t('g.enterNewNamePrompt'),
|
||||
defaultValue: widget.label,
|
||||
placeholder: widget.name
|
||||
})
|
||||
if (newLabel === null) return
|
||||
widget.label = newLabel || undefined
|
||||
input.label = newLabel || undefined
|
||||
widget.callback?.(widget.value)
|
||||
useCanvasStore().canvas?.setDirty(true)
|
||||
}
|
||||
|
||||
function getHovered(
|
||||
e: MouseEvent
|
||||
): undefined | [LGraphNode, undefined] | [LGraphNode, IBaseWidget] {
|
||||
@@ -266,7 +248,7 @@ const renderedInputs = computed<[string, MaybeRef<BoundStyle> | undefined][]>(
|
||||
<template #label>
|
||||
<div class="flex gap-3">
|
||||
{{ t('nodeHelpPage.inputs') }}
|
||||
<i class="icon-[lucide--circle-alert] bg-muted-foreground" />
|
||||
<i class="icon-[lucide--info] bg-muted-foreground" />
|
||||
</div>
|
||||
</template>
|
||||
<template #empty>
|
||||
@@ -321,7 +303,7 @@ const renderedInputs = computed<[string, MaybeRef<BoundStyle> | undefined][]>(
|
||||
<template #label>
|
||||
<div class="flex gap-3">
|
||||
{{ t('nodeHelpPage.outputs') }}
|
||||
<i class="icon-[lucide--circle-alert] bg-muted-foreground" />
|
||||
<i class="icon-[lucide--info] bg-muted-foreground" />
|
||||
</div>
|
||||
</template>
|
||||
<template #empty>
|
||||
|
||||
@@ -15,10 +15,9 @@ import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import type { SubgraphNode } from '@/lib/litegraph/src/subgraph/SubgraphNode'
|
||||
import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useNodeDefStore } from '@/stores/nodeDefStore'
|
||||
import { useFavoritedWidgetsStore } from '@/stores/workspace/favoritedWidgetsStore'
|
||||
import { getWidgetDefaultValue } from '@/utils/widgetUtil'
|
||||
import { getWidgetDefaultValue, promptWidgetLabel } from '@/utils/widgetUtil'
|
||||
import type { WidgetValue } from '@/utils/widgetUtil'
|
||||
|
||||
const {
|
||||
@@ -42,7 +41,6 @@ const label = defineModel<string>('label', { required: true })
|
||||
const canvasStore = useCanvasStore()
|
||||
const favoritedWidgetsStore = useFavoritedWidgetsStore()
|
||||
const nodeDefStore = useNodeDefStore()
|
||||
const dialogService = useDialogService()
|
||||
const { t } = useI18n()
|
||||
|
||||
const hasParents = computed(() => parents?.length > 0)
|
||||
@@ -67,15 +65,8 @@ const isCurrentValueDefault = computed(() => {
|
||||
})
|
||||
|
||||
async function handleRename() {
|
||||
const newLabel = await dialogService.prompt({
|
||||
title: t('g.rename'),
|
||||
message: t('g.enterNewNamePrompt'),
|
||||
defaultValue: widget.label,
|
||||
placeholder: widget.name
|
||||
})
|
||||
|
||||
if (newLabel === null) return
|
||||
label.value = newLabel
|
||||
const newLabel = await promptWidgetLabel(widget, t)
|
||||
if (newLabel !== null) label.value = newLabel
|
||||
}
|
||||
|
||||
function handleHideInput() {
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
@mouseup="handleMouseUp"
|
||||
@click="handleClick"
|
||||
>
|
||||
<i v-if="isBuilderState" class="bg-text-subtle icon-[lucide--hammer]" />
|
||||
<i
|
||||
v-if="workflowOption.workflow.initialMode === 'app'"
|
||||
v-else-if="workflowOption.workflow.initialMode === 'app'"
|
||||
class="icon-[lucide--panels-top-left] bg-primary-background"
|
||||
/>
|
||||
<span
|
||||
@@ -149,6 +150,11 @@ const shouldShowStatusIndicator = computed(() => {
|
||||
return false
|
||||
})
|
||||
|
||||
const isBuilderState = computed(() => {
|
||||
const currentMode = props.workflowOption.workflow.activeMode
|
||||
return typeof currentMode === 'string' && currentMode.startsWith('builder:')
|
||||
})
|
||||
|
||||
const isActiveTab = computed(() => {
|
||||
return workflowStore.activeWorkflow?.key === props.workflowOption.workflow.key
|
||||
})
|
||||
|
||||
@@ -3,7 +3,9 @@ import { resolvePromotedWidgetSource } from '@/core/graph/subgraph/resolvePromot
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||
import type { SubgraphNode } from '@/lib/litegraph/src/subgraph/SubgraphNode'
|
||||
import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import type { InputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
|
||||
export type WidgetValue = boolean | number | string | object | undefined
|
||||
|
||||
@@ -75,3 +77,34 @@ export function renameWidget(
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
export async function promptWidgetLabel(
|
||||
widget: IBaseWidget,
|
||||
t: (key: string) => string
|
||||
): Promise<string | null> {
|
||||
return useDialogService().prompt({
|
||||
title: t('g.rename'),
|
||||
message: t('g.enterNewNamePrompt'),
|
||||
defaultValue: widget.label,
|
||||
placeholder: widget.name
|
||||
})
|
||||
}
|
||||
|
||||
export async function promptRenameWidget(
|
||||
widget: IBaseWidget,
|
||||
node: LGraphNode,
|
||||
t: (key: string) => string,
|
||||
parents?: SubgraphNode[]
|
||||
): Promise<string | null> {
|
||||
const rawLabel = await promptWidgetLabel(widget, t)
|
||||
if (rawLabel === null) return null
|
||||
|
||||
const normalizedLabel = rawLabel.trim()
|
||||
if (!normalizedLabel) return null
|
||||
|
||||
if (!renameWidget(widget, node, normalizedLabel, parents)) return null
|
||||
|
||||
widget.callback?.(widget.value)
|
||||
useCanvasStore().canvas?.setDirty(true)
|
||||
return normalizedLabel
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user