Skip to content

Commit a149c82

Browse files
committed
Add ERU Capacity and it's filters
1 parent 86e9039 commit a149c82

File tree

13 files changed

+947
-113
lines changed

13 files changed

+947
-113
lines changed

app/src/views/EruReadinessForm/EruInputItem/index.tsx

+6-11
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ import {
66
TextArea,
77
} from '@ifrc-go/ui';
88
import { useTranslation } from '@ifrc-go/ui/hooks';
9-
import {
10-
isDefined,
11-
randomString,
12-
} from '@togglecorp/fujs';
9+
import { randomString } from '@togglecorp/fujs';
1310
import {
1411
type ArrayError,
1512
getErrorObject,
@@ -46,7 +43,7 @@ interface Props {
4643
index: number;
4744
value: PartialForm<EruType>;
4845
onChange: (value: SetValueArg<PartialForm<EruType>>, index: number) => void;
49-
title: Record<string, string> | undefined;
46+
title: string | undefined;
5047
error: ArrayError<EruType> | undefined;
5148
}
5249

@@ -70,17 +67,15 @@ function EruInputItem(props: Props) {
7067
onChange,
7168
defaultCollectionValue,
7269
);
73-
const eruTypeLabel = isDefined(value.type)
74-
? title?.[value.type]
75-
: undefined;
70+
7671
const error = (value && value.client_id && errorFromProps)
7772
? getErrorObject(errorFromProps?.[value.client_id])
7873
: undefined;
7974

8075
return (
8176
<Container
8277
childrenContainerClassName={styles.eruTypes}
83-
heading={eruTypeLabel}
78+
heading={title}
8479
>
8580
<InputSection
8681
className={styles.readinessOptions}
@@ -140,14 +135,14 @@ function EruInputItem(props: Props) {
140135
<Checkbox
141136
label={strings.eruLead}
142137
name="has_capacity_to_lead"
143-
value={value.has_capacity_to_lead}
138+
value={value?.has_capacity_to_lead}
144139
onChange={onFieldChange}
145140
error={error?.has_capacity_to_lead}
146141
/>
147142
<Checkbox
148143
label={strings.eruSupport}
149144
name="has_capacity_to_support"
150-
value={value.has_capacity_to_support}
145+
value={value?.has_capacity_to_support}
151146
onChange={onFieldChange}
152147
error={error?.has_capacity_to_support}
153148
/>

app/src/views/EruReadinessForm/i18n.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"eruFormCreatedSuccessfully": "ERU Readiness Created Successfully",
1212
"eruFormFailedToCreate": "Failed to create a ERU Readiness",
1313
"eruFormSuccessfullyUpdated": "Successfully Updated ERU Readiness Form",
14-
"eruFormFailedToUpdate": "Failed to Update ERU Readiness Form"
14+
"eruFormFailedToUpdate": "Failed to Update ERU Readiness Form",
15+
"eruNoRecord": "No Existing Record"
1516
}
1617
}

app/src/views/EruReadinessForm/index.tsx

+120-84
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {
22
useCallback,
3-
useMemo,
43
useState,
54
} from 'react';
65
import {
@@ -11,14 +10,9 @@ import {
1110
SelectInput,
1211
} from '@ifrc-go/ui';
1312
import { useTranslation } from '@ifrc-go/ui/hooks';
13+
import { stringValueSelector } from '@ifrc-go/ui/utils';
1414
import {
15-
numericKeySelector,
16-
stringValueSelector,
17-
} from '@ifrc-go/ui/utils';
18-
import {
19-
isDefined,
2015
isNotDefined,
21-
listToMap,
2216
randomString,
2317
} from '@togglecorp/fujs';
2418
import {
@@ -43,7 +37,6 @@ import EruInputItem from './EruInputItem';
4337
import schema, {
4438
type BaseFormType,
4539
type EruReadinessBody,
46-
type EruReadinessPostBody,
4740
} from './schema';
4841

4942
import i18n from './i18n.json';
@@ -63,13 +56,12 @@ function eruOwnerLabelSelector(option: EruOwnerOption) {
6356

6457
const defaultFormValues: PartialForm<EruReadinessBody> = {};
6558

59+
const eruTypeKeySelector = (eruType: EruTypeOption) => eruType.key;
60+
6661
/** @knipignore */
6762
// eslint-disable-next-line import/prefer-default-export
6863
export function Component() {
6964
const strings = useTranslation(i18n);
70-
// const { eruId } = useParams<{ eruId: number }>();
71-
// TODO: Use useParams for eruId
72-
const eruId = 1;
7365

7466
const alert = useAlertContext();
7567
const {
@@ -90,38 +82,19 @@ export function Component() {
9082

9183
const error = getErrorObject(formError);
9284

93-
const {
94-
pending: createEruReadinessPending,
95-
trigger: createEruReadiness,
96-
} = useLazyRequest({
97-
url: '/api/v2/eru-readiness/',
98-
method: 'POST',
99-
body: (ctx: EruReadinessPostBody) => ctx,
100-
onSuccess: () => {
101-
alert.show(
102-
strings.eruFormCreatedSuccessfully,
103-
{ variant: 'success' },
104-
);
105-
},
106-
onFailure: () => {
107-
alert.show(
108-
strings.eruFormFailedToCreate,
109-
{
110-
variant: 'danger',
111-
},
112-
);
113-
},
114-
});
85+
const [eruId, setEruId] = useState<number | undefined>();
86+
87+
const [selectedEruTypeList, setSelectedEruTypeList] = useState<EruTypeOption['key'][] | undefined>();
88+
89+
const [selectedEruOwner, setSelectedEruOwner] = useState<EruOwnerOption['id']>();
11590

11691
const {
11792
trigger: updateEruReadinessForm,
11893
pending: updateEruReadinessFormPending,
11994
} = useLazyRequest({
12095
url: '/api/v2/eru-readiness/{id}/',
12196
method: 'PATCH',
122-
pathVariables: isDefined(eruId) ? {
123-
id: Number(eruId),
124-
} : undefined,
97+
pathVariables: eruId !== undefined ? { id: Number(eruId) } : undefined,
12598
body: (ctx: EruReadinessBody) => ctx,
12699
onSuccess: () => {
127100
alert.show(
@@ -156,59 +129,86 @@ export function Component() {
156129
preserveResponse: true,
157130
});
158131

159-
const eruTypesTitleMap = useMemo(
160-
() => (
161-
listToMap(
162-
deployments_eru_type,
163-
(eruType) => eruType.key,
164-
(eruType) => eruType.value,
165-
)
166-
),
167-
[deployments_eru_type],
168-
);
132+
const {
133+
trigger: fetchEruReadinessData,
134+
pending: fetchEruReadinessDataPending,
135+
} = useLazyRequest({
136+
url: '/api/v2/eru-readiness/',
137+
query: (eruOwnerId: number) => ({ eru_owner: eruOwnerId }),
138+
onSuccess: (response) => {
139+
const results = response?.results ?? [];
140+
if (results?.length > 0) {
141+
const existingData = results[0];
142+
setEruId(existingData.id);
143+
setValue({
144+
...existingData,
145+
eru_owner: existingData.eru_owner_details?.id,
146+
eru_types: existingData.eru_types?.map((eruType) => ({
147+
...eruType,
148+
id: eruType.type,
149+
})),
150+
});
151+
setSelectedEruTypeList(existingData.eru_types?.map((eruType) => eruType.type));
152+
setSelectedEruOwner(existingData.eru_owner_details?.id);
153+
} else {
154+
setEruId(undefined);
155+
setValue({ ...defaultFormValues, eru_owner: undefined });
156+
setSelectedEruTypeList(undefined);
157+
setSelectedEruOwner(undefined);
158+
}
159+
},
160+
});
169161

170162
const {
171163
setValue: onEruChange,
172164
} = useFormArray('eru_types', setFieldValue);
173165

174166
const eruOwnerOption = eruOwnerResponse?.results;
175167

176-
const [selectedEruType, setSelectedEruType] = useState<EruTypeOption | undefined>();
177-
178-
const handleInputChange = useCallback((type: EruTypeOption['key']) => {
179-
const newEruTypeItem = {
180-
client_id: randomString(),
181-
type,
182-
id: eruId,
183-
};
184-
185-
setFieldValue(
186-
(oldValue: number[] | undefined) => (
187-
[...(oldValue ?? []), newEruTypeItem]
188-
),
189-
'eru_types' as const,
190-
);
191-
setSelectedEruType(undefined);
192-
}, [
193-
eruId,
194-
setFieldValue,
195-
]);
196-
197168
const handleSubmit = useCallback((finalValue: BaseFormType) => {
198169
setValue(finalValue);
199-
if (isNotDefined(finalValue)) {
170+
171+
if (isNotDefined(finalValue) || !finalValue.eru_owner) {
200172
return;
201173
}
174+
202175
if (isNotDefined(eruId)) {
203-
createEruReadiness(finalValue as EruReadinessPostBody);
204-
} else {
205-
updateEruReadinessForm(finalValue as EruReadinessBody);
176+
alert.show(
177+
strings.eruNoRecord,
178+
{ variant: 'warning' },
179+
);
180+
return;
206181
}
182+
183+
const updatedEruTypes = (selectedEruTypeList || []).map((type) => {
184+
const existingEru = finalValue.eru_types?.find((eruType) => eruType.type === type);
185+
186+
return {
187+
id: existingEru?.id ?? undefined,
188+
type,
189+
comment: existingEru?.comment ?? null,
190+
equipment_readiness: existingEru?.equipment_readiness ?? 1,
191+
people_readiness: existingEru?.people_readiness ?? 1,
192+
funding_readiness: existingEru?.funding_readiness ?? 1,
193+
has_capacity_to_lead: existingEru?.has_capacity_to_lead ?? false,
194+
has_capacity_to_support: existingEru?.has_capacity_to_support ?? false,
195+
};
196+
});
197+
198+
const updatedFinalValue: EruReadinessBody = {
199+
...finalValue,
200+
eru_types: updatedEruTypes,
201+
eru_owner: finalValue.eru_owner,
202+
};
203+
204+
updateEruReadinessForm(updatedFinalValue);
207205
}, [
206+
alert,
208207
setValue,
209-
createEruReadiness,
210208
updateEruReadinessForm,
211209
eruId,
210+
selectedEruTypeList,
211+
strings.eruNoRecord,
212212
]);
213213

214214
const handleSave = useCallback(() => {
@@ -224,16 +224,53 @@ export function Component() {
224224
handleSubmit,
225225
]);
226226

227-
const disabled = createEruReadinessPending || updateEruReadinessFormPending || eruOwnerPending;
227+
const disabled = updateEruReadinessFormPending
228+
|| eruOwnerPending || fetchEruReadinessDataPending;
228229

229230
const handleCancel = useCallback(() => {
230231
setFieldValue([], 'eru_types');
231-
setFieldValue(undefined, 'eru_owner');
232-
setSelectedEruType(undefined);
232+
setSelectedEruOwner(undefined);
233+
setSelectedEruTypeList(undefined);
233234
}, [
234235
setFieldValue,
235236
]);
236237

238+
const handleSelectERUType = useCallback((values: EruTypeOption['key'][] | undefined) => {
239+
setSelectedEruTypeList(values);
240+
241+
const existingEruTypeList = value.eru_types?.map((eruType) => eruType.id);
242+
const addedEruTypeList = values?.filter((v) => !existingEruTypeList?.includes(v));
243+
const removedEruTypeList = existingEruTypeList?.filter((v) => !values?.includes(v));
244+
245+
const addedEruTypeObjectList = addedEruTypeList?.map((a) => ({
246+
clientId: randomString(),
247+
id: a,
248+
type: a,
249+
}));
250+
251+
const newFieldValues = value.eru_types?.filter(
252+
(fv) => !removedEruTypeList?.includes(fv.id),
253+
);
254+
255+
setFieldValue([...(newFieldValues ?? []), ...(addedEruTypeObjectList ?? [])], 'eru_types');
256+
}, [value.eru_types, setFieldValue]);
257+
258+
const handleEruOwnerChange = useCallback(
259+
(newValue: number | undefined) => {
260+
setSelectedEruOwner(newValue);
261+
setFieldValue(newValue, 'eru_owner');
262+
263+
if (newValue) {
264+
setValue({});
265+
fetchEruReadinessData(newValue);
266+
} else {
267+
setValue({ ...defaultFormValues, eru_owner: undefined });
268+
setSelectedEruTypeList(undefined);
269+
}
270+
},
271+
[setFieldValue, fetchEruReadinessData, setValue],
272+
);
273+
237274
return (
238275
<Page
239276
className={styles.updateForm}
@@ -269,8 +306,8 @@ export function Component() {
269306
<SelectInput
270307
name="eru_owner"
271308
options={eruOwnerOption}
272-
onChange={setFieldValue}
273-
value={value.eru_owner}
309+
onChange={handleEruOwnerChange}
310+
value={selectedEruOwner}
274311
keySelector={eruOwnerKeySelector}
275312
labelSelector={eruOwnerLabelSelector}
276313
error={error?.eru_owner}
@@ -285,13 +322,10 @@ export function Component() {
285322
<MultiSelectInput
286323
name="eru_types"
287324
options={deployments_eru_type}
288-
value={selectedEruType}
289-
keySelector={numericKeySelector}
325+
value={selectedEruTypeList}
326+
keySelector={eruTypeKeySelector}
290327
labelSelector={stringValueSelector}
291-
onChange={(selected) => {
292-
const singleType = Array.isArray(selected) ? selected[0] : selected;
293-
handleInputChange(singleType);
294-
}}
328+
onChange={handleSelectERUType}
295329
disabled={disabled}
296330
/>
297331
</InputSection>
@@ -303,7 +337,9 @@ export function Component() {
303337
index={index}
304338
value={eruType}
305339
onChange={onEruChange}
306-
title={eruTypesTitleMap}
340+
title={deployments_eru_type?.find(
341+
(type) => type.key === eruType.type,
342+
)?.value}
307343
error={getErrorObject(error?.eru_types)}
308344
/>
309345
))}

0 commit comments

Comments
 (0)