From 87320fac6758b686e7a6925bf0563e9120c5ce93 Mon Sep 17 00:00:00 2001 From: popdrazvan Date: Thu, 13 Mar 2025 16:01:06 +0200 Subject: [PATCH 1/2] Show error for external set uri --- .changeset/tame-bobcats-shop.md | 7 ++++ .../src/components/portPanel/index.tsx | 10 +++++- .../graph-engine/src/annotations/index.ts | 7 ++++ .../src/nodes/externalTokens.ts | 34 ++++++++++++++++--- 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 .changeset/tame-bobcats-shop.md diff --git a/.changeset/tame-bobcats-shop.md b/.changeset/tame-bobcats-shop.md new file mode 100644 index 000000000..bf9467591 --- /dev/null +++ b/.changeset/tame-bobcats-shop.md @@ -0,0 +1,7 @@ +--- +"@tokens-studio/graph-engine-nodes-design-tokens": patch +"@tokens-studio/graph-editor": patch +"@tokens-studio/graph-engine": patch +--- + +Better handling of input error for the external tokens node. diff --git a/packages/graph-editor/src/components/portPanel/index.tsx b/packages/graph-editor/src/components/portPanel/index.tsx index 4fcc84818..56dd4f065 100644 --- a/packages/graph-editor/src/components/portPanel/index.tsx +++ b/packages/graph-editor/src/components/portPanel/index.tsx @@ -2,10 +2,14 @@ import { DropdownMenu, IconButton, Label, + Message, Stack, Tooltip, } from '@tokens-studio/ui'; -import { Port as GraphPort } from '@tokens-studio/graph-engine'; +import { + Port as GraphPort, + annotatedInputError, +} from '@tokens-studio/graph-engine'; import { Input } from '@tokens-studio/graph-engine'; import { observer } from 'mobx-react-lite'; import { useSelector } from 'react-redux'; @@ -47,6 +51,9 @@ export const PortPanel = observer(({ ports, readOnly }: IPortPanel) => { export const Port = observer(({ port, readOnly: isReadOnly }: IField) => { const readOnly = isReadOnly || port.isConnected; const controlSelector = useSelector(controls); + const hasError = Boolean(port.annotations[annotatedInputError]); + const errorMessage = port.annotations[annotatedInputError]?.message; + const graph = useGraph(); const isInput = 'studio.tokens.generic.input' === port.node.factory.type; const isDynamicInput = Boolean(port.annotations[deletable]); @@ -166,6 +173,7 @@ export const Port = observer(({ port, readOnly: isReadOnly }: IField) => { {inner} + {hasError && {errorMessage}} ); }); diff --git a/packages/graph-engine/src/annotations/index.ts b/packages/graph-engine/src/annotations/index.ts index 81991fa96..76ffb0e37 100644 --- a/packages/graph-engine/src/annotations/index.ts +++ b/packages/graph-engine/src/annotations/index.ts @@ -42,3 +42,10 @@ export const annotatedNodeRunning = 'engine.nodeRunning'; * Unique id of the entity */ export const annotatedId = 'engine.id'; + +/** + * Indicates that the node failed to load resources + */ +export const annotatedInputError = 'engine.inputError'; + + diff --git a/packages/nodes-design-tokens/src/nodes/externalTokens.ts b/packages/nodes-design-tokens/src/nodes/externalTokens.ts index d7bb48141..b27d8c2f3 100644 --- a/packages/nodes-design-tokens/src/nodes/externalTokens.ts +++ b/packages/nodes-design-tokens/src/nodes/externalTokens.ts @@ -1,7 +1,8 @@ import { INodeDefinition, Node, - StringSchema + StringSchema, + annotatedInputError } from '@tokens-studio/graph-engine'; import { TokenSchema } from '../schemas/index.js'; import { arrayOf } from '../schemas/utils.js'; @@ -22,15 +23,38 @@ export default class ExternalTokensNode extends Node { }); } - async execute() { + + override async execute() { const { uri } = this.getAllInputs(); if (!uri) { - this.outputs.tokenSet.set([]); - return; + throw new Error('No uri specified'); } const tokens = await this.load(uri); - this.outputs.tokenSet.set(tokens); + + if (!tokens) { + // set this so we can show a red border around the node to indicate an error + this.error = new Error('Failed to load tokens'); + if (this.inputs['uri']) { + // set this so we can show an error in the graph editor input sheet + this.inputs['uri'].annotations[annotatedInputError] = { + message: + 'Failed to load tokens. Check if the uri is valid and the set was not deleted or renamed.', + }; + } + } else { + if (this.outputs && this.outputs.tokenSet) { + this.outputs.tokenSet.set(tokens); + } + + // clear the error if there is one + if (this.error) { + this.error = null; + if (this.inputs['uri']) { + delete this.inputs['uri'].annotations[annotatedInputError]; + } + } + } } } From a155946c92b440c746120d4fb17e40b8ba40e346 Mon Sep 17 00:00:00 2001 From: popdrazvan Date: Fri, 14 Mar 2025 11:11:07 +0200 Subject: [PATCH 2/2] fix lint --- packages/nodes-design-tokens/src/nodes/externalTokens.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/nodes-design-tokens/src/nodes/externalTokens.ts b/packages/nodes-design-tokens/src/nodes/externalTokens.ts index b27d8c2f3..6d1129d31 100644 --- a/packages/nodes-design-tokens/src/nodes/externalTokens.ts +++ b/packages/nodes-design-tokens/src/nodes/externalTokens.ts @@ -23,7 +23,6 @@ export default class ExternalTokensNode extends Node { }); } - override async execute() { const { uri } = this.getAllInputs(); @@ -40,7 +39,7 @@ export default class ExternalTokensNode extends Node { // set this so we can show an error in the graph editor input sheet this.inputs['uri'].annotations[annotatedInputError] = { message: - 'Failed to load tokens. Check if the uri is valid and the set was not deleted or renamed.', + 'Failed to load tokens. Check if the uri is valid and the set was not deleted or renamed.' }; } } else {