From 41efed4ced3855a9520acc1482a2395dd1b66d78 Mon Sep 17 00:00:00 2001 From: David Code Howard Date: Fri, 3 Nov 2023 09:12:47 -0400 Subject: [PATCH] feat: Add new selectors site filter (#155) * 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). * refactor: Return lookup from selector * fix: Return empty object is userId is null --- src/selectors.test.ts | 25 +++++++++++++++++++++++++ src/selectors.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/selectors.test.ts b/src/selectors.test.ts index 757f9434..36844839 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'; @@ -185,3 +186,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]: 'manager', + [site2.id]: 'contributor', + [site3.id]: undefined, + [site4.id]: 'contributor', + }); +}); diff --git a/src/selectors.ts b/src/selectors.ts index f8253864..b81fd262 100644 --- a/src/selectors.ts +++ b/src/selectors.ts @@ -35,6 +35,37 @@ const selectProjectsWithUserRole = createSelector( ), ); +const selectProjectUserRoles = (state: SharedState, userId?: string) => { + return Object.fromEntries( + mapValues(state.project.projects, project => { + if (userId === undefined) { + return {}; + } + 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, role]; + }), + ); + }, +); + export const selectProjectsWithTransferrableSites = createSelector( [selectProjectsWithUserRole, selectSites], (projects, sites) => {