From ba2827e7bb45d17f47cf9fac2d0a4baabda8ba17 Mon Sep 17 00:00:00 2001 From: Alex Grozav Date: Mon, 21 Oct 2024 14:06:24 +0300 Subject: [PATCH] feat(editor): Create call to action tooltip for trying the new canvas (no-changelog) (#11230) --- cypress/support/commands.ts | 4 ++ .../N8nActionDropdown/ActionDropdown.vue | 3 + .../src/types/action-dropdown.ts | 1 + .../components/MainHeader/WorkflowDetails.vue | 69 ++++++++++--------- .../composables/useNodeViewVersionSwitcher.ts | 63 +++++++++++++++++ .../src/plugins/i18n/locales/en.json | 2 + .../editor-ui/src/views/NodeViewSwitcher.vue | 9 +-- 7 files changed, 113 insertions(+), 38 deletions(-) create mode 100644 packages/editor-ui/src/composables/useNodeViewVersionSwitcher.ts diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 35f100fded..e27468cd55 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -70,6 +70,10 @@ Cypress.Commands.add('signin', ({ email, password }) => { }) .then((response) => { Cypress.env('currentUserId', response.body.data.id); + + cy.window().then((win) => { + win.localStorage.setItem('NodeView.switcher.discovered', 'true'); // @TODO Remove this once the switcher is removed + }); }); }); }); diff --git a/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.vue b/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.vue index 7284dea7dd..4b3f4d7df4 100644 --- a/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.vue +++ b/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.vue @@ -117,6 +117,9 @@ defineExpose({ open, close }); {{ item.label }} + + {{ item.badge }} + (); const tagsEventBus = createEventBus(); const sourceControlModalEventBus = createEventBus(); -const nodeViewSwitcher = useLocalStorage('NodeView.switcher', ''); -const nodeViewVersion = useLocalStorage('NodeView.version', '1'); - -const isNodeViewSwitcherEnabled = computed(() => { - return ( - import.meta.env.DEV || - nodeViewSwitcher.value === 'true' || - settingsStore.deploymentType === 'n8n-internal' - ); -}); +const { + nodeViewVersion, + nodeViewSwitcherDiscovered, + isNodeViewDiscoveryTooltipVisible, + switchNodeViewVersion, + setNodeViewSwitcherDropdownOpened, + setNodeViewSwitcherDiscovered, +} = useNodeViewVersionSwitcher(); const hasChanged = (prev: string[], curr: string[]) => { if (prev.length !== curr.length) { @@ -189,16 +187,17 @@ const workflowMenuItems = computed(() => { disabled: !onWorkflowPage.value || isNewWorkflow.value, }); - if (isNodeViewSwitcherEnabled.value) { - 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, - }); - } + actions.push({ + id: WORKFLOW_MENU_ACTIONS.SWITCH_NODE_VIEW_VERSION, + ...(nodeViewSwitcherDiscovered.value + ? {} + : { badge: locale.baseText('menuActions.badge.new') }), + 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({ @@ -399,6 +398,10 @@ async function handleFileImport(): Promise { } } +function onWorkflowMenuOpen() { + setNodeViewSwitcherDropdownOpened(); +} + async function onWorkflowMenuSelect(action: WORKFLOW_MENU_ACTIONS): Promise { switch (action) { case WORKFLOW_MENU_ACTIONS.DUPLICATE: { @@ -499,6 +502,8 @@ async function onWorkflowMenuSelect(action: WORKFLOW_MENU_ACTIONS): Promise - + + + + diff --git a/packages/editor-ui/src/composables/useNodeViewVersionSwitcher.ts b/packages/editor-ui/src/composables/useNodeViewVersionSwitcher.ts new file mode 100644 index 0000000000..8e0690d692 --- /dev/null +++ b/packages/editor-ui/src/composables/useNodeViewVersionSwitcher.ts @@ -0,0 +1,63 @@ +import { computed, ref } from 'vue'; +import { useLocalStorage } from '@vueuse/core'; +import { useSettingsStore } from '@/stores/settings.store'; +import { useTelemetry } from '@/composables/useTelemetry'; +import { useWorkflowsStore } from '@/stores/workflows.store'; +import { debouncedRef } from '@vueuse/core'; + +export function useNodeViewVersionSwitcher() { + const workflowsStore = useWorkflowsStore(); + const settingsStore = useSettingsStore(); + const telemetry = useTelemetry(); + + const isNewUser = computed(() => workflowsStore.activeWorkflows.length === 0); + + const nodeViewVersion = useLocalStorage( + 'NodeView.version', + settingsStore.deploymentType === 'n8n-internal' ? '2' : '1', + ); + + const nodeViewSwitcherDropdownOpened = ref(false); + function setNodeViewSwitcherDropdownOpened() { + nodeViewSwitcherDropdownOpened.value = true; + } + + const nodeViewSwitcherDiscovered = useLocalStorage('NodeView.switcher.discovered', false); + function setNodeViewSwitcherDiscovered() { + nodeViewSwitcherDiscovered.value = true; + } + + const isNodeViewDiscoveryTooltipVisibleRaw = computed( + () => + nodeViewVersion.value !== '2' && + !( + isNewUser.value || + nodeViewSwitcherDropdownOpened.value || + nodeViewSwitcherDiscovered.value + ), + ); + + const isNodeViewDiscoveryTooltipVisible = debouncedRef( + isNodeViewDiscoveryTooltipVisibleRaw, + 3000, + ); + + function switchNodeViewVersion() { + const toVersion = nodeViewVersion.value === '1' ? '2' : '1'; + + telemetry.track('User switched canvas version', { + to_version: toVersion, + }); + + nodeViewVersion.value = toVersion; + } + + return { + nodeViewVersion, + nodeViewSwitcherDiscovered, + isNodeViewDiscoveryTooltipVisible, + setNodeViewSwitcherDropdownOpened, + setNodeViewSwitcherDiscovered, + switchNodeViewVersion, + }; +} diff --git a/packages/editor-ui/src/plugins/i18n/locales/en.json b/packages/editor-ui/src/plugins/i18n/locales/en.json index e975ebb12c..2a40bfbeb6 100644 --- a/packages/editor-ui/src/plugins/i18n/locales/en.json +++ b/packages/editor-ui/src/plugins/i18n/locales/en.json @@ -906,6 +906,8 @@ "menuActions.delete": "Delete", "menuActions.switchToNewNodeViewVersion": "Switch to new canvas", "menuActions.switchToOldNodeViewVersion": "Switch to old canvas", + "menuActions.badge.new": "NEW", + "menuActions.nodeViewDiscovery.tooltip": "Try our new, more performant canvas", "multipleParameter.addItem": "Add item", "multipleParameter.currentlyNoItemsExist": "Currently no items exist", "multipleParameter.deleteItem": "Delete item", diff --git a/packages/editor-ui/src/views/NodeViewSwitcher.vue b/packages/editor-ui/src/views/NodeViewSwitcher.vue index adcc58fc98..d40f92e626 100644 --- a/packages/editor-ui/src/views/NodeViewSwitcher.vue +++ b/packages/editor-ui/src/views/NodeViewSwitcher.vue @@ -1,5 +1,4 @@