Skip to content
Open
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
11 changes: 10 additions & 1 deletion src/api/schema/typePolicies/typePolicies.base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,19 @@ export const typePolicies: TypePolicies = {
engagements: {},
},
},
FieldRegion: {
fields: {
projects: {}, // no page merging (infinite scroll)
},
},
FieldZone: {
fields: {
projects: {}, // no page merging (infinite scroll)
},
},
Query: {
fields: {
projects: {},
engagements: {},
progressReports: {},
partners: {},
users: {},
Expand Down
17 changes: 17 additions & 0 deletions src/components/EngagementDataGrid/EngagementColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,25 @@ export const EngagementColumns: Array<GridColDef<Engagement>> = [
headerName: 'Country',
field: 'project.primaryLocation.name',
...textColumn(),
width: 250,
valueGetter: (_, row) => row.project.primaryLocation.value?.name.value,
},
{
field: 'project.fieldRegion.name',
headerName: 'Field Region',
...textColumn(),
width: 250,
valueGetter: (_, { project }) => project.fieldRegion.value?.name.value,
renderCell: ({ row: engagement }) => {
const { fieldRegion } = engagement.project;

return fieldRegion.value ? (
<Link to={`/field-regions/${fieldRegion.value.id}`}>
{fieldRegion.value.name.value}
</Link>
) : null;
},
},
{
headerName: 'ISO',
description: 'Ethnologue Code',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ fragment engagementDataGridRow on Engagement {
endDate {
value
}

project {
id
type
Expand All @@ -27,6 +26,14 @@ fragment engagementDataGridRow on Engagement {
}
}
}
fieldRegion {
value {
id
name {
value
}
}
}
mouStart {
value
}
Expand Down
16 changes: 16 additions & 0 deletions src/components/ProjectDataGrid/ProjectColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from '../Grid';
import { ProjectNameColumn } from '../Grid/Columns/ProjectNameColumn';
import { SensitivityColumn } from '../Grid/Columns/SensitivityColumn';
import { Link } from '../Routing';
import { ProjectDataGridRowFragment as Project } from './projectDataGridRow.graphql';

export const ProjectColumns: Array<GridColDef<Project>> = [
Expand All @@ -43,6 +44,21 @@ export const ProjectColumns: Array<GridColDef<Project>> = [
headerName: 'Country',
width: 300,
},
{
field: 'fieldRegion.name',
headerName: 'Field Region',
...textColumn(),
width: 250,
valueGetter: (_, { fieldRegion }) => fieldRegion.value?.name.value,
renderCell: ({ row: project }) => {
const { fieldRegion } = project;
return fieldRegion.value ? (
<Link to={`/field-regions/${fieldRegion.value.id}`}>
{fieldRegion.value.name.value}
</Link>
) : null;
},
},
{
field: 'step',
...enumColumn(ProjectStepList, ProjectStepLabels, {
Expand Down
9 changes: 9 additions & 0 deletions src/components/ProjectDataGrid/projectDataGridRow.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,21 @@ fragment projectDataGridRow on Project {
}
}
}
fieldRegion {
value {
id
name {
value
}
}
}
mouStart {
value
}
mouEnd {
value
}

isMember
pinned
}
153 changes: 49 additions & 104 deletions src/scenes/FieldRegions/Detail/FieldRegionDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,154 +1,99 @@
import { useQuery } from '@apollo/client';
import { Edit } from '@mui/icons-material';
import { Box, Skeleton, Typography } from '@mui/material';
import { TabContext, TabList, TabPanel } from '@mui/lab';
import { Box, Skeleton, Stack, Typography } from '@mui/material';
import { Helmet } from 'react-helmet-async';
import { useParams } from 'react-router-dom';
import { canEditAny } from '~/common';
import { useDialog } from '~/components/Dialog';
import {
DisplaySimpleProperty,
DisplaySimplePropertyProps,
} from '~/components/DisplaySimpleProperty';
import { EditFieldRegion } from '~/components/FieldRegion';
import { Link } from '~/components/Routing';
import { Tab, TabsContainer } from '~/components/Tabs';
import { EnumParam, makeQueryHandler, withDefault } from '~/hooks';
import { Error } from '../../../components/Error';
import { Fab } from '../../../components/Fab';
import { Redacted } from '../../../components/Redacted';
import { FieldRegionDetailDocument } from './FieldRegionDetail.graphql';
import { FieldRegionProfile } from './Tabs/Profile/FieldRegionProfile';
import { FieldRegionProjects } from './Tabs/Projects/FieldRegionProjects';

const useFieldRegionDetailsFilters = makeQueryHandler({
tab: withDefault(EnumParam(['profile', 'projects']), 'profile'),
});

export const FieldRegionDetail = () => {
const { fieldRegionId = '' } = useParams();

const [editRegionState, editRegion] = useDialog();

const { data, error } = useQuery(FieldRegionDetailDocument, {
const { data, error, loading } = useQuery(FieldRegionDetailDocument, {
variables: { fieldRegionId },
});

const [filters, setFilters] = useFieldRegionDetailsFilters();

const fieldRegion = data?.fieldRegion;

return (
<Box
<Stack
component="main"
sx={{
flex: 1,
overflowY: 'auto',
p: 4,
gap: 3,
flex: 1,
maxWidth: (theme) => theme.breakpoints.values.xl,
}}
>
<Helmet title={fieldRegion?.name.value || undefined} />
<Error error={error}>
{{
NotFound: 'Could not find field region',
Default: 'Error loading field region',
}}
</Error>
<Helmet title={fieldRegion?.name.value ?? undefined} />

{!error && (
<Box
sx={{
maxWidth: (theme) => theme.breakpoints.values.md,
display: 'flex',
flexDirection: 'column',
gap: 3,
}}
>
<>
<Box
component="header"
sx={{
flex: 1,
display: 'flex',
gap: 1,
}}
>
<Typography
variant="h2"
sx={{
mr: 4,
width: !fieldRegion?.name.value ? '40%' : undefined,
mr: 2,
lineHeight: 'inherit',
}}
>
{!fieldRegion ? (
<Skeleton width="100%" />
{loading ? (
<Skeleton width={200} />
) : !fieldRegion ? (
<Skeleton width={200} />
) : (
fieldRegion.name.value ?? (
<Redacted
info="You don't have permission to view this field region's name"
width="40%"
width="20ch"
/>
)
)}
</Typography>
{canEditAny(fieldRegion, true) && (
<Fab
color="primary"
aria-label="edit region"
onClick={editRegion}
loading={!fieldRegion}
>
<Edit />
</Fab>
)}
</Box>
<Box
sx={{
display: 'flex',
}}
>
<Typography variant="h4">
{fieldRegion ? 'Field Region' : <Skeleton width={200} />}
</Typography>
</Box>
<DisplayProperty
label="Field Zone"
value={
<Link to={`/field-zones/${fieldRegion?.fieldZone.value?.id}`}>
{fieldRegion?.fieldZone.value?.name.value}
</Link>
}
loading={!fieldRegion}
/>
<DisplayProperty
label="Director"
value={
<Link to={`/users/${fieldRegion?.director.value?.id}`}>
{fieldRegion?.director.value?.fullName}
</Link>
}
loading={!fieldRegion}
/>
</Box>
)}
{fieldRegion && (
<EditFieldRegion fieldRegion={fieldRegion} {...editRegionState} />
<TabsContainer>
<TabContext value={filters.tab}>
<TabList
onChange={(_e, tab) => setFilters({ ...filters, tab })}
aria-label="field region navigation tabs"
variant="scrollable"
>
<Tab label="Profile" value="profile" />
<Tab label="Projects" value="projects" />
</TabList>
<TabPanel value="profile">
<FieldRegionProfile fieldRegion={fieldRegion} />
</TabPanel>
<TabPanel value="projects">
<FieldRegionProjects />
</TabPanel>
</TabContext>
</TabsContainer>
</>
)}
</Box>
</Stack>
);
};

const DisplayProperty = (props: DisplaySimplePropertyProps) =>
!props.value && !props.loading ? null : (
<DisplaySimpleProperty
variant="body1"
{...{ component: 'div' }}
{...props}
loading={
props.loading ? (
<>
<Typography variant="body2">
<Skeleton width="10%" />
</Typography>
<Typography variant="body1">
<Skeleton width="40%" />
</Typography>
</>
) : null
}
LabelProps={{
color: 'textSecondary',
variant: 'body2',
...props.LabelProps,
}}
ValueProps={{
color: 'textPrimary',
...props.ValueProps,
}}
/>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fragment FieldRegionProfile on FieldRegion {
...DisplayFieldRegion
...FieldRegionForm
}
Loading
Loading