From c0a876bd014815eb58a40cdb5a5324051d1d6200 Mon Sep 17 00:00:00 2001 From: David Code Howard Date: Thu, 5 Oct 2023 09:36:41 -0400 Subject: [PATCH] feat: Add GraphQL mutation to add user to project (#106) * feat: Add GraphQL mutation to add user to project * build: Bump backend version --- package-lock.json | 4 ++-- package.json | 2 +- src/account/accountSlice.ts | 6 +++++- src/project/projectService.ts | 20 ++++++++++++++++++ src/project/projectSlice.ts | 40 +++++++++++++++++++++++++++++++++-- 5 files changed, 66 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 51d45da1..7f9962ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "lodash": "^4.17.21", "react": "^18.2.0", "react-redux": "^8.1.2", - "terraso-backend": "github:techmatters/terraso-backend#4170565", + "terraso-backend": "github:techmatters/terraso-backend#4929e5f", "uuid": "^9.0.0" }, "devDependencies": { @@ -13101,7 +13101,7 @@ }, "node_modules/terraso-backend": { "version": "0.1.0", - "resolved": "git+ssh://git@github.com/techmatters/terraso-backend.git#4170565525a1b85462685d4e2c861a3cfeec7fba" + "resolved": "git+ssh://git@github.com/techmatters/terraso-backend.git#4929e5f4599cebc2f107873dd0075885c4df5e46" }, "node_modules/test-exclude": { "version": "6.0.0", diff --git a/package.json b/package.json index f45f2b99..57e1ae84 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "lodash": "^4.17.21", "react": "^18.2.0", "react-redux": "^8.1.2", - "terraso-backend": "github:techmatters/terraso-backend#4170565", + "terraso-backend": "github:techmatters/terraso-backend#4929e5f", "uuid": "^9.0.0" }, "scripts": { diff --git a/src/account/accountSlice.ts b/src/account/accountSlice.ts index 37cafdb7..414ca186 100644 --- a/src/account/accountSlice.ts +++ b/src/account/accountSlice.ts @@ -114,6 +114,10 @@ export const userSlice = createSlice({ setUsers: (state, { payload: users }) => { Object.assign(state.users, users); }, + + addUser: (state, { payload: user }) => { + state.users[user.id] = user; + }, }, extraReducers: builder => { @@ -265,7 +269,7 @@ export const userSlice = createSlice({ }, }); -export const { setUser, setHasToken } = userSlice.actions; +export const { setUser, setHasToken, addUser } = userSlice.actions; export default userSlice.reducer; diff --git a/src/project/projectService.ts b/src/project/projectService.ts index e59bc794..91a3dd5f 100644 --- a/src/project/projectService.ts +++ b/src/project/projectService.ts @@ -19,6 +19,7 @@ import type { User } from 'terraso-client-shared/account/accountSlice'; import { graphql } from 'terraso-client-shared/graphqlSchema'; import type { ProjectAddMutationInput, + ProjectAddUserMutationInput, ProjectArchiveMutationInput, ProjectDataFragment, ProjectDeleteMutationInput, @@ -201,3 +202,22 @@ export const archiveProject = (project: ProjectArchiveMutationInput) => { }) .then(_ => project.archived); }; + +export const addUserToProject = (input: ProjectAddUserMutationInput) => { + const command = graphql(` + mutation addUserToProject($input: ProjectAddUserMutationInput!) { + addUserToProject(input: $input) { + errors + project { + id + } + membership { + ...projectMembershipFields + } + } + } + `); + return terrasoApi + .requestGraphQL(command, { input }) + .then(output => output.addUserToProject); +}; diff --git a/src/project/projectSlice.ts b/src/project/projectSlice.ts index 48c73cfa..a3d439f1 100644 --- a/src/project/projectSlice.ts +++ b/src/project/projectSlice.ts @@ -16,8 +16,15 @@ */ import { createAction, createSlice } from '@reduxjs/toolkit'; -import { setUsers, User } from 'terraso-client-shared/account/accountSlice'; -import { UserRole } from 'terraso-client-shared/graphqlSchema/graphql'; +import { + addUser, + setUsers, + User, +} from 'terraso-client-shared/account/accountSlice'; +import { + ProjectAddUserMutationInput, + UserRole, +} from 'terraso-client-shared/graphqlSchema/graphql'; import * as projectService from 'terraso-client-shared/project/projectService'; import { setSites, Site } from 'terraso-client-shared/site/siteSlice'; import { @@ -122,6 +129,24 @@ export const archiveProject = createAsyncThunk( projectService.archiveProject, ); +export const addUserToProject = createAsyncThunk< + ProjectMembership, + ProjectAddUserMutationInput +>('project/addUser', async (input, _, { dispatch }) => { + const res = await projectService.addUserToProject(input); + // TODO: Should make user required in future! + // https://github.com/techmatters/terraso-backend/issues/859 + if (res.membership.user === undefined || res.membership.user === null) { + throw Error(`Membership ${res.membership.id} created without user!`); + } + dispatch(addUser(res.membership.user)); + return { + userId: res.membership.user.id, + userRole: res.membership.userRole, + id: res.membership.id, + }; +}); + const projectSlice = createSlice({ name: 'project', initialState, @@ -189,6 +214,17 @@ const projectSlice = createSlice({ state.projects[meta.arg.id].archived = archived; }, ); + + builder.addCase( + addUserToProject.fulfilled, + (state, { meta, payload: { id: membershipId, userRole, userId } }) => { + state.projects[meta.arg.projectId].memberships[membershipId] = { + id: membershipId, + userRole, + userId, + }; + }, + ); }, });