mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
Devex: Linter updates (#7309)
## Summary Updates for the linter/formatter deps, turning on some more rules. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7309-WIP-Linter-updates-2c56d73d36508101b3ece6bcaf7e5212) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Christian Byrne <cbyrne@comfy.org>
This commit is contained in:
@@ -13,14 +13,37 @@
|
||||
"src/types/generatedManagerTypes.ts",
|
||||
"src/types/vue-shim.d.ts"
|
||||
],
|
||||
"plugins": [
|
||||
"eslint",
|
||||
"import",
|
||||
"oxc",
|
||||
"typescript",
|
||||
"unicorn",
|
||||
"vitest",
|
||||
"vue"
|
||||
],
|
||||
"rules": {
|
||||
"no-async-promise-executor": "off",
|
||||
"no-control-regex": "off",
|
||||
"no-eval": "off",
|
||||
"no-redeclare": "error",
|
||||
"no-self-assign": "allow",
|
||||
"no-unused-expressions": "off",
|
||||
"no-unused-private-class-members": "off",
|
||||
"no-useless-rename": "off",
|
||||
"import/default": "error",
|
||||
"import/export": "error",
|
||||
"import/namespace": "error",
|
||||
"import/no-duplicates": "error",
|
||||
"import/consistent-type-specifier-style": [
|
||||
"error",
|
||||
"prefer-top-level"
|
||||
],
|
||||
"jest/expect-expect": "off",
|
||||
"jest/no-conditional-expect": "off",
|
||||
"jest/no-disabled-tests": "off",
|
||||
"jest/no-standalone-expect": "off",
|
||||
"jest/valid-title": "off",
|
||||
"typescript/no-this-alias": "off",
|
||||
"typescript/no-unnecessary-parameter-property-assignment": "off",
|
||||
"typescript/no-unsafe-declaration-merging": "off",
|
||||
@@ -39,6 +62,7 @@
|
||||
"typescript/restrict-template-expressions": "off",
|
||||
"typescript/unbound-method": "off",
|
||||
"typescript/no-floating-promises": "error",
|
||||
"vue/no-import-compiler-macros": "error"
|
||||
"vue/no-import-compiler-macros": "error",
|
||||
"vue/no-dupe-keys": "error"
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,9 @@
|
||||
"declaration-property-value-no-unknown": [
|
||||
true,
|
||||
{
|
||||
"typesSyntax": {
|
||||
"radial-gradient()": "| <any-value>"
|
||||
},
|
||||
"ignoreProperties": {
|
||||
"speak": ["none"],
|
||||
"app-region": ["drag", "no-drag"],
|
||||
@@ -56,10 +59,7 @@
|
||||
"function-no-unknown": [
|
||||
true,
|
||||
{
|
||||
"ignoreFunctions": [
|
||||
"theme",
|
||||
"v-bind"
|
||||
]
|
||||
"ignoreFunctions": ["theme", "v-bind"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -135,7 +135,6 @@ export default defineConfig([
|
||||
allowInterfaces: 'always'
|
||||
}
|
||||
],
|
||||
'import-x/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
||||
'import-x/no-useless-path-segments': 'error',
|
||||
'import-x/no-relative-packages': 'error',
|
||||
'unused-imports/no-unused-imports': 'error',
|
||||
@@ -146,14 +145,13 @@ export default defineConfig([
|
||||
'vue/multi-word-component-names': 'off', // TODO: fix
|
||||
'vue/no-template-shadow': 'off', // TODO: fix
|
||||
'vue/match-component-import-name': 'error',
|
||||
/* Toggle on to do additional until we can clean up existing violations.
|
||||
'vue/no-unused-emit-declarations': 'error',
|
||||
'vue/no-unused-properties': 'error',
|
||||
'vue/no-unused-refs': 'error',
|
||||
'vue/no-use-v-else-with-v-for': 'error',
|
||||
'vue/no-useless-mustaches': 'error',
|
||||
'vue/no-useless-v-bind': 'error',
|
||||
// */
|
||||
'vue/one-component-per-file': 'off', // TODO: fix
|
||||
'vue/no-unused-emit-declarations': 'error',
|
||||
'vue/no-use-v-else-with-v-for': 'error',
|
||||
'vue/one-component-per-file': 'error',
|
||||
'vue/require-default-prop': 'off', // TODO: fix -- this one is very worthwhile
|
||||
// Restrict deprecated PrimeVue components
|
||||
'no-restricted-imports': [
|
||||
@@ -297,5 +295,14 @@ export default defineConfig([
|
||||
// Turn off ESLint rules that are already handled by oxlint
|
||||
...oxlint.buildFromOxlintConfigFile(
|
||||
path.resolve(import.meta.dirname, '.oxlintrc.json')
|
||||
)
|
||||
),
|
||||
{
|
||||
rules: {
|
||||
'import-x/default': 'off',
|
||||
'import-x/export': 'off',
|
||||
'import-x/namespace': 'off',
|
||||
'import-x/no-duplicates': 'off',
|
||||
'import-x/consistent-type-specifier-style': 'off'
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
1648
pnpm-lock.yaml
generated
1648
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@ packages:
|
||||
catalog:
|
||||
'@alloc/quick-lru': ^5.2.0
|
||||
'@comfyorg/comfyui-electron-types': 0.5.5
|
||||
'@eslint/js': ^9.35.0
|
||||
'@eslint/js': ^9.39.1
|
||||
'@iconify-json/lucide': ^1.1.178
|
||||
'@iconify/json': ^2.2.380
|
||||
'@iconify/tailwind': ^1.1.3
|
||||
@@ -17,7 +17,7 @@ catalog:
|
||||
'@nx/vite': 21.4.1
|
||||
'@pinia/testing': ^0.1.5
|
||||
'@playwright/test': ^1.52.0
|
||||
'@prettier/plugin-oxc': ^0.0.4
|
||||
'@prettier/plugin-oxc': ^0.1.3
|
||||
'@primeuix/forms': 0.0.2
|
||||
'@primeuix/styled': 0.3.2
|
||||
'@primeuix/utils': ^0.3.2
|
||||
@@ -48,15 +48,15 @@ catalog:
|
||||
axios: ^1.8.2
|
||||
cross-env: ^10.1.0
|
||||
dotenv: ^16.4.5
|
||||
eslint: ^9.34.0
|
||||
eslint: ^9.39.1
|
||||
eslint-config-prettier: ^10.1.8
|
||||
eslint-import-resolver-typescript: ^4.4.4
|
||||
eslint-plugin-import-x: ^4.16.1
|
||||
eslint-plugin-oxlint: 1.25.0
|
||||
eslint-plugin-prettier: ^5.5.4
|
||||
eslint-plugin-storybook: ^9.1.6
|
||||
eslint-plugin-unused-imports: ^4.2.0
|
||||
eslint-plugin-vue: ^10.4.0
|
||||
eslint-plugin-storybook: ^9.1.16
|
||||
eslint-plugin-unused-imports: ^4.3.0
|
||||
eslint-plugin-vue: ^10.6.2
|
||||
firebase: ^11.6.0
|
||||
globals: ^15.9.0
|
||||
happy-dom: ^15.11.0
|
||||
@@ -64,29 +64,29 @@ catalog:
|
||||
jiti: 2.4.2
|
||||
jsdom: ^26.1.0
|
||||
knip: ^5.62.0
|
||||
lint-staged: ^15.2.7
|
||||
lint-staged: ^15.5.2
|
||||
markdown-table: ^3.0.4
|
||||
mixpanel-browser: ^2.71.0
|
||||
nx: 21.4.1
|
||||
oxlint: ^1.25.0
|
||||
oxlint-tsgolint: ^0.4.0
|
||||
oxlint: ^1.32.0
|
||||
oxlint-tsgolint: ^0.8.4
|
||||
picocolors: ^1.1.1
|
||||
pinia: ^2.1.7
|
||||
postcss-html: ^1.8.0
|
||||
prettier: ^3.6.2
|
||||
prettier: ^3.7.4
|
||||
pretty-bytes: ^7.1.0
|
||||
primeicons: ^7.0.0
|
||||
primevue: ^4.2.5
|
||||
rollup-plugin-visualizer: ^6.0.4
|
||||
storybook: ^9.1.6
|
||||
stylelint: ^16.24.0
|
||||
storybook: ^9.1.16
|
||||
stylelint: ^16.26.1
|
||||
tailwindcss: ^4.1.12
|
||||
tailwindcss-primeui: ^0.6.1
|
||||
tsx: ^4.15.6
|
||||
tw-animate-css: ^1.3.8
|
||||
typegpu: ^0.8.2
|
||||
typescript: ^5.9.2
|
||||
typescript-eslint: ^8.44.0
|
||||
typescript: ^5.9.3
|
||||
typescript-eslint: ^8.49.0
|
||||
unplugin-icons: ^0.22.0
|
||||
unplugin-typegpu: 0.8.0
|
||||
unplugin-vue-components: ^0.28.0
|
||||
@@ -100,7 +100,7 @@ catalog:
|
||||
vue-eslint-parser: ^10.2.0
|
||||
vue-i18n: ^9.14.3
|
||||
vue-router: ^4.4.3
|
||||
vue-tsc: ^3.0.7
|
||||
vue-tsc: ^3.1.8
|
||||
vuefire: ^3.2.1
|
||||
yjs: ^13.6.27
|
||||
zod: ^3.23.8
|
||||
|
||||
@@ -55,7 +55,6 @@ import { normalizeI18nKey } from '@/utils/formatUtil'
|
||||
const { t } = useI18n()
|
||||
|
||||
const { subcategories } = defineProps<{
|
||||
commands: ComfyCommandImpl[]
|
||||
subcategories: Record<string, ComfyCommandImpl[]>
|
||||
}>()
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
class="icon-[lucide--triangle-alert] text-warning-background"
|
||||
/>
|
||||
<span class="p-breadcrumb-item-label px-2">{{ item.label }}</span>
|
||||
<Tag v-if="item.isBlueprint" :value="'Blueprint'" severity="primary" />
|
||||
<Tag v-if="item.isBlueprint" value="Blueprint" severity="primary" />
|
||||
<i v-if="isActive" class="pi pi-angle-down text-[10px]"></i>
|
||||
</a>
|
||||
<Menu
|
||||
|
||||
@@ -41,7 +41,7 @@ const {
|
||||
inputAttrs?: Record<string, string>
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'edit', 'cancel'])
|
||||
const emit = defineEmits(['edit', 'cancel'])
|
||||
const inputValue = ref<string>(modelValue)
|
||||
const inputRef = ref<InstanceType<typeof InputText> | undefined>()
|
||||
const isCanceling = ref(false)
|
||||
|
||||
@@ -11,7 +11,6 @@ import InputText from 'primevue/inputtext'
|
||||
|
||||
const modelValue = defineModel<string>('modelValue')
|
||||
defineProps<{
|
||||
defaultValue?: string
|
||||
label?: string
|
||||
}>()
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon="pi pi-exclamation-circle"
|
||||
:title="title"
|
||||
:message="error.exceptionMessage"
|
||||
:text-class="'break-words max-w-[60vw]'"
|
||||
text-class="break-words max-w-[60vw]"
|
||||
/>
|
||||
<template v-if="error.extensionFile">
|
||||
<span>{{ t('errorDialog.extensionFileHint') }}:</span>
|
||||
|
||||
@@ -465,9 +465,8 @@ onMounted(async () => {
|
||||
await workflowPersistence.loadTemplateFromUrlIfPresent()
|
||||
|
||||
// Initialize release store to fetch releases from comfy-api (fire-and-forget)
|
||||
const { useReleaseStore } = await import(
|
||||
'@/platform/updates/common/releaseStore'
|
||||
)
|
||||
const { useReleaseStore } =
|
||||
await import('@/platform/updates/common/releaseStore')
|
||||
const releaseStore = useReleaseStore()
|
||||
void releaseStore.initialize()
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
ref="zoomButton"
|
||||
v-tooltip.top="t('zoomControls.label')"
|
||||
severity="secondary"
|
||||
:label="t('zoomControls.label')"
|
||||
@@ -56,7 +55,6 @@
|
||||
<div class="h-[27px] w-[1px] self-center bg-node-divider" />
|
||||
|
||||
<Button
|
||||
ref="minimapButton"
|
||||
v-tooltip.top="minimapTooltip"
|
||||
severity="secondary"
|
||||
:aria-label="minimapTooltip"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<Popover
|
||||
ref="popover"
|
||||
:append-to="'body'"
|
||||
append-to="body"
|
||||
:auto-z-index="true"
|
||||
:base-z-index="1000"
|
||||
:dismissable="true"
|
||||
|
||||
@@ -21,7 +21,6 @@ import { linkifyHtml, nl2br } from '@/utils/formatUtil'
|
||||
|
||||
const modelValue = defineModel<string>({ required: true })
|
||||
const props = defineProps<{
|
||||
widget?: object
|
||||
nodeId: NodeId
|
||||
}>()
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
<div v-show="activeCategory" class="rounded-lg bg-smoke-700/30">
|
||||
<SceneControls
|
||||
v-if="showSceneControls"
|
||||
ref="sceneControlsRef"
|
||||
v-model:show-grid="sceneConfig!.showGrid"
|
||||
v-model:background-color="sceneConfig!.backgroundColor"
|
||||
v-model:background-image="sceneConfig!.backgroundImage"
|
||||
@@ -46,28 +45,24 @@
|
||||
|
||||
<ModelControls
|
||||
v-if="showModelControls"
|
||||
ref="modelControlsRef"
|
||||
v-model:material-mode="modelConfig!.materialMode"
|
||||
v-model:up-direction="modelConfig!.upDirection"
|
||||
/>
|
||||
|
||||
<CameraControls
|
||||
v-if="showCameraControls"
|
||||
ref="cameraControlsRef"
|
||||
v-model:camera-type="cameraConfig!.cameraType"
|
||||
v-model:fov="cameraConfig!.fov"
|
||||
/>
|
||||
|
||||
<LightControls
|
||||
v-if="showLightControls"
|
||||
ref="lightControlsRef"
|
||||
v-model:light-intensity="lightConfig!.intensity"
|
||||
v-model:material-mode="modelConfig!.materialMode"
|
||||
/>
|
||||
|
||||
<ExportControls
|
||||
v-if="showExportControls"
|
||||
ref="exportControlsRef"
|
||||
@export-model="handleExportModel"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<span v-if="props.mode === 'allFailed'" class="inline-flex items-center">
|
||||
<i
|
||||
class="ml-1 icon-[lucide--circle-alert] block size-4 leading-none"
|
||||
:class="'text-destructive-background'"
|
||||
class="ml-1 icon-[lucide--circle-alert] block size-4 leading-none text-destructive-background"
|
||||
/>
|
||||
</span>
|
||||
|
||||
|
||||
@@ -64,8 +64,7 @@ export const RunningWithCurrent: Story = {
|
||||
state: 'running',
|
||||
title: 'Generating image',
|
||||
progressTotalPercent: 66,
|
||||
progressCurrentPercent: 10,
|
||||
runningNodeName: 'KSampler'
|
||||
progressCurrentPercent: 10
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -225,7 +225,6 @@ const props = withDefaults(
|
||||
showMenu?: boolean
|
||||
progressTotalPercent?: number
|
||||
progressCurrentPercent?: number
|
||||
runningNodeName?: string
|
||||
activeDetailsId?: string | null
|
||||
}>(),
|
||||
{
|
||||
|
||||
@@ -7,7 +7,6 @@ import type { ClassValue } from '@/utils/tailwindUtil'
|
||||
const props = defineProps<{
|
||||
nodeTitle: string
|
||||
widgetName: string
|
||||
isShown?: boolean
|
||||
isDraggable?: boolean
|
||||
isPhysical?: boolean
|
||||
class?: ClassValue
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
auto-option-focus
|
||||
force-selection
|
||||
multiple
|
||||
:option-label="'display_name'"
|
||||
option-label="display_name"
|
||||
@complete="search($event.query)"
|
||||
@option-select="onAddNode($event.value)"
|
||||
@focused-option-changed="setHoverSuggestion($event)"
|
||||
|
||||
@@ -59,7 +59,6 @@ interface WorkflowOption {
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
class?: string
|
||||
workflowOption: WorkflowOption
|
||||
}>()
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
|
||||
const props = defineProps<
|
||||
// eslint-disable-next-line vue/no-unused-properties
|
||||
SliderRootProps & { class?: HTMLAttributes['class'] }
|
||||
>()
|
||||
|
||||
|
||||
@@ -249,9 +249,7 @@ const link_bounding = new Rectangle()
|
||||
* This class is in charge of rendering one graph inside a canvas. And provides all the interaction required.
|
||||
* Valid callbacks are: onNodeSelected, onNodeDeselected, onShowNodePanel, onNodeDblClicked
|
||||
*/
|
||||
export class LGraphCanvas
|
||||
implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
{
|
||||
export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap> {
|
||||
static DEFAULT_BACKGROUND_IMAGE =
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQBJREFUeNrs1rEKwjAUhlETUkj3vP9rdmr1Ysammk2w5wdxuLgcMHyptfawuZX4pJSWZTnfnu/lnIe/jNNxHHGNn//HNbbv+4dr6V+11uF527arU7+u63qfa/bnmh8sWLBgwYJlqRf8MEptXPBXJXa37BSl3ixYsGDBMliwFLyCV/DeLIMFCxYsWLBMwSt4Be/NggXLYMGCBUvBK3iNruC9WbBgwYJlsGApeAWv4L1ZBgsWLFiwYJmCV/AK3psFC5bBggULloJX8BpdwXuzYMGCBctgwVLwCl7Be7MMFixYsGDBsu8FH1FaSmExVfAxBa/gvVmwYMGCZbBg/W4vAQYA5tRF9QYlv/QAAAAASUVORK5CYII='
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
* Temporary workaround until downstream consumers migrate to Map.
|
||||
* A brittle wrapper with many flaws, but should be fine for simple maps using int indexes.
|
||||
*/
|
||||
export class MapProxyHandler<V>
|
||||
implements ProxyHandler<Map<number | string, V>>
|
||||
{
|
||||
export class MapProxyHandler<V> implements ProxyHandler<
|
||||
Map<number | string, V>
|
||||
> {
|
||||
getOwnPropertyDescriptor(
|
||||
target: Map<number | string, V>,
|
||||
p: string | symbol
|
||||
|
||||
@@ -81,9 +81,9 @@ export interface CustomEventDispatcher<
|
||||
* ```
|
||||
*/
|
||||
export class CustomEventTarget<
|
||||
EventMap extends Record<Keys, unknown>,
|
||||
Keys extends keyof EventMap & string = keyof EventMap & string
|
||||
>
|
||||
EventMap extends Record<Keys, unknown>,
|
||||
Keys extends keyof EventMap & string = keyof EventMap & string
|
||||
>
|
||||
extends EventTarget
|
||||
implements ICustomEventTarget<EventMap, Keys>
|
||||
{
|
||||
|
||||
@@ -380,8 +380,10 @@ interface IContextMenuBase {
|
||||
}
|
||||
|
||||
/** ContextMenu */
|
||||
export interface IContextMenuOptions<TValue = unknown, TExtra = unknown>
|
||||
extends IContextMenuBase {
|
||||
export interface IContextMenuOptions<
|
||||
TValue = unknown,
|
||||
TExtra = unknown
|
||||
> extends IContextMenuBase {
|
||||
ignore_item_callbacks?: boolean
|
||||
parentMenu?: ContextMenu<TValue>
|
||||
event?: MouseEvent
|
||||
@@ -426,13 +428,15 @@ export interface IContextMenuValue<
|
||||
): void | boolean | Promise<void | boolean>
|
||||
}
|
||||
|
||||
interface IContextMenuSubmenu<TValue = unknown>
|
||||
extends IContextMenuOptions<TValue> {
|
||||
interface IContextMenuSubmenu<
|
||||
TValue = unknown
|
||||
> extends IContextMenuOptions<TValue> {
|
||||
options: ConstructorParameters<typeof ContextMenu<TValue>>[0]
|
||||
}
|
||||
|
||||
export interface ContextMenuDivElement<TValue = unknown>
|
||||
extends HTMLDivElement {
|
||||
export interface ContextMenuDivElement<
|
||||
TValue = unknown
|
||||
> extends HTMLDivElement {
|
||||
value?: string | IContextMenuValue<TValue>
|
||||
onclick_callback?: never
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ import type { SubgraphInput } from './SubgraphInput'
|
||||
import type { SubgraphOutput } from './SubgraphOutput'
|
||||
|
||||
export abstract class SubgraphIONodeBase<
|
||||
TSlot extends SubgraphInput | SubgraphOutput
|
||||
>
|
||||
TSlot extends SubgraphInput | SubgraphOutput
|
||||
>
|
||||
implements Positionable, Hoverable, Serialisable<ExportedSubgraphIONode>
|
||||
{
|
||||
static margin = 10
|
||||
|
||||
@@ -46,9 +46,7 @@ export interface CanvasPointerEvent extends PointerEvent, CanvasMouseEvent {}
|
||||
|
||||
/** MouseEvent with canvasX/Y and deltaX/Y properties */
|
||||
interface CanvasMouseEvent
|
||||
extends MouseEvent,
|
||||
Readonly<CanvasPointerExtensions>,
|
||||
LegacyMouseEvent {}
|
||||
extends MouseEvent, Readonly<CanvasPointerExtensions>, LegacyMouseEvent {}
|
||||
|
||||
export type CanvasEventDetail =
|
||||
| GenericEventDetail
|
||||
|
||||
@@ -94,27 +94,32 @@ export interface INumericWidget extends IBaseWidget<number, 'number'> {
|
||||
value: number
|
||||
}
|
||||
|
||||
export interface ISliderWidget
|
||||
extends IBaseWidget<number, 'slider', IWidgetSliderOptions> {
|
||||
export interface ISliderWidget extends IBaseWidget<
|
||||
number,
|
||||
'slider',
|
||||
IWidgetSliderOptions
|
||||
> {
|
||||
type: 'slider'
|
||||
value: number
|
||||
marker?: number
|
||||
}
|
||||
|
||||
export interface IKnobWidget
|
||||
extends IBaseWidget<number, 'knob', IWidgetKnobOptions> {
|
||||
export interface IKnobWidget extends IBaseWidget<
|
||||
number,
|
||||
'knob',
|
||||
IWidgetKnobOptions
|
||||
> {
|
||||
type: 'knob'
|
||||
value: number
|
||||
options: IWidgetKnobOptions
|
||||
}
|
||||
|
||||
/** Avoids the type issues with the legacy IComboWidget type */
|
||||
export interface IStringComboWidget
|
||||
extends IBaseWidget<
|
||||
string,
|
||||
'combo',
|
||||
RequiredProps<IWidgetOptions<string[]>, 'values'>
|
||||
> {
|
||||
export interface IStringComboWidget extends IBaseWidget<
|
||||
string,
|
||||
'combo',
|
||||
RequiredProps<IWidgetOptions<string[]>, 'values'>
|
||||
> {
|
||||
type: 'combo'
|
||||
value: string
|
||||
}
|
||||
@@ -125,25 +130,29 @@ type ComboWidgetValues =
|
||||
| ((widget?: IComboWidget, node?: LGraphNode) => string[])
|
||||
|
||||
/** A combo-box widget (dropdown, select, etc) */
|
||||
export interface IComboWidget
|
||||
extends IBaseWidget<
|
||||
string | number,
|
||||
'combo',
|
||||
RequiredProps<IWidgetOptions<ComboWidgetValues>, 'values'>
|
||||
> {
|
||||
export interface IComboWidget extends IBaseWidget<
|
||||
string | number,
|
||||
'combo',
|
||||
RequiredProps<IWidgetOptions<ComboWidgetValues>, 'values'>
|
||||
> {
|
||||
type: 'combo'
|
||||
value: string | number
|
||||
}
|
||||
|
||||
/** A widget with a string value */
|
||||
export interface IStringWidget
|
||||
extends IBaseWidget<string, 'string' | 'text', IWidgetOptions<string[]>> {
|
||||
export interface IStringWidget extends IBaseWidget<
|
||||
string,
|
||||
'string' | 'text',
|
||||
IWidgetOptions<string[]>
|
||||
> {
|
||||
type: 'string' | 'text'
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface IButtonWidget
|
||||
extends IBaseWidget<string | undefined, 'button'> {
|
||||
export interface IButtonWidget extends IBaseWidget<
|
||||
string | undefined,
|
||||
'button'
|
||||
> {
|
||||
type: 'button'
|
||||
value: string | undefined
|
||||
clicked: boolean
|
||||
@@ -181,15 +190,19 @@ interface IImageWidget extends IBaseWidget<string, 'image'> {
|
||||
}
|
||||
|
||||
/** Tree select widget for hierarchical selection */
|
||||
export interface ITreeSelectWidget
|
||||
extends IBaseWidget<string | string[], 'treeselect'> {
|
||||
export interface ITreeSelectWidget extends IBaseWidget<
|
||||
string | string[],
|
||||
'treeselect'
|
||||
> {
|
||||
type: 'treeselect'
|
||||
value: string | string[]
|
||||
}
|
||||
|
||||
/** Multi-select widget for selecting multiple options */
|
||||
export interface IMultiSelectWidget
|
||||
extends IBaseWidget<string[], 'multiselect'> {
|
||||
export interface IMultiSelectWidget extends IBaseWidget<
|
||||
string[],
|
||||
'multiselect'
|
||||
> {
|
||||
type: 'multiselect'
|
||||
value: string[]
|
||||
}
|
||||
@@ -207,19 +220,20 @@ export interface IGalleriaWidget extends IBaseWidget<string[], 'galleria'> {
|
||||
}
|
||||
|
||||
/** Image comparison widget for comparing two images side by side */
|
||||
export interface IImageCompareWidget
|
||||
extends IBaseWidget<string[], 'imagecompare'> {
|
||||
export interface IImageCompareWidget extends IBaseWidget<
|
||||
string[],
|
||||
'imagecompare'
|
||||
> {
|
||||
type: 'imagecompare'
|
||||
value: string[]
|
||||
}
|
||||
|
||||
/** Select button widget for selecting from a group of buttons */
|
||||
export interface ISelectButtonWidget
|
||||
extends IBaseWidget<
|
||||
string,
|
||||
'selectbutton',
|
||||
RequiredProps<IWidgetOptions<string[]>, 'values'>
|
||||
> {
|
||||
export interface ISelectButtonWidget extends IBaseWidget<
|
||||
string,
|
||||
'selectbutton',
|
||||
RequiredProps<IWidgetOptions<string[]>, 'values'>
|
||||
> {
|
||||
type: 'selectbutton'
|
||||
value: string
|
||||
}
|
||||
@@ -230,8 +244,11 @@ export interface ITextareaWidget extends IBaseWidget<string, 'textarea'> {
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface IAssetWidget
|
||||
extends IBaseWidget<string, 'asset', IWidgetOptions<string[]>> {
|
||||
export interface IAssetWidget extends IBaseWidget<
|
||||
string,
|
||||
'asset',
|
||||
IWidgetOptions<string[]>
|
||||
> {
|
||||
type: 'asset'
|
||||
value: string
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ export interface WidgetEventOptions {
|
||||
canvas: LGraphCanvas
|
||||
}
|
||||
|
||||
export abstract class BaseWidget<TWidget extends IBaseWidget = IBaseWidget>
|
||||
implements IBaseWidget
|
||||
{
|
||||
export abstract class BaseWidget<
|
||||
TWidget extends IBaseWidget = IBaseWidget
|
||||
> implements IBaseWidget {
|
||||
/** From node edge to widget edge */
|
||||
static margin = 15
|
||||
/** From widget edge to tip of arrow button */
|
||||
|
||||
@@ -27,9 +27,8 @@ import { i18n } from './i18n'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
|
||||
if (isCloud) {
|
||||
const { loadRemoteConfig } = await import(
|
||||
'@/platform/remoteConfig/remoteConfig'
|
||||
)
|
||||
const { loadRemoteConfig } =
|
||||
await import('@/platform/remoteConfig/remoteConfig')
|
||||
await loadRemoteConfig()
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,6 @@ import { OnCloseKey } from '@/types/widgetTypes'
|
||||
|
||||
const props = defineProps<{
|
||||
nodeType?: string
|
||||
inputName?: string
|
||||
onSelect?: (asset: AssetItem) => void
|
||||
onClose?: () => void
|
||||
showLeftPanel?: boolean
|
||||
|
||||
@@ -44,7 +44,6 @@ TODO: Extract checkbox pattern into reusable Checkbox component
|
||||
<script setup lang="ts">
|
||||
const { mediaTypeFilters } = defineProps<{
|
||||
mediaTypeFilters: string[]
|
||||
close: () => void
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<Popover
|
||||
ref="popover"
|
||||
:append-to="'body'"
|
||||
append-to="body"
|
||||
:auto-z-index="true"
|
||||
:base-z-index="1000"
|
||||
:dismissable="true"
|
||||
|
||||
@@ -16,12 +16,11 @@ import { computed } from 'vue'
|
||||
|
||||
import { formatSize, getFilenameDetails } from '@/utils/formatUtil'
|
||||
|
||||
import type { AssetContext, AssetMeta } from '../schemas/mediaAssetSchema'
|
||||
import type { AssetMeta } from '../schemas/mediaAssetSchema'
|
||||
import MediaTitle from './MediaTitle.vue'
|
||||
|
||||
const { asset } = defineProps<{
|
||||
asset: AssetMeta
|
||||
context: AssetContext
|
||||
}>()
|
||||
|
||||
const fileName = computed(() => {
|
||||
|
||||
@@ -14,12 +14,11 @@ import { computed } from 'vue'
|
||||
|
||||
import { getFilenameDetails } from '@/utils/formatUtil'
|
||||
|
||||
import type { AssetContext, AssetMeta } from '../schemas/mediaAssetSchema'
|
||||
import type { AssetMeta } from '../schemas/mediaAssetSchema'
|
||||
import MediaTitle from './MediaTitle.vue'
|
||||
|
||||
const { asset } = defineProps<{
|
||||
asset: AssetMeta
|
||||
context: AssetContext
|
||||
}>()
|
||||
|
||||
const fileName = computed(() => {
|
||||
|
||||
@@ -13,12 +13,11 @@ import { computed } from 'vue'
|
||||
|
||||
import { formatSize, getFilenameDetails } from '@/utils/formatUtil'
|
||||
|
||||
import type { AssetContext, AssetMeta } from '../schemas/mediaAssetSchema'
|
||||
import type { AssetMeta } from '../schemas/mediaAssetSchema'
|
||||
import MediaTitle from './MediaTitle.vue'
|
||||
|
||||
const { asset } = defineProps<{
|
||||
asset: AssetMeta
|
||||
context: AssetContext
|
||||
}>()
|
||||
|
||||
const fileName = computed(() => {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
@mouseleave="isHovered = false"
|
||||
>
|
||||
<video
|
||||
ref="videoRef"
|
||||
:controls="shouldShowControls"
|
||||
preload="metadata"
|
||||
autoplay
|
||||
@@ -27,20 +26,17 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import type { AssetContext, AssetMeta } from '../schemas/mediaAssetSchema'
|
||||
import type { AssetMeta } from '../schemas/mediaAssetSchema'
|
||||
|
||||
const { asset } = defineProps<{
|
||||
asset: AssetMeta
|
||||
context: AssetContext
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
play: [assetId: string]
|
||||
videoPlayingStateChanged: [isPlaying: boolean]
|
||||
videoControlsChanged: [showControls: boolean]
|
||||
}>()
|
||||
|
||||
const videoRef = ref<HTMLVideoElement>()
|
||||
const isHovered = ref(false)
|
||||
const isPlaying = ref(false)
|
||||
|
||||
|
||||
@@ -14,9 +14,8 @@ export const cloudOnboardingRoutes: RouteRecordRaw[] = [
|
||||
beforeEnter: async (to, _from, next) => {
|
||||
// Only redirect if not explicitly switching accounts
|
||||
if (!to.query.switchAccount) {
|
||||
const { useCurrentUser } = await import(
|
||||
'@/composables/auth/useCurrentUser'
|
||||
)
|
||||
const { useCurrentUser } =
|
||||
await import('@/composables/auth/useCurrentUser')
|
||||
const { isLoggedIn } = useCurrentUser()
|
||||
|
||||
if (isLoggedIn.value) {
|
||||
|
||||
@@ -28,9 +28,7 @@ export const useSubscriptionDialog = () => {
|
||||
key: DIALOG_KEY,
|
||||
component: defineAsyncComponent(
|
||||
() =>
|
||||
import(
|
||||
'@/platform/cloud/subscription/components/SubscriptionRequiredDialogContent.vue'
|
||||
)
|
||||
import('@/platform/cloud/subscription/components/SubscriptionRequiredDialogContent.vue')
|
||||
),
|
||||
props: {
|
||||
onClose: hide
|
||||
|
||||
@@ -100,9 +100,7 @@ export function useSettingUI(
|
||||
},
|
||||
component: defineAsyncComponent(
|
||||
() =>
|
||||
import(
|
||||
'@/platform/cloud/subscription/components/SubscriptionPanel.vue'
|
||||
)
|
||||
import('@/platform/cloud/subscription/components/SubscriptionPanel.vue')
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,6 @@ import NodeWidgets from './NodeWidgets.vue'
|
||||
interface LGraphNodeProps {
|
||||
nodeData: VueNodeData
|
||||
error?: string | null
|
||||
zoomLevel?: number
|
||||
}
|
||||
|
||||
const { nodeData, error = null } = defineProps<LGraphNodeProps>()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable vue/one-component-per-file */
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { createPinia } from 'pinia'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
@@ -9,7 +9,6 @@ import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
const props = defineProps<{
|
||||
widget: SimplifiedWidget<void>
|
||||
nodeId: string
|
||||
readonly?: boolean
|
||||
}>()
|
||||
|
||||
const domEl = ref<HTMLElement>()
|
||||
|
||||
@@ -14,7 +14,6 @@ import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
|
||||
const props = defineProps<{
|
||||
widget: SimplifiedWidget<void>
|
||||
readonly?: boolean
|
||||
}>()
|
||||
|
||||
const canvasEl = ref()
|
||||
|
||||
@@ -92,7 +92,6 @@ import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
import { app } from '@/scripts/app'
|
||||
import { useAudioService } from '@/services/audioService'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
|
||||
import { useAudioPlayback } from '../composables/audio/useAudioPlayback'
|
||||
import { useAudioRecorder } from '../composables/audio/useAudioRecorder'
|
||||
@@ -100,7 +99,6 @@ import { useAudioWaveform } from '../composables/audio/useAudioWaveform'
|
||||
import { formatTime } from '../utils/audioUtils'
|
||||
|
||||
const props = defineProps<{
|
||||
widget: SimplifiedWidget<string | number | undefined>
|
||||
readonly?: boolean
|
||||
nodeId: string
|
||||
}>()
|
||||
|
||||
@@ -82,7 +82,6 @@
|
||||
<!-- Options Button -->
|
||||
<div
|
||||
v-if="showOptionsButton"
|
||||
ref="optionsButtonRef"
|
||||
role="button"
|
||||
:tabindex="0"
|
||||
:aria-label="$t('g.moreOptions')"
|
||||
@@ -155,10 +154,8 @@ const { t } = useI18n()
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
readonly?: boolean
|
||||
hideWhenEmpty?: boolean
|
||||
showOptionsButton?: boolean
|
||||
modelValue?: string
|
||||
nodeId?: string
|
||||
audioUrl?: string
|
||||
}>(),
|
||||
@@ -170,7 +167,6 @@ const props = withDefaults(
|
||||
// Refs
|
||||
const audioRef = ref<HTMLAudioElement>()
|
||||
const optionsMenu = ref()
|
||||
const optionsButtonRef = ref<HTMLElement>()
|
||||
const isPlaying = ref(false)
|
||||
const isMuted = ref(false)
|
||||
const volume = ref(1)
|
||||
|
||||
@@ -9,7 +9,6 @@ import type { DropdownItem, SelectedKey } from './types'
|
||||
interface Props {
|
||||
isOpen?: boolean
|
||||
placeholder?: string
|
||||
files: File[]
|
||||
items: DropdownItem[]
|
||||
selected: Set<SelectedKey>
|
||||
maxSelectable: number
|
||||
|
||||
@@ -169,9 +169,8 @@ if (isCloud) {
|
||||
// For root path, check actual user status to handle waitlisted users
|
||||
if (!isElectron() && isLoggedIn && to.path === '/') {
|
||||
// Import auth functions dynamically to avoid circular dependency
|
||||
const { getSurveyCompletedStatus } = await import(
|
||||
'@/platform/cloud/onboarding/auth'
|
||||
)
|
||||
const { getSurveyCompletedStatus } =
|
||||
await import('@/platform/cloud/onboarding/auth')
|
||||
try {
|
||||
// Check user's actual status
|
||||
const surveyCompleted = await getSurveyCompletedStatus()
|
||||
|
||||
@@ -15,8 +15,9 @@ import type { InputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import { useDomWidgetStore } from '@/stores/domWidgetStore'
|
||||
import { generateUUID } from '@/utils/formatUtil'
|
||||
|
||||
export interface BaseDOMWidget<V extends object | string = object | string>
|
||||
extends IBaseWidget<V, string, DOMWidgetOptions<V>> {
|
||||
export interface BaseDOMWidget<
|
||||
V extends object | string = object | string
|
||||
> extends IBaseWidget<V, string, DOMWidgetOptions<V>> {
|
||||
// ICustomWidget properties
|
||||
type: string
|
||||
options: DOMWidgetOptions<V>
|
||||
@@ -37,8 +38,10 @@ export interface BaseDOMWidget<V extends object | string = object | string>
|
||||
/**
|
||||
* A DOM widget that wraps a custom HTML element as a litegraph widget.
|
||||
*/
|
||||
export interface DOMWidget<T extends HTMLElement, V extends object | string>
|
||||
extends BaseDOMWidget<V> {
|
||||
export interface DOMWidget<
|
||||
T extends HTMLElement,
|
||||
V extends object | string
|
||||
> extends BaseDOMWidget<V> {
|
||||
element: T
|
||||
/**
|
||||
* @deprecated Legacy property used by some extensions for customtext
|
||||
@@ -78,8 +81,9 @@ export interface ComponentWidget<
|
||||
readonly props?: P
|
||||
}
|
||||
|
||||
export interface DOMWidgetOptions<V extends object | string>
|
||||
extends IWidgetOptions {
|
||||
export interface DOMWidgetOptions<
|
||||
V extends object | string
|
||||
> extends IWidgetOptions {
|
||||
/**
|
||||
* Whether to render a placeholder rectangle when zoomed out.
|
||||
*/
|
||||
@@ -286,9 +290,9 @@ export class DOMWidgetImpl<T extends HTMLElement, V extends object | string>
|
||||
}
|
||||
|
||||
export class ComponentWidgetImpl<
|
||||
V extends object | string,
|
||||
P extends ComponentWidgetCustomProps = ComponentWidgetCustomProps
|
||||
>
|
||||
V extends object | string,
|
||||
P extends ComponentWidgetCustomProps = ComponentWidgetCustomProps
|
||||
>
|
||||
extends BaseDOMWidgetImpl<V>
|
||||
implements ComponentWidget<V, P>
|
||||
{
|
||||
|
||||
@@ -535,9 +535,8 @@ export const useDialogService = () => {
|
||||
return
|
||||
}
|
||||
|
||||
const { useSubscriptionDialog } = await import(
|
||||
'@/platform/cloud/subscription/composables/useSubscriptionDialog'
|
||||
)
|
||||
const { useSubscriptionDialog } =
|
||||
await import('@/platform/cloud/subscription/composables/useSubscriptionDialog')
|
||||
const { show } = useSubscriptionDialog()
|
||||
show()
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@ import { computed, ref } from 'vue'
|
||||
|
||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
|
||||
export interface ElectronDownload
|
||||
extends Pick<DownloadState, 'url' | 'filename'> {
|
||||
export interface ElectronDownload extends Pick<
|
||||
DownloadState,
|
||||
'url' | 'filename'
|
||||
> {
|
||||
progress?: number
|
||||
savePath?: string
|
||||
status?: DownloadStatus
|
||||
|
||||
@@ -549,9 +549,8 @@ export function useConflictDetection() {
|
||||
async function initializeConflictDetection(): Promise<void> {
|
||||
try {
|
||||
// Check if manager is new Manager before proceeding
|
||||
const { useManagerState } = await import(
|
||||
'@/workbench/extensions/manager/composables/useManagerState'
|
||||
)
|
||||
const { useManagerState } =
|
||||
await import('@/workbench/extensions/manager/composables/useManagerState')
|
||||
const managerState = useManagerState()
|
||||
|
||||
if (!managerState.isNewManagerUI.value) {
|
||||
|
||||
@@ -61,13 +61,6 @@ describe('EssentialsPanel', () => {
|
||||
|
||||
const shortcutsList = wrapper.findComponent(ShortcutsList)
|
||||
expect(shortcutsList.exists()).toBe(true)
|
||||
|
||||
// Should pass only essentials commands
|
||||
const commands = shortcutsList.props('commands')
|
||||
expect(commands).toHaveLength(3)
|
||||
commands.forEach((cmd: ComfyCommandImpl) => {
|
||||
expect(cmd.category).toBe('essentials')
|
||||
})
|
||||
})
|
||||
|
||||
it('should categorize commands into subcategories', () => {
|
||||
@@ -18,9 +18,8 @@ describe('useConflictAcknowledgment', () => {
|
||||
describe('initial state loading', () => {
|
||||
it('should load empty state when localStorage is empty', async () => {
|
||||
vi.resetModules()
|
||||
const { useConflictAcknowledgment } = await import(
|
||||
'@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
)
|
||||
const { useConflictAcknowledgment } =
|
||||
await import('@/workbench/extensions/manager/composables/useConflictAcknowledgment')
|
||||
const { acknowledgmentState } = useConflictAcknowledgment()
|
||||
|
||||
expect(acknowledgmentState.value).toEqual({
|
||||
@@ -44,9 +43,8 @@ describe('useConflictAcknowledgment', () => {
|
||||
|
||||
// Need to import the module after localStorage is set
|
||||
vi.resetModules()
|
||||
const { useConflictAcknowledgment } = await import(
|
||||
'@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
)
|
||||
const { useConflictAcknowledgment } =
|
||||
await import('@/workbench/extensions/manager/composables/useConflictAcknowledgment')
|
||||
const { acknowledgmentState } = useConflictAcknowledgment()
|
||||
|
||||
expect(acknowledgmentState.value).toEqual({
|
||||
@@ -60,9 +58,8 @@ describe('useConflictAcknowledgment', () => {
|
||||
describe('dismissal functions', () => {
|
||||
it('should mark conflicts as seen with unified function', async () => {
|
||||
vi.resetModules()
|
||||
const { useConflictAcknowledgment } = await import(
|
||||
'@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
)
|
||||
const { useConflictAcknowledgment } =
|
||||
await import('@/workbench/extensions/manager/composables/useConflictAcknowledgment')
|
||||
const { markConflictsAsSeen, acknowledgmentState } =
|
||||
useConflictAcknowledgment()
|
||||
|
||||
@@ -73,9 +70,8 @@ describe('useConflictAcknowledgment', () => {
|
||||
|
||||
it('should dismiss red dot notification', async () => {
|
||||
vi.resetModules()
|
||||
const { useConflictAcknowledgment } = await import(
|
||||
'@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
)
|
||||
const { useConflictAcknowledgment } =
|
||||
await import('@/workbench/extensions/manager/composables/useConflictAcknowledgment')
|
||||
const { dismissRedDotNotification, acknowledgmentState } =
|
||||
useConflictAcknowledgment()
|
||||
|
||||
@@ -86,9 +82,8 @@ describe('useConflictAcknowledgment', () => {
|
||||
|
||||
it('should dismiss warning banner', async () => {
|
||||
vi.resetModules()
|
||||
const { useConflictAcknowledgment } = await import(
|
||||
'@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
)
|
||||
const { useConflictAcknowledgment } =
|
||||
await import('@/workbench/extensions/manager/composables/useConflictAcknowledgment')
|
||||
const { dismissWarningBanner, acknowledgmentState } =
|
||||
useConflictAcknowledgment()
|
||||
|
||||
@@ -99,9 +94,8 @@ describe('useConflictAcknowledgment', () => {
|
||||
|
||||
it('should mark all conflicts as seen', async () => {
|
||||
vi.resetModules()
|
||||
const { useConflictAcknowledgment } = await import(
|
||||
'@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
)
|
||||
const { useConflictAcknowledgment } =
|
||||
await import('@/workbench/extensions/manager/composables/useConflictAcknowledgment')
|
||||
const { markConflictsAsSeen, acknowledgmentState } =
|
||||
useConflictAcknowledgment()
|
||||
|
||||
@@ -117,9 +111,8 @@ describe('useConflictAcknowledgment', () => {
|
||||
it('should calculate shouldShowConflictModal correctly', async () => {
|
||||
// Need fresh module import to ensure clean state
|
||||
vi.resetModules()
|
||||
const { useConflictAcknowledgment } = await import(
|
||||
'@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
)
|
||||
const { useConflictAcknowledgment } =
|
||||
await import('@/workbench/extensions/manager/composables/useConflictAcknowledgment')
|
||||
const { shouldShowConflictModal, markConflictsAsSeen } =
|
||||
useConflictAcknowledgment()
|
||||
|
||||
@@ -131,9 +124,8 @@ describe('useConflictAcknowledgment', () => {
|
||||
|
||||
it('should calculate shouldShowRedDot correctly based on conflicts', async () => {
|
||||
vi.resetModules()
|
||||
const { useConflictAcknowledgment } = await import(
|
||||
'@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
)
|
||||
const { useConflictAcknowledgment } =
|
||||
await import('@/workbench/extensions/manager/composables/useConflictAcknowledgment')
|
||||
const { shouldShowRedDot, dismissRedDotNotification } =
|
||||
useConflictAcknowledgment()
|
||||
|
||||
@@ -146,9 +138,8 @@ describe('useConflictAcknowledgment', () => {
|
||||
|
||||
it('should calculate shouldShowManagerBanner correctly', async () => {
|
||||
vi.resetModules()
|
||||
const { useConflictAcknowledgment } = await import(
|
||||
'@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
)
|
||||
const { useConflictAcknowledgment } =
|
||||
await import('@/workbench/extensions/manager/composables/useConflictAcknowledgment')
|
||||
const { shouldShowManagerBanner, dismissWarningBanner } =
|
||||
useConflictAcknowledgment()
|
||||
|
||||
@@ -164,9 +155,8 @@ describe('useConflictAcknowledgment', () => {
|
||||
it('should persist to localStorage automatically', async () => {
|
||||
// Need fresh module import to ensure clean state
|
||||
vi.resetModules()
|
||||
const { useConflictAcknowledgment } = await import(
|
||||
'@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
)
|
||||
const { useConflictAcknowledgment } =
|
||||
await import('@/workbench/extensions/manager/composables/useConflictAcknowledgment')
|
||||
const { markConflictsAsSeen, dismissWarningBanner } =
|
||||
useConflictAcknowledgment()
|
||||
|
||||
|
||||
@@ -153,9 +153,8 @@ vi.mock('@/platform/workflow/management/stores/workflowStore', () => ({
|
||||
}))
|
||||
}))
|
||||
|
||||
const { useMinimap } = await import(
|
||||
'@/renderer/extensions/minimap/composables/useMinimap'
|
||||
)
|
||||
const { useMinimap } =
|
||||
await import('@/renderer/extensions/minimap/composables/useMinimap')
|
||||
const { api } = await import('@/scripts/api')
|
||||
|
||||
describe('useMinimap', () => {
|
||||
|
||||
@@ -29,9 +29,8 @@ vi.mock('@/platform/telemetry', () => ({
|
||||
}))
|
||||
}))
|
||||
|
||||
const { useTemplateFiltering } = await import(
|
||||
'@/composables/useTemplateFiltering'
|
||||
)
|
||||
const { useTemplateFiltering } =
|
||||
await import('@/composables/useTemplateFiltering')
|
||||
|
||||
describe('useTemplateFiltering', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -103,9 +103,8 @@ describe('useMinimapRenderer', () => {
|
||||
})
|
||||
|
||||
it('should only render when redraw is needed', async () => {
|
||||
const { renderMinimapToCanvas } = await import(
|
||||
'@/renderer/extensions/minimap/minimapCanvasRenderer'
|
||||
)
|
||||
const { renderMinimapToCanvas } =
|
||||
await import('@/renderer/extensions/minimap/minimapCanvasRenderer')
|
||||
const canvasRef = ref(mockCanvas)
|
||||
const graphRef = ref(mockGraph as any)
|
||||
const boundsRef = ref({ minX: 0, minY: 0, width: 100, height: 100 })
|
||||
|
||||
@@ -66,9 +66,8 @@ describe('useMinimapViewport', () => {
|
||||
})
|
||||
|
||||
it('should calculate graph bounds from nodes', async () => {
|
||||
const { calculateNodeBounds, enforceMinimumBounds } = await import(
|
||||
'@/renderer/core/spatial/boundsCalculator'
|
||||
)
|
||||
const { calculateNodeBounds, enforceMinimumBounds } =
|
||||
await import('@/renderer/core/spatial/boundsCalculator')
|
||||
|
||||
vi.mocked(calculateNodeBounds).mockReturnValue({
|
||||
minX: 100,
|
||||
@@ -93,9 +92,8 @@ describe('useMinimapViewport', () => {
|
||||
})
|
||||
|
||||
it('should handle empty graph', async () => {
|
||||
const { calculateNodeBounds } = await import(
|
||||
'@/renderer/core/spatial/boundsCalculator'
|
||||
)
|
||||
const { calculateNodeBounds } =
|
||||
await import('@/renderer/core/spatial/boundsCalculator')
|
||||
|
||||
vi.mocked(calculateNodeBounds).mockReturnValue(null)
|
||||
|
||||
|
||||
@@ -19,12 +19,10 @@ vi.mock('@/scripts/api', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
const { useWorkflowThumbnail } = await import(
|
||||
'@/renderer/core/thumbnail/useWorkflowThumbnail'
|
||||
)
|
||||
const { createGraphThumbnail } = await import(
|
||||
'@/renderer/core/thumbnail/graphThumbnailRenderer'
|
||||
)
|
||||
const { useWorkflowThumbnail } =
|
||||
await import('@/renderer/core/thumbnail/useWorkflowThumbnail')
|
||||
const { createGraphThumbnail } =
|
||||
await import('@/renderer/core/thumbnail/graphThumbnailRenderer')
|
||||
const { api } = await import('@/scripts/api')
|
||||
|
||||
describe('useWorkflowThumbnail', () => {
|
||||
|
||||
@@ -62,9 +62,8 @@ describe('useReleaseStore', () => {
|
||||
}
|
||||
|
||||
// Setup mock implementations
|
||||
const { useReleaseService } = await import(
|
||||
'@/platform/updates/common/releaseService'
|
||||
)
|
||||
const { useReleaseService } =
|
||||
await import('@/platform/updates/common/releaseService')
|
||||
const { useSettingStore } = await import('@/platform/settings/settingStore')
|
||||
const { useSystemStatsStore } = await import('@/stores/systemStatsStore')
|
||||
const { isElectron } = await import('@/utils/envUtil')
|
||||
|
||||
@@ -287,9 +287,8 @@ describe('versionUtil', () => {
|
||||
vi.resetModules()
|
||||
|
||||
// Import fresh module
|
||||
const versionUtil = await import(
|
||||
'@/workbench/extensions/manager/utils/versionUtil'
|
||||
)
|
||||
const versionUtil =
|
||||
await import('@/workbench/extensions/manager/utils/versionUtil')
|
||||
|
||||
const version = versionUtil.getFrontendVersion()
|
||||
expect(version).toBe('2.0.0')
|
||||
@@ -322,9 +321,8 @@ describe('versionUtil', () => {
|
||||
vi.resetModules()
|
||||
|
||||
// Import fresh module
|
||||
const versionUtil = await import(
|
||||
'@/workbench/extensions/manager/utils/versionUtil'
|
||||
)
|
||||
const versionUtil =
|
||||
await import('@/workbench/extensions/manager/utils/versionUtil')
|
||||
|
||||
const version = versionUtil.getFrontendVersion()
|
||||
expect(version).toBeUndefined()
|
||||
|
||||
Reference in New Issue
Block a user