diff --git a/cypress/composables/projects.ts b/cypress/composables/projects.ts index de5669ae11..6fa2c6f502 100644 --- a/cypress/composables/projects.ts +++ b/cypress/composables/projects.ts @@ -21,7 +21,7 @@ export const addProjectMember = (email: string) => { getProjectMembersSelect().click(); getProjectMembersSelect().get('.el-select-dropdown__item').contains(email.toLowerCase()).click(); }; -export const getProjectNameInput = () => cy.get('#projectName'); +export const getProjectNameInput = () => cy.get('#projectName').find('input'); export const getResourceMoveModal = () => cy.getByTestId('project-move-resource-modal'); export const getResourceMoveConfirmModal = () => cy.getByTestId('project-move-resource-confirm-modal'); diff --git a/packages/design-system/src/components/N8nAvatar/Avatar.vue b/packages/design-system/src/components/N8nAvatar/Avatar.vue index 933b55343e..f7993a84a0 100644 --- a/packages/design-system/src/components/N8nAvatar/Avatar.vue +++ b/packages/design-system/src/components/N8nAvatar/Avatar.vue @@ -15,6 +15,7 @@ diff --git a/packages/editor-ui/src/components/Projects/ProjectMoveResourceConfirmModal.test.ts b/packages/editor-ui/src/components/Projects/ProjectMoveResourceConfirmModal.test.ts index a81e412685..b413550a39 100644 --- a/packages/editor-ui/src/components/Projects/ProjectMoveResourceConfirmModal.test.ts +++ b/packages/editor-ui/src/components/Projects/ProjectMoveResourceConfirmModal.test.ts @@ -49,6 +49,7 @@ describe('ProjectMoveResourceConfirmModal', () => { id: '1', }, projectId: '1', + projectName: 'My Project', }, }; const { getByRole, getAllByRole } = renderComponent({ props }); diff --git a/packages/editor-ui/src/components/Projects/ProjectMoveResourceConfirmModal.vue b/packages/editor-ui/src/components/Projects/ProjectMoveResourceConfirmModal.vue index 454fe163cb..dcccb49a34 100644 --- a/packages/editor-ui/src/components/Projects/ProjectMoveResourceConfirmModal.vue +++ b/packages/editor-ui/src/components/Projects/ProjectMoveResourceConfirmModal.vue @@ -1,5 +1,5 @@ + diff --git a/packages/editor-ui/src/components/Projects/ProjectNavigation.vue b/packages/editor-ui/src/components/Projects/ProjectNavigation.vue index 03b6331be4..d1f5bac9ce 100644 --- a/packages/editor-ui/src/components/Projects/ProjectNavigation.vue +++ b/packages/editor-ui/src/components/Projects/ProjectNavigation.vue @@ -124,6 +124,9 @@ onMounted(async () => { { color: var(--color-primary); cursor: pointer; } + +.collapsed { + text-transform: uppercase; +} + + diff --git a/packages/editor-ui/src/plugins/i18n/locales/en.json b/packages/editor-ui/src/plugins/i18n/locales/en.json index c552869039..56af9fcade 100644 --- a/packages/editor-ui/src/plugins/i18n/locales/en.json +++ b/packages/editor-ui/src/plugins/i18n/locales/en.json @@ -2473,15 +2473,22 @@ "projects.create.limit": "{num} project | {num} projects", "projects.create.limitReached": "You have reached the {planName} plan limit of {limit}. Upgrade your plan to unlock more projects. {link}", "projects.create.limitReached.link": "View plans", - "projects.move.resource.modal.title": "Choose a project to move this {resourceType} to", - "projects.move.resource.modal.message": "\"{resourceName}\" is currently in the \"{resourceHomeProjectName}\" project. Which project would you like to move this {resourceType} to?", + "projects.move.resource.modal.title": "Choose a project to move this {resourceTypeLabel} to", + "projects.move.resource.modal.message": "\"{resourceName}\" is currently in the \"{resourceHomeProjectName}\" project. Which project would you like to move this {resourceTypeLabel} to?", "projects.move.resource.confirm.modal.title": "Please confirm the following", "projects.move.resource.confirm.modal.button.confirm": "Confirm move to new project", "projects.move.workflow.confirm.modal.label": "This workflow may stop working if the credentials used with it do not exist in the project its being moved to", "projects.move.credential.confirm.modal.label": "Any workflows currently using this credential will stop working once this credential has been moved", - "projects.move.resource.confirm.modal.label": "Any individual sharing currently associated with this {resourceType} will be removed. (currently shared with {numberOfUsers})", + "projects.move.resource.confirm.modal.label": "Any individual sharing currently associated with this {resourceTypeLabel} will be removed. (currently shared with {numberOfUsers})", "projects.move.resource.confirm.modal.numberOfUsers": "{numberOfUsers} user | {numberOfUsers} users", - "projects.move.resource.error.title": "Error moving {resourceName} {resourceType}", + "projects.move.resource.error.title": "Error moving {resourceName} {resourceTypeLabel}", + "projects.move.resource.success.title": "Successfully moved {resourceTypeLabel}", + "projects.move.resource.success.message": "{resourceName} {resourceTypeLabel} was moved to {targetProjectName} {link}", + "projects.move.resource.success.link": "View {targetProjectName}", + "projects.badge.tooltip.sharedOwned": "This {resourceTypeLabel} is owned by you and shared with one or more other users", + "projects.badge.tooltip.sharedPersonal": "This {resourceTypeLabel} is owned by {name} and shared with one or more other users", + "projects.badge.tooltip.personal": "This {resourceTypeLabel} is owned by {name}", + "projects.badge.tooltip.team": "This {resourceTypeLabel} is owned by the {name} project. All users in this project have access to this.", "mfa.setup.invalidAuthenticatorCode": "{code} is not a valid number", "mfa.setup.invalidCode": "Two-factor code failed. Please try again.", "mfa.code.modal.title": "Two-factor authentication", diff --git a/packages/editor-ui/src/routes/projects.routes.ts b/packages/editor-ui/src/routes/projects.routes.ts index 0bb9300fec..09c13311cc 100644 --- a/packages/editor-ui/src/routes/projects.routes.ts +++ b/packages/editor-ui/src/routes/projects.routes.ts @@ -4,7 +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('@/components/Projects/ProjectSettings.vue'); +const ProjectSettings = async () => await import('@/views/ProjectSettings.vue'); const commonChildRoutes: RouteRecordRaw[] = [ { diff --git a/packages/editor-ui/src/utils/projects.utils.ts b/packages/editor-ui/src/utils/projects.utils.ts index 5e9537ddd9..99aa8baf05 100644 --- a/packages/editor-ui/src/utils/projects.utils.ts +++ b/packages/editor-ui/src/utils/projects.utils.ts @@ -26,3 +26,8 @@ export const splitName = ( } } }; + +export const enum ResourceType { + Credential = 'credential', + Workflow = 'workflow', +} diff --git a/packages/editor-ui/src/views/CredentialsView.vue b/packages/editor-ui/src/views/CredentialsView.vue index b876858d7c..56bb977dfc 100644 --- a/packages/editor-ui/src/views/CredentialsView.vue +++ b/packages/editor-ui/src/views/CredentialsView.vue @@ -7,6 +7,7 @@ :filters="filters" :additional-filters-handler="onFilter" :type-props="{ itemSize: 77 }" + :loading="loading" @click:add="addCredential" @update:filters="filters = $event" > @@ -79,8 +80,6 @@ import ProjectTabs from '@/components/Projects/ProjectTabs.vue'; import useEnvironmentsStore from '@/stores/environments.ee.store'; import { useSettingsStore } from '@/stores/settings.store'; -type IResourcesListLayoutInstance = InstanceType; - export default defineComponent({ name: 'CredentialsView', components: { @@ -96,6 +95,7 @@ export default defineComponent({ type: '', }, sourceControlStoreUnsubscribe: () => {}, + loading: false, }; }, computed: { @@ -133,9 +133,6 @@ export default defineComponent({ }, }, watch: { - 'filters.type'() { - this.sendFiltersTelemetry('type'); - }, '$route.params.projectId'() { void this.initialize(); }, @@ -161,6 +158,7 @@ export default defineComponent({ }); }, async initialize() { + this.loading = true; const isVarsEnabled = useSettingsStore().isEnterpriseFeatureEnabled( EnterpriseEditionFeature.Variables, ); @@ -176,6 +174,7 @@ export default defineComponent({ ]; await Promise.all(loadPromises); + this.loading = false; }, onFilter( resource: ICredentialsResponse, @@ -199,9 +198,6 @@ export default defineComponent({ return matches; }, - sendFiltersTelemetry(source: string) { - (this.$refs.layout as IResourcesListLayoutInstance).sendFiltersTelemetry(source); - }, }, }); diff --git a/packages/editor-ui/src/components/Projects/ProjectSettings.test.ts b/packages/editor-ui/src/views/ProjectSettings.test.ts similarity index 98% rename from packages/editor-ui/src/components/Projects/ProjectSettings.test.ts rename to packages/editor-ui/src/views/ProjectSettings.test.ts index 3a55ca24e5..594db154d5 100644 --- a/packages/editor-ui/src/components/Projects/ProjectSettings.test.ts +++ b/packages/editor-ui/src/views/ProjectSettings.test.ts @@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event'; import { createComponentRenderer } from '@/__tests__/render'; import { getDropdownItems } from '@/__tests__/utils'; import { useRouter } from 'vue-router'; -import ProjectSettings from '@/components/Projects/ProjectSettings.vue'; +import ProjectSettings from '@/views/ProjectSettings.vue'; import { useProjectsStore } from '@/stores/projects.store'; import { VIEWS } from '@/constants'; import { useUsersStore } from '@/stores/users.store'; diff --git a/packages/editor-ui/src/components/Projects/ProjectSettings.vue b/packages/editor-ui/src/views/ProjectSettings.vue similarity index 95% rename from packages/editor-ui/src/components/Projects/ProjectSettings.vue rename to packages/editor-ui/src/views/ProjectSettings.vue index 6002335fe8..31db1d6689 100644 --- a/packages/editor-ui/src/components/Projects/ProjectSettings.vue +++ b/packages/editor-ui/src/views/ProjectSettings.vue @@ -1,7 +1,8 @@