From 00faf6ed883180f5829e76d1a8039898d5a9c785 Mon Sep 17 00:00:00 2001 From: David Code Howard Date: Wed, 1 Nov 2023 13:34:37 -0400 Subject: [PATCH] feat: Add new selectors site filter We need to associate sites to user roles. The user role is selected as the user's role in the project to which the site belongs (undefined if the site does not belong to a project). --- src/selectors.test.ts | 25 +++++++++++++++++++++++++ src/selectors.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/selectors.test.ts b/src/selectors.test.ts index e021e6a6..f55d6771 100644 --- a/src/selectors.test.ts +++ b/src/selectors.test.ts @@ -14,6 +14,7 @@ import { import { selectProjectMembershipsWithUsers, selectProjectsWithTransferrableSites, + selectSitesAndUserRoles, } from 'terraso-client-shared/selectors'; import { Site } from 'terraso-client-shared/site/siteSlice'; import { SerializableSet } from 'terraso-client-shared/store/utils'; @@ -184,3 +185,27 @@ test('can access all projects with role', () => { unaffiliatedSites: [{ siteId: site3.id, siteName: site3.name }], }); }); + +test('select user sites with project role', () => { + const user = generateUser(); + const project1 = generateProject([generateMembership(user.id, 'manager')]); + const project2 = generateProject([ + generateMembership(user.id, 'contributor'), + ]); + const site1 = generateSite(project1); + const site2 = generateSite(project2); + const site3 = generateSite(); + const site4 = generateSite(project2); + + const store = createStore( + initState([project1, project2], [user], [site1, site2, site3, site4]), + ); + + const roles = selectSitesAndUserRoles(store.getState(), user.id); + expect(roles).toStrictEqual({ + [site1.id]: [site1, 'manager'], + [site2.id]: [site2, 'contributor'], + [site3.id]: [site3, undefined], + [site4.id]: [site4, 'contributor'], + }); +}); diff --git a/src/selectors.ts b/src/selectors.ts index f8253864..843ee17a 100644 --- a/src/selectors.ts +++ b/src/selectors.ts @@ -35,6 +35,34 @@ const selectProjectsWithUserRole = createSelector( ), ); +const selectProjectUserRoles = (state: SharedState, userId: string) => { + return Object.fromEntries( + mapValues(state.project.projects, project => { + const membership = Object.values(project.memberships).find( + ({ userId: membUserId }) => membUserId === userId, + ); + if (membership) { + return [project.id, membership.userRole]; + } + }).filter((item): item is [string, UserRole] => item !== undefined), + ); +}; + +export const selectSitesAndUserRoles = createSelector( + [selectProjectUserRoles, selectSites], + (userRoleMap, sites) => { + return Object.fromEntries( + mapValues(sites, site => { + let role = undefined; + if (site.projectId !== undefined) { + role = userRoleMap[site.projectId]; + } + return [site.id, [site, role]]; + }), + ); + }, +); + export const selectProjectsWithTransferrableSites = createSelector( [selectProjectsWithUserRole, selectSites], (projects, sites) => {