mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-31 05:19:53 +00:00
[TS] Fix ts-strict errors in Vue components (Part 1) (#3119)
This commit is contained in:
@@ -28,7 +28,7 @@ const handleKey = (e: KeyboardEvent) => {
|
||||
useEventListener(window, 'keydown', handleKey)
|
||||
useEventListener(window, 'keyup', handleKey)
|
||||
|
||||
const showContextMenu = (event: PointerEvent) => {
|
||||
const showContextMenu = (event: MouseEvent) => {
|
||||
const { target } = event
|
||||
switch (true) {
|
||||
case target instanceof HTMLTextAreaElement:
|
||||
|
||||
@@ -135,8 +135,11 @@ const hasPendingTasks = computed(
|
||||
)
|
||||
|
||||
const commandStore = useCommandStore()
|
||||
const queuePrompt = (e: MouseEvent) => {
|
||||
const commandId = e.shiftKey ? 'Comfy.QueuePromptFront' : 'Comfy.QueuePrompt'
|
||||
const queuePrompt = (e: Event) => {
|
||||
const commandId =
|
||||
'shiftKey' in e && e.shiftKey
|
||||
? 'Comfy.QueuePromptFront'
|
||||
: 'Comfy.QueuePrompt'
|
||||
commandStore.execute(commandId)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -12,11 +12,11 @@ import { Ref, onUnmounted, ref } from 'vue'
|
||||
import { useTerminal } from '@/composables/bottomPanelTabs/useTerminal'
|
||||
|
||||
const emit = defineEmits<{
|
||||
created: [ReturnType<typeof useTerminal>, Ref<HTMLElement>]
|
||||
created: [ReturnType<typeof useTerminal>, Ref<HTMLElement | undefined>]
|
||||
unmounted: []
|
||||
}>()
|
||||
const terminalEl = ref<HTMLElement>()
|
||||
const rootEl = ref<HTMLElement>()
|
||||
const terminalEl = ref<HTMLElement | undefined>()
|
||||
const rootEl = ref<HTMLElement | undefined>()
|
||||
emit('created', useTerminal(terminalEl), rootEl)
|
||||
|
||||
onUnmounted(() => emit('unmounted'))
|
||||
|
||||
@@ -13,7 +13,7 @@ import BaseTerminal from './BaseTerminal.vue'
|
||||
|
||||
const terminalCreated = (
|
||||
{ terminal, useAutoSize }: ReturnType<typeof useTerminal>,
|
||||
root: Ref<HTMLElement>
|
||||
root: Ref<HTMLElement | undefined>
|
||||
) => {
|
||||
const terminalApi = electronAPI().Terminal
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ const loading = ref(true)
|
||||
|
||||
const terminalCreated = (
|
||||
{ terminal, useAutoSize }: ReturnType<typeof useTerminal>,
|
||||
root: Ref<HTMLElement>
|
||||
root: Ref<HTMLElement | undefined>
|
||||
) => {
|
||||
// `autoCols` is false because we don't want the progress bar in the terminal
|
||||
// to render incorrectly as the progress bar is rendered based on the
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
<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>{{ formatValue(props.device[col.field], col.field) }}</div>
|
||||
<div>
|
||||
{{ formatValue(props.device[col.field], col.field) }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@@ -15,7 +17,7 @@ const props = defineProps<{
|
||||
device: DeviceStats
|
||||
}>()
|
||||
|
||||
const deviceColumns = [
|
||||
const deviceColumns: { field: keyof DeviceStats; header: string }[] = [
|
||||
{ field: 'name', header: 'Name' },
|
||||
{ field: 'type', header: 'Type' },
|
||||
{ field: 'vram_total', header: 'VRAM Total' },
|
||||
|
||||
@@ -38,9 +38,10 @@ const props = withDefaults(defineProps<EditableTextProps>(), {
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'edit'])
|
||||
const inputValue = ref<string>(props.modelValue)
|
||||
const inputRef = ref(null)
|
||||
const inputRef = ref<InstanceType<typeof InputText> | undefined>()
|
||||
|
||||
const blurInputElement = () => {
|
||||
// @ts-expect-error - $el is an internal property of the InputText component
|
||||
inputRef.value?.$el.blur()
|
||||
}
|
||||
const finishEditing = () => {
|
||||
@@ -58,6 +59,7 @@ watch(
|
||||
: inputValue.value
|
||||
const start = 0
|
||||
const end = fileName.length
|
||||
// @ts-expect-error - $el is an internal property of the InputText component
|
||||
const inputElement = inputRef.value.$el
|
||||
inputElement.setSelectionRange?.(start, end)
|
||||
})
|
||||
|
||||
@@ -72,7 +72,7 @@ function getFormAttrs(item: FormItem) {
|
||||
item.options(formValue.value)
|
||||
: item.options
|
||||
|
||||
if (typeof item.options[0] !== 'string') {
|
||||
if (typeof item.options?.[0] !== 'string') {
|
||||
attrs['optionLabel'] = 'text'
|
||||
attrs['optionValue'] = 'value'
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ const updateValue = (newValue: number | null) => {
|
||||
|
||||
const displayValue = (value: number): string => {
|
||||
updateValue(value)
|
||||
const stepString = props.step.toString()
|
||||
const stepString = (props.step ?? 1).toString()
|
||||
const resolution = stepString.includes('.')
|
||||
? stepString.split('.')[1].length
|
||||
: 0
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="input-slider flex flex-row items-center gap-2">
|
||||
<Slider
|
||||
:modelValue="modelValue"
|
||||
@update:modelValue="updateValue"
|
||||
@update:modelValue="(value) => updateValue(value as number)"
|
||||
class="slider-part"
|
||||
:class="sliderClass"
|
||||
:min="min"
|
||||
|
||||
@@ -48,15 +48,16 @@ const systemInfo = computed(() => ({
|
||||
argv: props.stats.system.argv.join(' ')
|
||||
}))
|
||||
|
||||
const systemColumns = [
|
||||
{ field: 'os', header: 'OS' },
|
||||
{ field: 'python_version', header: 'Python Version' },
|
||||
{ field: 'embedded_python', header: 'Embedded Python' },
|
||||
{ field: 'pytorch_version', header: 'Pytorch Version' },
|
||||
{ field: 'argv', header: 'Arguments' },
|
||||
{ field: 'ram_total', header: 'RAM Total' },
|
||||
{ field: 'ram_free', header: 'RAM Free' }
|
||||
]
|
||||
const systemColumns: { field: keyof SystemStats['system']; header: string }[] =
|
||||
[
|
||||
{ field: 'os', header: 'OS' },
|
||||
{ field: 'python_version', header: 'Python Version' },
|
||||
{ field: 'embedded_python', header: 'Embedded Python' },
|
||||
{ field: 'pytorch_version', header: 'Pytorch Version' },
|
||||
{ field: 'argv', header: 'Arguments' },
|
||||
{ field: 'ram_total', header: 'RAM Total' },
|
||||
{ field: 'ram_free', header: 'RAM Free' }
|
||||
]
|
||||
|
||||
const formatValue = (value: any, field: string) => {
|
||||
if (['ram_total', 'ram_free'].includes(field)) {
|
||||
|
||||
@@ -53,7 +53,9 @@ import {
|
||||
} from '@/types/treeExplorerTypes'
|
||||
import { combineTrees, findNodeByKey } from '@/utils/treeUtil'
|
||||
|
||||
const expandedKeys = defineModel<Record<string, boolean>>('expandedKeys')
|
||||
const expandedKeys = defineModel<Record<string, boolean>>('expandedKeys', {
|
||||
required: true
|
||||
})
|
||||
provide(InjectKeyExpandedKeys, expandedKeys)
|
||||
const selectionKeys = defineModel<Record<string, boolean>>('selectionKeys')
|
||||
// Tracks whether the caller has set the selectionKeys model.
|
||||
@@ -103,7 +105,7 @@ const getTreeNodeIcon = (node: TreeExplorerNode) => {
|
||||
return isExpanded ? 'pi pi-folder-open' : 'pi pi-folder'
|
||||
}
|
||||
const fillNodeInfo = (node: TreeExplorerNode): RenderedTreeExplorerNode => {
|
||||
const children = node.children?.map(fillNodeInfo)
|
||||
const children = node.children?.map(fillNodeInfo) ?? []
|
||||
const totalLeaves = node.leaf
|
||||
? 1
|
||||
: children.reduce((acc, child) => acc + child.totalLeaves, 0)
|
||||
@@ -113,7 +115,7 @@ const fillNodeInfo = (node: TreeExplorerNode): RenderedTreeExplorerNode => {
|
||||
children,
|
||||
type: node.leaf ? 'node' : 'folder',
|
||||
totalLeaves,
|
||||
badgeText: node.getBadgeText ? node.getBadgeText() : null,
|
||||
badgeText: node.getBadgeText ? node.getBadgeText() : undefined,
|
||||
isEditingLabel: node.key === renameEditingNode.value?.key
|
||||
}
|
||||
}
|
||||
@@ -149,7 +151,7 @@ const handleNodeLabelEdit = async (
|
||||
if (node.key === newFolderNode.value?.key) {
|
||||
await handleFolderCreation(newName)
|
||||
} else {
|
||||
await node.handleRename(newName)
|
||||
await node.handleRename?.(newName)
|
||||
}
|
||||
},
|
||||
node.handleError,
|
||||
|
||||
@@ -76,10 +76,10 @@ const nodeBadgeText = computed<string>(() => {
|
||||
})
|
||||
const showNodeBadgeText = computed<boolean>(() => nodeBadgeText.value !== '')
|
||||
|
||||
const isEditing = computed<boolean>(() => props.node.isEditingLabel)
|
||||
const isEditing = computed<boolean>(() => props.node.isEditingLabel ?? false)
|
||||
const handleEditLabel = inject(InjectKeyHandleEditLabelFunction)
|
||||
const handleRename = (newName: string) => {
|
||||
handleEditLabel(props.node, newName)
|
||||
handleEditLabel?.(props.node, newName)
|
||||
}
|
||||
|
||||
const container = ref<HTMLElement | null>(null)
|
||||
@@ -102,7 +102,7 @@ if (props.node.draggable) {
|
||||
? ({ nativeSetDragImage }) => {
|
||||
setCustomNativeDragPreview({
|
||||
render: ({ container }) => {
|
||||
return props.node.renderDragPreview(container)
|
||||
return props.node.renderDragPreview?.(container)
|
||||
},
|
||||
nativeSetDragImage
|
||||
})
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
<TreeExplorer
|
||||
:root="renderTreeNode(openWorkflowsTree, WorkflowTreeType.Open)"
|
||||
:selectionKeys="selectionKeys"
|
||||
v-model:expandedKeys="dummyExpandedKeys"
|
||||
>
|
||||
<template #node="{ node }">
|
||||
<TreeExplorerTreeNode :node="node">
|
||||
@@ -75,6 +76,7 @@
|
||||
)
|
||||
"
|
||||
:selectionKeys="selectionKeys"
|
||||
v-model:expandedKeys="dummyExpandedKeys"
|
||||
>
|
||||
<template #node="{ node }">
|
||||
<WorkflowTreeLeaf :node="node" />
|
||||
@@ -179,6 +181,7 @@ const workspaceStore = useWorkspaceStore()
|
||||
const { t } = useI18n()
|
||||
const expandedKeys = ref<Record<string, boolean>>({})
|
||||
const { expandNode, toggleNodeOnEvent } = useTreeExpansion(expandedKeys)
|
||||
const dummyExpandedKeys = ref<Record<string, boolean>>({})
|
||||
|
||||
const handleCloseWorkflow = (workflow?: ComfyWorkflow) => {
|
||||
if (workflow) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import '@xterm/xterm/css/xterm.css'
|
||||
import { debounce } from 'lodash'
|
||||
import { Ref, markRaw, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
export function useTerminal(element: Ref<HTMLElement>) {
|
||||
export function useTerminal(element: Ref<HTMLElement | undefined>) {
|
||||
const fitAddon = new FitAddon()
|
||||
const terminal = markRaw(
|
||||
new Terminal({
|
||||
@@ -27,7 +27,9 @@ export function useTerminal(element: Ref<HTMLElement>) {
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
terminal.open(element.value)
|
||||
if (element.value) {
|
||||
terminal.open(element.value)
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
@@ -44,16 +46,16 @@ export function useTerminal(element: Ref<HTMLElement>) {
|
||||
minRows = Number.NEGATIVE_INFINITY,
|
||||
onResize
|
||||
}: {
|
||||
root: Ref<HTMLElement>
|
||||
root: Ref<HTMLElement | undefined>
|
||||
autoRows?: boolean
|
||||
autoCols?: boolean
|
||||
minCols?: number
|
||||
minRows?: number
|
||||
onResize?: () => void
|
||||
}) {
|
||||
const ensureValidRows = (rows: number | undefined) => {
|
||||
const ensureValidRows = (rows: number | undefined): number => {
|
||||
if (rows == null || isNaN(rows)) {
|
||||
return root.value?.clientHeight / 20
|
||||
return (root.value?.clientHeight ?? 80) / 20
|
||||
}
|
||||
return rows
|
||||
}
|
||||
@@ -61,7 +63,7 @@ export function useTerminal(element: Ref<HTMLElement>) {
|
||||
const ensureValidCols = (cols: number | undefined): number => {
|
||||
if (cols == null || isNaN(cols)) {
|
||||
// Sometimes this is NaN if so, estimate.
|
||||
return root.value?.clientWidth / 8
|
||||
return (root.value?.clientWidth ?? 80) / 8
|
||||
}
|
||||
return cols
|
||||
}
|
||||
@@ -85,8 +87,10 @@ export function useTerminal(element: Ref<HTMLElement>) {
|
||||
const resizeObserver = new ResizeObserver(debounce(resize, 25))
|
||||
|
||||
onMounted(async () => {
|
||||
resizeObserver.observe(root.value)
|
||||
resize()
|
||||
if (root.value) {
|
||||
resizeObserver.observe(root.value)
|
||||
resize()
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
|
||||
@@ -21,7 +21,7 @@ export const useBottomPanelStore = defineStore('bottomPanel', () => {
|
||||
}
|
||||
|
||||
const bottomPanelTabs = ref<BottomPanelExtension[]>([])
|
||||
const activeBottomPanelTabId = ref<string | null>(null)
|
||||
const activeBottomPanelTabId = ref<string>('')
|
||||
const activeBottomPanelTab = computed<BottomPanelExtension | null>(() => {
|
||||
return (
|
||||
bottomPanelTabs.value.find(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { MenuItem } from 'primevue/menuitem'
|
||||
import type { InjectionKey, Ref } from 'vue'
|
||||
import type { InjectionKey, ModelRef } from 'vue'
|
||||
|
||||
export interface TreeExplorerNode<T = any> {
|
||||
key: string
|
||||
@@ -72,5 +72,6 @@ export const InjectKeyHandleEditLabelFunction: InjectionKey<
|
||||
(node: RenderedTreeExplorerNode, newName: string) => void
|
||||
> = Symbol()
|
||||
|
||||
export const InjectKeyExpandedKeys: InjectionKey<Ref<Record<string, boolean>>> =
|
||||
Symbol()
|
||||
export const InjectKeyExpandedKeys: InjectionKey<
|
||||
ModelRef<Record<string, boolean>>
|
||||
> = Symbol()
|
||||
|
||||
Reference in New Issue
Block a user