From ff8ca201c16ab4a7ab806cc9ab7748ca47f02d1f Mon Sep 17 00:00:00 2001 From: "L. Ellenbeck" <ellenbeck@itc.rwth-aachen.de> Date: Tue, 30 May 2023 15:07:39 +0200 Subject: [PATCH] WIP: working project role management (coscine/issues#2436) --- src/modules/project/pages/Members.vue | 95 ++++++++++--------- .../project/pages/components/MembersList.vue | 13 +-- .../pages/components/UserSearchRow.vue | 29 +++--- .../components/modals/ImportUserModal.vue | 18 ++-- src/modules/project/store.ts | 16 +++- 5 files changed, 90 insertions(+), 81 deletions(-) diff --git a/src/modules/project/pages/Members.vue b/src/modules/project/pages/Members.vue index 75b23c4c..9d21feec 100644 --- a/src/modules/project/pages/Members.vue +++ b/src/modules/project/pages/Members.vue @@ -129,7 +129,7 @@ import useProjectStore from "../store"; import useUserStore from "@/modules/user/store"; import useNotificationStore from "@/store/notification"; -import type { ProjectDto, ProjectInvitationDto, ProjectInvitationForProjectManipulationDto, ProjectRoleDto, RoleDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; +import type { ProjectDto, ProjectInvitationDto, ProjectInvitationForProjectManipulationDto, ProjectRoleDto, ProjectRoleForProjectCreationDto, ProjectRoleForProjectManipulationDto, RoleDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; import type { ExtendedProjectInvitationDto } from "../types"; export default defineComponent({ @@ -361,34 +361,35 @@ export default defineComponent({ }, async setRole(projectRole: ProjectRoleDto) { - if (this.project) { + if (this.project && this.project.id && projectRole.id) { projectRole.projectId = this.project.id; - } - if (projectRole.role) { - projectRole.role.displayName = - projectRole.role.displayName === this.roleStrings.member - ? this.roleStrings.owner - : this.roleStrings.member; - } + + if (projectRole.role) { + projectRole.role.displayName = + projectRole.role.displayName === this.roleStrings.member + ? this.roleStrings.owner + : this.roleStrings.member; + } - const text = this.$t("page.members.changedRole", { - project: this.projectName, - role: - projectRole.role && projectRole.role.id - ? this.getRoleNameFromId(projectRole.role.id) - : "", - user: - projectRole.user && projectRole.user.displayName - ? projectRole.user.displayName - : "", - }).toString(); + const text = this.$t("page.members.changedRole", { + project: this.projectName, + role: + projectRole.role && projectRole.role.id + ? this.getRoleNameFromId(projectRole.role.id) + : "", + user: + projectRole.user && projectRole.user.displayName + ? projectRole.user.displayName + : "", + }).toString(); - await this.projectStore.storeProjectRole(projectRole); - await this.getProjectRoles(); - this.notificationStore.postNotification({ - title: this.$t("page.members.userManagement").toString(), - body: text, - }); + await this.projectStore.updateMembershipOfProject(this.project.id, projectRole.id, { roleId: projectRole.role?.id} as ProjectRoleForProjectManipulationDto); + await this.getProjectRoles(); + this.notificationStore.postNotification({ + title: this.$t("page.members.userManagement").toString(), + body: text, + }); + } }, getRoleNameFromId(roleId: string): string | null | undefined { @@ -404,30 +405,30 @@ export default defineComponent({ }, async addUser(projectRole: ProjectRoleDto, callback?: () => void) { - if (this.project) { + if (this.project && this.project.id) { projectRole.projectId = this.project.id; - } - const text = this.$t("page.members.addedUser", { - project: this.projectName, - role: - projectRole.role && projectRole.role.id - ? this.getRoleNameFromId(projectRole.role.id) - : "", - user: - projectRole.user && projectRole.user.displayName - ? projectRole.user.displayName - : "", - }).toString(); + const text = this.$t("page.members.addedUser", { + project: this.projectName, + role: + projectRole.role && projectRole.role.id + ? this.getRoleNameFromId(projectRole.role.id) + : "", + user: + projectRole.user && projectRole.user.displayName + ? projectRole.user.displayName + : "", + }).toString(); - await this.projectStore.storeProjectRole(projectRole); - await this.getProjectRoles(); - this.notificationStore.postNotification({ - title: this.$t("page.members.userManagement").toString(), - body: text, - }); - if (callback) { - callback(); + await this.projectStore.addMembershipToProject(this.project.id, {roleId: projectRole.role?.id, userId: projectRole.user?.userId} as ProjectRoleForProjectCreationDto); + await this.getProjectRoles(); + this.notificationStore.postNotification({ + title: this.$t("page.members.userManagement").toString(), + body: text, + }); + if (callback) { + callback(); + } } }, diff --git a/src/modules/project/pages/components/MembersList.vue b/src/modules/project/pages/components/MembersList.vue index 2820f553..ab0694d7 100644 --- a/src/modules/project/pages/components/MembersList.vue +++ b/src/modules/project/pages/components/MembersList.vue @@ -21,7 +21,7 @@ v-if=" projectRole.user && currentUser && - projectRole.user.id === currentUser.id + projectRole.user.userId === currentUser.id " class="badge badge-pill badge-primary ml-2" > @@ -62,7 +62,7 @@ v-if=" projectRole.user && currentUser && - projectRole.user.id === currentUser.id + projectRole.user.userId === currentUser.id " class="float-right" variant="primary" @@ -128,14 +128,13 @@ import { defineComponent } from "vue"; import type { - ProjectRoleObject, UserObject, } from "@coscine/api-client/dist/types/Coscine.Api.Project"; // import the store for current module import useProjectStore from "../../store"; import useUserStore from "@/modules/user/store"; -import type { ProjectDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; +import type { ProjectDto, ProjectRoleDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; export default defineComponent({ setup() { @@ -159,7 +158,7 @@ export default defineComponent({ project(): ProjectDto | null { return this.projectStore.currentProject; }, - projectRoles(): ProjectRoleObject[] | null { + projectRoles(): ProjectRoleDto[] | null { return this.projectStore.currentProjectRolesSorted; }, isOwner(): boolean | undefined { @@ -180,7 +179,9 @@ export default defineComponent({ methods: { leaveProject() { - this.projectStore.deleteProjectAssociation(this.project); + if(this.project) { + this.projectStore.deleteProjectAssociation(this.project, null); + } }, }, }); diff --git a/src/modules/project/pages/components/UserSearchRow.vue b/src/modules/project/pages/components/UserSearchRow.vue index edcf54e6..ff6e64ca 100644 --- a/src/modules/project/pages/components/UserSearchRow.vue +++ b/src/modules/project/pages/components/UserSearchRow.vue @@ -143,19 +143,15 @@ Vue.component("VSelect", vSelect); import useUserStore from "@/modules/user/store"; -import type { - ProjectRoleObject, - RoleObject, -} from "@coscine/api-client/dist/types/Coscine.Api.Project"; import type { UserObject } from "@coscine/api-client/dist/types/Coscine.Api.User"; -import type { ProjectDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; +import type { ProjectDto, ProjectRoleDto, ProjectRoleUserDto, RoleDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; export default defineComponent({ props: { memberRole: { default: null, type: [Object, null, undefined] as PropType< - RoleObject | null | undefined + RoleDto | null | undefined >, }, project: { @@ -164,7 +160,7 @@ export default defineComponent({ }, roles: { default: null, - type: [Array, null] as PropType<RoleObject[] | null>, + type: [Array, null] as PropType<RoleDto[] | null>, }, isOwner: { default: false, @@ -185,10 +181,10 @@ export default defineComponent({ displayName: "", }, user: { - id: "", + userId: "", emailAddress: "", }, - } as ProjectRoleObject, + } as ProjectRoleDto, queryTimer: 0, queriedUsers: [] as UserObject[], searchString: "", @@ -218,7 +214,7 @@ export default defineComponent({ this.newUserRole.role && this.newUserRole.role.id && this.newUserRole.user && - !this.newUserRole.user.id && + !this.newUserRole.user.userId && this.newUserRole.user.emailAddress ) { return true; @@ -230,7 +226,7 @@ export default defineComponent({ this.newUserRole && this.newUserRole.projectId && this.newUserRole.user && - this.newUserRole.user.id && + this.newUserRole.user.userId && this.newUserRole.role && this.newUserRole.role.id ) { @@ -252,7 +248,7 @@ export default defineComponent({ } }, methods: { - addUser(projectRole: ProjectRoleObject) { + addUser(projectRole: ProjectRoleDto) { this.searchString = ""; this.$emit("addUser", projectRole, () => { this.newUserRole.user = undefined; @@ -263,14 +259,19 @@ export default defineComponent({ filterMock(option: unknown, label: string, search: string) { return search.length > 0; }, - prepareInvitation(projectRole: ProjectRoleObject) { + prepareInvitation(projectRole: ProjectRoleDto) { this.$emit("prepareInvitation", projectRole); }, setFilter(filter: string) { this.$emit("setFilter", filter); }, setNewUser(value: UserObject) { - this.newUserRole.user = value; + this.newUserRole.user = { + userId: value.id, + displayName: value.displayName, + emailAddress: value.emailAddress + } as ProjectRoleUserDto; + if (this.project) { this.newUserRole.projectId = this.project.id; } diff --git a/src/modules/project/pages/components/modals/ImportUserModal.vue b/src/modules/project/pages/components/modals/ImportUserModal.vue index 263d257d..ec2773e4 100644 --- a/src/modules/project/pages/components/modals/ImportUserModal.vue +++ b/src/modules/project/pages/components/modals/ImportUserModal.vue @@ -74,11 +74,7 @@ import useProjectStore from "../../../store"; import MembersTable from "../MembersTable.vue"; -import type { - ProjectRoleObject, - RoleObject, -} from "@coscine/api-client/dist/types/Coscine.Api.Project"; -import type { ProjectDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; +import type { ProjectDto, ProjectRoleDto, RoleDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; export default defineComponent({ components: { @@ -92,7 +88,7 @@ export default defineComponent({ memberRole: { default: null, type: [Object, null, undefined] as PropType< - RoleObject | null | undefined + RoleDto | null | undefined >, }, project: { @@ -101,11 +97,11 @@ export default defineComponent({ }, projectRoles: { default: null, - type: [Array, null] as PropType<ProjectRoleObject[] | null>, + type: [Array, null] as PropType<ProjectRoleDto[] | null>, }, roles: { default: null, - type: [Array, null] as PropType<RoleObject[] | null>, + type: [Array, null] as PropType<RoleDto[] | null>, }, }, setup() { @@ -115,7 +111,7 @@ export default defineComponent({ }, data() { return { - additionalMembers: [] as ProjectRoleObject[], + additionalMembers: [] as ProjectRoleDto[], isBusy: false, selectedProject: null as string | null, }; @@ -142,7 +138,7 @@ export default defineComponent({ (projectRole) => !this.projectRoles?.some( (currentProjectRole) => - projectRole.user?.id === currentProjectRole.user?.id + projectRole.user?.userId === currentProjectRole.user?.userId ) ); this.additionalMembers.forEach((additionalMember) => { @@ -166,7 +162,7 @@ export default defineComponent({ this.$bvModal.hide("importUserModal"); this.additionalMembers = []; }, - removeSelectedRow(projectRole: ProjectRoleObject) { + removeSelectedRow(projectRole: ProjectRoleDto) { const index = this.additionalMembers.indexOf(projectRole); this.additionalMembers.splice(index, 1); }, diff --git a/src/modules/project/store.ts b/src/modules/project/store.ts index 1ab002dd..1467c1cc 100644 --- a/src/modules/project/store.ts +++ b/src/modules/project/store.ts @@ -24,7 +24,7 @@ import type { Route } from "vue-router"; import useNotificationStore from "@/store/notification"; import useUserStore from "../user/store"; import type { AxiosError } from "axios"; -import type { ProjectDto, ProjectForCreationDto, ProjectForUpdateDto, ProjectInvitationDto, ProjectInvitationForProjectManipulationDto, ProjectQuotaDto, ProjectQuotaForUpdateDto, ProjectRoleDto, ResourceDto, RoleDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; +import type { ProjectDto, ProjectForCreationDto, ProjectForUpdateDto, ProjectInvitationDto, ProjectInvitationForProjectManipulationDto, ProjectQuotaDto, ProjectQuotaForUpdateDto, ProjectRoleDto, ProjectRoleForProjectCreationDto, ProjectRoleForProjectManipulationDto, ResourceDto, RoleDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; /* Store variable name is "this.<id>Store" @@ -665,12 +665,22 @@ export const useProjectStore = defineStore({ notificationStore.postApiErrorNotification(error as AxiosError); return false; } + }, + + async addMembershipToProject(projectId: string, projectRoleForProjectCreationDto: ProjectRoleForProjectCreationDto) { + const notificationStore = useNotificationStore(); + try { + await ProjectMemberApi.addMembership(projectId, projectRoleForProjectCreationDto) + } catch (error) { + // Handle other Status Codes + notificationStore.postApiErrorNotification(error as AxiosError); + } }, - async storeProjectRole(projectRole: ProjectRoleDto) { + async updateMembershipOfProject(projectId: string, membershipId: string, projectRoleForProjectManipulationDto: ProjectRoleForProjectManipulationDto) { const notificationStore = useNotificationStore(); try { - await ProjectRoleApi.projectRoleSet(projectRole); + await ProjectMemberApi.updateMembership(projectId, membershipId, projectRoleForProjectManipulationDto) } catch (error) { // Handle other Status Codes notificationStore.postApiErrorNotification(error as AxiosError); -- GitLab