Skip to content

Commit 1930a98

Browse files
authored
Merge pull request #1647 from SeedCompany/type-and-reach-partner-profile
2 parents cc9616f + fe50384 commit 1930a98

File tree

6 files changed

+140
-3
lines changed

6 files changed

+140
-3
lines changed

src/scenes/Partners/Detail/PartnerDetail.graphql

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@ query Partner($input: ID!) {
66

77
fragment partnerDetails on Partner {
88
...Id
9-
createdAt
9+
...partnerOwnDetails
1010
organization {
1111
canRead
1212
canEdit
1313
value {
1414
...organizationDetails
1515
}
1616
}
17+
}
18+
19+
# Seperated for UpdatePartner mutation
20+
fragment partnerOwnDetails on Partner {
21+
...Id
22+
createdAt
1723
pointOfContact {
1824
canRead
1925
canEdit
@@ -72,4 +78,14 @@ fragment organizationDetails on Organization {
7278
canEdit
7379
value
7480
}
81+
types {
82+
canRead
83+
canEdit
84+
value
85+
}
86+
reach {
87+
canRead
88+
canEdit
89+
value
90+
}
7591
}

src/scenes/Partners/Detail/Tabs/Profile/PartnerDetailProfile.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { TabPanelContent } from '~/components/Tabs';
55
import { EditablePartnerField } from '../../../Edit';
66
import { PartnerDetailsFragment } from '../../PartnerDetail.graphql';
77
import { PartnerContactSection } from './PartnerContactSection';
8+
import { PartnerOrgReachAndTypeSection } from './PartnerOrgReachAndTypeSection';
89
import { PartnerTypesSection } from './PartnerTypesSection';
910

1011
interface Props {
@@ -35,6 +36,12 @@ export const PartnerDetailProfile = ({ partner, editPartner: edit }: Props) => (
3536
}
3637
/>
3738
</Grid>
39+
<Grid xs={12} md={6}>
40+
<PartnerOrgReachAndTypeSection
41+
partner={partner}
42+
onEdit={() => edit(['organization.types', 'organization.reach'])}
43+
/>
44+
</Grid>
3845
</Grid>
3946
</TabPanelContent>
4047
);
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { Edit } from '@mui/icons-material';
2+
import { Stack, Tooltip } from '@mui/material';
3+
import {
4+
OrganizationReachLabels,
5+
OrganizationTypeLabels,
6+
} from '~/api/schema.graphql';
7+
import { canEditAny, labelFrom } from '~/common';
8+
import { ActionableSection } from '~/components/ActionableSection';
9+
import { IconButton } from '~/components/IconButton';
10+
import { PartnerDetailsFragment } from '../../PartnerDetail.graphql';
11+
import { DisplaySecuredList } from './PartnerTypesSection';
12+
13+
interface PartnerOrgReachAndTypeProps {
14+
partner?: PartnerDetailsFragment;
15+
onEdit: () => void;
16+
className?: string;
17+
}
18+
19+
export const PartnerOrgReachAndTypeSection = ({
20+
partner,
21+
onEdit,
22+
}: PartnerOrgReachAndTypeProps) => {
23+
const canEdit = canEditAny(
24+
partner?.organization.value,
25+
false,
26+
'types',
27+
'reach'
28+
);
29+
30+
return (
31+
<ActionableSection
32+
title="Additional Information"
33+
loading={!partner}
34+
action={
35+
<Tooltip title="Edit">
36+
<span>
37+
<IconButton
38+
disabled={!canEdit}
39+
onClick={onEdit}
40+
loading={!partner}
41+
size="small"
42+
>
43+
<Edit />
44+
</IconButton>
45+
</span>
46+
</Tooltip>
47+
}
48+
>
49+
<Stack
50+
direction="row"
51+
columnGap={4}
52+
rowGap={3}
53+
justifyContent="space-between"
54+
flexWrap="wrap"
55+
maxWidth={350}
56+
>
57+
<DisplaySecuredList
58+
title="Organizational Types"
59+
data={partner?.organization.value?.types}
60+
labelBy={labelFrom(OrganizationTypeLabels)}
61+
redacted={{ fieldDescription: `organizational types` }}
62+
/>
63+
<DisplaySecuredList
64+
title="Reach"
65+
data={partner?.organization.value?.reach}
66+
labelBy={labelFrom(OrganizationReachLabels)}
67+
redacted={{
68+
fieldDescription: `partner's reach`,
69+
width: `75%`,
70+
}}
71+
/>
72+
</Stack>
73+
</ActionableSection>
74+
);
75+
};

src/scenes/Partners/Detail/Tabs/Profile/PartnerTypesSection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export const PartnerTypesSection = ({
7575
);
7676
};
7777

78-
const DisplaySecuredList = <T extends string>({
78+
export const DisplaySecuredList = <T extends string>({
7979
title,
8080
data,
8181
labelBy,

src/scenes/Partners/Edit/EditPartner.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import {
88
CoerceNonPrimitives,
99
FinancialReportingTypeLabels,
1010
FinancialReportingTypeList,
11+
OrganizationReachLabels,
12+
OrganizationReachList,
13+
OrganizationTypeLabels,
14+
OrganizationTypeList,
1115
PartnerTypeList,
1216
UpdateOrganization,
1317
UpdatePartner,
@@ -108,6 +112,26 @@ const fieldMapping = {
108112
'organization.acronym': ({ props }) => (
109113
<TextField {...props} label="Acronym" />
110114
),
115+
'organization.reach': ({ props }) => (
116+
<EnumField
117+
multiple
118+
label="Reach"
119+
options={OrganizationReachList}
120+
getLabel={labelFrom(OrganizationReachLabels)}
121+
layout="column"
122+
{...props}
123+
/>
124+
),
125+
'organization.types': ({ props }) => (
126+
<EnumField
127+
multiple
128+
label="Organizational Types"
129+
options={OrganizationTypeList}
130+
getLabel={labelFrom(OrganizationTypeLabels)}
131+
layout="two-column"
132+
{...props}
133+
/>
134+
),
111135
} satisfies PossibleFields;
112136

113137
const decorators: Array<Decorator<PartnerFormValues>> = [
@@ -151,6 +175,8 @@ export const EditPartner = ({
151175
id: organization.id,
152176
name: organization.name.value,
153177
acronym: organization.acronym.value,
178+
types: organization.types.value,
179+
reach: organization.reach.value,
154180
},
155181
} satisfies PartnerFormValues;
156182
}, [partner]);

src/scenes/Partners/Edit/UpdatePartner.graphql

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,20 @@ mutation UpdatePartner(
44
) {
55
updatePartner(input: { partner: $partner }) {
66
partner {
7-
...partnerDetails
7+
# Organization data cannot be fetched here as it will be stale.
8+
#
9+
# The API executes these two mutations in parallel, independently.
10+
# `Partner.organization` doesn't know it there's another organization update going on,
11+
# and will return the stale data.
12+
# Apollo Client would then receive two sets of org data:
13+
# - `updateOrganization.organization` result
14+
# - `updatePartner.partner.organization` result
15+
# They will be conflict, with the former fresh, and the latter stale.
16+
# We can avoid this race / nondeterministic behavior by only returning one org data set.
17+
#
18+
# Also, Apollo Client still has the normalized organization for the partner record,
19+
# so it knows how to connect it together when requested for the detail page.
20+
...partnerOwnDetails
821
}
922
}
1023
updateOrganization(input: { organization: $organization }) {

0 commit comments

Comments
 (0)