Skip to content

Commit

Permalink
feat: site transfer mutation (#148)
Browse files Browse the repository at this point in the history
* feat: Add service method to transfer sites

* feat: Add reducer for site transfer mutation

* feat: Include unaffiliated sites
  • Loading branch information
david-code authored Oct 30, 2023
1 parent 982fd0a commit ca1f283
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 11 deletions.
5 changes: 2 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-redux": "^8.1.3",
"terraso-backend": "github:techmatters/terraso-backend#3d323b5",
"terraso-backend": "github:techmatters/terraso-backend#f671497",
"uuid": "^9.0.1"
},
"scripts": {
Expand Down
12 changes: 8 additions & 4 deletions src/selectors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ const generateProject = (
};
};

const generateSite = (project: Project): Site => {
const generateSite = (project?: Project): Site => {
const id = uuidv4();
const site: Site = {
projectId: project.id,
projectId: project?.id,
ownerId: undefined,
id,
name: 'Test Site',
Expand All @@ -68,7 +68,9 @@ const generateSite = (project: Project): Site => {
archived: false,
updatedAt: '2023-10-24',
};
project.sites[site.id] = true;
if (project !== undefined) {
project.sites[site.id] = true;
}
return site;
};

Expand Down Expand Up @@ -157,9 +159,10 @@ test('can access all projects with role', () => {
const project3 = generateProject([generateMembership(user.id, 'manager')]);
const site1 = generateSite(project1);
const site2 = generateSite(project2);
const site3 = generateSite();

const store = createStore(
initState([project1, project2, project3], [user], [site1, site2]),
initState([project1, project2, project3], [user], [site1, site2, site3]),
);
const pairs = selectProjectsWithTransferrableSites(
store.getState(),
Expand All @@ -178,5 +181,6 @@ test('can access all projects with role', () => {
siteName: site1.name,
},
],
unaffiliatedSites: [{ siteId: site3.id, siteName: site3.name }],
});
});
8 changes: 6 additions & 2 deletions src/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,17 @@ export const selectProjectsWithTransferrableSites = createSelector(
};
}),
);
let projectRecord = projects.reduce(

const unaffiliatedSites = Object.values(sites)
.filter(({ projectId }) => projectId === undefined)
.map(({ id, name }) => ({ siteId: id, siteName: name }));
const projectRecord = projects.reduce(
(x, { id, name }) => ({
...x,
[id]: { projectId: id, projectName: name },
}),
{} as Record<string, { projectId: string; projectName: string }>,
);
return { projects: projectRecord, sites: projectSites };
return { projects: projectRecord, sites: projectSites, unaffiliatedSites };
},
);
40 changes: 40 additions & 0 deletions src/site/siteService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { graphql } from 'terraso-client-shared/graphqlSchema';
import type {
SiteAddMutationInput,
SiteDataFragment,
SiteTransferMutationInput,
SiteUpdateMutationInput,
} from 'terraso-client-shared/graphqlSchema/graphql';
import type { Site } from 'terraso-client-shared/site/siteSlice';
Expand Down Expand Up @@ -154,3 +155,42 @@ export const deleteSite = (site: Site) => {
.requestGraphQL(query, { input: { id: site.id } })
.then(_ => site.id);
};

export const transferSitesToProject = (input: SiteTransferMutationInput) => {
const query = graphql(`
mutation transferSites($input: SiteTransferMutationInput!) {
transferSites(input: $input) {
project {
id
}
updated {
site {
id
}
oldProject {
id
}
}
}
}
`);
return terrasoApi.requestGraphQL(query, { input }).then(
({
transferSites: {
project: { id: projectId },
updated,
},
}) => {
const condensedUpdated = updated.map(
({ site: { id: siteId }, oldProject }) => {
const obj: { siteId: string; oldProjectId?: string } = { siteId };
if (oldProject) {
obj.oldProjectId = oldProject.id;
}
return obj;
},
);
return { projectId, updated: condensedUpdated };
},
);
};
29 changes: 28 additions & 1 deletion src/site/siteSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@
*/

import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { SiteAddMutationInput } from 'terraso-client-shared/graphqlSchema/graphql';
import {
SiteAddMutationInput,
SiteTransferMutationInput,
} from 'terraso-client-shared/graphqlSchema/graphql';
import {
addSiteToProject,
removeSiteFromAllProjects,
removeSiteFromProject,
} from 'terraso-client-shared/project/projectSlice';
import * as siteService from 'terraso-client-shared/site/siteService';
import { createAsyncThunk } from 'terraso-client-shared/store/utils';
Expand Down Expand Up @@ -82,6 +86,20 @@ export const deleteSite = createAsyncThunk<string, Site>(
},
);

export const transferSites = createAsyncThunk<
Awaited<ReturnType<typeof siteService.transferSitesToProject>>,
SiteTransferMutationInput
>('site/transferSites', async (input, _currentUser, { dispatch }) => {
const result = await siteService.transferSitesToProject(input);
for (const { siteId, oldProjectId } of result.updated) {
if (oldProjectId !== undefined) {
dispatch(removeSiteFromProject({ siteId, projectId: oldProjectId }));
}
dispatch(addSiteToProject({ siteId, projectId: result.projectId }));
}
return result;
});

const siteSlice = createSlice({
name: 'site',
initialState,
Expand Down Expand Up @@ -133,6 +151,15 @@ const siteSlice = createSlice({
builder.addCase(deleteSite.fulfilled, (state, { meta }) => {
delete state.sites[meta.arg.id];
});

builder.addCase(
transferSites.fulfilled,
(state, { payload: { projectId, updated } }) => {
for (const { siteId } of updated) {
state.sites[siteId].projectId = projectId;
}
},
);
},
});

Expand Down

0 comments on commit ca1f283

Please sign in to comment.