mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-30 21:09:53 +00:00
[TS] Fix ts-strict errors in Vue components (Part 3) (#3126)
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
<Splitter
|
||||
class="splitter-overlay-root splitter-overlay"
|
||||
:pt:gutter="sidebarPanelVisible ? '' : 'hidden'"
|
||||
:key="activeSidebarTabId"
|
||||
:stateKey="activeSidebarTabId"
|
||||
:key="activeSidebarTabId ?? undefined"
|
||||
:stateKey="activeSidebarTabId ?? undefined"
|
||||
stateStorage="local"
|
||||
>
|
||||
<SplitterPanel
|
||||
|
||||
@@ -99,7 +99,7 @@ const isValidSource = computed(
|
||||
() => sourcePath.value !== '' && pathError.value === ''
|
||||
)
|
||||
|
||||
const validateSource = async (sourcePath: string) => {
|
||||
const validateSource = async (sourcePath: string | undefined) => {
|
||||
if (!sourcePath) {
|
||||
pathError.value = ''
|
||||
return
|
||||
@@ -109,7 +109,7 @@ const validateSource = async (sourcePath: string) => {
|
||||
pathError.value = ''
|
||||
const validation = await electron.validateComfyUISource(sourcePath)
|
||||
|
||||
if (!validation.isValid) pathError.value = validation.error
|
||||
if (!validation.isValid) pathError.value = validation.error ?? 'ERROR'
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
pathError.value = t('install.pathValidationFailed')
|
||||
|
||||
@@ -74,8 +74,8 @@ const description = computed(() =>
|
||||
)
|
||||
|
||||
// Use a minimum run time to ensure tasks "feel" like they have run
|
||||
const reactiveLoading = computed(() => runner.value.refreshing)
|
||||
const reactiveExecuting = computed(() => runner.value.executing)
|
||||
const reactiveLoading = computed(() => !!runner.value.refreshing)
|
||||
const reactiveExecuting = computed(() => !!runner.value.executing)
|
||||
|
||||
const isLoading = useMinLoadingDurationRef(reactiveLoading, 250)
|
||||
const isExecuting = useMinLoadingDurationRef(reactiveExecuting, 250)
|
||||
|
||||
@@ -71,16 +71,16 @@ const severity = computed<VueSeverity>(() =>
|
||||
)
|
||||
|
||||
// Use a minimum run time to ensure tasks "feel" like they have run
|
||||
const reactiveLoading = computed(() => runner.value.refreshing)
|
||||
const reactiveExecuting = computed(() => runner.value.executing)
|
||||
const reactiveLoading = computed(() => !!runner.value.refreshing)
|
||||
const reactiveExecuting = computed(() => !!runner.value.executing)
|
||||
|
||||
const isLoading = useMinLoadingDurationRef(reactiveLoading, 250)
|
||||
const isExecuting = useMinLoadingDurationRef(reactiveExecuting, 250)
|
||||
|
||||
// Popover
|
||||
const infoPopover = ref()
|
||||
const infoPopover = ref<InstanceType<typeof Popover> | null>(null)
|
||||
|
||||
const toggle = (event: Event) => {
|
||||
infoPopover.value.toggle(event)
|
||||
infoPopover.value?.toggle(event)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -35,7 +35,7 @@ let xterm: Terminal | null = null
|
||||
// Created and destroyed with the Drawer - contents copied from hidden buffer
|
||||
const terminalCreated = (
|
||||
{ terminal, useAutoSize }: ReturnType<typeof useTerminal>,
|
||||
root: Ref<HTMLElement>
|
||||
root: Ref<HTMLElement | undefined>
|
||||
) => {
|
||||
xterm = terminal
|
||||
useAutoSize({ root, autoRows: true, autoCols: true })
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
class="node-lib-search-box p-2 2xl:p-4"
|
||||
v-model:modelValue="searchQuery"
|
||||
@search="handleSearch"
|
||||
@show-filter="($event) => searchFilter.toggle($event)"
|
||||
@show-filter="($event) => searchFilter?.toggle($event)"
|
||||
@remove-filter="onRemoveFilter"
|
||||
:placeholder="$t('g.searchNodes') + '...'"
|
||||
filter-icon="pi pi-filter"
|
||||
@@ -97,7 +97,7 @@ const { expandNode, toggleNodeOnEvent } = useTreeExpansion(expandedKeys)
|
||||
const nodeBookmarkTreeExplorerRef = ref<InstanceType<
|
||||
typeof NodeBookmarkTreeExplorer
|
||||
> | null>(null)
|
||||
const searchFilter = ref(null)
|
||||
const searchFilter = ref<InstanceType<typeof Popover> | null>(null)
|
||||
const alphabeticalSort = ref(false)
|
||||
|
||||
const searchQuery = ref<string>('')
|
||||
|
||||
@@ -194,7 +194,7 @@ const confirmRemoveAll = (event: Event) => {
|
||||
})
|
||||
}
|
||||
|
||||
const menu = ref(null)
|
||||
const menu = ref<InstanceType<typeof ContextMenu> | null>(null)
|
||||
const menuTargetTask = ref<TaskItemImpl | null>(null)
|
||||
const menuTargetNode = ref<ComfyNode | null>(null)
|
||||
const menuItems = computed<MenuItem[]>(() => [
|
||||
@@ -213,7 +213,11 @@ const menuItems = computed<MenuItem[]>(() => [
|
||||
{
|
||||
label: t('g.goToNode'),
|
||||
icon: 'pi pi-arrow-circle-right',
|
||||
command: () => useLitegraphService().goToNode(menuTargetNode.value?.id),
|
||||
command: () => {
|
||||
if (!menuTargetNode.value) return
|
||||
|
||||
useLitegraphService().goToNode(menuTargetNode.value.id)
|
||||
},
|
||||
visible: !!menuTargetNode.value
|
||||
}
|
||||
])
|
||||
@@ -225,7 +229,7 @@ const handleContextMenu = ({
|
||||
}: {
|
||||
task: TaskItemImpl
|
||||
event: Event
|
||||
node?: ComfyNode
|
||||
node: ComfyNode | null
|
||||
}) => {
|
||||
menuTargetTask.value = task
|
||||
menuTargetNode.value = node
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div>
|
||||
{{ getDownloadLabel(download.savePath) }}
|
||||
{{ getDownloadLabel(download.savePath ?? '') }}
|
||||
</div>
|
||||
<div v-if="['cancelled', 'error'].includes(download.status)">
|
||||
<div v-if="['cancelled', 'error'].includes(download.status ?? '')">
|
||||
<Chip
|
||||
class="h-6 text-sm font-light bg-red-700 mt-2"
|
||||
removable
|
||||
@@ -14,15 +14,17 @@
|
||||
</div>
|
||||
<div
|
||||
class="mt-2 flex flex-row items-center gap-2"
|
||||
v-if="['in_progress', 'paused', 'completed'].includes(download.status)"
|
||||
v-if="
|
||||
['in_progress', 'paused', 'completed'].includes(download.status ?? '')
|
||||
"
|
||||
>
|
||||
<!-- 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
|
||||
-->
|
||||
<ProgressBar
|
||||
class="flex-1"
|
||||
:value="Number((download.progress * 100).toFixed(1))"
|
||||
:show-value="download.progress > 0.1"
|
||||
:value="Number(((download.progress ?? 0) * 100).toFixed(1))"
|
||||
:show-value="(download.progress ?? 0) > 0.1"
|
||||
/>
|
||||
|
||||
<Button
|
||||
@@ -51,7 +53,7 @@
|
||||
rounded
|
||||
severity="danger"
|
||||
@click="triggerCancelDownload"
|
||||
v-if="['in_progress', 'paused'].includes(download.status)"
|
||||
v-if="['in_progress', 'paused'].includes(download.status ?? '')"
|
||||
icon="pi pi-times-circle"
|
||||
v-tooltip.top="t('electronFileDownload.cancel')"
|
||||
/>
|
||||
@@ -79,7 +81,7 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const getDownloadLabel = (savePath: string) => {
|
||||
let parts = (savePath ?? '').split('/')
|
||||
let parts = savePath.split('/')
|
||||
parts = parts.length === 1 ? parts[0].split('\\') : parts
|
||||
const name = parts.pop()
|
||||
const dir = parts.pop()
|
||||
|
||||
@@ -97,6 +97,8 @@ const extraMenuItems = (
|
||||
label: t('g.customize'),
|
||||
icon: 'pi pi-palette',
|
||||
command: () => {
|
||||
if (!menuTargetNode.data) return
|
||||
|
||||
const customization =
|
||||
nodeBookmarkStore.bookmarksCustomization[menuTargetNode.data.nodePath]
|
||||
initialIcon.value =
|
||||
|
||||
@@ -79,6 +79,8 @@ const nodePreviewStyle = ref<CSSProperties>({
|
||||
|
||||
const handleNodeHover = async () => {
|
||||
const hoverTarget = nodeContentElement.value
|
||||
if (!hoverTarget) return
|
||||
|
||||
const targetRect = hoverTarget.getBoundingClientRect()
|
||||
|
||||
const previewHeight = previewRef.value?.$el.offsetHeight || 0
|
||||
@@ -107,7 +109,8 @@ const handleMouseLeave = () => {
|
||||
isHovered.value = false
|
||||
}
|
||||
onMounted(() => {
|
||||
nodeContentElement.value = container.value?.closest('.p-tree-node-content')
|
||||
nodeContentElement.value =
|
||||
container.value?.closest('.p-tree-node-content') ?? null
|
||||
nodeContentElement.value?.addEventListener('mouseenter', handleMouseEnter)
|
||||
nodeContentElement.value?.addEventListener('mouseleave', handleMouseLeave)
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"
|
||||
>
|
||||
<ResultItem
|
||||
v-if="flatOutputs.length"
|
||||
v-if="flatOutputs.length && coverResult"
|
||||
:result="coverResult"
|
||||
@preview="handlePreview"
|
||||
/>
|
||||
@@ -42,7 +42,12 @@
|
||||
:label="`${node?.type} (#${node?.id})`"
|
||||
link
|
||||
size="small"
|
||||
@click="litegraphService.goToNode(node?.id)"
|
||||
@click="
|
||||
() => {
|
||||
if (!node) return
|
||||
litegraphService.goToNode(node.id)
|
||||
}
|
||||
"
|
||||
/>
|
||||
</Tag>
|
||||
<Tag :severity="taskTagSeverity(task.displayStatus)">
|
||||
@@ -95,7 +100,7 @@ const coverResult = flatOutputs.length
|
||||
const node: ComfyNode | null =
|
||||
flatOutputs.length && props.task.workflow
|
||||
? props.task.workflow.nodes.find(
|
||||
(n: ComfyNode) => n.id == coverResult.nodeId
|
||||
(n: ComfyNode) => n.id == coverResult?.nodeId
|
||||
) ?? null
|
||||
: null
|
||||
const progressPreviewBlobUrl = ref('')
|
||||
@@ -103,7 +108,7 @@ const progressPreviewBlobUrl = ref('')
|
||||
const emit = defineEmits<{
|
||||
(
|
||||
e: 'contextmenu',
|
||||
value: { task: TaskItemImpl; event: MouseEvent; node?: ComfyNode }
|
||||
value: { task: TaskItemImpl; event: MouseEvent; node: ComfyNode | null }
|
||||
): void
|
||||
(e: 'preview', value: TaskItemImpl): void
|
||||
(e: 'task-output-length-clicked', value: TaskItemImpl): void
|
||||
|
||||
@@ -20,12 +20,12 @@ import TreeExplorerTreeNode from '@/components/common/TreeExplorerTreeNode.vue'
|
||||
import { ComfyWorkflow, useWorkflowBookmarkStore } from '@/stores/workflowStore'
|
||||
import type { RenderedTreeExplorerNode } from '@/types/treeExplorerTypes'
|
||||
|
||||
const props = defineProps<{
|
||||
const { node } = defineProps<{
|
||||
node: RenderedTreeExplorerNode<ComfyWorkflow>
|
||||
}>()
|
||||
|
||||
const workflowBookmarkStore = useWorkflowBookmarkStore()
|
||||
const isBookmarked = computed(() =>
|
||||
workflowBookmarkStore.isBookmarked(props.node.data.path)
|
||||
const isBookmarked = computed(
|
||||
() => node.data && workflowBookmarkStore.isBookmarked(node.data.path)
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -90,7 +90,7 @@ const { isReady } = useAsyncState(
|
||||
null
|
||||
)
|
||||
|
||||
const selectedTab = ref<WorkflowTemplates | null>()
|
||||
const selectedTab = ref<WorkflowTemplates | null>(null)
|
||||
const selectFirstTab = () => {
|
||||
const firstTab = workflowTemplatesStore.groupedTemplates[0].modules[0]
|
||||
handleTabSelection(firstTab)
|
||||
@@ -118,7 +118,7 @@ const loadWorkflow = async (id: string) => {
|
||||
|
||||
workflowLoading.value = id
|
||||
let json
|
||||
if (selectedTab.value.moduleName === 'default') {
|
||||
if (selectedTab.value?.moduleName === 'default') {
|
||||
// Default templates provided by frontend are served on this separate endpoint
|
||||
json = await fetch(api.fileURL(`/templates/${id}.json`)).then((r) =>
|
||||
r.json()
|
||||
@@ -126,13 +126,13 @@ const loadWorkflow = async (id: string) => {
|
||||
} else {
|
||||
json = await fetch(
|
||||
api.apiURL(
|
||||
`/workflow_templates/${selectedTab.value.moduleName}/${id}.json`
|
||||
`/workflow_templates/${selectedTab.value?.moduleName}/${id}.json`
|
||||
)
|
||||
).then((r) => r.json())
|
||||
}
|
||||
useDialogStore().closeDialog()
|
||||
const workflowName =
|
||||
selectedTab.value.moduleName === 'default'
|
||||
selectedTab.value?.moduleName === 'default'
|
||||
? t(`templateWorkflows.template.${id}`, id)
|
||||
: id
|
||||
await app.loadGraphData(json, true, true, workflowName)
|
||||
|
||||
@@ -131,7 +131,7 @@ import MirrorsConfiguration from '@/components/install/MirrorsConfiguration.vue'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
import BaseViewTemplate from '@/views/templates/BaseViewTemplate.vue'
|
||||
|
||||
const device = ref<TorchDeviceType>(null)
|
||||
const device = ref<TorchDeviceType | null>(null)
|
||||
|
||||
const installPath = ref('')
|
||||
const pathError = ref('')
|
||||
|
||||
@@ -64,7 +64,7 @@ const { t } = useI18n()
|
||||
|
||||
const electron = electronAPI()
|
||||
|
||||
const basePath = ref<string>(null)
|
||||
const basePath = ref<string | null>(null)
|
||||
const sep = ref<'\\' | '/'>('/')
|
||||
|
||||
const restartApp = (message?: string) => electron.restartApp(message)
|
||||
|
||||
@@ -74,7 +74,7 @@ const updateProgress = ({ status: newStatus }: { status: ProgressStatus }) => {
|
||||
|
||||
const terminalCreated = (
|
||||
{ terminal, useAutoSize }: ReturnType<typeof useTerminal>,
|
||||
root: Ref<HTMLElement>
|
||||
root: Ref<HTMLElement | undefined>
|
||||
) => {
|
||||
xterm = terminal
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ const login = async () => {
|
||||
userStore.login(user)
|
||||
router.push('/')
|
||||
} catch (err) {
|
||||
loginError.value = err.message ?? JSON.stringify(err)
|
||||
loginError.value = err instanceof Error ? err.message : JSON.stringify(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ onMounted(async () => {
|
||||
|
||||
electronAPI().changeTheme({
|
||||
...(props.dark ? darkTheme : lightTheme),
|
||||
height: topMenuRef.value.getBoundingClientRect().height
|
||||
height: topMenuRef.value?.getBoundingClientRect().height ?? 0
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user