mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-19 19:11:13 +00:00
feat: RBAC (#8922)
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com> Co-authored-by: Val <68596159+valya@users.noreply.github.com> Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in> Co-authored-by: Valya Bullions <valya@n8n.io> Co-authored-by: Danny Martini <danny@n8n.io> Co-authored-by: Danny Martini <despair.blue@gmail.com> Co-authored-by: Iván Ovejero <ivov.src@gmail.com> Co-authored-by: Omar Ajoue <krynble@gmail.com> Co-authored-by: oleg <me@olegivaniv.com> Co-authored-by: Michael Kret <michael.k@radency.com> Co-authored-by: Michael Kret <88898367+michael-radency@users.noreply.github.com> Co-authored-by: Elias Meire <elias@meire.dev> Co-authored-by: Giulio Andreini <andreini@netseven.it> Co-authored-by: Giulio Andreini <g.andreini@gmail.com> Co-authored-by: Ayato Hayashi <go12limchangyong@gmail.com>
This commit is contained in:
@@ -11,6 +11,8 @@ import {
|
||||
WORKFLOW_SETTINGS_MODAL_KEY,
|
||||
WORKFLOW_SHARE_MODAL_KEY,
|
||||
} from '@/constants';
|
||||
import type { PermissionsMap } from '@/permissions';
|
||||
import type { WorkflowScope } from '@n8n/permissions';
|
||||
|
||||
import ShortenName from '@/components/ShortenName.vue';
|
||||
import TagsContainer from '@/components/TagsContainer.vue';
|
||||
@@ -29,6 +31,7 @@ import { useTagsStore } from '@/stores/tags.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useUsersStore } from '@/stores/users.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useProjectsStore } from '@/features/projects/projects.store';
|
||||
|
||||
import { saveAs } from 'file-saver';
|
||||
import { useTitleChange } from '@/composables/useTitleChange';
|
||||
@@ -69,6 +72,7 @@ const tagsStore = useTagsStore();
|
||||
const uiStore = useUIStore();
|
||||
const usersStore = useUsersStore();
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
const projectsStore = useProjectsStore();
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
@@ -122,8 +126,8 @@ const onExecutionsTab = computed(() => {
|
||||
].includes((route.name as string) || '');
|
||||
});
|
||||
|
||||
const workflowPermissions = computed(() => {
|
||||
return getWorkflowPermissions(usersStore.currentUser, props.workflow);
|
||||
const workflowPermissions = computed<PermissionsMap<WorkflowScope>>(() => {
|
||||
return getWorkflowPermissions(workflowsStore.getWorkflowById(props.workflow.id));
|
||||
});
|
||||
|
||||
const workflowMenuItems = computed<ActionDropdownItem[]>(() => {
|
||||
@@ -174,7 +178,7 @@ const workflowMenuItems = computed<ActionDropdownItem[]>(() => {
|
||||
disabled: !onWorkflowPage.value || isNewWorkflow.value,
|
||||
});
|
||||
|
||||
if (workflowPermissions.value.delete && !props.readOnly) {
|
||||
if ((workflowPermissions.value.delete && !props.readOnly) || isNewWorkflow.value) {
|
||||
actions.push({
|
||||
id: WORKFLOW_MENU_ACTIONS.DELETE,
|
||||
label: locale.baseText('menuActions.delete'),
|
||||
@@ -212,12 +216,7 @@ watch(
|
||||
},
|
||||
);
|
||||
|
||||
async function onSaveButtonClick() {
|
||||
// If the workflow is saving, do not allow another save
|
||||
if (isWorkflowSaving.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
function getWorkflowId(): string | undefined {
|
||||
let id: string | undefined = undefined;
|
||||
if (props.workflow.id !== PLACEHOLDER_EMPTY_WORKFLOW_ID) {
|
||||
id = props.workflow.id;
|
||||
@@ -225,6 +224,17 @@ async function onSaveButtonClick() {
|
||||
id = route.params.name as string;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
async function onSaveButtonClick() {
|
||||
// If the workflow is saving, do not allow another save
|
||||
if (isWorkflowSaving.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const id = getWorkflowId();
|
||||
|
||||
const name = props.workflow.name;
|
||||
const tags = props.workflow.tags as string[];
|
||||
|
||||
@@ -235,6 +245,8 @@ async function onSaveButtonClick() {
|
||||
});
|
||||
|
||||
if (saved) {
|
||||
showCreateWorkflowSuccessToast(id);
|
||||
|
||||
await settingsStore.fetchPromptsData();
|
||||
|
||||
if (route.name === VIEWS.EXECUTION_DEBUG) {
|
||||
@@ -337,9 +349,11 @@ async function onNameSubmit({
|
||||
}
|
||||
|
||||
uiStore.addActiveAction('workflowSaving');
|
||||
const id = getWorkflowId();
|
||||
const saved = await workflowHelpers.saveCurrentWorkflow({ name });
|
||||
if (saved) {
|
||||
isNameEditEnabled.value = false;
|
||||
showCreateWorkflowSuccessToast(id);
|
||||
}
|
||||
uiStore.removeActiveAction('workflowSaving');
|
||||
onSubmit(saved);
|
||||
@@ -516,6 +530,28 @@ async function onWorkflowMenuSelect(action: string): Promise<void> {
|
||||
function goToUpgrade() {
|
||||
void uiStore.goToUpgrade('workflow_sharing', 'upgrade-workflow-sharing');
|
||||
}
|
||||
|
||||
function showCreateWorkflowSuccessToast(id?: string) {
|
||||
if (!id || ['new', PLACEHOLDER_EMPTY_WORKFLOW_ID].includes(id)) {
|
||||
let toastTitle = locale.baseText('workflows.create.personal.toast.title');
|
||||
let toastText = locale.baseText('workflows.create.personal.toast.text');
|
||||
if (projectsStore.currentProject) {
|
||||
toastTitle = locale.baseText('workflows.create.project.toast.title', {
|
||||
interpolate: { projectName: projectsStore.currentProject.name ?? '' },
|
||||
});
|
||||
|
||||
toastText = locale.baseText('workflows.create.project.toast.text', {
|
||||
interpolate: { projectName: projectsStore.currentProject.name ?? '' },
|
||||
});
|
||||
}
|
||||
|
||||
toast.showMessage({
|
||||
title: toastTitle,
|
||||
message: toastText,
|
||||
type: 'success',
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
Reference in New Issue
Block a user