Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: define more types and enums #359

Merged
merged 4 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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',
shrouxm marked this conversation as resolved.
Show resolved Hide resolved
] 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[];
Loading