Author:
Siarhei Vaitsiakhovich
Changed on:
7 July 2024
To ensure a seamless experience for users managing customers' address information, the following use cases outline the process for adding and editing customer addresses:
The feature can be implemented via the declaration of a custom mutation user actions
`createCustomerAddress`
`updateCustomerAddress`
For a better user experience, part of the default mutation field components have to be overridden. List of fields to override:
Additionally, the fields have to be reordered to enhance the logical flow of the user interface, making it more intuitive for users to navigate and input their information efficiently. New fields order:
To save data consistency, options for Timezone and Country selectors have to be loaded from settings. For 'Edit Customer Address' action, all fields have to be prefilled with current user information.
To support the business solution design, the following technical areas need to be enhanced:
`SettingBaseStringSelector`
Each of these tasks will be described below in steps.
`SettingBaseStringSelector`
Create a new file:
`SettingBaseStringSelector.tsx`
1const SettingBaseStringSelector: FC<FormFieldProps<any>> = (props) => {
2 const auth = useAuth();
3
4 const settingName = props.extensions?.settingName;
5 const [items, setItems] = useState<string[]>([]);
6 const [currentItem, setCurrentItem] = useState<string | undefined>(
7 props.value,
8 );
9
10 useEffect(() => {
11 if (settingName) {
12 getSettings(
13 { setting: settingName },
14 parseInt(auth.context.current.contextId),
15 ).then((value) => {
16 if (value.setting.status == 'ok') {
17 const list: string[] = [...value.setting.result.value];
18 if (props.value && !list.includes(props.value)) {
19 list.push(props.value);
20 }
21 setItems(list);
22 }
23 });
24 } else {
25 setItems([]);
26 }
27 }, [settingName]);
28
29 useEffect(() => {
30 if (currentItem) {
31 props.onChange(currentItem);
32 } else {
33 props.onChange(undefined);
34 }
35 }, [currentItem]);
36
37 const handleChange = (event: any) => {
38 setCurrentItem(event.target.value as string);
39 };
40
41 const handleOnBlur = () => {
42 props && props.onBlur && props.onBlur();
43 };
44
45 return (
46 <FormControl fullWidth error={!!props.error}>
47 <InputLabel id="string-select-label">{props.label}</InputLabel>
48 <Select
49 labelId="string-select-label"
50 id="string-select"
51 label={props.label}
52 onChange={handleChange}
53 onBlur={handleOnBlur}
54 value={currentItem}
55 >
56 {items.map((value, idx) => {
57 return (
58 <MenuItem key={idx} value={value} selected={currentItem === value}>
59 {value}
60 </MenuItem>
61 );
62 })}
63 </Select>
64 {props.error && <FormHelperText>{props.error}</FormHelperText>}
65 </FormControl>
66 );
67};
68
69export default SettingBaseStringSelector;
Language: typescript
Name: SettingBaseStringSelector.tsx
Description:
SettingBaseStringSelector component implementation example
1FieldRegistry.register(
2 ['settingBaseStringSelector'],
3 SettingBaseStringSelector,
4);
Language: typescript
Name: index.tsx
Description:
SettingBaseStringSelector field component registration
`EDIT_LOCATION_COUNTRIES`
Name | EDIT_LOCATION_COUNTRIES |
Value Type | JSON |
Context | ACCOUNT or RETAILER |
Context ID | 0 or Retailer ID |
JSON Value | [ "Australia", "Canada", "France", "Germany", "United Kingdom", "United States" ] |
`EDIT_LOCATION_TIME_ZONES`
Name | EDIT_LOCATION_TIME_ZONES |
Value Type | JSON |
Context | ACCOUNT or RETAILER |
Context ID | 0 or Retailer ID |
JSON Value | [ "GMT", "UTC", "ECT", "EET", "ACT", "AET", "HST", "AST", "PST", "PNT", "MST", "CST", "EST", "IET", "PRT", "CNT" ] |
`Add and Edit Customer Address`
`Add Customer Address`
`Edit Customer Address`
`createCustomerAddress`
`updateCustomerAddress`
`condition`
`Add Customer Address`
`Edit Customer Address`
1{
2 "type": "mutation",
3 "label": "Add Customer Address",
4 "name": "createCustomerAddress",
5 "condition": "{{eq customerAddresses.edges.length 0}}",
6 "filter": {
7 "type": "exclude",
8 "names": [
9 "latitude",
10 "longitude"
11 ]
12 },
13 "overrides": {
14 "ref": {
15 "sortPrefix": 11
16 },
17 "companyName": {
18 "sortPrefix": 12
19 },
20 "street": {
21 "sortPrefix": 13
22 },
23 "city": {
24 "sortPrefix": 14
25 },
26 "state": {
27 "sortPrefix": 15
28 },
29 "postcode": {
30 "sortPrefix": 16
31 },
32 "region": {
33 "sortPrefix": 17
34 },
35 "country": {
36 "sortPrefix": 18,
37 "component": "settingBaseStringSelector",
38 "extensions": {
39 "settingName": "EDIT_LOCATION_COUNTRIES"
40 }
41 },
42 "timeZone": {
43 "sortPrefix": 19,
44 "component": "settingBaseStringSelector",
45 "extensions": {
46 "settingName": "EDIT_LOCATION_TIME_ZONES"
47 }
48 },
49 "name": {
50 "component": "input",
51 "sortPrefix": 20,
52 "options": [
53 {
54 "label": "Customer Name",
55 "value": "{{customerById.firstName}} {{customerById.lastName}}"
56 }
57 ]
58 }
59 }
60},
61{
62 "type": "mutation",
63 "label": "Edit Customer Address",
64 "name": "updateCustomerAddress",
65 "condition": "{{gt customerAddresses.edges.length 0}}",
66 "filter": {
67 "type": "exclude",
68 "names": [
69 "name",
70 "latitude",
71 "longitude"
72 ]
73 },
74 "args": {
75 "id": "{{customerAddresses.edges.0.node.id}}"
76 },
77 "overrides": {
78 "companyName": {
79 "sortPrefix": 12
80 },
81 "street": {
82 "sortPrefix": 13
83 },
84 "city": {
85 "sortPrefix": 14
86 },
87 "state": {
88 "sortPrefix": 15
89 },
90 "postcode": {
91 "sortPrefix": 16
92 },
93 "region": {
94 "sortPrefix": 17
95 },
96 "country": {
97 "sortPrefix": 18,
98 "component": "settingBaseStringSelector",
99 "extensions": {
100 "settingName": "EDIT_LOCATION_COUNTRIES"
101 }
102 },
103 "timeZone": {
104 "sortPrefix": 19,
105 "component": "settingBaseStringSelector",
106 "extensions": {
107 "settingName": "EDIT_LOCATION_TIME_ZONES"
108 }
109 },
110 "name": {
111 "component": "input",
112 "sortPrefix": 20,
113 "options": [
114 {
115 "label": "Customer Name",
116 "value": "{{customerById.firstName}} {{customerById.lastName}}"
117 }
118 ]
119 }
120 }
121}
122
123
Language: json
Name: Add and Edit Customer Address actions
Description:
Add and Edit Customer Address mutation user actions declaration example. Property
`sortPrefix`
Localization of fields is done by creating localization entries for mutation fields according to name convention (see Languages and Localisation, chapter 'Adding new Mutation Actions').
1{
2 "translation": {
3 "fc.gql.customerAddress.ref": "Ref",
4 "fc.gql.customerAddress.companyName": "Company Name",
5 "fc.gql.customerAddress.street": "Street",
6 "fc.gql.customerAddress.city": "City",
7 "fc.gql.customerAddress.state": "State",
8 "fc.gql.customerAddress.postcode": "Postcode",
9 "fc.gql.customerAddress.region": "Region",
10 "fc.gql.customerAddress.country": "Country",
11 "fc.gql.customerAddress.timeZone": "Timezone"
12 }
13}
Language: json
Name: New localization entries
Description:
Example of mutation field labels localisation with using name convention
After all steps,
`Add Customer Address`
`Edit Customer Address`
`Add Customer Address`
`Edit Customer Address`
Copyright © 2024 Fluent Retail Pty Ltd (trading as Fluent Commerce). All rights reserved. No materials on this docs.fluentcommerce.com site may be used in any way and/or for any purpose without prior written authorisation from Fluent Commerce. Current customers and partners shall use these materials strictly in accordance with the terms and conditions of their written agreements with Fluent Commerce or its affiliates.