Skip to content

Commit

Permalink
chore: Merge remote-tracking branch 'origin/main' into fix/account-em…
Browse files Browse the repository at this point in the history
…ail-case-insensitive
  • Loading branch information
David Code Howard committed Oct 16, 2023
2 parents 6cf2412 + fbdcacd commit 9b10c53
Show file tree
Hide file tree
Showing 16 changed files with 781 additions and 329 deletions.
18 changes: 2 additions & 16 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.2",
"terraso-backend": "github:techmatters/terraso-backend#b619a7d",
"terraso-backend": "github:techmatters/terraso-backend#5476cb6",
"uuid": "^9.0.1"
},
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/account/accountService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import type {
} from 'terraso-client-shared/graphqlSchema/graphql';
import * as terrasoApi from 'terraso-client-shared/terrasoApi/api';

const parsePreferences = (
export const parsePreferences = (
user: UserFieldsFragment & UserPreferencesFragment,
): User => ({
...user,
Expand Down
10 changes: 6 additions & 4 deletions src/account/accountSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import { createAction, createSlice } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import _ from 'lodash/fp';
import * as accountService from 'terraso-client-shared/account/accountService';
import { getToken, removeToken } from 'terraso-client-shared/account/auth';
Expand Down Expand Up @@ -58,8 +58,6 @@ export type User = {
preferences: Record<string, string>;
};

export const setUsers = createAction<Record<string, User>>('user/setUsers');

export const setHasAccessTokenAsync = createAsyncThunk(
'account/setHasAccessTokenAsync',
() => getToken(),
Expand Down Expand Up @@ -112,6 +110,9 @@ export const userSlice = createSlice({
hasToken: action.payload,
}),
setUsers: (state, { payload: users }) => {
state.users = users;
},
updateUsers: (state, { payload: users }) => {
Object.assign(state.users, users);
},

Expand Down Expand Up @@ -269,7 +270,8 @@ export const userSlice = createSlice({
},
});

export const { setUser, setHasToken, addUser } = userSlice.actions;
export const { setUser, setUsers, updateUsers, setHasToken, addUser } =
userSlice.actions;

export default userSlice.reducer;

Expand Down
1 change: 1 addition & 0 deletions src/project/projectFragments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const projectMembershipFields = /* GraphQL */ `
userRole
user {
...userFields
...userPreferences
}
}
`;
Expand Down
138 changes: 62 additions & 76 deletions src/project/projectService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import { parsePreferences } from 'terraso-client-shared/account/accountService';
import type { User } from 'terraso-client-shared/account/accountSlice';
import { graphql } from 'terraso-client-shared/graphqlSchema';
import type {
Expand All @@ -23,83 +24,70 @@ import type {
ProjectArchiveMutationInput,
ProjectDataFragment,
ProjectDeleteMutationInput,
ProjectMembershipFieldsFragment,
ProjectUpdateMutationInput,
} from 'terraso-client-shared/graphqlSchema/graphql';
import type {
HydratedProject,
Project,
ProjectMembership,
SerializableSet,
} from 'terraso-client-shared/project/projectSlice';
import { collapseSiteFields } from 'terraso-client-shared/site/siteService';
import { Site } from 'terraso-client-shared/site/siteSlice';
import { collapseSites } from 'terraso-client-shared/site/siteService';
import * as terrasoApi from 'terraso-client-shared/terrasoApi/api';
import {
collapseConnectionEdges,
collapseFields,
collapseEdges,
collapseMaps,
collapseToSet,
Connection,
} from 'terraso-client-shared/terrasoApi/utils';

const collapseProjectFields = collapseFields<
ProjectDataFragment,
HydratedProject
>(
{
dehydrated: inp => {
const siteIds = inp.siteSet.edges
.map(edge => edge.node.id)
.reduce((x, y) => ({ ...x, [y]: true }), {} as SerializableSet);
const memberships =
inp.membershipList.memberships?.edges
.map(edge => edge.node)
.reduce(
(x, { id, user, userRole }) => {
if (user === null || user === undefined) {
return x;
}
return { ...x, [id]: { userId: user.id, userRole, id } };
},
{} as Record<string, ProjectMembership>,
) || {};

const { siteSet: _x, membershipList: _y, updatedAt, ...rest } = inp;
const output: Project = {
...rest,
updatedAt: new Date(updatedAt).toLocaleString(),
siteIds,
memberships,
};
return output;
const collapseProjectMembership = ({
user,
...fields
}: ProjectMembershipFieldsFragment) => ({
membership: { userId: user.id, ...fields },
user: parsePreferences(user),
});

const collapseProjectMemberships = (
connection: Connection<ProjectMembershipFieldsFragment>,
) => {
const memberships = collapseEdges(connection).map(collapseProjectMembership);
return {
memberships: Object.fromEntries(
memberships.map(({ membership }) => [membership.id, membership]),
),
users: Object.fromEntries(memberships.map(({ user }) => [user.id, user])),
};
};

export const collapseProject = ({
membershipList,
siteSet,
...project
}: ProjectDataFragment) => {
const sites = collapseSites(siteSet);
const { memberships, users } = collapseProjectMemberships(
membershipList.memberships,
);
return {
project: {
...project,
sites: collapseToSet(Object.keys(sites)),
memberships,
},
sites: inp =>
inp.siteSet.edges
.map(edge => edge.node)
.reduce(
(x, y) => ({ ...x, [y.id]: collapseSiteFields(y) }),
{} as Record<string, Site>,
),
users: inp =>
inp.membershipList.memberships?.edges
.map(({ node: { user } }) => {
if (user === undefined || user === null) {
return undefined;
}
return {
...user,
preferences: {},
};
})
.reduce(
(x, y) => {
if (y !== undefined) {
return { ...x, [y.id]: y };
}
return x;
},
{} as Record<string, User>,
) || {},
},
true,
);
sites,
users,
};
};

export const collapseProjects = (
projectConnection: Connection<ProjectDataFragment>,
) => {
const projects = collapseEdges(projectConnection).map(collapseProject);
return {
projects: Object.fromEntries(
projects.map(({ project }) => [project.id, project]),
),
sites: collapseMaps(...projects.map(({ sites }) => sites)),
users: collapseMaps(...projects.map(({ users }) => users)),
};
};

export const fetchProject = (id: string) => {
const query = graphql(`
Expand All @@ -112,7 +100,7 @@ export const fetchProject = (id: string) => {

return terrasoApi
.requestGraphQL(query, { id })
.then(resp => collapseProjectFields(resp.project));
.then(resp => collapseProject(resp.project));
};

export const fetchProjectsForUser = async (_: undefined, user: User | null) => {
Expand All @@ -134,9 +122,7 @@ export const fetchProjectsForUser = async (_: undefined, user: User | null) => {

return terrasoApi
.requestGraphQL(query, { id: user.id })
.then(resp =>
collapseConnectionEdges(resp.projects).map(collapseProjectFields),
);
.then(resp => collapseProjects(resp.projects));
};

export const addProject = (project: ProjectAddMutationInput) => {
Expand All @@ -153,7 +139,7 @@ export const addProject = (project: ProjectAddMutationInput) => {

return terrasoApi
.requestGraphQL(query, { input: project })
.then(resp => collapseProjectFields(resp.addProject.project));
.then(resp => collapseProject(resp.addProject.project));
};

export const updateProject = (project: ProjectUpdateMutationInput) => {
Expand All @@ -170,7 +156,7 @@ export const updateProject = (project: ProjectUpdateMutationInput) => {

return terrasoApi
.requestGraphQL(query, { input: project })
.then(resp => collapseProjectFields(resp.updateProject.project!));
.then(resp => collapseProject(resp.updateProject.project!));
};

export const deleteProject = (project: ProjectDeleteMutationInput) => {
Expand Down
Loading

0 comments on commit 9b10c53

Please sign in to comment.