mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
fix(editor): Enable moving resources only if team projects are available by the license (#10271)
This commit is contained in:
parent
43ae159ea4
commit
42ba8841c4
|
@ -6,7 +6,7 @@ import { createComponentRenderer } from '@/__tests__/render';
|
|||
import CredentialCard from '@/components/CredentialCard.vue';
|
||||
import type { ICredentialsResponse } from '@/Interface';
|
||||
import type { ProjectSharingData } from '@/types/projects.types';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useProjectsStore } from '@/stores/projects.store';
|
||||
|
||||
const renderComponent = createComponentRenderer(CredentialCard);
|
||||
|
||||
|
@ -22,12 +22,12 @@ const createCredential = (overrides = {}): ICredentialsResponse => ({
|
|||
});
|
||||
|
||||
describe('CredentialCard', () => {
|
||||
let settingsStore: ReturnType<typeof useSettingsStore>;
|
||||
let projectsStore: ReturnType<typeof useProjectsStore>;
|
||||
|
||||
beforeEach(() => {
|
||||
const pinia = createTestingPinia();
|
||||
setActivePinia(pinia);
|
||||
settingsStore = useSettingsStore();
|
||||
projectsStore = useProjectsStore();
|
||||
});
|
||||
|
||||
it('should render name and home project name', () => {
|
||||
|
@ -63,7 +63,7 @@ describe('CredentialCard', () => {
|
|||
});
|
||||
|
||||
it('should show Move action only if there is resource permission and not on community plan', async () => {
|
||||
vi.spyOn(settingsStore, 'isCommunityPlan', 'get').mockReturnValue(false);
|
||||
vi.spyOn(projectsStore, 'isTeamProjectFeatureEnabled', 'get').mockReturnValue(true);
|
||||
|
||||
const data = createCredential({
|
||||
scopes: ['credential:move'],
|
||||
|
|
|
@ -14,7 +14,6 @@ import { useProjectsStore } from '@/stores/projects.store';
|
|||
import ProjectCardBadge from '@/components/Projects/ProjectCardBadge.vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import { ResourceType } from '@/utils/projects.utils';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
|
||||
const CREDENTIAL_LIST_ITEM_ACTIONS = {
|
||||
OPEN: 'open',
|
||||
|
@ -46,7 +45,6 @@ const message = useMessage();
|
|||
const uiStore = useUIStore();
|
||||
const credentialsStore = useCredentialsStore();
|
||||
const projectsStore = useProjectsStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
const resourceTypeLabel = computed(() => locale.baseText('generic.credential').toLowerCase());
|
||||
const credentialType = computed(() => credentialsStore.getCredentialTypeByName(props.data.type));
|
||||
|
@ -66,7 +64,7 @@ const actions = computed(() => {
|
|||
});
|
||||
}
|
||||
|
||||
if (credentialPermissions.value.move && !settingsStore.isCommunityPlan) {
|
||||
if (credentialPermissions.value.move && projectsStore.isTeamProjectFeatureEnabled) {
|
||||
items.push({
|
||||
label: locale.baseText('credentials.item.move'),
|
||||
value: CREDENTIAL_LIST_ITEM_ACTIONS.MOVE,
|
||||
|
|
|
@ -116,7 +116,7 @@ onMounted(async () => {
|
|||
<hr
|
||||
v-if="
|
||||
displayProjects.length ||
|
||||
(projectsStore.hasPermissionToCreateProjects && projectsStore.teamProjectsAvailable)
|
||||
(projectsStore.hasPermissionToCreateProjects && projectsStore.isTeamProjectFeatureEnabled)
|
||||
"
|
||||
class="mt-m mb-m"
|
||||
/>
|
||||
|
@ -137,7 +137,9 @@ onMounted(async () => {
|
|||
</ElMenu>
|
||||
<N8nTooltip placement="right" :disabled="projectsStore.canCreateProjects">
|
||||
<ElMenu
|
||||
v-if="projectsStore.hasPermissionToCreateProjects && projectsStore.teamProjectsAvailable"
|
||||
v-if="
|
||||
projectsStore.hasPermissionToCreateProjects && projectsStore.isTeamProjectFeatureEnabled
|
||||
"
|
||||
:collapse="props.collapsed"
|
||||
class="pl-xs pr-xs"
|
||||
>
|
||||
|
@ -171,7 +173,7 @@ onMounted(async () => {
|
|||
<hr
|
||||
v-if="
|
||||
displayProjects.length ||
|
||||
(projectsStore.hasPermissionToCreateProjects && projectsStore.teamProjectsAvailable)
|
||||
(projectsStore.hasPermissionToCreateProjects && projectsStore.isTeamProjectFeatureEnabled)
|
||||
"
|
||||
class="mt-m mb-m"
|
||||
/>
|
||||
|
|
|
@ -7,7 +7,7 @@ import { VIEWS } from '@/constants';
|
|||
import WorkflowCard from '@/components/WorkflowCard.vue';
|
||||
import type { IWorkflowDb } from '@/Interface';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useProjectsStore } from '@/stores/projects.store';
|
||||
|
||||
vi.mock('vue-router', () => {
|
||||
const push = vi.fn();
|
||||
|
@ -40,13 +40,13 @@ describe('WorkflowCard', () => {
|
|||
let pinia: ReturnType<typeof createPinia>;
|
||||
let windowOpenSpy: MockInstance;
|
||||
let router: ReturnType<typeof useRouter>;
|
||||
let settingsStore: ReturnType<typeof useSettingsStore>;
|
||||
let projectsStore: ReturnType<typeof useProjectsStore>;
|
||||
|
||||
beforeEach(async () => {
|
||||
pinia = createPinia();
|
||||
setActivePinia(pinia);
|
||||
router = useRouter();
|
||||
settingsStore = useSettingsStore();
|
||||
projectsStore = useProjectsStore();
|
||||
windowOpenSpy = vi.spyOn(window, 'open').mockImplementation(() => null);
|
||||
});
|
||||
|
||||
|
@ -143,8 +143,8 @@ describe('WorkflowCard', () => {
|
|||
expect(badge).toHaveTextContent('John Doe');
|
||||
});
|
||||
|
||||
it('should show Move action only if there is resource permission and not on community plan', async () => {
|
||||
vi.spyOn(settingsStore, 'isCommunityPlan', 'get').mockReturnValue(false);
|
||||
it('should show Move action only if there is resource permission and team projects available', async () => {
|
||||
vi.spyOn(projectsStore, 'isTeamProjectFeatureEnabled', 'get').mockReturnValue(true);
|
||||
|
||||
const data = createWorkflow({
|
||||
scopes: ['workflow:move'],
|
||||
|
|
|
@ -95,7 +95,7 @@ const actions = computed(() => {
|
|||
});
|
||||
}
|
||||
|
||||
if (workflowPermissions.value.move && !settingsStore.isCommunityPlan) {
|
||||
if (workflowPermissions.value.move && projectsStore.isTeamProjectFeatureEnabled) {
|
||||
items.push({
|
||||
label: locale.baseText('workflows.item.move'),
|
||||
value: WORKFLOW_LIST_ITEM_ACTIONS.MOVE,
|
||||
|
|
|
@ -49,19 +49,19 @@ export const useProjectsStore = defineStore('projects', () => {
|
|||
);
|
||||
const teamProjects = computed(() => projects.value.filter((p) => p.type === ProjectTypes.Team));
|
||||
const teamProjectsLimit = computed(() => settingsStore.settings.enterprise.projects.team.limit);
|
||||
const teamProjectsAvailable = computed<boolean>(
|
||||
const isTeamProjectFeatureEnabled = computed<boolean>(
|
||||
() => settingsStore.settings.enterprise.projects.team.limit !== 0,
|
||||
);
|
||||
const hasUnlimitedProjects = computed<boolean>(
|
||||
() => settingsStore.settings.enterprise.projects.team.limit === -1,
|
||||
);
|
||||
const teamProjectLimitExceeded = computed<boolean>(
|
||||
const isTeamProjectLimitExceeded = computed<boolean>(
|
||||
() => projectsCount.value.team >= teamProjectsLimit.value,
|
||||
);
|
||||
const canCreateProjects = computed<boolean>(
|
||||
() =>
|
||||
hasUnlimitedProjects.value ||
|
||||
(teamProjectsAvailable.value && !teamProjectLimitExceeded.value),
|
||||
(isTeamProjectFeatureEnabled.value && !isTeamProjectLimitExceeded.value),
|
||||
);
|
||||
const hasPermissionToCreateProjects = computed(() =>
|
||||
hasPermission(['rbac'], { rbac: { scope: 'project:create' } }),
|
||||
|
@ -199,7 +199,7 @@ export const useProjectsStore = defineStore('projects', () => {
|
|||
hasUnlimitedProjects,
|
||||
canCreateProjects,
|
||||
hasPermissionToCreateProjects,
|
||||
teamProjectsAvailable,
|
||||
isTeamProjectFeatureEnabled,
|
||||
projectNavActiveId,
|
||||
setCurrentProject,
|
||||
getAllProjects,
|
||||
|
|
Loading…
Reference in a new issue