fix(editor): Move projects and rbac files (no-changelog) (#9651)

This commit is contained in:
Csaba Tuncsik 2024-06-06 15:30:17 +02:00 committed by GitHub
parent 58cfd2fde8
commit ed963011c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
94 changed files with 172 additions and 212 deletions

View file

@ -55,7 +55,7 @@ import type { PartialBy, TupleToUnion } from '@/utils/typeHelpers';
import type { Component } from 'vue';
import type { Scope } from '@n8n/permissions';
import type { NotificationOptions as ElementNotificationOptions } from 'element-plus';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import type { ProjectSharingData } from '@/types/projects.types';
import type { Connection } from '@jsplumb/core';
import type { BaseTextKey } from './plugins/i18n';

View file

@ -1,10 +1,6 @@
import { faker } from '@faker-js/faker';
import type {
ProjectListItem,
ProjectSharingData,
ProjectType,
} from '@/features/projects/projects.types';
import { ProjectTypes } from '@/features/projects/projects.utils';
import type { ProjectListItem, ProjectSharingData, ProjectType } from '@/types/projects.types';
import { ProjectTypes } from '@/types/projects.types';
export const createProjectSharingData = (projectType?: ProjectType): ProjectSharingData => ({
id: faker.string.uuid(),

View file

@ -13,7 +13,7 @@ import { NodeHelpers, Workflow } from 'n8n-workflow';
import { uuid } from '@jsplumb/util';
import { defaultMockNodeTypes } from '@/__tests__/defaults';
import type { INodeUi, ITag, IUsedCredential, IWorkflowDb, WorkflowMetadata } from '@/Interface';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import type { ProjectSharingData } from '@/types/projects.types';
import type { RouteLocationNormalized } from 'vue-router';
export function createTestNodeTypes(data: INodeTypeData = {}): INodeTypes {

View file

@ -5,7 +5,7 @@ import {
getWorkflowPermissions,
} from '@/permissions';
import type { ICredentialsResponse, IUser, IWorkflowDb } from '@/Interface';
import type { Project } from '@/features/projects/projects.types';
import type { Project } from '@/types/projects.types';
describe('permissions', () => {
it('getVariablesPermissions', () => {

View file

@ -6,7 +6,7 @@ import type {
ProjectListItem,
ProjectUpdateRequest,
ProjectsCount,
} from '@/features/projects/projects.types';
} from '@/types/projects.types';
export const getAllProjects = async (context: IRestApiContext): Promise<ProjectListItem[]> => {
return await makeRestApiRequest(context, 'GET', '/projects');

View file

@ -44,10 +44,10 @@ import { useUIStore } from '@/stores/ui.store';
import { useUsersStore } from '@/stores/users.store';
import { useCredentialsStore } from '@/stores/credentials.store';
import TimeAgo from '@/components/TimeAgo.vue';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import { useProjectsStore } from '@/features/projects/projects.store';
import type { ProjectSharingData } from '@/types/projects.types';
import { useProjectsStore } from '@/stores/projects.store';
import type { CredentialScope } from '@n8n/permissions';
import ProjectCardBadge from '@/features/projects/components/ProjectCardBadge.vue';
import ProjectCardBadge from '@/components/Projects/ProjectCardBadge.vue';
export const CREDENTIAL_LIST_ITEM_ACTIONS = {
OPEN: 'open',

View file

@ -157,7 +157,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
import { useNDVStore } from '@/stores/ndv.store';
import { useCredentialsStore } from '@/stores/credentials.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import type { ProjectSharingData } from '@/types/projects.types';
import { assert } from '@/utils/assert';
import {
@ -168,7 +168,7 @@ import {
import { isValidCredentialResponse, isCredentialModalState } from '@/utils/typeGuards';
import { isExpression, isTestableExpression } from '@/utils/expressions';
import { useExternalHooks } from '@/composables/useExternalHooks';
import { useProjectsStore } from '@/features/projects/projects.store';
import { useProjectsStore } from '@/stores/projects.store';
import type { CredentialScope } from '@n8n/permissions';
export default defineComponent({

View file

@ -83,20 +83,16 @@ import { useUIStore } from '@/stores/ui.store';
import { useCredentialsStore } from '@/stores/credentials.store';
import { useUsageStore } from '@/stores/usage.store';
import { EnterpriseEditionFeature } from '@/constants';
import ProjectSharing from '@/features/projects/components/ProjectSharing.vue';
import { useProjectsStore } from '@/features/projects/projects.store';
import type {
ProjectListItem,
ProjectSharingData,
Project,
} from '@/features/projects/projects.types';
import ProjectSharing from '@/components/Projects/ProjectSharing.vue';
import { useProjectsStore } from '@/stores/projects.store';
import type { ProjectListItem, ProjectSharingData, Project } from '@/types/projects.types';
import { ProjectTypes } from '@/types/projects.types';
import type { ICredentialDataDecryptedObject } from 'n8n-workflow';
import type { PermissionsMap } from '@/permissions';
import type { CredentialScope } from '@n8n/permissions';
import type { EventBus } from 'n8n-design-system/utils';
import { useRolesStore } from '@/stores/roles.store';
import type { RoleMap } from '@/types/roles.types';
import { ProjectTypes } from '@/features/projects/projects.utils';
export default defineComponent({
name: 'CredentialSharing',

View file

@ -83,9 +83,9 @@ import type { IUser } from '@/Interface';
import { mapStores } from 'pinia';
import { useUsersStore } from '@/stores/users.store';
import { createEventBus } from 'n8n-design-system/utils';
import { useProjectsStore } from '@/features/projects/projects.store';
import type { ProjectListItem, ProjectSharingData } from '@/features/projects/projects.types';
import ProjectSharing from '@/features/projects/components/ProjectSharing.vue';
import { useProjectsStore } from '@/stores/projects.store';
import type { ProjectListItem, ProjectSharingData } from '@/types/projects.types';
import ProjectSharing from '@/components/Projects/ProjectSharing.vue';
export default defineComponent({
name: 'DeleteUserModal',

View file

@ -31,7 +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 { useProjectsStore } from '@/stores/projects.store';
import { saveAs } from 'file-saver';
import { useTitleChange } from '@/composables/useTitleChange';
@ -41,7 +41,7 @@ import { useToast } from '@/composables/useToast';
import { getWorkflowPermissions } from '@/permissions';
import { createEventBus } from 'n8n-design-system/utils';
import { nodeViewEventBus } from '@/event-bus';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
import { useCanvasStore } from '@/stores/canvas.store';
import { useRoute, useRouter } from 'vue-router';
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';

View file

@ -126,11 +126,11 @@ import { useTemplatesStore } from '@/stores/templates.store';
import ExecutionsUsage from '@/components/executions/ExecutionsUsage.vue';
import BecomeTemplateCreatorCta from '@/components/BecomeTemplateCreatorCta/BecomeTemplateCreatorCta.vue';
import MainSidebarSourceControl from '@/components/MainSidebarSourceControl.vue';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
import { useExternalHooks } from '@/composables/useExternalHooks';
import { useDebounce } from '@/composables/useDebounce';
import { useBecomeTemplateCreatorStore } from '@/components/BecomeTemplateCreatorCta/becomeTemplateCreatorStore';
import ProjectNavigation from '@/features/projects/components/ProjectNavigation.vue';
import ProjectNavigation from '@/components/Projects/ProjectNavigation.vue';
export default defineComponent({
name: 'MainSidebar',

View file

@ -3,7 +3,7 @@ import { computed, nextTick, ref } from 'vue';
import { useRouter } from 'vue-router';
import { createEventBus } from 'n8n-design-system/utils';
import { useI18n } from '@/composables/useI18n';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
import { useToast } from '@/composables/useToast';
import { useLoadingService } from '@/composables/useLoadingService';
import { useUIStore } from '@/stores/ui.store';

View file

@ -1,5 +1,5 @@
import { createComponentRenderer } from '@/__tests__/render';
import ProjectCardBadge from '@/features/projects/components/ProjectCardBadge.vue';
import ProjectCardBadge from '@/components/Projects/ProjectCardBadge.vue';
const renderComponent = createComponentRenderer(ProjectCardBadge);

View file

@ -1,9 +1,10 @@
<script lang="ts" setup>
import { computed } from 'vue';
import { useI18n } from '@/composables/useI18n';
import { ProjectTypes, splitName } from '@/features/projects/projects.utils';
import { splitName } from '@/utils/projects.utils';
import type { ICredentialsResponse, IWorkflowDb } from '@/Interface';
import type { Project } from '@/features/projects/projects.types';
import type { Project } from '@/types/projects.types';
import { ProjectTypes } from '@/types/projects.types';
type Props = {
resource: IWorkflowDb | ICredentialsResponse;

View file

@ -1,11 +1,7 @@
<script lang="ts" setup>
import { ref, computed } from 'vue';
import type {
Project,
ProjectListItem,
ProjectSharingData,
} from '@/features/projects/projects.types';
import ProjectSharing from '@/features/projects/components/ProjectSharing.vue';
import type { Project, ProjectListItem, ProjectSharingData } from '@/types/projects.types';
import ProjectSharing from '@/components/Projects/ProjectSharing.vue';
import { useI18n } from '@/composables/useI18n';
type Props = {

View file

@ -4,8 +4,8 @@ import { useRouter } from 'vue-router';
import type { IMenuItem } from 'n8n-design-system/types';
import { useI18n } from '@/composables/useI18n';
import { VIEWS } from '@/constants';
import { useProjectsStore } from '@/features/projects/projects.store';
import type { ProjectListItem } from '@/features/projects/projects.types';
import { useProjectsStore } from '@/stores/projects.store';
import type { ProjectListItem } from '@/types/projects.types';
import { useToast } from '@/composables/useToast';
import { useUIStore } from '@/stores/ui.store';

View file

@ -4,8 +4,8 @@ import userEvent from '@testing-library/user-event';
import { createComponentRenderer } from '@/__tests__/render';
import { getDropdownItems } from '@/__tests__/utils';
import { useRoute, useRouter } from 'vue-router';
import ProjectSettings from '@/features/projects/components/ProjectSettings.vue';
import { useProjectsStore } from '@/features/projects/projects.store';
import ProjectSettings from '@/components/Projects/ProjectSettings.vue';
import { useProjectsStore } from '@/stores/projects.store';
import { VIEWS } from '@/constants';
import { useUsersStore } from '@/stores/users.store';
import { createProjectListItem } from '@/__tests__/data/projects';
@ -81,7 +81,7 @@ describe('ProjectSettings', () => {
await userEvent.click(deleteButton);
expect(deleteProjectSpy).not.toHaveBeenCalled();
let modal = getByRole('dialog');
const modal = getByRole('dialog');
expect(modal).toBeVisible();
const confirmButton = getByTestId('project-settings-delete-confirm-button');
expect(confirmButton).toBeDisabled();
@ -107,7 +107,7 @@ describe('ProjectSettings', () => {
await userEvent.click(deleteButton);
expect(deleteProjectSpy).not.toHaveBeenCalled();
let modal = getByRole('dialog');
const modal = getByRole('dialog');
expect(modal).toBeVisible();
const confirmButton = getByTestId('project-settings-delete-confirm-button');
expect(confirmButton).toBeDisabled();

View file

@ -5,13 +5,13 @@ import { deepCopy } from 'n8n-workflow';
import { useUsersStore } from '@/stores/users.store';
import type { IUser } from '@/Interface';
import { useI18n } from '@/composables/useI18n';
import { useProjectsStore } from '@/features/projects/projects.store';
import ProjectTabs from '@/features/projects/components/ProjectTabs.vue';
import type { Project, ProjectRelation } from '@/features/projects/projects.types';
import { useProjectsStore } from '@/stores/projects.store';
import ProjectTabs from '@/components/Projects/ProjectTabs.vue';
import type { Project, ProjectRelation } from '@/types/projects.types';
import { useToast } from '@/composables/useToast';
import { VIEWS } from '@/constants';
import ProjectDeleteDialog from '@/features/projects/components/ProjectDeleteDialog.vue';
import ProjectRoleUpgradeDialog from '@/features/projects/components/ProjectRoleUpgradeDialog.vue';
import ProjectDeleteDialog from '@/components/Projects/ProjectDeleteDialog.vue';
import ProjectRoleUpgradeDialog from '@/components/Projects/ProjectRoleUpgradeDialog.vue';
import { useRolesStore } from '@/stores/roles.store';
import type { ProjectRole } from '@/types/roles.types';
import { useCloudPlanStore } from '@/stores/cloudPlan.store';

View file

@ -3,7 +3,7 @@ import userEvent from '@testing-library/user-event';
import { createComponentRenderer } from '@/__tests__/render';
import { getDropdownItems } from '@/__tests__/utils';
import { createProjectListItem, createProjectSharingData } from '@/__tests__/data/projects';
import ProjectSharing from '@/features/projects/components/ProjectSharing.vue';
import ProjectSharing from '@/components/Projects/ProjectSharing.vue';
const renderComponent = createComponentRenderer(ProjectSharing);

View file

@ -1,8 +1,8 @@
<script lang="ts" setup>
import { computed, ref, watch } from 'vue';
import { useI18n } from '@/composables/useI18n';
import type { ProjectListItem, ProjectSharingData } from '@/features/projects/projects.types';
import ProjectSharingInfo from '@/features/projects/components/ProjectSharingInfo.vue';
import type { ProjectListItem, ProjectSharingData } from '@/types/projects.types';
import ProjectSharingInfo from '@/components/Projects/ProjectSharingInfo.vue';
import type { RoleMap } from '@/types/roles.types';
const locale = useI18n();

View file

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { computed } from 'vue';
import type { ProjectListItem, ProjectSharingData } from '@/features/projects/projects.types';
import { splitName } from '@/features/projects/projects.utils';
import type { ProjectListItem, ProjectSharingData } from '@/types/projects.types';
import { splitName } from '@/utils/projects.utils';
type Props = {
project: ProjectListItem | ProjectSharingData;

View file

@ -1,7 +1,7 @@
import { createComponentRenderer } from '@/__tests__/render';
import ProjectTabs from '@/features/projects/components/ProjectTabs.vue';
import ProjectTabs from '@/components/Projects/ProjectTabs.vue';
import { useRoute, useRouter } from 'vue-router';
import { useProjectsStore } from '@/features/projects/projects.store';
import { useProjectsStore } from '@/stores/projects.store';
vi.mock('vue-router', () => {
const params = {};
@ -23,11 +23,11 @@ vi.mock('@/stores/users.store', () => ({
})),
}));
vi.mock('@/features/projects/projects.store', () => ({
vi.mock('@/stores/projects.store', () => ({
useProjectsStore: vi.fn().mockReturnValue({}),
}));
vi.mock('@/rbac/permissions', () => ({
vi.mock('@/utils/rbac/permissions', () => ({
hasPermission: vi.fn().mockReturnValue(false),
}));
@ -35,11 +35,13 @@ const renderComponent = createComponentRenderer(ProjectTabs);
let router: ReturnType<typeof useRouter>;
let route: ReturnType<typeof useRoute>;
let projectsStore: ReturnType<typeof useProjectsStore>;
describe('ProjectTabs', () => {
beforeEach(() => {
route = useRoute();
router = useRouter();
projectsStore = useProjectsStore();
});
it('should render home tabs', async () => {
@ -52,17 +54,15 @@ describe('ProjectTabs', () => {
it('should render project tabs if use has permissions', () => {
route.params.projectId = '123';
vi.mocked(useProjectsStore).mockImplementationOnce(() => ({
currentProject: {
id: '123',
type: 'team',
name: 'Project',
relations: [],
scopes: ['project:update'],
createdAt: '',
updatedAt: '',
},
}));
projectsStore.currentProject = {
id: '123',
type: 'team',
name: 'Project',
relations: [],
scopes: ['project:update'],
createdAt: '',
updatedAt: '',
};
const { getByText } = renderComponent();
expect(getByText('Workflows')).toBeInTheDocument();
@ -72,17 +72,15 @@ describe('ProjectTabs', () => {
it('should render project tabs', () => {
route.params.projectId = '123';
vi.mocked(useProjectsStore).mockImplementationOnce(() => ({
currentProject: {
id: '123',
type: 'team',
name: 'Project',
relations: [],
scopes: ['project:read'],
createdAt: '',
updatedAt: '',
},
}));
projectsStore.currentProject = {
id: '123',
type: 'team',
name: 'Project',
relations: [],
scopes: ['project:read'],
createdAt: '',
updatedAt: '',
};
const { queryByText, getByText } = renderComponent();
expect(getByText('Workflows')).toBeInTheDocument();

View file

@ -4,7 +4,7 @@ import type { RouteRecordName } from 'vue-router';
import { useRoute } from 'vue-router';
import { VIEWS } from '@/constants';
import { useI18n } from '@/composables/useI18n';
import { useProjectsStore } from '../projects.store';
import { useProjectsStore } from '@/stores/projects.store';
import { getProjectPermissions } from '@/permissions';
const locale = useI18n();

View file

@ -194,7 +194,7 @@ import { LOG_STREAM_MODAL_KEY, MODAL_CONFIRM } from '@/constants';
import Modal from '@/components/Modal.vue';
import { useMessage } from '@/composables/useMessage';
import { useUIStore } from '@/stores/ui.store';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
import { destinationToFakeINodeUi } from '@/components/SettingsLogStreaming/Helpers.ee';
import {
webhookModalDescription,

View file

@ -31,7 +31,7 @@ import type { BaseTextKey } from '@/plugins/i18n';
import { useUIStore } from '@/stores/ui.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useRootStore } from '@/stores/n8nRoot.store';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
export default defineComponent({
name: 'SettingsSidebar',

View file

@ -9,7 +9,7 @@ import { useRootStore } from '@/stores/n8nRoot.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
import type { ITelemetrySettings } from 'n8n-workflow';
import { useProjectsStore } from '@/features/projects/projects.store';
import { useProjectsStore } from '@/stores/projects.store';
export default defineComponent({
name: 'Telemetry',

View file

@ -68,9 +68,9 @@ import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import TimeAgo from '@/components/TimeAgo.vue';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import { useProjectsStore } from '@/features/projects/projects.store';
import ProjectCardBadge from '@/features/projects/components/ProjectCardBadge.vue';
import type { ProjectSharingData } from '@/types/projects.types';
import { useProjectsStore } from '@/stores/projects.store';
import ProjectCardBadge from '@/components/Projects/ProjectCardBadge.vue';
export const WORKFLOW_LIST_ITEM_ACTIONS = {
OPEN: 'open',

View file

@ -384,7 +384,7 @@ import type { WorkflowScope } from '@n8n/permissions';
import { getWorkflowPermissions } from '@/permissions';
import { useExternalHooks } from '@/composables/useExternalHooks';
import { useSourceControlStore } from '@/stores/sourceControl.store';
import { ProjectTypes } from '@/features/projects/projects.utils';
import { ProjectTypes } from '@/types/projects.types';
export default defineComponent({
name: 'WorkflowSettings',

View file

@ -143,16 +143,12 @@ import { useWorkflowsEEStore } from '@/stores/workflows.ee.store';
import type { ITelemetryTrackProperties } from 'n8n-workflow';
import type { BaseTextKey } from '@/plugins/i18n';
import { isNavigationFailure } from 'vue-router';
import ProjectSharing from '@/features/projects/components/ProjectSharing.vue';
import { useProjectsStore } from '@/features/projects/projects.store';
import type {
ProjectListItem,
ProjectSharingData,
Project,
} from '@/features/projects/projects.types';
import ProjectSharing from '@/components/Projects/ProjectSharing.vue';
import { useProjectsStore } from '@/stores/projects.store';
import type { ProjectListItem, ProjectSharingData, Project } from '@/types/projects.types';
import { ProjectTypes } from '@/types/projects.types';
import { useRolesStore } from '@/stores/roles.store';
import type { RoleMap } from '@/types/roles.types';
import { ProjectTypes } from '@/features/projects/projects.utils';
export default defineComponent({
name: 'WorkflowShareModal',

View file

@ -6,7 +6,7 @@ import { useUIStore } from '@/stores/ui.store';
import { useUsersStore } from '@/stores/users.store';
import { useCredentialsStore } from '@/stores/credentials.store';
import type { ICredentialsResponse } from '@/Interface';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import type { ProjectSharingData } from '@/types/projects.types';
const renderComponent = createComponentRenderer(CredentialCard);

View file

@ -2,7 +2,7 @@
import { computed } from 'vue';
import BaseBanner from '@/components/banners/BaseBanner.vue';
import { i18n as locale } from '@/plugins/i18n';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
import { useUIStore } from '@/stores/ui.store';
const uiStore = useUIStore();

View file

@ -49,10 +49,10 @@
import { defineComponent } from 'vue';
import { EnterpriseEditionFeature } from '@/constants';
import { mapStores } from 'pinia';
import { useProjectsStore } from '@/features/projects/projects.store';
import { useProjectsStore } from '@/stores/projects.store';
import type { PropType } from 'vue';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import ProjectSharing from '@/features/projects/components/ProjectSharing.vue';
import type { ProjectSharingData } from '@/types/projects.types';
import ProjectSharing from '@/components/Projects/ProjectSharing.vue';
export type IResourceFiltersType = Record<string, boolean | string | string[]>;

View file

@ -146,7 +146,7 @@
import { computed, defineComponent, nextTick, ref, onMounted, watch } from 'vue';
import type { PropType } from 'vue';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import type { ProjectSharingData } from '@/types/projects.types';
import PageViewLayout from '@/components/layouts/PageViewLayout.vue';
import PageViewLayoutList from '@/components/layouts/PageViewLayoutList.vue';
import ResourceFiltersDropdown from '@/components/forms/ResourceFiltersDropdown.vue';

View file

@ -45,7 +45,7 @@ import { get } from 'lodash-es';
import { useI18n } from './useI18n';
import { EnableNodeToggleCommand } from '@/models/history';
import { useTelemetry } from './useTelemetry';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
import type { N8nPlusEndpoint } from '@/plugins/jsplumb/N8nPlusEndpointType';
import * as NodeViewUtils from '@/utils/nodeViewUtils';
import { useCanvasStore } from '@/stores/canvas.store';

View file

@ -68,7 +68,7 @@ import { tryToParseNumber } from '@/utils/typesUtils';
import { useI18n } from '@/composables/useI18n';
import type { useRouter } from 'vue-router';
import { useTelemetry } from '@/composables/useTelemetry';
import { useProjectsStore } from '@/features/projects/projects.store';
import { useProjectsStore } from '@/stores/projects.store';
export function resolveParameter<T = IDataObject>(
parameter: NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[],

View file

@ -1,21 +0,0 @@
import { splitName } from '@/features/projects/projects.utils';
describe('splitName', () => {
it('should return name as firstName if it is only one word', () => {
const name = 'Projectname';
const result = splitName(name);
expect(result).toEqual({ firstName: name });
});
it('should return name as is when it does not contain email', () => {
const name = 'First Last';
const result = splitName(name);
expect(result).toEqual({ firstName: 'First', lastName: 'Last' });
});
it('should return firstName, lastName and email when name is in the proper format', () => {
const name = 'First Last <email@domain.com>';
const result = splitName(name);
expect(result).toEqual({ firstName: 'First', lastName: 'Last', email: 'email@domain.com' });
});
});

View file

@ -6,7 +6,7 @@ import { useSourceControlStore } from '@/stores/sourceControl.store';
import { useUsersStore } from '@/stores/users.store';
import { initializeCloudHooks } from '@/hooks/register';
import { useVersionsStore } from '@/stores/versions.store';
import { useProjectsStore } from '@/features/projects/projects.store';
import { useProjectsStore } from '@/stores/projects.store';
import { useRolesStore } from './stores/roles.store';
let coreInitialized = false;

View file

@ -1,6 +1,6 @@
import { defineComponent } from 'vue';
import type { RouteLocation } from 'vue-router';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
import type { RouteConfig } from '@/types/router';
import type { PermissionTypeOptions } from '@/types/rbac';

View file

@ -6,7 +6,7 @@ import type {
WorkflowScope,
VariableScope,
} from '@n8n/permissions';
import type { Project } from './features/projects/projects.types';
import type { Project } from '@/types/projects.types';
type ExtractAfterColon<T> = T extends `${infer _Prefix}:${infer Suffix}` ? Suffix : never;
export type PermissionsMap<T> = {

View file

@ -1,22 +0,0 @@
import type { RouterMiddleware, RouterMiddlewareType, MiddlewareOptions } from '@/types/router';
import { authenticatedMiddleware } from '@/rbac/middleware/authenticated';
import { enterpriseMiddleware } from '@/rbac/middleware/enterprise';
import { guestMiddleware } from '@/rbac/middleware/guest';
import { rbacMiddleware } from '@/rbac/middleware/rbac';
import { roleMiddleware } from '@/rbac/middleware/role';
import { customMiddleware } from '@/rbac/middleware/custom';
import { defaultUserMiddleware } from '@/rbac/middleware/defaultUser';
type Middleware = {
[key in RouterMiddlewareType]: RouterMiddleware<MiddlewareOptions[key]>;
};
export const middleware: Middleware = {
authenticated: authenticatedMiddleware,
custom: customMiddleware,
defaultUser: defaultUserMiddleware,
enterprise: enterpriseMiddleware,
guest: guestMiddleware,
rbac: rbacMiddleware,
role: roleMiddleware,
};

View file

@ -13,11 +13,11 @@ import { useUIStore } from '@/stores/ui.store';
import { useSSOStore } from '@/stores/sso.store';
import { EnterpriseEditionFeature, VIEWS, EDITABLE_CANVAS_VIEWS } from '@/constants';
import { useTelemetry } from '@/composables/useTelemetry';
import { middleware } from '@/rbac/middleware';
import { middleware } from '@/utils/rbac/middleware';
import type { RouteConfig, RouterMiddleware } from '@/types/router';
import { initializeCore } from '@/init';
import { tryToParseNumber } from '@/utils/typesUtils';
import { projectsRoutes } from '@/features/projects/projects.routes';
import { projectsRoutes } from '@/routes/projects.routes';
const ChangePasswordView = async () => await import('./views/ChangePasswordView.vue');
const ErrorView = async () => await import('./views/ErrorView.vue');

View file

@ -4,8 +4,7 @@ import { VIEWS } from '@/constants';
const MainSidebar = async () => await import('@/components/MainSidebar.vue');
const WorkflowsView = async () => await import('@/views/WorkflowsView.vue');
const CredentialsView = async () => await import('@/views/CredentialsView.vue');
const ProjectSettings = async () =>
await import('@/features/projects/components/ProjectSettings.vue');
const ProjectSettings = async () => await import('@/components/Projects/ProjectSettings.vue');
const commonChildRoutes: RouteRecordRaw[] = [
{

View file

@ -8,7 +8,7 @@ import { useUsersStore } from '@/stores/users.store';
import { getAdminPanelLoginCode, getCurrentPlan, getCurrentUsage } from '@/api/cloudPlans';
import { DateTime } from 'luxon';
import { CLOUD_TRIAL_CHECK_INTERVAL, STORES } from '@/constants';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
const DEFAULT_STATE: CloudPlanState = {
initialized: false,

View file

@ -35,8 +35,8 @@ import { useRootStore } from './n8nRoot.store';
import { useNodeTypesStore } from './nodeTypes.store';
import { useSettingsStore } from './settings.store';
import { isEmpty } from '@/utils/typesUtils';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import { splitName } from '@/features/projects/projects.utils';
import type { ProjectSharingData } from '@/types/projects.types';
import { splitName } from '@/utils/projects.utils';
const DEFAULT_CREDENTIAL_NAME = 'Unnamed credential';
const DEFAULT_CREDENTIAL_POSTFIX = 'account';

View file

@ -2,17 +2,17 @@ import { defineStore } from 'pinia';
import { ref, watch, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useRootStore } from '@/stores/n8nRoot.store';
import * as projectsApi from '@/features/projects/projects.api';
import * as projectsApi from '@/api/projects.api';
import type {
Project,
ProjectCreateRequest,
ProjectListItem,
ProjectUpdateRequest,
ProjectsCount,
} from '@/features/projects/projects.types';
} from '@/types/projects.types';
import { ProjectTypes } from '@/types/projects.types';
import { useSettingsStore } from '@/stores/settings.store';
import { hasPermission } from '@/rbac/permissions';
import { ProjectTypes } from './projects.utils';
import { hasPermission } from '@/utils/rbac/permissions';
import type { IWorkflowDb } from '@/Interface';
export const useProjectsStore = defineStore('projects', () => {

View file

@ -62,7 +62,7 @@ import { getCurlToJson } from '@/api/curlHelper';
import { useCloudPlanStore } from '@/stores/cloudPlan.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useSettingsStore } from '@/stores/settings.store';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
import { useTelemetryStore } from '@/stores/telemetry.store';
import { useUsersStore } from '@/stores/users.store';
import { dismissBannerPermanently } from '@/api/ui';

View file

@ -5,8 +5,8 @@ import { useSettingsStore } from '@/stores/settings.store';
import { defineStore } from 'pinia';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { i18n } from '@/plugins/i18n';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import { splitName } from '@/features/projects/projects.utils';
import type { ProjectSharingData } from '@/types/projects.types';
import { splitName } from '@/utils/projects.utils';
export const useWorkflowsEEStore = defineStore(STORES.WORKFLOWS_EE, {
state() {

View file

@ -73,7 +73,7 @@ import { getCredentialOnlyNodeTypeName } from '@/utils/credentialOnlyNodes';
import { i18n } from '@/plugins/i18n';
import { computed, ref } from 'vue';
import { useProjectsStore } from '@/features/projects/projects.store';
import { useProjectsStore } from '@/stores/projects.store';
import { useSettingsStore } from './settings.store';
import { useUsersStore } from './users.store';

View file

@ -1,7 +1,12 @@
import type { Scope } from '@n8n/permissions';
import type { IUserResponse } from '@/Interface';
import type { ProjectRole } from '@/types/roles.types';
import type { ProjectTypes } from '@/features/projects/projects.utils';
export const ProjectTypes = {
Personal: 'personal',
Team: 'team',
Public: 'public',
} as const;
type ProjectTypeKeys = typeof ProjectTypes;

View file

@ -1,4 +1,4 @@
import { splitName } from '@/features/projects/projects.utils';
import { splitName } from '@/utils/projects.utils';
describe('splitName', () => {
test.each([

View file

@ -26,9 +26,3 @@ export const splitName = (
}
}
};
export const ProjectTypes = {
Personal: 'personal',
Team: 'team',
Public: 'public',
} as const;

View file

@ -1,5 +1,5 @@
import { useUsersStore } from '@/stores/users.store';
import { hasRole } from '@/rbac/checks';
import { hasRole } from '@/utils/rbac/checks';
import { ROLE } from '@/constants';
vi.mock('@/stores/users.store', () => ({

View file

@ -1,5 +1,5 @@
import { useRBACStore } from '@/stores/rbac.store';
import { hasScope } from '@/rbac/checks/hasScope';
import { hasScope } from '@/utils/rbac/checks/hasScope';
import type { ScopeOptions } from '@n8n/permissions';
vi.mock('@/stores/rbac.store', () => ({

View file

@ -1,5 +1,5 @@
import { useUsersStore } from '@/stores/users.store';
import { isAuthenticated } from '@/rbac/checks/isAuthenticated';
import { isAuthenticated } from '@/utils/rbac/checks/isAuthenticated';
import type { IUser } from '@/Interface';
vi.mock('@/stores/users.store', () => ({

View file

@ -1,5 +1,5 @@
import { useUsersStore } from '@/stores/users.store';
import { isDefaultUser } from '@/rbac/checks/isDefaultUser';
import { isDefaultUser } from '@/utils/rbac/checks/isDefaultUser';
vi.mock('@/stores/users.store', () => ({
useUsersStore: vi.fn(),

View file

@ -1,5 +1,5 @@
import { useSettingsStore } from '@/stores/settings.store';
import { isEnterpriseFeatureEnabled } from '@/rbac/checks/isEnterpriseFeatureEnabled';
import { isEnterpriseFeatureEnabled } from '@/utils/rbac/checks/isEnterpriseFeatureEnabled';
import { EnterpriseEditionFeature } from '@/constants';
vi.mock('@/stores/settings.store', () => ({

View file

@ -1,5 +1,5 @@
import { useUsersStore } from '@/stores/users.store';
import { isGuest } from '@/rbac/checks/isGuest';
import { isGuest } from '@/utils/rbac/checks/isGuest';
vi.mock('@/stores/users.store', () => ({
useUsersStore: vi.fn(),

View file

@ -1,5 +1,5 @@
import { useUsersStore } from '@/stores/users.store';
import { isInstanceOwner } from '@/rbac/checks/isInstanceOwner';
import { isInstanceOwner } from '@/utils/rbac/checks/isInstanceOwner';
vi.mock('@/stores/users.store', () => ({
useUsersStore: vi.fn(),

View file

@ -1,4 +1,4 @@
import { isValid } from '@/rbac/checks/isValid';
import { isValid } from '@/utils/rbac/checks/isValid';
describe('Checks', () => {
describe('isValid()', () => {

View file

@ -0,0 +1,22 @@
import type { RouterMiddleware, RouterMiddlewareType, MiddlewareOptions } from '@/types/router';
import { authenticatedMiddleware } from '@/utils/rbac/middleware/authenticated';
import { enterpriseMiddleware } from '@/utils/rbac/middleware/enterprise';
import { guestMiddleware } from '@/utils/rbac/middleware/guest';
import { rbacMiddleware } from '@/utils/rbac/middleware/rbac';
import { roleMiddleware } from '@/utils/rbac/middleware/role';
import { customMiddleware } from '@/utils/rbac/middleware/custom';
import { defaultUserMiddleware } from '@/utils/rbac/middleware/defaultUser';
type Middleware = {
[key in RouterMiddlewareType]: RouterMiddleware<MiddlewareOptions[key]>;
};
export const middleware: Middleware = {
authenticated: authenticatedMiddleware,
custom: customMiddleware,
defaultUser: defaultUserMiddleware,
enterprise: enterpriseMiddleware,
guest: guestMiddleware,
rbac: rbacMiddleware,
role: roleMiddleware,
};

View file

@ -1,4 +1,4 @@
import { authenticatedMiddleware } from '@/rbac/middleware/authenticated';
import { authenticatedMiddleware } from '@/utils/rbac/middleware/authenticated';
import { useUsersStore } from '@/stores/users.store';
import { VIEWS } from '@/constants';
import type { RouteLocationNormalized } from 'vue-router';

View file

@ -1,7 +1,7 @@
import type { RouterMiddleware } from '@/types/router';
import { VIEWS } from '@/constants';
import type { AuthenticatedPermissionOptions } from '@/types/rbac';
import { isAuthenticated } from '@/rbac/checks';
import { isAuthenticated } from '@/utils/rbac/checks';
export const authenticatedMiddleware: RouterMiddleware<AuthenticatedPermissionOptions> = async (
to,

View file

@ -1,4 +1,4 @@
import { customMiddleware } from '@/rbac/middleware/custom';
import { customMiddleware } from '@/utils/rbac/middleware/custom';
import type { RouteLocationNormalized } from 'vue-router';
import { VIEWS } from '@/constants';

View file

@ -1,6 +1,6 @@
import { useUsersStore } from '@/stores/users.store';
import { VIEWS } from '@/constants';
import { defaultUserMiddleware } from '@/rbac/middleware/defaultUser';
import { defaultUserMiddleware } from '@/utils/rbac/middleware/defaultUser';
import type { RouteLocationNormalized } from 'vue-router';
vi.mock('@/stores/users.store', () => ({

View file

@ -1,7 +1,7 @@
import type { RouterMiddleware } from '@/types/router';
import { VIEWS } from '@/constants';
import type { DefaultUserMiddlewareOptions } from '@/types/rbac';
import { isDefaultUser } from '@/rbac/checks';
import { isDefaultUser } from '@/utils/rbac/checks';
export const defaultUserMiddleware: RouterMiddleware<DefaultUserMiddlewareOptions> = async (
_to,

View file

@ -1,6 +1,6 @@
import { useSettingsStore } from '@/stores/settings.store';
import { VIEWS, EnterpriseEditionFeature } from '@/constants';
import { enterpriseMiddleware } from '@/rbac/middleware/enterprise';
import { enterpriseMiddleware } from '@/utils/rbac/middleware/enterprise';
import { type RouteLocationNormalized } from 'vue-router';
import type { EnterprisePermissionOptions } from '@/types/rbac';

View file

@ -1,7 +1,7 @@
import type { RouterMiddleware } from '@/types/router';
import { VIEWS } from '@/constants';
import type { EnterprisePermissionOptions } from '@/types/rbac';
import { isEnterpriseFeatureEnabled } from '@/rbac/checks';
import { isEnterpriseFeatureEnabled } from '@/utils/rbac/checks';
export const enterpriseMiddleware: RouterMiddleware<EnterprisePermissionOptions> = async (
_to,

View file

@ -1,6 +1,6 @@
import { useUsersStore } from '@/stores/users.store';
import { VIEWS } from '@/constants';
import { guestMiddleware } from '@/rbac/middleware/guest';
import { guestMiddleware } from '@/utils/rbac/middleware/guest';
import type { RouteLocationNormalized } from 'vue-router';
vi.mock('@/stores/users.store', () => ({

View file

@ -1,7 +1,7 @@
import type { RouterMiddleware } from '@/types/router';
import { VIEWS } from '@/constants';
import type { GuestPermissionOptions } from '@/types/rbac';
import { isGuest } from '@/rbac/checks';
import { isGuest } from '@/utils/rbac/checks';
export const guestMiddleware: RouterMiddleware<GuestPermissionOptions> = async (
to,

View file

@ -1,5 +1,5 @@
import { useRBACStore } from '@/stores/rbac.store';
import { rbacMiddleware } from '@/rbac/middleware/rbac';
import { rbacMiddleware } from '@/utils/rbac/middleware/rbac';
import { VIEWS } from '@/constants';
import {
inferProjectIdFromRoute,

View file

@ -6,7 +6,7 @@ import {
inferResourceTypeFromRoute,
} from '@/utils/rbacUtils';
import type { RBACPermissionOptions } from '@/types/rbac';
import { hasScope } from '@/rbac/checks';
import { hasScope } from '@/utils/rbac/checks';
export const rbacMiddleware: RouterMiddleware<RBACPermissionOptions> = async (
to,

View file

@ -1,4 +1,4 @@
import { roleMiddleware } from '@/rbac/middleware/role';
import { roleMiddleware } from '@/utils/rbac/middleware/role';
import { useUsersStore } from '@/stores/users.store';
import type { IUser } from '@/Interface';
import type { RouteLocationNormalized } from 'vue-router';

View file

@ -1,7 +1,7 @@
import type { RouterMiddleware } from '@/types/router';
import type { RolePermissionOptions } from '@/types/rbac';
import { VIEWS } from '@/constants';
import { hasRole } from '@/rbac/checks';
import { hasRole } from '@/utils/rbac/checks';
export const roleMiddleware: RouterMiddleware<RolePermissionOptions> = async (
_to,

View file

@ -1,7 +1,7 @@
import { hasPermission } from '@/rbac/permissions';
import * as checks from '@/rbac/checks';
import { hasPermission } from '@/utils/rbac/permissions';
import * as checks from '@/utils/rbac/checks';
vi.mock('@/rbac/checks', () => ({
vi.mock('@/utils/rbac/checks', () => ({
hasRole: vi.fn(),
hasScope: vi.fn(),
isGuest: vi.fn(),

View file

@ -7,7 +7,7 @@ import {
isEnterpriseFeatureEnabled,
isGuest,
isValid,
} from '@/rbac/checks';
} from '@/utils/rbac/checks';
import type { PermissionType, PermissionTypeOptions, RBACPermissionCheck } from '@/types/rbac';
type Permissions = {

View file

@ -73,8 +73,8 @@ import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useCredentialsStore } from '@/stores/credentials.store';
import { useExternalSecretsStore } from '@/stores/externalSecrets.ee.store';
import { useSourceControlStore } from '@/stores/sourceControl.store';
import { useProjectsStore } from '@/features/projects/projects.store';
import ProjectTabs from '@/features/projects/components/ProjectTabs.vue';
import { useProjectsStore } from '@/stores/projects.store';
import ProjectTabs from '@/components/Projects/ProjectTabs.vue';
import useEnvironmentsStore from '@/stores/environments.ee.store';
import { useSettingsStore } from '@/stores/settings.store';

View file

@ -396,13 +396,13 @@ import { useCanvasPanning } from '@/composables/useCanvasPanning';
import { tryToParseNumber } from '@/utils/typesUtils';
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
import { useRunWorkflow } from '@/composables/useRunWorkflow';
import { useProjectsStore } from '@/features/projects/projects.store';
import type { ProjectSharingData } from '@/features/projects/projects.types';
import { useProjectsStore } from '@/stores/projects.store';
import type { ProjectSharingData } from '@/types/projects.types';
import { ProjectTypes } from '@/types/projects.types';
import { useAIStore } from '@/stores/ai.store';
import { useStorage } from '@/composables/useStorage';
import { isJSPlumbEndpointElement, isJSPlumbConnection } from '@/utils/typeGuards';
import { usePostHog } from '@/stores/posthog.store';
import { ProjectTypes } from '@/features/projects/projects.utils';
interface AddNodeOptions {
position?: XYPosition;

View file

@ -77,7 +77,7 @@ import { defineComponent, nextTick } from 'vue';
import { mapStores } from 'pinia';
import { v4 as uuid } from 'uuid';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
import { useCredentialsStore } from '@/stores/credentials.store';
import { useLogStreamingStore } from '@/stores/logStreaming.store';
import { useSettingsStore } from '@/stores/settings.store';

View file

@ -8,7 +8,7 @@ import { i18n as locale } from '@/plugins/i18n';
import { useUIStore } from '@/stores/ui.store';
import { N8N_PRICING_PAGE_URL } from '@/constants';
import { useToast } from '@/composables/useToast';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
const usageStore = useUsageStore();
const route = useRoute();

View file

@ -91,7 +91,7 @@ import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
import { useUsageStore } from '@/stores/usage.store';
import { useSSOStore } from '@/stores/sso.store';
import { hasPermission } from '@/rbac/permissions';
import { hasPermission } from '@/utils/rbac/permissions';
import { useClipboard } from '@/composables/useClipboard';
import type { UpdateGlobalRolePayload } from '@/api/users';

View file

@ -158,8 +158,8 @@ import { useUsersStore } from '@/stores/users.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useSourceControlStore } from '@/stores/sourceControl.store';
import { useTagsStore } from '@/stores/tags.store';
import { useProjectsStore } from '@/features/projects/projects.store';
import ProjectTabs from '@/features/projects/components/ProjectTabs.vue';
import { useProjectsStore } from '@/stores/projects.store';
import ProjectTabs from '@/components/Projects/ProjectTabs.vue';
import { useTemplatesStore } from '@/stores/templates.store';
type IResourcesListLayoutInstance = InstanceType<typeof ResourcesListLayout>;

View file

@ -6,7 +6,7 @@ import { getDropdownItems } from '@/__tests__/utils';
import ModalRoot from '@/components/ModalRoot.vue';
import DeleteUserModal from '@/components/DeleteUserModal.vue';
import SettingsUsersView from '@/views/SettingsUsersView.vue';
import { useProjectsStore } from '@/features/projects/projects.store';
import { useProjectsStore } from '@/stores/projects.store';
import { useUsersStore } from '@/stores/users.store';
import { createUser } from '@/__tests__/data/users';
import { createProjectListItem } from '@/__tests__/data/projects';

View file

@ -7,7 +7,7 @@ import WorkflowsView from '@/views/WorkflowsView.vue';
import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
import { createComponentRenderer } from '@/__tests__/render';
import { useProjectsStore } from '@/features/projects/projects.store';
import { useProjectsStore } from '@/stores/projects.store';
const originalOffsetHeight = Object.getOwnPropertyDescriptor(
HTMLElement.prototype,