Skip to content

Commit 97eda52

Browse files
Pre-fill school field if possible; minor refactor
1 parent 6b1495a commit 97eda52

3 files changed

Lines changed: 82 additions & 45 deletions

File tree

src/components/HelpMenu/HelpMenu.stories.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,18 @@ const BodyPortalGlobalStyle = createGlobalStyle`
1111
}
1212
`;
1313

14+
const contactParams = [
15+
{ key: 'userId', value: 'test' },
16+
{ key: 'userFirstName', value: 'test' },
17+
{ key: 'organizationName', value: 'org' },
18+
];
19+
1420
export const Default = () => {
1521
return (
1622
<BodyPortalSlotsContext.Provider value={['nav', 'root']}>
1723
<BodyPortalGlobalStyle />
1824
<NavBar logo>
19-
<HelpMenu contactFormParams={[{key: 'userId', value: 'test'}, {key: 'userFirstName', value: 'test'}]}>
25+
<HelpMenu contactFormParams={contactParams}>
2026
<HelpMenuItem onAction={() => window.alert('Ran HelpMenu callback function')}>
2127
Test Callback
2228
</HelpMenuItem>

src/components/HelpMenu/hooks.spec.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,10 +599,11 @@ describe('usePreChatFields', () => {
599599
(window as WindowWithEmbed).embeddedservice_bootstrap = mockService as any;
600600
})
601601

602-
it('sets hidden pre-chat fields', () => {
602+
it('sets pre-chat fields', () => {
603603
const fields = [
604604
{key: 'contextId', value: '1'},
605605
{key: 'userEmail', value: 't@t'},
606+
{key: 'organizationName', value: 'org'},
606607
{key: 'b', value: '2'},
607608
];
608609
const { unmount } = renderHook(() => usePreChatFields(fields));
@@ -620,6 +621,10 @@ describe('usePreChatFields', () => {
620621
Array [
621622
Array [
622623
Object {
624+
"School": Object {
625+
"isEditableByEndUser": true,
626+
"value": "org",
627+
},
623628
"_email": Object {
624629
"isEditableByEndUser": false,
625630
"value": "t@t",
@@ -636,6 +641,10 @@ Array [
636641
],
637642
Array [
638643
Object {
644+
"School": Object {
645+
"isEditableByEndUser": true,
646+
"value": "org",
647+
},
639648
"_email": Object {
640649
"isEditableByEndUser": false,
641650
"value": "t@t",
@@ -658,12 +667,14 @@ Array [
658667
Object {
659668
"Context_Id": "1",
660669
"Email": "t@t",
670+
"School": "org",
661671
},
662672
],
663673
Array [
664674
Object {
665675
"Context_Id": "1",
666676
"Email": "t@t",
677+
"School": "org",
667678
},
668679
],
669680
]
@@ -690,6 +701,10 @@ Array [
690701
Array [
691702
Array [
692703
Object {
704+
"School": Object {
705+
"isEditableByEndUser": true,
706+
"value": "",
707+
},
693708
"_email": Object {
694709
"isEditableByEndUser": true,
695710
"value": "",
@@ -706,6 +721,10 @@ Array [
706721
],
707722
Array [
708723
Object {
724+
"School": Object {
725+
"isEditableByEndUser": true,
726+
"value": "",
727+
},
709728
"_email": Object {
710729
"isEditableByEndUser": true,
711730
"value": "",

src/components/HelpMenu/hooks.ts

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -126,54 +126,66 @@ export const getChatEmbed = (
126126
return todaysHours ? { ...todaysHours, openChat } : null;
127127
};
128128

129+
// map assignable field name to Salesforce field name
130+
// These are currently defined in:
131+
// assignments/packages/frontend/src/components/SupportInfo.tsx
132+
const hiddenFieldsMapping = [
133+
['assignmentId', 'Assignment_Id'],
134+
['contextId', 'Context_Id'],
135+
['deploymentId', 'Deployment_Id'],
136+
['platformId', 'Platform_Id'],
137+
['registration', 'Registration_Id'],
138+
['organizationName', 'School'],
139+
['userEmail', 'Email'],
140+
['userFirstName', 'First_Name'],
141+
['userId', 'OpenStax_UUID'],
142+
['userLastName', 'Last_Name'],
143+
];
144+
145+
const mapHiddenFields = (supportInfoMapping: { [key: string]: string }) => (
146+
Object.fromEntries(
147+
hiddenFieldsMapping
148+
.map(([fromKey, toKey]) => [toKey, supportInfoMapping[fromKey]])
149+
.filter((tuple): tuple is [string, string] =>
150+
typeof tuple[0] === 'string' && typeof tuple[1] == 'string'
151+
)
152+
)
153+
);
154+
155+
const mapVisibleFields = (supportInfoMapping: { [key: string]: string }) => {
156+
// userFirstName, userLastName are from accounts
157+
const {
158+
userName, userFirstName, userLastName, userEmail, organizationName
159+
} = supportInfoMapping;
160+
const nameParts = userName?.split(' ') ?? [];
161+
// Multiple first names?
162+
const firstName = userFirstName ?? nameParts.slice(0, -1).join(' ');
163+
// Hopefully no middle name
164+
const lastName = userLastName ?? nameParts.slice(-1).join('');
165+
// Fields that start with '_' are standard, non-custom fields
166+
// If we don't get the info from accounts, then the field should be editable
167+
const visibleEntries: [string, string, boolean][] = [
168+
['_firstName', firstName, userFirstName === undefined],
169+
['_lastName', lastName, userLastName === undefined],
170+
['_email', userEmail ?? '', userEmail === undefined],
171+
['School', organizationName ?? '', true],
172+
];
173+
return Object.fromEntries(
174+
visibleEntries.map(([key, value, isEditableByEndUser]) => [
175+
key, { value, isEditableByEndUser }
176+
])
177+
);
178+
};
179+
129180
export const usePreChatFields = (contactFormParams: { key: string, value: string }[]) => {
130-
const { visibleFields, hiddenFields } = React.useMemo(() => {
131-
// map assignable field name to Salesforce field name
132-
// These are currently defined in:
133-
// assignments/packages/frontend/src/components/SupportInfo.tsx
134-
const hiddenFieldsMapping = [
135-
['assignmentId', 'Assignment_Id'],
136-
['contextId', 'Context_Id'],
137-
['deploymentId', 'Deployment_Id'],
138-
['platformId', 'Platform_Id'],
139-
['registration', 'Registration_Id'],
140-
['schoolName', 'School'],
141-
['userEmail', 'Email'],
142-
['userFirstName', 'First_Name'],
143-
['userId', 'OpenStax_UUID'],
144-
['userLastName', 'Last_Name'],
145-
];
181+
const { visibleFields, hiddenFields } = React.useMemo(() => {
146182
const supportInfoMapping = Object.fromEntries(
147183
contactFormParams.map(({key, value}) => [key, value])
148184
);
149-
const hiddenFields = Object.fromEntries(
150-
hiddenFieldsMapping
151-
.map(([fromKey, toKey]) => [toKey, supportInfoMapping[fromKey]])
152-
.filter((tuple): tuple is [string, string] => tuple[1] !== undefined)
153-
);
154-
const { userName, userFirstName, userLastName, userEmail } = supportInfoMapping;
155-
const nameParts = userName?.split(' ') ?? [];
156-
// Multiple first names?
157-
const firstName = userFirstName ?? nameParts.slice(0, -1).join(' ');
158-
// Hopefully no middle name
159-
const lastName = userLastName ?? nameParts.slice(-1).join('');
160-
// Unless we used the name from accounts, assume we are wrong and allow
161-
// the user to edit it
162-
const visibleFields = {
163-
_firstName: {
164-
value: firstName,
165-
isEditableByEndUser: userFirstName === undefined,
166-
},
167-
_lastName: {
168-
value: lastName,
169-
isEditableByEndUser: userLastName === undefined,
170-
},
171-
_email: {
172-
value: userEmail ?? '',
173-
isEditableByEndUser: userEmail === undefined,
174-
},
185+
return {
186+
visibleFields: mapVisibleFields(supportInfoMapping),
187+
hiddenFields: mapHiddenFields(supportInfoMapping),
175188
};
176-
return { visibleFields, hiddenFields };
177189
}, [contactFormParams]);
178190
const ready = React.useRef(false);
179191

0 commit comments

Comments
 (0)