diff --git a/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue b/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue index ca875836ad..44a5027f63 100644 --- a/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue +++ b/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue @@ -148,7 +148,7 @@ import BreakpointsObserver from '@/components/BreakpointsObserver.vue'; import { IUser, IWorkflowDataUpdate, IWorkflowDb, IWorkflowToShare } from '@/Interface'; import { saveAs } from 'file-saver'; -import { titleChange } from '@/mixins/titleChange'; +import { useTitleChange } from '@/composables/useTitleChange'; import type { MessageBoxInputData } from 'element-ui/types/message-box'; import { mapStores } from 'pinia'; import { useUIStore } from '@/stores/ui'; @@ -159,7 +159,6 @@ import { useTagsStore } from '@/stores/tags'; import { getWorkflowPermissions, IPermissions } from '@/permissions'; import { useUsersStore } from '@/stores/users'; import { useUsageStore } from '@/stores/usage'; -import { BaseTextKey } from '@/plugins/i18n'; import { createEventBus } from '@/event-bus'; const hasChanged = (prev: string[], curr: string[]) => { @@ -171,7 +170,7 @@ const hasChanged = (prev: string[], curr: string[]) => { return curr.reduce((accu, val) => accu || !set.has(val), false); }; -export default mixins(workflowHelpers, titleChange).extend({ +export default mixins(workflowHelpers).extend({ name: 'WorkflowDetails', components: { TagsContainer, @@ -183,6 +182,11 @@ export default mixins(workflowHelpers, titleChange).extend({ InlineTextEdit, BreakpointsObserver, }, + setup() { + return { + ...useTitleChange(), + }; + }, data() { return { isTagsEditEnabled: false, @@ -515,7 +519,7 @@ export default mixins(workflowHelpers, titleChange).extend({ } this.uiStore.stateIsDirty = false; // Reset tab title since workflow is deleted. - this.$titleReset(); + this.titleReset(); this.$showMessage({ title: this.$locale.baseText('mainSidebar.showMessage.handleSelect1.title'), type: 'success', diff --git a/packages/editor-ui/src/components/MainSidebar.vue b/packages/editor-ui/src/components/MainSidebar.vue index 8809d660a2..942e1119b0 100644 --- a/packages/editor-ui/src/components/MainSidebar.vue +++ b/packages/editor-ui/src/components/MainSidebar.vue @@ -99,7 +99,6 @@ import WorkflowSettings from '@/components/WorkflowSettings.vue'; import { genericHelpers } from '@/mixins/genericHelpers'; import { restApi } from '@/mixins/restApi'; import { showMessage } from '@/mixins/showMessage'; -import { titleChange } from '@/mixins/titleChange'; import { workflowHelpers } from '@/mixins/workflowHelpers'; import { workflowRun } from '@/mixins/workflowRun'; @@ -115,13 +114,12 @@ import { useUsersStore } from '@/stores/users'; import { useWorkflowsStore } from '@/stores/workflows'; import { useRootStore } from '@/stores/n8nRootStore'; import { useVersionsStore } from '@/stores/versions'; -import { isNavigationFailure, NavigationFailureType, Route } from 'vue-router'; +import { isNavigationFailure } from 'vue-router'; export default mixins( genericHelpers, restApi, showMessage, - titleChange, workflowHelpers, workflowRun, userHelpers, diff --git a/packages/editor-ui/src/composables/useTitleChange.ts b/packages/editor-ui/src/composables/useTitleChange.ts new file mode 100644 index 0000000000..45ed1ab013 --- /dev/null +++ b/packages/editor-ui/src/composables/useTitleChange.ts @@ -0,0 +1,19 @@ +import { WorkflowTitleStatus } from '@/Interface'; + +export function useTitleChange() { + return { + titleSet(workflow: string, status: WorkflowTitleStatus) { + let icon = '⚠️'; + if (status === 'EXECUTING') { + icon = '🔄'; + } else if (status === 'IDLE') { + icon = '▶️'; + } + + window.document.title = `n8n - ${icon} ${workflow}`; + }, + titleReset() { + document.title = 'n8n - Workflow Automation'; + }, + }; +} diff --git a/packages/editor-ui/src/mixins/pushConnection.ts b/packages/editor-ui/src/mixins/pushConnection.ts index a43c5a5c35..01b40ceaa9 100644 --- a/packages/editor-ui/src/mixins/pushConnection.ts +++ b/packages/editor-ui/src/mixins/pushConnection.ts @@ -8,7 +8,7 @@ import { import { externalHooks } from '@/mixins/externalHooks'; import { nodeHelpers } from '@/mixins/nodeHelpers'; import { showMessage } from '@/mixins/showMessage'; -import { titleChange } from '@/mixins/titleChange'; +import { useTitleChange } from '@/composables/useTitleChange'; import { workflowHelpers } from '@/mixins/workflowHelpers'; import { @@ -39,9 +39,13 @@ export const pushConnection = mixins( externalHooks, nodeHelpers, showMessage, - titleChange, workflowHelpers, ).extend({ + setup() { + return { + ...useTitleChange(), + }; + }, data() { return { pushSource: null as WebSocket | EventSource | null, @@ -362,7 +366,7 @@ export const pushConnection = mixins( } // Workflow did start but had been put to wait - this.$titleSet(workflow.name as string, 'IDLE'); + this.titleSet(workflow.name as string, 'IDLE'); this.$showToast({ title: 'Workflow started waiting', message: `${action} More info`, @@ -370,7 +374,7 @@ export const pushConnection = mixins( duration: 0, }); } else if (runDataExecuted.finished !== true) { - this.$titleSet(workflow.name as string, 'ERROR'); + this.titleSet(workflow.name as string, 'ERROR'); if ( runDataExecuted.data.resultData.error?.name === 'ExpressionError' && @@ -441,7 +445,7 @@ export const pushConnection = mixins( } } else { // Workflow did execute without a problem - this.$titleSet(workflow.name as string, 'IDLE'); + this.titleSet(workflow.name as string, 'IDLE'); const execution = this.workflowsStore.getWorkflowExecution; if (execution && execution.executedNode) { diff --git a/packages/editor-ui/src/mixins/titleChange.ts b/packages/editor-ui/src/mixins/titleChange.ts deleted file mode 100644 index 63cde777c4..0000000000 --- a/packages/editor-ui/src/mixins/titleChange.ts +++ /dev/null @@ -1,28 +0,0 @@ -import Vue from 'vue'; - -import { WorkflowTitleStatus } from '@/Interface'; - -export const titleChange = Vue.extend({ - methods: { - /** - * Change title of n8n tab - * - * @param {string} workflow Name of workflow - * @param {WorkflowTitleStatus} status Status of workflow - */ - $titleSet(workflow: string, status: WorkflowTitleStatus) { - let icon = '⚠️'; - if (status === 'EXECUTING') { - icon = '🔄'; - } else if (status === 'IDLE') { - icon = '▶️'; - } - - window.document.title = `n8n - ${icon} ${workflow}`; - }, - - $titleReset() { - document.title = 'n8n - Workflow Automation'; - }, - }, -}); diff --git a/packages/editor-ui/src/mixins/workflowRun.ts b/packages/editor-ui/src/mixins/workflowRun.ts index 80a5a137b0..9b52780057 100644 --- a/packages/editor-ui/src/mixins/workflowRun.ts +++ b/packages/editor-ui/src/mixins/workflowRun.ts @@ -14,19 +14,18 @@ import { workflowHelpers } from '@/mixins/workflowHelpers'; import { showMessage } from '@/mixins/showMessage'; import mixins from 'vue-typed-mixins'; -import { titleChange } from './titleChange'; +import { useTitleChange } from '@/composables/useTitleChange'; import { mapStores } from 'pinia'; import { useUIStore } from '@/stores/ui'; import { useWorkflowsStore } from '@/stores/workflows'; import { useRootStore } from '@/stores/n8nRootStore'; -export const workflowRun = mixins( - externalHooks, - restApi, - workflowHelpers, - showMessage, - titleChange, -).extend({ +export const workflowRun = mixins(externalHooks, restApi, workflowHelpers, showMessage).extend({ + setup() { + return { + ...useTitleChange(), + }; + }, computed: { ...mapStores(useRootStore, useUIStore, useWorkflowsStore), }, @@ -72,7 +71,7 @@ export const workflowRun = mixins( return; } - this.$titleSet(workflow.name as string, 'EXECUTING'); + this.titleSet(workflow.name as string, 'EXECUTING'); this.clearAllStickyNotifications(); @@ -119,7 +118,7 @@ export const workflowRun = mixins( type: 'error', duration: 0, }); - this.$titleSet(workflow.name as string, 'ERROR'); + this.titleSet(workflow.name as string, 'ERROR'); this.$externalHooks().run('workflowRun.runError', { errorMessages, nodeName }); this.getWorkflowDataToSave().then((workflowData) => { @@ -245,7 +244,7 @@ export const workflowRun = mixins( return runWorkflowApiResponse; } catch (error) { - this.$titleSet(workflow.name as string, 'ERROR'); + this.titleSet(workflow.name as string, 'ERROR'); this.$showError(error, this.$locale.baseText('workflowRun.showError.title')); return undefined; } diff --git a/packages/editor-ui/src/views/NodeView.vue b/packages/editor-ui/src/views/NodeView.vue index e3b020bfe5..2cc7730866 100644 --- a/packages/editor-ui/src/views/NodeView.vue +++ b/packages/editor-ui/src/views/NodeView.vue @@ -209,7 +209,7 @@ import { restApi } from '@/mixins/restApi'; import useGlobalLinkActions from '@/composables/useGlobalLinkActions'; import useCanvasMouseSelect from '@/composables/useCanvasMouseSelect'; import { showMessage } from '@/mixins/showMessage'; -import { titleChange } from '@/mixins/titleChange'; +import { useTitleChange } from '@/composables/useTitleChange'; import { workflowHelpers } from '@/mixins/workflowHelpers'; import { workflowRun } from '@/mixins/workflowRun'; @@ -226,6 +226,7 @@ import { IConnection, IConnections, IDataObject, + IExecutionsSummary, INode, INodeConnections, INodeCredentialsDetails, @@ -254,7 +255,6 @@ import type { ITag, INewWorkflowData, IWorkflowTemplate, - IExecutionsSummary, IWorkflowToShare, IUser, INodeUpdatePropertiesInformation, @@ -307,7 +307,6 @@ import { N8nPlusEndpointType, EVENT_PLUS_ENDPOINT_CLICK, } from '@/plugins/endpoints/N8nPlusEndpointType'; -import { usePostHog } from '@/stores/posthog'; interface AddNodeOptions { position?: XYPosition; @@ -325,7 +324,6 @@ export default mixins( moveNodeWorkflow, restApi, showMessage, - titleChange, workflowHelpers, workflowRun, debounceHelper, @@ -345,6 +343,7 @@ export default mixins( return { ...useCanvasMouseSelect(), ...useGlobalLinkActions(), + ...useTitleChange(), }; }, errorCaptured: (err, vm, info) => { @@ -1423,7 +1422,7 @@ export default mixins( this.workflowsStore.executingNode = null; this.uiStore.removeActiveAction('workflowRunning'); - this.$titleSet(this.workflowsStore.workflowName, 'IDLE'); + this.titleSet(this.workflowsStore.workflowName, 'IDLE'); this.$showMessage({ title: this.$locale.baseText('nodeView.showMessage.stopExecutionCatch.unsaved.title'), message: this.$locale.baseText( @@ -1447,7 +1446,7 @@ export default mixins( retryOf: execution.retryOf, } as IPushDataExecutionFinished; this.workflowsStore.finishActiveExecution(pushData); - this.$titleSet(execution.workflowData.name, 'IDLE'); + this.titleSet(execution.workflowData.name, 'IDLE'); this.workflowsStore.executingNode = null; this.workflowsStore.setWorkflowExecutionData(executedData as IExecutionResponse); this.uiStore.removeActiveAction('workflowRunning'); @@ -2597,7 +2596,7 @@ export default mixins( } if (workflow) { - this.$titleSet(workflow.name, 'IDLE'); + this.titleSet(workflow.name, 'IDLE'); // Open existing workflow await this.openWorkflow(workflow); } @@ -3848,7 +3847,7 @@ export default mixins( async mounted() { this.resetWorkspace(); this.canvasStore.initInstance(this.$refs.nodeView as HTMLElement); - this.$titleReset(); + this.titleReset(); window.addEventListener('message', this.onPostMessageReceived); this.startLoading();