From 4e2f0adb2a81f12dcebfe8fd984f35afb19fcd3a Mon Sep 17 00:00:00 2001 From: Alex Grozav Date: Tue, 9 Jul 2024 15:58:36 +0300 Subject: [PATCH] feat(editor): Add workflow action to switch between new and old canvas (no-changelog) (#9969) --- packages/editor-ui/src/App.vue | 2 +- .../components/MainHeader/WorkflowDetails.vue | 48 +++++++++++++++++++ packages/editor-ui/src/constants.ts | 12 ++--- .../src/plugins/i18n/locales/en.json | 2 + packages/editor-ui/src/router.ts | 41 +--------------- packages/editor-ui/src/views/NodeView.v2.vue | 8 ++-- .../editor-ui/src/views/NodeViewSwitcher.vue | 20 ++++++++ 7 files changed, 79 insertions(+), 54 deletions(-) create mode 100644 packages/editor-ui/src/views/NodeViewSwitcher.vue diff --git a/packages/editor-ui/src/App.vue b/packages/editor-ui/src/App.vue index bb29530e52..d07062db18 100644 --- a/packages/editor-ui/src/App.vue +++ b/packages/editor-ui/src/App.vue @@ -20,7 +20,7 @@
- + diff --git a/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue b/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue index 9cda6ebc9d..2e56fcb60a 100644 --- a/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue +++ b/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue @@ -3,6 +3,7 @@ import { DUPLICATE_MODAL_KEY, EnterpriseEditionFeature, MAX_WORKFLOW_NAME_LENGTH, + MODAL_CLOSE, MODAL_CONFIRM, PLACEHOLDER_EMPTY_WORKFLOW_ID, SOURCE_CONTROL_PUSH_MODAL_KEY, @@ -55,6 +56,7 @@ import { useI18n } from '@/composables/useI18n'; import { useTelemetry } from '@/composables/useTelemetry'; import type { BaseTextKey } from '../../plugins/i18n'; import { useNpsSurveyStore } from '@/stores/npsSurvey.store'; +import { useLocalStorage } from '@vueuse/core'; const props = defineProps<{ workflow: IWorkflowDb; @@ -93,6 +95,9 @@ const importFileRef = ref(); const tagsEventBus = createEventBus(); const sourceControlModalEventBus = createEventBus(); +const nodeViewSwitcher = useLocalStorage('NodeView.switcher', ''); +const nodeViewVersion = useLocalStorage('NodeView.version', '1'); + const hasChanged = (prev: string[], curr: string[]) => { if (prev.length !== curr.length) { return true; @@ -178,6 +183,17 @@ const workflowMenuItems = computed(() => { disabled: !onWorkflowPage.value || isNewWorkflow.value, }); + if (nodeViewSwitcher.value === 'true') { + actions.push({ + id: WORKFLOW_MENU_ACTIONS.SWITCH_NODE_VIEW_VERSION, + label: + nodeViewVersion.value === '2' + ? locale.baseText('menuActions.switchToOldNodeViewVersion') + : locale.baseText('menuActions.switchToNewNodeViewVersion'), + disabled: !onWorkflowPage.value, + }); + } + if ((workflowPermissions.value.delete && !props.readOnly) || isNewWorkflow.value) { actions.push({ id: WORKFLOW_MENU_ACTIONS.DELETE, @@ -488,6 +504,38 @@ async function onWorkflowMenuSelect(action: WORKFLOW_MENU_ACTIONS): Promise()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; @@ -451,9 +452,7 @@ export const enum VIEWS { CREDENTIALS = 'CredentialsView', VARIABLES = 'VariablesView', NEW_WORKFLOW = 'NodeViewNew', - NEW_WORKFLOW_V2 = 'NodeViewNewV2', WORKFLOW = 'NodeViewExisting', - WORKFLOW_V2 = 'NodeViewV2', DEMO = 'WorkflowDemo', TEMPLATE_IMPORT = 'WorkflowTemplate', WORKFLOW_ONBOARDING = 'WorkflowOnboarding', @@ -487,13 +486,7 @@ export const enum VIEWS { PROJECT_SETTINGS = 'ProjectSettings', } -export const EDITABLE_CANVAS_VIEWS = [ - VIEWS.WORKFLOW, - VIEWS.NEW_WORKFLOW, - VIEWS.WORKFLOW_V2, - VIEWS.NEW_WORKFLOW_V2, - VIEWS.EXECUTION_DEBUG, -]; +export const EDITABLE_CANVAS_VIEWS = [VIEWS.WORKFLOW, VIEWS.NEW_WORKFLOW, VIEWS.EXECUTION_DEBUG]; export const enum FAKE_DOOR_FEATURES { ENVIRONMENTS = 'environments', @@ -547,6 +540,7 @@ export const enum WORKFLOW_MENU_ACTIONS { PUSH = 'push', SETTINGS = 'settings', DELETE = 'delete', + SWITCH_NODE_VIEW_VERSION = 'switch-node-view-version', } /** diff --git a/packages/editor-ui/src/plugins/i18n/locales/en.json b/packages/editor-ui/src/plugins/i18n/locales/en.json index e4eae1e4e3..7d20b3139d 100644 --- a/packages/editor-ui/src/plugins/i18n/locales/en.json +++ b/packages/editor-ui/src/plugins/i18n/locales/en.json @@ -860,6 +860,8 @@ "menuActions.importFromUrl": "Import from URL...", "menuActions.importFromFile": "Import from File...", "menuActions.delete": "Delete", + "menuActions.switchToNewNodeViewVersion": "Switch to new canvas", + "menuActions.switchToOldNodeViewVersion": "Switch to old canvas", "multipleParameter.addItem": "Add item", "multipleParameter.currentlyNoItemsExist": "Currently no items exist", "multipleParameter.deleteItem": "Delete item", diff --git a/packages/editor-ui/src/router.ts b/packages/editor-ui/src/router.ts index 0a02ddac31..6c6a68b22d 100644 --- a/packages/editor-ui/src/router.ts +++ b/packages/editor-ui/src/router.ts @@ -24,8 +24,7 @@ const ErrorView = async () => await import('./views/ErrorView.vue'); const ForgotMyPasswordView = async () => await import('./views/ForgotMyPasswordView.vue'); const MainHeader = async () => await import('@/components/MainHeader/MainHeader.vue'); const MainSidebar = async () => await import('@/components/MainSidebar.vue'); -const NodeView = async () => await import('@/views/NodeView.vue'); -const NodeViewV2 = async () => await import('@/views/NodeView.v2.vue'); +const NodeView = async () => await import('@/views/NodeViewSwitcher.vue'); const WorkflowExecutionsView = async () => await import('@/views/WorkflowExecutionsView.vue'); const WorkflowExecutionsLandingPage = async () => await import('@/components/executions/workflow/WorkflowExecutionsLandingPage.vue'); @@ -70,10 +69,6 @@ function getTemplatesRedirect(defaultRedirect: VIEWS[keyof VIEWS]): { name: stri return false; } -function nodeViewV2CustomMiddleware() { - return !!localStorage.getItem('features.NodeViewV2'); -} - export const routes: RouteRecordRaw[] = [ { path: '/', @@ -362,40 +357,6 @@ export const routes: RouteRecordRaw[] = [ path: '/workflow', redirect: '/workflow/new', }, - { - path: '/workflow-v2/:name', - name: VIEWS.WORKFLOW_V2, - components: { - default: NodeViewV2, - header: MainHeader, - sidebar: MainSidebar, - }, - meta: { - nodeView: true, - keepWorkflowAlive: true, - middleware: ['authenticated', 'custom'], - middlewareOptions: { - custom: nodeViewV2CustomMiddleware, - }, - }, - }, - { - path: '/workflow-v2/new', - name: VIEWS.NEW_WORKFLOW_V2, - components: { - default: NodeViewV2, - header: MainHeader, - sidebar: MainSidebar, - }, - meta: { - nodeView: true, - keepWorkflowAlive: true, - middleware: ['authenticated', 'custom'], - middlewareOptions: { - custom: nodeViewV2CustomMiddleware, - }, - }, - }, { path: '/signin', name: VIEWS.SIGNIN, diff --git a/packages/editor-ui/src/views/NodeView.v2.vue b/packages/editor-ui/src/views/NodeView.v2.vue index 1f9c4086e9..dedc2e239e 100644 --- a/packages/editor-ui/src/views/NodeView.v2.vue +++ b/packages/editor-ui/src/views/NodeView.v2.vue @@ -153,7 +153,7 @@ const hideNodeIssues = ref(false); const workflowId = computed(() => route.params.name as string); const workflow = computed(() => workflowsStore.workflowsById[workflowId.value]); -const isNewWorkflowRoute = computed(() => route.name === VIEWS.NEW_WORKFLOW_V2); +const isNewWorkflowRoute = computed(() => route.name === VIEWS.NEW_WORKFLOW); const isDemoRoute = computed(() => route.name === VIEWS.DEMO); const isReadOnlyRoute = computed(() => route?.meta?.readOnlyCanvas === true); const isReadOnlyEnvironment = computed(() => { @@ -265,7 +265,7 @@ async function initializeView() { toast.showError(error, i18n.baseText('openWorkflow.workflowNotFoundError')); void router.push({ - name: VIEWS.NEW_WORKFLOW_V2, + name: VIEWS.NEW_WORKFLOW, }); } } @@ -844,11 +844,11 @@ onBeforeRouteLeave(async (to, from, next) => { } uiStore.stateIsDirty = false; - if (from.name === VIEWS.NEW_WORKFLOW_V2) { + if (from.name === VIEWS.NEW_WORKFLOW) { // Replace the current route with the new workflow route // before navigating to the new route when saving new workflow. await router.replace({ - name: VIEWS.WORKFLOW_V2, + name: VIEWS.WORKFLOW, params: { name: workflowId.value }, }); diff --git a/packages/editor-ui/src/views/NodeViewSwitcher.vue b/packages/editor-ui/src/views/NodeViewSwitcher.vue new file mode 100644 index 0000000000..0c6f80166d --- /dev/null +++ b/packages/editor-ui/src/views/NodeViewSwitcher.vue @@ -0,0 +1,20 @@ + + +