diff --git a/eslint.config.ts b/eslint.config.ts index 13068d621d8..ba0b7b5916f 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -320,5 +320,15 @@ export default defineConfig([ } ] } + }, + + // Storybook-only mock components (__stories__/**/*.vue) + // These are not shipped to production and do not require i18n or strict Vue patterns. + { + files: ['**/__stories__/**/*.vue'], + rules: { + '@intlify/vue-i18n/no-raw-text': 'off', + 'vue/no-unused-properties': 'off' + } } ]) diff --git a/src/components/TopMenuSection.vue b/src/components/TopMenuSection.vue index 27be55962c9..296182dd5b4 100644 --- a/src/components/TopMenuSection.vue +++ b/src/components/TopMenuSection.vue @@ -110,6 +110,7 @@ + + +
+
+ +
+ + {{ errorCountLabel }} + + +
+ + +
+
    +
  • + + {{ message }} +
  • +
+
+ + +
+ + +
+
+
+
+ + + diff --git a/src/components/rightSidePanel/RightSidePanel.vue b/src/components/rightSidePanel/RightSidePanel.vue index 3b36a629964..1ef8441aa76 100644 --- a/src/components/rightSidePanel/RightSidePanel.vue +++ b/src/components/rightSidePanel/RightSidePanel.vue @@ -19,8 +19,8 @@ import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore' import type { RightSidePanelTab } from '@/stores/workspace/rightSidePanelStore' import { resolveNodeDisplayName } from '@/utils/nodeTitleUtil' import { cn } from '@/utils/tailwindUtil' +import { isGroupNode } from '@/utils/executableGroupNodeDto' -import TabError from './TabError.vue' import TabInfo from './info/TabInfo.vue' import TabGlobalParameters from './parameters/TabGlobalParameters.vue' import TabNodes from './parameters/TabNodes.vue' @@ -41,7 +41,7 @@ const rightSidePanelStore = useRightSidePanelStore() const settingStore = useSettingStore() const { t } = useI18n() -const { hasAnyError } = storeToRefs(executionStore) +const { hasAnyError, allErrorExecutionIds } = storeToRefs(executionStore) const { findParentGroup } = useGraphHierarchy() @@ -96,30 +96,31 @@ type RightSidePanelTabList = Array<{ icon?: string }> -//FIXME all errors if nothing selected? -const selectedNodeErrors = computed(() => - selectedNodes.value - .map((node) => executionStore.getNodeErrors(`${node.id}`)) - .filter((nodeError) => !!nodeError) +const hasDirectNodeError = computed(() => + selectedNodes.value.some((node) => + executionStore.activeGraphErrorNodeIds.has(String(node.id)) + ) ) +const hasContainerInternalError = computed(() => { + if (allErrorExecutionIds.value.length === 0) return false + return selectedNodes.value.some((node) => { + if (!(node instanceof SubgraphNode || isGroupNode(node))) return false + return executionStore.hasInternalErrorForNode(node.id) + }) +}) + +const hasRelevantErrors = computed(() => { + if (!hasSelection.value) return hasAnyError.value + return hasDirectNodeError.value || hasContainerInternalError.value +}) + const tabs = computed(() => { const list: RightSidePanelTabList = [] - if ( - selectedNodeErrors.value.length && - settingStore.get('Comfy.RightSidePanel.ShowErrorsTab') - ) { - list.push({ - label: () => t('g.error'), - value: 'error', - icon: 'icon-[lucide--octagon-alert] bg-node-stroke-error ml-1' - }) - } if ( - hasAnyError.value && - !hasSelection.value && - settingStore.get('Comfy.RightSidePanel.ShowErrorsTab') + settingStore.get('Comfy.RightSidePanel.ShowErrorsTab') && + hasRelevantErrors.value ) { list.push({ label: () => t('rightSidePanel.errors'), @@ -315,9 +316,9 @@ function handleProxyWidgetsUpdate(value: ProxyWidgetsProperty) {
-