diff --git a/packages/editor-ui/src/components/AiUpdatedCodeMessage.vue b/packages/editor-ui/src/components/AiUpdatedCodeMessage.vue new file mode 100644 index 0000000000..faad97a189 --- /dev/null +++ b/packages/editor-ui/src/components/AiUpdatedCodeMessage.vue @@ -0,0 +1,16 @@ + + + diff --git a/packages/editor-ui/src/components/NodeExecutionErrorMessage.vue b/packages/editor-ui/src/components/NodeExecutionErrorMessage.vue new file mode 100644 index 0000000000..5786495df4 --- /dev/null +++ b/packages/editor-ui/src/components/NodeExecutionErrorMessage.vue @@ -0,0 +1,18 @@ + + + diff --git a/packages/editor-ui/src/components/WorkflowActivationErrorMessage.vue b/packages/editor-ui/src/components/WorkflowActivationErrorMessage.vue new file mode 100644 index 0000000000..eff43d4f1f --- /dev/null +++ b/packages/editor-ui/src/components/WorkflowActivationErrorMessage.vue @@ -0,0 +1,19 @@ + + + diff --git a/packages/editor-ui/src/components/WorkflowActivator.vue b/packages/editor-ui/src/components/WorkflowActivator.vue index cc5d4cf2ad..d55c143aae 100644 --- a/packages/editor-ui/src/components/WorkflowActivator.vue +++ b/packages/editor-ui/src/components/WorkflowActivator.vue @@ -3,10 +3,12 @@ import { useToast } from '@/composables/useToast'; import { useWorkflowActivate } from '@/composables/useWorkflowActivate'; import { useWorkflowsStore } from '@/stores/workflows.store'; import { getActivatableTriggerNodes } from '@/utils/nodeTypesUtils'; -import { computed } from 'vue'; +import type { VNode } from 'vue'; +import { computed, h } from 'vue'; import { useI18n } from '@/composables/useI18n'; import type { PermissionsRecord } from '@/permissions'; import { PLACEHOLDER_EMPTY_WORKFLOW_ID } from '@/constants'; +import WorkflowActivationErrorMessage from './WorkflowActivationErrorMessage.vue'; const props = defineProps<{ workflowActive: boolean; @@ -61,7 +63,7 @@ async function activeChanged(newActiveState: boolean) { } async function displayActivationError() { - let errorMessage: string; + let errorMessage: string | VNode; try { const errorData = await workflowsStore.getActivationError(props.workflowId); @@ -70,10 +72,9 @@ async function displayActivationError() { 'workflowActivator.showMessage.displayActivationError.message.errorDataUndefined', ); } else { - errorMessage = i18n.baseText( - 'workflowActivator.showMessage.displayActivationError.message.errorDataNotUndefined', - { interpolate: { message: errorData } }, - ); + errorMessage = h(WorkflowActivationErrorMessage, { + message: errorData, + }); } } catch (error) { errorMessage = i18n.baseText( @@ -86,7 +87,6 @@ async function displayActivationError() { message: errorMessage, type: 'warning', duration: 0, - dangerouslyUseHTMLString: true, }); } diff --git a/packages/editor-ui/src/composables/usePushConnection.ts b/packages/editor-ui/src/composables/usePushConnection.ts index 77d7201ca1..60de6ad19b 100644 --- a/packages/editor-ui/src/composables/usePushConnection.ts +++ b/packages/editor-ui/src/composables/usePushConnection.ts @@ -32,7 +32,7 @@ import { useNodeTypesStore } from '@/stores/nodeTypes.store'; import { useCredentialsStore } from '@/stores/credentials.store'; import { useSettingsStore } from '@/stores/settings.store'; import { parse } from 'flatted'; -import { ref } from 'vue'; +import { h, ref } from 'vue'; import { useOrchestrationStore } from '@/stores/orchestration.store'; import { usePushConnectionStore } from '@/stores/pushConnection.store'; import { useExternalHooks } from '@/composables/useExternalHooks'; @@ -42,6 +42,7 @@ import { useI18n } from '@/composables/useI18n'; import { useTelemetry } from '@/composables/useTelemetry'; import type { PushMessageQueueItem } from '@/types'; import { useAssistantStore } from '@/stores/assistant.store'; +import NodeExecutionErrorMessage from '@/components/NodeExecutionErrorMessage.vue'; export function usePushConnection({ router }: { router: ReturnType }) { const workflowHelpers = useWorkflowHelpers({ router }); @@ -407,16 +408,12 @@ export function usePushConnection({ router }: { router: ReturnType{nodeName} node to see the changes", + "aiAssistant.codeUpdated.message.body1": "Open the", + "aiAssistant.codeUpdated.message.body2": "node to see the changes", "aiAssistant.thinkingSteps.analyzingError": "Analyzing the error...", "aiAssistant.thinkingSteps.thinking": "Thinking...", "banners.confirmEmail.message.1": "To secure your account and prevent future access issues, please confirm your", @@ -1002,6 +1003,7 @@ "node.waitingForYouToCreateAnEventIn": "Waiting for you to create an event in {nodeType}", "node.discovery.pinData.canvas": "You can pin this output instead of waiting for a test event. Open node to do so.", "node.discovery.pinData.ndv": "You can pin this output instead of waiting for a test event.", + "node.executionError.openNode": "Open node", "nodeBase.clickToAddNodeOrDragToConnect": "Click to add node \n or drag to connect", "nodeCreator.actionsPlaceholderNode.scheduleTrigger": "On a Schedule", "nodeCreator.actionsPlaceholderNode.webhook": "On a Webhook call", @@ -2016,7 +2018,6 @@ "nodeIssues.credentials.notIdentified": "Credentials with name {name} exist for {type}.", "nodeIssues.credentials.notIdentified.hint": "Credentials are not clearly identified. Please select the correct credentials.", "nodeIssues.input.missing": "No node connected to required input \"{inputName}\"", - "nodeIssues.input.missingSubNode": "On the canvas, add a ‘{inputName}’ connected to the ‘{node}’ node ", "ndv.trigger.moreInfo": "More info", "ndv.trigger.copiedTestUrl": "Test URL copied to clipboard", "ndv.trigger.webhookBasedNode.executionsHelp.inactive": "While building your workflow, click the 'listen' button, then go to {service} and make an event happen. This will trigger an execution, which will show up in this editor.

Once you're happy with your workflow, activate it. Then every time there's a matching event in {service}, the workflow will execute. These executions will show up in the executions list, but not in the editor.", @@ -2070,7 +2071,7 @@ "workflowActivator.showMessage.activeChangedWorkflowIdUndefined.message": "Please save it before activating", "workflowActivator.showMessage.activeChangedWorkflowIdUndefined.title": "Problem activating workflow", "workflowActivator.showMessage.displayActivationError.message.catchBlock": "Sorry there was a problem requesting the error", - "workflowActivator.showMessage.displayActivationError.message.errorDataNotUndefined": "The following error occurred on workflow activation:
{message}", + "workflowActivator.showMessage.displayActivationError.message.errorDataNotUndefined": "The following error occurred on workflow activation:", "workflowActivator.showMessage.displayActivationError.message.errorDataUndefined": "Unknown error", "workflowActivator.showMessage.displayActivationError.title": "Problem activating workflow", "workflowActivator.theWorkflowIsSetToBeActiveBut": "The workflow is activated but could not be started.
Click to display error message.", diff --git a/packages/editor-ui/src/stores/assistant.store.ts b/packages/editor-ui/src/stores/assistant.store.ts index de50aa6261..7ea0b84bc1 100644 --- a/packages/editor-ui/src/stores/assistant.store.ts +++ b/packages/editor-ui/src/stores/assistant.store.ts @@ -9,7 +9,7 @@ import { import type { ChatRequest } from '@/types/assistant.types'; import type { ChatUI } from 'n8n-design-system/types/assistant'; import { defineStore } from 'pinia'; -import { computed, ref, watch } from 'vue'; +import { computed, h, ref, watch } from 'vue'; import { useRootStore } from './root.store'; import { useUsersStore } from './users.store'; import { useRoute } from 'vue-router'; @@ -34,6 +34,7 @@ import { useI18n } from '@/composables/useI18n'; import { useTelemetry } from '@/composables/useTelemetry'; import { useToast } from '@/composables/useToast'; import { useUIStore } from './ui.store'; +import AiUpdatedCodeMessage from '@/components/AiUpdatedCodeMessage.vue'; export const MAX_CHAT_WIDTH = 425; export const MIN_CHAT_WIDTH = 250; @@ -576,7 +577,7 @@ export const useAssistantStore = defineStore(STORES.ASSISTANT, () => { codeDiffMessage.replaced = true; codeNodeEditorEventBus.emit('codeDiffApplied'); - checkIfNodeNDVIsOpen(activeNode.name); + showCodeUpdateToastIfNeeded(activeNode.name); } catch (e) { console.error(e); codeDiffMessage.error = true; @@ -609,7 +610,7 @@ export const useAssistantStore = defineStore(STORES.ASSISTANT, () => { codeDiffMessage.replaced = false; codeNodeEditorEventBus.emit('codeDiffApplied'); - checkIfNodeNDVIsOpen(activeNode.name); + showCodeUpdateToastIfNeeded(activeNode.name); } catch (e) { console.error(e); codeDiffMessage.error = true; @@ -617,15 +618,14 @@ export const useAssistantStore = defineStore(STORES.ASSISTANT, () => { codeDiffMessage.replacing = false; } - function checkIfNodeNDVIsOpen(errorNodeName: string) { + function showCodeUpdateToastIfNeeded(errorNodeName: string) { if (errorNodeName !== ndvStore.activeNodeName) { useToast().showMessage({ type: 'success', title: locale.baseText('aiAssistant.codeUpdated.message.title'), - message: locale.baseText('aiAssistant.codeUpdated.message.body', { - interpolate: { nodeName: errorNodeName }, + message: h(AiUpdatedCodeMessage, { + nodeName: errorNodeName, }), - dangerouslyUseHTMLString: true, duration: 4000, }); }