|
1 | 1 | <script lang="ts" setup>
|
| 2 | +import BreakpointsObserver from '@/components/BreakpointsObserver.vue'; |
| 3 | +import InlineTextEdit from '@/components/InlineTextEdit.vue'; |
| 4 | +import CollaborationPane from '@/components/MainHeader/CollaborationPane.vue'; |
| 5 | +import WorkflowHistoryButton from '@/components/MainHeader/WorkflowHistoryButton.vue'; |
| 6 | +import PushConnectionTracker from '@/components/PushConnectionTracker.vue'; |
| 7 | +import SaveButton from '@/components/SaveButton.vue'; |
| 8 | +import ShortenName from '@/components/ShortenName.vue'; |
| 9 | +import WorkflowActivator from '@/components/WorkflowActivator.vue'; |
| 10 | +import WorkflowTagsContainer from '@/components/WorkflowTagsContainer.vue'; |
| 11 | +import WorkflowTagsDropdown from '@/components/WorkflowTagsDropdown.vue'; |
2 | 12 | import {
|
3 | 13 | DUPLICATE_MODAL_KEY,
|
4 | 14 | EnterpriseEditionFeature,
|
| 15 | + IMPORT_WORKFLOW_URL_MODAL_KEY, |
5 | 16 | MAX_WORKFLOW_NAME_LENGTH,
|
6 | 17 | MODAL_CONFIRM,
|
7 | 18 | PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
| 19 | + PROJECT_MOVE_RESOURCE_MODAL, |
8 | 20 | SOURCE_CONTROL_PUSH_MODAL_KEY,
|
9 | 21 | VIEWS,
|
10 | 22 | WORKFLOW_MENU_ACTIONS,
|
11 | 23 | WORKFLOW_SETTINGS_MODAL_KEY,
|
12 | 24 | WORKFLOW_SHARE_MODAL_KEY,
|
13 |
| - IMPORT_WORKFLOW_URL_MODAL_KEY, |
14 | 25 | } from '@/constants';
|
15 |
| -import ShortenName from '@/components/ShortenName.vue'; |
16 |
| -import WorkflowTagsContainer from '@/components/WorkflowTagsContainer.vue'; |
17 |
| -import PushConnectionTracker from '@/components/PushConnectionTracker.vue'; |
18 |
| -import WorkflowActivator from '@/components/WorkflowActivator.vue'; |
19 |
| -import SaveButton from '@/components/SaveButton.vue'; |
20 |
| -import WorkflowTagsDropdown from '@/components/WorkflowTagsDropdown.vue'; |
21 |
| -import InlineTextEdit from '@/components/InlineTextEdit.vue'; |
22 |
| -import BreakpointsObserver from '@/components/BreakpointsObserver.vue'; |
23 |
| -import WorkflowHistoryButton from '@/components/MainHeader/WorkflowHistoryButton.vue'; |
24 |
| -import CollaborationPane from '@/components/MainHeader/CollaborationPane.vue'; |
| 26 | +import { ResourceType } from '@/utils/projects.utils'; |
25 | 27 |
|
26 |
| -import { useRootStore } from '@n8n/stores/useRootStore'; |
| 28 | +import { useProjectsStore } from '@/stores/projects.store'; |
27 | 29 | import { useSettingsStore } from '@/stores/settings.store';
|
28 | 30 | import { useSourceControlStore } from '@/stores/sourceControl.store';
|
29 | 31 | import { useTagsStore } from '@/stores/tags.store';
|
30 | 32 | import { useUIStore } from '@/stores/ui.store';
|
31 | 33 | import { useUsersStore } from '@/stores/users.store';
|
32 | 34 | import { useWorkflowsStore } from '@/stores/workflows.store';
|
33 |
| -import { useProjectsStore } from '@/stores/projects.store'; |
| 35 | +import { useRootStore } from '@n8n/stores/useRootStore'; |
34 | 36 |
|
35 |
| -import { saveAs } from 'file-saver'; |
36 |
| -import { useDocumentTitle } from '@/composables/useDocumentTitle'; |
37 |
| -import { useMessage } from '@/composables/useMessage'; |
38 |
| -import { useToast } from '@/composables/useToast'; |
39 |
| -import { getResourcePermissions } from '@/permissions'; |
40 |
| -import { createEventBus } from '@n8n/utils/event-bus'; |
41 |
| -import { nodeViewEventBus } from '@/event-bus'; |
42 |
| -import { hasPermission } from '@/utils/rbac/permissions'; |
43 |
| -import { useCanvasStore } from '@/stores/canvas.store'; |
44 |
| -import { useRoute, useRouter } from 'vue-router'; |
45 |
| -import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers'; |
46 |
| -import { computed, ref, useCssModule, watch } from 'vue'; |
47 | 37 | import type {
|
48 | 38 | ActionDropdownItem,
|
49 | 39 | FolderShortInfo,
|
50 | 40 | IWorkflowDataUpdate,
|
51 | 41 | IWorkflowDb,
|
52 | 42 | IWorkflowToShare,
|
53 | 43 | } from '@/Interface';
|
54 |
| -import { useI18n } from '@n8n/i18n'; |
| 44 | +import { useDocumentTitle } from '@/composables/useDocumentTitle'; |
| 45 | +import { useMessage } from '@/composables/useMessage'; |
| 46 | +import { usePageRedirectionHelper } from '@/composables/usePageRedirectionHelper'; |
55 | 47 | import { useTelemetry } from '@/composables/useTelemetry';
|
56 |
| -import type { BaseTextKey } from '@n8n/i18n'; |
| 48 | +import { useToast } from '@/composables/useToast'; |
| 49 | +import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers'; |
| 50 | +import { nodeViewEventBus } from '@/event-bus'; |
| 51 | +import { getResourcePermissions } from '@/permissions'; |
| 52 | +import { useCanvasStore } from '@/stores/canvas.store'; |
| 53 | +import { useFoldersStore } from '@/stores/folders.store'; |
57 | 54 | import { useNpsSurveyStore } from '@/stores/npsSurvey.store';
|
58 |
| -import { usePageRedirectionHelper } from '@/composables/usePageRedirectionHelper'; |
59 | 55 | import { ProjectTypes } from '@/types/projects.types';
|
60 |
| -import { useFoldersStore } from '@/stores/folders.store'; |
| 56 | +import { hasPermission } from '@/utils/rbac/permissions'; |
61 | 57 | import type { PathItem } from '@n8n/design-system/components/N8nBreadcrumbs/Breadcrumbs.vue';
|
| 58 | +import type { BaseTextKey } from '@n8n/i18n'; |
| 59 | +import { useI18n } from '@n8n/i18n'; |
| 60 | +import { createEventBus } from '@n8n/utils/event-bus'; |
| 61 | +import { saveAs } from 'file-saver'; |
| 62 | +import { computed, ref, useCssModule, watch } from 'vue'; |
| 63 | +import { useRoute, useRouter } from 'vue-router'; |
62 | 64 |
|
63 | 65 | const props = defineProps<{
|
64 | 66 | readOnly?: boolean;
|
@@ -106,6 +108,7 @@ const importFileRef = ref<HTMLInputElement | undefined>();
|
106 | 108 |
|
107 | 109 | const tagsEventBus = createEventBus();
|
108 | 110 | const sourceControlModalEventBus = createEventBus();
|
| 111 | +const changeOwnerEventBus = createEventBus(); |
109 | 112 |
|
110 | 113 | const hasChanged = (prev: string[], curr: string[]) => {
|
111 | 114 | if (prev.length !== curr.length) {
|
@@ -147,6 +150,14 @@ const workflowMenuItems = computed<ActionDropdownItem[]>(() => {
|
147 | 150 | },
|
148 | 151 | ];
|
149 | 152 |
|
| 153 | + if (workflowPermissions.value.move && projectsStore.isTeamProjectFeatureEnabled) { |
| 154 | + actions.push({ |
| 155 | + id: WORKFLOW_MENU_ACTIONS.CHANGE_OWNER, |
| 156 | + label: locale.baseText('workflows.item.changeOwner'), |
| 157 | + disabled: isNewWorkflow.value, |
| 158 | + }); |
| 159 | + } |
| 160 | +
|
150 | 161 | if (!props.readOnly && !props.isArchived) {
|
151 | 162 | actions.push({
|
152 | 163 | id: WORKFLOW_MENU_ACTIONS.RENAME,
|
@@ -609,6 +620,27 @@ async function onWorkflowMenuSelect(action: WORKFLOW_MENU_ACTIONS): Promise<void
|
609 | 620 | await router.push({ name: VIEWS.WORKFLOWS });
|
610 | 621 | break;
|
611 | 622 | }
|
| 623 | + case WORKFLOW_MENU_ACTIONS.CHANGE_OWNER: { |
| 624 | + const workflowId = getWorkflowId(); |
| 625 | + if (!workflowId) { |
| 626 | + return; |
| 627 | + } |
| 628 | + changeOwnerEventBus.once( |
| 629 | + 'resource-moved', |
| 630 | + async () => await router.push({ name: VIEWS.WORKFLOWS }), |
| 631 | + ); |
| 632 | +
|
| 633 | + uiStore.openModalWithData({ |
| 634 | + name: PROJECT_MOVE_RESOURCE_MODAL, |
| 635 | + data: { |
| 636 | + resource: workflowsStore.workflowsById[workflowId], |
| 637 | + resourceType: ResourceType.Workflow, |
| 638 | + resourceTypeLabel: locale.baseText('generic.workflow').toLowerCase(), |
| 639 | + eventBus: changeOwnerEventBus, |
| 640 | + }, |
| 641 | + }); |
| 642 | + break; |
| 643 | + } |
612 | 644 | default:
|
613 | 645 | break;
|
614 | 646 | }
|
|
0 commit comments