Skip to content

Commit

Permalink
feat: define more types and enums (#359)
Browse files Browse the repository at this point in the history
  • Loading branch information
shrouxm authored Mar 26, 2024
1 parent 28a7e9d commit 33509bf
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 43 deletions.
4 changes: 2 additions & 2 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#f19112f",
"terraso-backend": "github:techmatters/terraso-backend#ae60684",
"uuid": "^9.0.1"
},
"scripts": {
Expand Down
1 change: 0 additions & 1 deletion src/project/projectFragments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export const projectData = /* GraphQL */ `
siteInstructions
updatedAt
archived
measurementUnits
membershipList {
...projectMembershipList
}
Expand Down
20 changes: 16 additions & 4 deletions src/project/projectSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import {
updateUsers,
} from 'terraso-client-shared/account/accountSlice';
import {
MeasurementUnits,
ProjectAddUserMutationInput,
UserRole,
ProjectManagementProjectPrivacyChoices,
ProjectMembershipProjectRoleChoices,
} from 'terraso-client-shared/graphqlSchema/graphql';
import * as projectService from 'terraso-client-shared/project/projectService';
import { setSites, updateSites } from 'terraso-client-shared/site/siteSlice';
Expand All @@ -37,10 +37,23 @@ import {

export type ProjectMembership = {
userId: string;
userRole: UserRole;
userRole: ProjectRole;
id: string;
};

export type ProjectRole = ProjectMembershipProjectRoleChoices;
export const PROJECT_ROLES = [
'MANAGER',
'CONTRIBUTOR',
'VIEWER',
] as const satisfies readonly ProjectRole[];

export type ProjectPrivacy = ProjectManagementProjectPrivacyChoices;
export const PROJECT_PRIVACIES = [
'PRIVATE',
'PUBLIC',
] as const satisfies readonly ProjectPrivacy[];

export type Project = {
id: string;
name: string;
Expand All @@ -51,7 +64,6 @@ export type Project = {
memberships: Record<string, ProjectMembership>;
sites: SerializableSet;
archived: boolean;
measurementUnits: MeasurementUnits;
};

interface MembershipKey {
Expand Down
47 changes: 22 additions & 25 deletions src/selectors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,11 @@ import {
DEFAULT_ENABLED_SOIL_PIT_METHODS,
DEPTH_INTERVAL_PRESETS,
} from 'terraso-client-shared/constants';
import {
DepthInterval,
ProjectPrivacy,
UserRole,
} from 'terraso-client-shared/graphqlSchema/graphql';
import {
Project,
ProjectMembership,
ProjectPrivacy,
ProjectRole,
} from 'terraso-client-shared/project/projectSlice';
import {
selectProjectMembershipsWithUsers,
Expand All @@ -42,6 +39,7 @@ import {
} from 'terraso-client-shared/selectors';
import { Site } from 'terraso-client-shared/site/siteSlice';
import {
DepthInterval,
methodEnabled,
methodRequired,
ProjectDepthInterval,
Expand Down Expand Up @@ -91,7 +89,6 @@ const generateProject = (
sites: siteSet,
archived: false,
memberships: keyBy(memberships, 'id'),
measurementUnits: 'METRIC',
siteInstructions: '',
};
};
Expand Down Expand Up @@ -123,7 +120,7 @@ const generateSite = (args?: { project: Project } | { owner: User }): Site => {
return site;
};

const generateMembership = (userId: string, userRole: UserRole) => {
const generateMembership = (userId: string, userRole: ProjectRole) => {
return { id: uuidv4(), userId, userRole };
};

Expand Down Expand Up @@ -274,7 +271,7 @@ test('can select memberships', () => {
const membership: ProjectMembership = {
id: uuidv4(),
userId: user.id,
userRole: 'manager',
userRole: 'MANAGER',
};
const project = generateProject([membership]);
const store = createStore(initState([project], [user]));
Expand All @@ -288,8 +285,8 @@ test('can select memberships', () => {

test('can select memberships of specific project', () => {
const user = generateUser();
const membershipA = generateMembership(user.id, 'viewer');
const membershipB = generateMembership(user.id, 'manager');
const membershipA = generateMembership(user.id, 'VIEWER');
const membershipB = generateMembership(user.id, 'MANAGER');
const projectA = generateProject([membershipA]);
const projectB = generateProject([membershipB]);
const store = createStore(initState([projectA, projectB], [user]));
Expand All @@ -312,11 +309,11 @@ test('not found project returns empty membership', () => {

test('can access all projects with role', () => {
const user = generateUser();
const project1 = generateProject([generateMembership(user.id, 'manager')]);
const project1 = generateProject([generateMembership(user.id, 'MANAGER')]);
const project2 = generateProject([
generateMembership(user.id, 'contributor'),
generateMembership(user.id, 'CONTRIBUTOR'),
]);
const project3 = generateProject([generateMembership(user.id, 'manager')]);
const project3 = generateProject([generateMembership(user.id, 'MANAGER')]);
const site1 = generateSite({ project: project1 });
const site2 = generateSite({ project: project2 });
const site3 = generateSite();
Expand All @@ -331,7 +328,7 @@ test('can access all projects with role', () => {
);
const pairs = selectProjectsWithTransferrableSites(
store.getState(),
'manager',
'MANAGER',
);
expect(pairs).toStrictEqual({
projects: {
Expand All @@ -352,9 +349,9 @@ test('can access all projects with role', () => {

test('select user sites with project role', () => {
const user = generateUser();
const project1 = generateProject([generateMembership(user.id, 'manager')]);
const project1 = generateProject([generateMembership(user.id, 'MANAGER')]);
const project2 = generateProject([
generateMembership(user.id, 'contributor'),
generateMembership(user.id, 'CONTRIBUTOR'),
]);
const site1 = generateSite({ project: project1 });
const site2 = generateSite({ project: project2 });
Expand All @@ -372,10 +369,10 @@ test('select user sites with project role', () => {

const roles = selectSitesAndUserRoles(store.getState());
expect(roles).toStrictEqual({
[site1.id]: 'manager',
[site2.id]: 'contributor',
[site1.id]: 'MANAGER',
[site2.id]: 'CONTRIBUTOR',
[site3.id]: undefined,
[site4.id]: 'contributor',
[site4.id]: 'CONTRIBUTOR',
});
});

Expand All @@ -385,22 +382,22 @@ test('select user role when site owned', () => {
const store = createStore(initState([], [user], [site], user.id));

const siteRole = selectUserRoleSite(store.getState(), site.id);
expect(siteRole).toStrictEqual({ kind: 'site', role: 'owner' });
expect(siteRole).toStrictEqual({ kind: 'site', role: 'OWNER' });
});

test('select user role in project of site', () => {
const user = generateUser();
const project = generateProject([generateMembership(user.id, 'viewer')]);
const project = generateProject([generateMembership(user.id, 'VIEWER')]);
const site = generateSite({ project });
const store = createStore(initState([project], [user], [site], user.id));

const siteRole = selectUserRoleSite(store.getState(), site.id);
expect(siteRole).toStrictEqual({ kind: 'project', role: 'viewer' });
expect(siteRole).toStrictEqual({ kind: 'project', role: 'VIEWER' });
});

test('select predefined project selector', () => {
const user = generateUser();
const project = generateProject([generateMembership(user.id, 'manager')]);
const project = generateProject([generateMembership(user.id, 'MANAGER')]);
const site = generateSite({ project });
const soilData = createSoilData(site);
const projectSettings = createProjectSettings(project, {
Expand All @@ -424,7 +421,7 @@ test('select predefined project selector', () => {

test('select predefined project selector with custom preset', () => {
const user = generateUser();
const project = generateProject([generateMembership(user.id, 'manager')]);
const project = generateProject([generateMembership(user.id, 'MANAGER')]);
const site = generateSite({ project });
const projectDepthIntervals = [
{ depthInterval: { start: 2, end: 3 }, label: 'first' },
Expand Down Expand Up @@ -479,7 +476,7 @@ test('select predefined project selector with custom preset', () => {

test('overlapping site intervals get the project values of the preset interval', () => {
const user = generateUser();
const project = generateProject([generateMembership(user.id, 'manager')]);
const project = generateProject([generateMembership(user.id, 'MANAGER')]);
const site = generateSite({ project });

const projectDepthIntervals = [
Expand Down
18 changes: 8 additions & 10 deletions src/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,14 @@ import {
DEFAULT_SOIL_DATA,
DEPTH_INTERVAL_PRESETS,
} from 'terraso-client-shared/constants';
import {
DepthInterval,
UserRole,
} from 'terraso-client-shared/graphqlSchema/graphql';
import {
Project,
ProjectMembership,
ProjectRole,
} from 'terraso-client-shared/project/projectSlice';
import {
compareInterval,
DepthInterval,
methodEnabled,
methodRequired,
overlaps,
Expand Down Expand Up @@ -82,7 +80,7 @@ export const selectSite = (siteId: string) => (state: SharedState) =>

const selectSites = (state: SharedState) => state.site.sites;

const selectUserRole = (_state: SharedState, userRole: UserRole) => userRole;
const selectUserRole = (_state: SharedState, userRole: ProjectRole) => userRole;

const selectProjectsWithUserRole = createSelector(
[selectProjects, selectUserRole],
Expand Down Expand Up @@ -110,7 +108,7 @@ const createUserRoleMap = (
if (membership) {
return [project.id, membership.userRole];
}
}).filter((item): item is [string, UserRole] => item !== undefined),
}).filter((item): item is [string, ProjectRole] => item !== undefined),
);
};

Expand Down Expand Up @@ -145,7 +143,7 @@ export const selectProjectsWithTransferrableSites = createSelector(
Object.keys(project.sites)
.filter(
siteId =>
siteId in project.sites && sitesWithRoles[siteId] === 'manager',
siteId in project.sites && sitesWithRoles[siteId] === 'MANAGER',
)
.map(siteId => {
const joinedSite = sites[siteId];
Expand Down Expand Up @@ -176,8 +174,8 @@ export const selectProjectsWithTransferrableSites = createSelector(
// Note on "site" kind: In the future, there will also be site level roles, like manager and viewer
// For now we only care if a user owns a site or not.
export type SiteUserRole =
| { kind: 'site'; role: 'owner' }
| { kind: 'project'; role: UserRole };
| { kind: 'site'; role: 'OWNER' }
| { kind: 'project'; role: ProjectRole };

const selectSiteId = (_state: any, siteId: string) => siteId;

Expand All @@ -189,7 +187,7 @@ export const selectUserRoleSite = createSelector(
return null;
}
if (site.ownerId === userId) {
return { kind: 'site', role: 'owner' };
return { kind: 'site', role: 'OWNER' };
}
if (site.projectId === undefined) {
return null;
Expand Down
17 changes: 17 additions & 0 deletions src/soilId/soilIdTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import type {
SoilDataNode,
SoilIdDepthDependentSoilDataRockFragmentVolumeChoices,
SoilIdDepthDependentSoilDataTextureChoices,
SoilIdProjectSoilSettingsDepthIntervalPresetChoices,
SoilIdProjectSoilSettingsMeasurementUnitsChoices,
SoilIdSoilDataSurfaceCracksSelectChoices,
} from 'terraso-client-shared/graphqlSchema/graphql';

Expand All @@ -50,6 +52,12 @@ export const collectionMethods = [
export type SoilPitMethod = (typeof soilPitMethods)[number];
export type CollectionMethod = (typeof collectionMethods)[number];

export type MeasurementUnit = SoilIdProjectSoilSettingsMeasurementUnitsChoices;
export const MEASUREMENT_UNITS = [
'METRIC',
'IMPERIAL',
] as const satisfies readonly MeasurementUnit[];

export { DepthInterval };
export type LabelledDepthInterval = {
label: string;
Expand Down Expand Up @@ -115,3 +123,12 @@ export const surfaceCracks = [
'SURFACE_CRACKING_ONLY',
'DEEP_VERTICAL_CRACKS',
] as const satisfies readonly SurfaceCracks[];

export type ProjectDepthIntervalPreset =
SoilIdProjectSoilSettingsDepthIntervalPresetChoices;
export const DEPTH_PRESETS = [
'LANDPKS',
'NRCS',
'CUSTOM',
'NONE',
] as const satisfies readonly ProjectDepthIntervalPreset[];

0 comments on commit 33509bf

Please sign in to comment.