@iapps/ng-dhis2-ui 1.1.67 → 1.1.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -8,7 +8,7 @@ import { NgxDhis2HttpClientService } from '@iapps/ngx-dhis2-http-client';
|
|
|
8
8
|
import * as React from 'react';
|
|
9
9
|
import React__default, { useState, useCallback, useRef, useEffect, createContext, useContext, useMemo } from 'react';
|
|
10
10
|
import * as ReactDOM from 'react-dom/client';
|
|
11
|
-
import { catchError, of, map, zip, firstValueFrom, filter, Subject, takeUntil } from 'rxjs';
|
|
11
|
+
import { catchError, of, map, zip, firstValueFrom, take, filter, Subject, takeUntil } from 'rxjs';
|
|
12
12
|
import i18n from '@dhis2/d2-i18n';
|
|
13
13
|
import { colors, theme, spacers } from '@dhis2/ui-constants';
|
|
14
14
|
import PropTypes from 'prop-types';
|
|
@@ -3446,31 +3446,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
3446
3446
|
type: Injectable
|
|
3447
3447
|
}], ctorParameters: () => [{ type: i1.NgxDhis2HttpClientService }] });
|
|
3448
3448
|
|
|
3449
|
-
const getProgramStageData = (
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
}
|
|
3449
|
+
// export const getProgramStageData = (
|
|
3450
|
+
// response: LineListResponse,
|
|
3451
|
+
// programStageId: string,
|
|
3452
|
+
// pager: any,
|
|
3453
|
+
// isOptionSetNameVisible: boolean
|
|
3454
|
+
// ): { columns: ColumnDefinition[]; data: TableRow[] } => {
|
|
3455
|
+
// const events = (response.data as EventsResponse).events;
|
|
3456
|
+
// const allDataElements = new Set<string>();
|
|
3457
|
+
// events.forEach((event: any) => {
|
|
3458
|
+
// event.dataValues.forEach((dv: any) => allDataElements.add(dv.dataElement));
|
|
3459
|
+
// });
|
|
3460
|
+
// const stageFromMetaData = response.metadata.programStages.find(
|
|
3461
|
+
// (stage: any) => stage.id === programStageId
|
|
3462
|
+
// );
|
|
3463
|
+
// if (!stageFromMetaData) {
|
|
3464
|
+
// throw new Error(`Program stage with ID ${programStageId} not found`);
|
|
3465
|
+
// }
|
|
3466
|
+
// const entityColumns = Array.from(allDataElements).map(
|
|
3467
|
+
// (dataElementId: string) => ({
|
|
3468
|
+
// label:
|
|
3469
|
+
// stageFromMetaData.programStageDataElements.find(
|
|
3470
|
+
// (psde: any) => psde.dataElement.id === dataElementId
|
|
3471
|
+
// )?.dataElement.name || dataElementId,
|
|
3472
|
+
// key: dataElementId,
|
|
3473
|
+
// })
|
|
3474
|
+
// );
|
|
3475
|
+
// const dataElementsData: TableRow[] = events.map((event: any, idx: number) => {
|
|
3476
|
+
// const row: TableRow = {
|
|
3477
|
+
// event: event.event,
|
|
3478
|
+
// index: (pager.page - 1) * pager.pageSize + idx + 1,
|
|
3479
|
+
// };
|
|
3480
|
+
// allDataElements.forEach(
|
|
3481
|
+
// (dataElementId: string) => (row[dataElementId] = '')
|
|
3482
|
+
// );
|
|
3483
|
+
// if (isOptionSetNameVisible) {
|
|
3484
|
+
// event.dataValues.forEach((dv: any) => (row[dv.dataElement] = dv.value));
|
|
3485
|
+
// } else {
|
|
3486
|
+
// event.dataValues.forEach((dv: any) => (row[dv.dataElement] = dv.value));
|
|
3487
|
+
// }
|
|
3488
|
+
// return row;
|
|
3489
|
+
// });
|
|
3490
|
+
// return { columns: entityColumns, data: dataElementsData };
|
|
3491
|
+
// };
|
|
3474
3492
|
// export const getTrackedEntityData = (
|
|
3475
3493
|
// response: LineListResponse,
|
|
3476
3494
|
// programId: string,
|
|
@@ -3603,6 +3621,44 @@ const getProgramStageData = (response, programStageId, pager) => {
|
|
|
3603
3621
|
// filteredEntityColumns: filteredEntityColumns,
|
|
3604
3622
|
// };
|
|
3605
3623
|
// };
|
|
3624
|
+
const getProgramStageData = (response, programStageId, pager, isOptionSetNameVisible) => {
|
|
3625
|
+
const events = response.data.events;
|
|
3626
|
+
const allDataElements = new Set();
|
|
3627
|
+
events.forEach((event) => {
|
|
3628
|
+
event.dataValues.forEach((dv) => allDataElements.add(dv.dataElement));
|
|
3629
|
+
});
|
|
3630
|
+
const stageFromMetaData = response.metadata.programStages.find((stage) => stage.id === programStageId);
|
|
3631
|
+
if (!stageFromMetaData) {
|
|
3632
|
+
throw new Error(`Program stage with ID ${programStageId} not found`);
|
|
3633
|
+
}
|
|
3634
|
+
const entityColumns = Array.from(allDataElements).map((dataElementId) => {
|
|
3635
|
+
const dataElementMeta = stageFromMetaData.programStageDataElements.find((psde) => psde.dataElement.id === dataElementId);
|
|
3636
|
+
return {
|
|
3637
|
+
label: dataElementMeta?.dataElement.name || dataElementId,
|
|
3638
|
+
key: dataElementId,
|
|
3639
|
+
};
|
|
3640
|
+
});
|
|
3641
|
+
const dataElementsData = events.map((event, idx) => {
|
|
3642
|
+
const row = {
|
|
3643
|
+
event: event.event,
|
|
3644
|
+
index: (pager.page - 1) * pager.pageSize + idx + 1,
|
|
3645
|
+
};
|
|
3646
|
+
allDataElements.forEach((dataElementId) => (row[dataElementId] = ''));
|
|
3647
|
+
event.dataValues.forEach((dv) => {
|
|
3648
|
+
const dataElementMeta = stageFromMetaData.programStageDataElements.find((psde) => psde.dataElement.id === dv.dataElement);
|
|
3649
|
+
if (isOptionSetNameVisible && dataElementMeta?.dataElement.optionSet) {
|
|
3650
|
+
const optionSet = dataElementMeta.dataElement.optionSet;
|
|
3651
|
+
const matchingOption = optionSet.options.find((option) => option.code === dv.value);
|
|
3652
|
+
row[dv.dataElement] = matchingOption ? matchingOption.name : dv.value;
|
|
3653
|
+
}
|
|
3654
|
+
else {
|
|
3655
|
+
row[dv.dataElement] = dv.value;
|
|
3656
|
+
}
|
|
3657
|
+
});
|
|
3658
|
+
return row;
|
|
3659
|
+
});
|
|
3660
|
+
return { columns: entityColumns, data: dataElementsData };
|
|
3661
|
+
};
|
|
3606
3662
|
const getTrackedEntityData = (response, programId, pager, isOptionSetNameVisible, filters) => {
|
|
3607
3663
|
let teis = response.data?.trackedEntities ??
|
|
3608
3664
|
response.data?.instances ??
|
|
@@ -4040,10 +4096,132 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
4040
4096
|
useEffect(() => {
|
|
4041
4097
|
this.setReactStateUpdaters?.(updateRefs.current);
|
|
4042
4098
|
}, []);
|
|
4099
|
+
// TODO: START: Improve the approach of handling observables
|
|
4100
|
+
// useEffect(() => {
|
|
4101
|
+
// setLoading(true);
|
|
4102
|
+
// this.lineListService
|
|
4103
|
+
// .getLineListData(
|
|
4104
|
+
// this.programId,
|
|
4105
|
+
// orgUnitState,
|
|
4106
|
+
// this.programStageId,
|
|
4107
|
+
// pager.page,
|
|
4108
|
+
// pager.pageSize,
|
|
4109
|
+
// attributeFiltersState,
|
|
4110
|
+
// startDateState,
|
|
4111
|
+
// endDateState,
|
|
4112
|
+
// this.ouMode,
|
|
4113
|
+
// this.filterRootOrgUnit,
|
|
4114
|
+
// this.useOuModeWithOlderDHIS2Instance
|
|
4115
|
+
// )
|
|
4116
|
+
// .subscribe((response: LineListResponse) => {
|
|
4117
|
+
// let entityColumns: ColumnDefinition[] = [];
|
|
4118
|
+
// let responsePager: Pager;
|
|
4119
|
+
// let entityData: TableRow[] = [];
|
|
4120
|
+
// let filteredDataColumns: ColumnDefinition[] = [];
|
|
4121
|
+
// if (this.programStageId) {
|
|
4122
|
+
// responsePager = (response.data as EventsResponse).pager;
|
|
4123
|
+
// const { columns, data } = getProgramStageData(
|
|
4124
|
+
// response,
|
|
4125
|
+
// this.programStageId,
|
|
4126
|
+
// pager,
|
|
4127
|
+
// this.isOptionSetNameVisible
|
|
4128
|
+
// );
|
|
4129
|
+
// entityColumns = columns;
|
|
4130
|
+
// entityData = data;
|
|
4131
|
+
// } else if (
|
|
4132
|
+
// 'trackedEntities' in response.data ||
|
|
4133
|
+
// 'instances' in response.data
|
|
4134
|
+
// ) {
|
|
4135
|
+
// const responseData: any = response.data as TrackedEntityResponse;
|
|
4136
|
+
// responsePager = (response.data as TrackedEntityResponse).pager || {
|
|
4137
|
+
// page: responseData.page,
|
|
4138
|
+
// pageSize: responseData.pageSize,
|
|
4139
|
+
// total: responseData.total,
|
|
4140
|
+
// pageCount: responseData.pageCount,
|
|
4141
|
+
// };
|
|
4142
|
+
// const { columns, data, filteredEntityColumns } =
|
|
4143
|
+
// getTrackedEntityData(
|
|
4144
|
+
// response,
|
|
4145
|
+
// this.programId,
|
|
4146
|
+
// pager,
|
|
4147
|
+
// this.isOptionSetNameVisible,
|
|
4148
|
+
// this.filters
|
|
4149
|
+
// );
|
|
4150
|
+
// entityColumns = columns;
|
|
4151
|
+
// entityData = data;
|
|
4152
|
+
// //TODO: Should be done on the parent
|
|
4153
|
+
// const checkValues = [
|
|
4154
|
+
// ...new Set(
|
|
4155
|
+
// (
|
|
4156
|
+
// response.data as TrackedEntityResponse
|
|
4157
|
+
// )?.trackedEntities?.[0]?.enrollments?.[0]?.events?.flatMap(
|
|
4158
|
+
// (event) =>
|
|
4159
|
+
// event.dataValues
|
|
4160
|
+
// .filter((dataValue) =>
|
|
4161
|
+
// /^[A-Za-z]{3}$/.test(dataValue.value)
|
|
4162
|
+
// )
|
|
4163
|
+
// .map((dataValue) => dataValue.value)
|
|
4164
|
+
// ) ??
|
|
4165
|
+
// (
|
|
4166
|
+
// response.data as TrackedEntityResponse
|
|
4167
|
+
// )?.instances?.[0]?.enrollments?.[0]?.events?.flatMap(
|
|
4168
|
+
// (event) =>
|
|
4169
|
+
// event.dataValues
|
|
4170
|
+
// .filter((dataValue) =>
|
|
4171
|
+
// /^[A-Za-z]{3}$/.test(dataValue.value)
|
|
4172
|
+
// )
|
|
4173
|
+
// .map((dataValue) => dataValue.value)
|
|
4174
|
+
// )
|
|
4175
|
+
// ),
|
|
4176
|
+
// ];
|
|
4177
|
+
// if (checkValues) {
|
|
4178
|
+
// // this.firstValue.emit(firstTei);
|
|
4179
|
+
// setCheckValue(checkValues);
|
|
4180
|
+
// setValuesMatch(!checkValues.includes(this.buttonFilter));
|
|
4181
|
+
// }
|
|
4182
|
+
// // setFilteredColumns(filteredEntityColumns);
|
|
4183
|
+
// // Ensure filter inputs do not disappear when no data is returned
|
|
4184
|
+
// // If filteredEntityColumns is empty, keep the previous columns instead of clearing them
|
|
4185
|
+
// setFilteredColumns((prev) =>
|
|
4186
|
+
// filteredEntityColumns.length > 0 ? filteredEntityColumns : prev
|
|
4187
|
+
// );
|
|
4188
|
+
// filteredDataColumns = filteredEntityColumns;
|
|
4189
|
+
// } else {
|
|
4190
|
+
// responsePager = (response.data as EventsResponse).pager;
|
|
4191
|
+
// const { columns, data } = getEventData(
|
|
4192
|
+
// response,
|
|
4193
|
+
// pager,
|
|
4194
|
+
// this.isOptionSetNameVisible
|
|
4195
|
+
// );
|
|
4196
|
+
// entityColumns = columns;
|
|
4197
|
+
// entityData = data;
|
|
4198
|
+
// }
|
|
4199
|
+
// const finalColumns: ColumnDefinition[] = addActionsColumn(
|
|
4200
|
+
// [{ label: '#', key: 'index' }, ...entityColumns],
|
|
4201
|
+
// this.actionOptions
|
|
4202
|
+
// );
|
|
4203
|
+
// setLoading(false);
|
|
4204
|
+
// setColumns(...[finalColumns]);
|
|
4205
|
+
// setData(...[entityData]);
|
|
4206
|
+
// setPager(...[responsePager]);
|
|
4207
|
+
// });
|
|
4208
|
+
// }, [
|
|
4209
|
+
// programIdState,
|
|
4210
|
+
// orgUnitState,
|
|
4211
|
+
// programStageIdState,
|
|
4212
|
+
// attributeFiltersState,
|
|
4213
|
+
// startDateState,
|
|
4214
|
+
// endDateState,
|
|
4215
|
+
// pager.page,
|
|
4216
|
+
// pager.pageSize,
|
|
4217
|
+
// isOptionSetNameVisibleState,
|
|
4218
|
+
// ]);
|
|
4219
|
+
// TODO: END: Improve the approach of handling observables
|
|
4043
4220
|
useEffect(() => {
|
|
4044
4221
|
setLoading(true);
|
|
4045
|
-
this.lineListService
|
|
4222
|
+
const subscription = this.lineListService
|
|
4046
4223
|
.getLineListData(this.programId, orgUnitState, this.programStageId, pager.page, pager.pageSize, attributeFiltersState, startDateState, endDateState, this.ouMode, this.filterRootOrgUnit, this.useOuModeWithOlderDHIS2Instance)
|
|
4224
|
+
.pipe(take(1)) // Automatically unsubscribe after the first emission
|
|
4047
4225
|
.subscribe((response) => {
|
|
4048
4226
|
let entityColumns = [];
|
|
4049
4227
|
let responsePager;
|
|
@@ -4051,14 +4229,14 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
4051
4229
|
let filteredDataColumns = [];
|
|
4052
4230
|
if (this.programStageId) {
|
|
4053
4231
|
responsePager = response.data.pager;
|
|
4054
|
-
const { columns, data } = getProgramStageData(response, this.programStageId, pager);
|
|
4232
|
+
const { columns, data } = getProgramStageData(response, this.programStageId, pager, this.isOptionSetNameVisible);
|
|
4055
4233
|
entityColumns = columns;
|
|
4056
4234
|
entityData = data;
|
|
4057
4235
|
}
|
|
4058
|
-
else if (
|
|
4059
|
-
|
|
4236
|
+
else if ("trackedEntities" in response.data ||
|
|
4237
|
+
"instances" in response.data) {
|
|
4060
4238
|
const responseData = response.data;
|
|
4061
|
-
responsePager =
|
|
4239
|
+
responsePager = responseData.pager || {
|
|
4062
4240
|
page: responseData.page,
|
|
4063
4241
|
pageSize: responseData.pageSize,
|
|
4064
4242
|
total: responseData.total,
|
|
@@ -4067,23 +4245,18 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
4067
4245
|
const { columns, data, filteredEntityColumns } = getTrackedEntityData(response, this.programId, pager, this.isOptionSetNameVisible, this.filters);
|
|
4068
4246
|
entityColumns = columns;
|
|
4069
4247
|
entityData = data;
|
|
4070
|
-
//TODO: Should be done on the parent
|
|
4071
4248
|
const checkValues = [
|
|
4072
|
-
...new Set(
|
|
4249
|
+
...new Set(responseData?.trackedEntities?.[0]?.enrollments?.[0]?.events?.flatMap((event) => event.dataValues
|
|
4073
4250
|
.filter((dataValue) => /^[A-Za-z]{3}$/.test(dataValue.value))
|
|
4074
4251
|
.map((dataValue) => dataValue.value)) ??
|
|
4075
|
-
|
|
4252
|
+
responseData?.instances?.[0]?.enrollments?.[0]?.events?.flatMap((event) => event.dataValues
|
|
4076
4253
|
.filter((dataValue) => /^[A-Za-z]{3}$/.test(dataValue.value))
|
|
4077
4254
|
.map((dataValue) => dataValue.value))),
|
|
4078
4255
|
];
|
|
4079
|
-
if (checkValues) {
|
|
4080
|
-
// this.firstValue.emit(firstTei);
|
|
4256
|
+
if (checkValues.length > 0) {
|
|
4081
4257
|
setCheckValue(checkValues);
|
|
4082
4258
|
setValuesMatch(!checkValues.includes(this.buttonFilter));
|
|
4083
4259
|
}
|
|
4084
|
-
// setFilteredColumns(filteredEntityColumns);
|
|
4085
|
-
// Ensure filter inputs do not disappear when no data is returned
|
|
4086
|
-
// If filteredEntityColumns is empty, keep the previous columns instead of clearing them
|
|
4087
4260
|
setFilteredColumns((prev) => filteredEntityColumns.length > 0 ? filteredEntityColumns : prev);
|
|
4088
4261
|
filteredDataColumns = filteredEntityColumns;
|
|
4089
4262
|
}
|
|
@@ -4093,12 +4266,15 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
4093
4266
|
entityColumns = columns;
|
|
4094
4267
|
entityData = data;
|
|
4095
4268
|
}
|
|
4096
|
-
const finalColumns = addActionsColumn([{ label:
|
|
4269
|
+
const finalColumns = addActionsColumn([{ label: "#", key: "index" }, ...entityColumns], this.actionOptions);
|
|
4097
4270
|
setLoading(false);
|
|
4098
|
-
setColumns(
|
|
4099
|
-
setData(
|
|
4100
|
-
setPager(
|
|
4271
|
+
setColumns(finalColumns);
|
|
4272
|
+
setData(entityData);
|
|
4273
|
+
setPager(responsePager);
|
|
4101
4274
|
});
|
|
4275
|
+
return () => {
|
|
4276
|
+
subscription.unsubscribe(); // Ensure cleanup on unmount
|
|
4277
|
+
};
|
|
4102
4278
|
}, [
|
|
4103
4279
|
programIdState,
|
|
4104
4280
|
orgUnitState,
|
|
@@ -4119,20 +4295,64 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
4119
4295
|
},
|
|
4120
4296
|
}));
|
|
4121
4297
|
};
|
|
4298
|
+
// TODO: START::: Improve the approach on handling observables
|
|
4299
|
+
// const handleApprovalClick = () => {
|
|
4300
|
+
// setIsButtonLoading(true);
|
|
4301
|
+
// this.lineListService
|
|
4302
|
+
// .getLineListData(
|
|
4303
|
+
// this.programId,
|
|
4304
|
+
// this.orgUnit,
|
|
4305
|
+
// this.programStageId,
|
|
4306
|
+
// pager.page,
|
|
4307
|
+
// 1000,
|
|
4308
|
+
// this.attributeFilters,
|
|
4309
|
+
// this.startDate,
|
|
4310
|
+
// this.endDate,
|
|
4311
|
+
// this.ouMode
|
|
4312
|
+
// )
|
|
4313
|
+
// .subscribe((response: LineListResponse) => {
|
|
4314
|
+
// if (
|
|
4315
|
+
// 'trackedEntities' in response.data ||
|
|
4316
|
+
// 'instances' in response.data
|
|
4317
|
+
// ) {
|
|
4318
|
+
// const trackedEntityInstances = (
|
|
4319
|
+
// response.data as TrackedEntityResponse
|
|
4320
|
+
// ).trackedEntities;
|
|
4321
|
+
// // Map TEIs to objects with teiId and enrollmentId
|
|
4322
|
+
// const teiEnrollmentList = trackedEntityInstances
|
|
4323
|
+
// .map((tei) => {
|
|
4324
|
+
// // Find the enrollment where program matches this.programId
|
|
4325
|
+
// const matchingEnrollment = tei.enrollments?.find(
|
|
4326
|
+
// (enrollment) => enrollment.program === this.programId
|
|
4327
|
+
// );
|
|
4328
|
+
// // Return object with teiId and enrollmentId (if found)
|
|
4329
|
+
// return matchingEnrollment
|
|
4330
|
+
// ? {
|
|
4331
|
+
// teiId: tei.trackedEntity,
|
|
4332
|
+
// enrollmentId: matchingEnrollment.enrollment,
|
|
4333
|
+
// }
|
|
4334
|
+
// : null;
|
|
4335
|
+
// })
|
|
4336
|
+
// .filter((item) => item !== null); // Remove null entries (no matching enrollment)
|
|
4337
|
+
// this.approvalSelected.emit(teiEnrollmentList);
|
|
4338
|
+
// } else {
|
|
4339
|
+
// this.approvalSelected.emit([]); // Emit empty array if no TEIs
|
|
4340
|
+
// }
|
|
4341
|
+
// });
|
|
4342
|
+
// };
|
|
4343
|
+
// TODO: END::: Improve the approach on handling observables
|
|
4122
4344
|
const handleApprovalClick = () => {
|
|
4123
4345
|
setIsButtonLoading(true);
|
|
4124
|
-
this.lineListService
|
|
4346
|
+
const subscription = this.lineListService
|
|
4125
4347
|
.getLineListData(this.programId, this.orgUnit, this.programStageId, pager.page, 1000, this.attributeFilters, this.startDate, this.endDate, this.ouMode)
|
|
4348
|
+
.pipe(take(1)) // Ensures the observable emits only once
|
|
4126
4349
|
.subscribe((response) => {
|
|
4127
|
-
if (
|
|
4128
|
-
'instances' in response.data) {
|
|
4350
|
+
if ("trackedEntities" in response.data || "instances" in response.data) {
|
|
4129
4351
|
const trackedEntityInstances = response.data.trackedEntities;
|
|
4130
4352
|
// Map TEIs to objects with teiId and enrollmentId
|
|
4131
4353
|
const teiEnrollmentList = trackedEntityInstances
|
|
4132
4354
|
.map((tei) => {
|
|
4133
|
-
// Find the enrollment where program matches this.programId
|
|
4134
4355
|
const matchingEnrollment = tei.enrollments?.find((enrollment) => enrollment.program === this.programId);
|
|
4135
|
-
// Return object with teiId and enrollmentId (if found)
|
|
4136
4356
|
return matchingEnrollment
|
|
4137
4357
|
? {
|
|
4138
4358
|
teiId: tei.trackedEntity,
|
|
@@ -4140,13 +4360,17 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
4140
4360
|
}
|
|
4141
4361
|
: null;
|
|
4142
4362
|
})
|
|
4143
|
-
.filter(
|
|
4363
|
+
.filter(Boolean); // Removes null entries
|
|
4144
4364
|
this.approvalSelected.emit(teiEnrollmentList);
|
|
4145
4365
|
}
|
|
4146
4366
|
else {
|
|
4147
4367
|
this.approvalSelected.emit([]); // Emit empty array if no TEIs
|
|
4148
4368
|
}
|
|
4369
|
+
setIsButtonLoading(false); // Stop loading after processing
|
|
4149
4370
|
});
|
|
4371
|
+
return () => {
|
|
4372
|
+
subscription.unsubscribe(); // Cleanup to avoid potential memory leaks
|
|
4373
|
+
};
|
|
4150
4374
|
};
|
|
4151
4375
|
const handleInputChange = (key, value) => {
|
|
4152
4376
|
setInputValues((prevValues) => ({
|
|
@@ -5919,9 +6143,24 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
5919
6143
|
checkValueUniqueness();
|
|
5920
6144
|
}
|
|
5921
6145
|
}, [this.isValueAssigned()]);
|
|
6146
|
+
// TODO: START: Improve the approach of handling observables
|
|
6147
|
+
// useEffect(() => {
|
|
6148
|
+
// const fieldErrorSubscription = this.fieldError$
|
|
6149
|
+
// .pipe(filter((error) => error !== initialError))
|
|
6150
|
+
// .subscribe({
|
|
6151
|
+
// next: (error: string | undefined) => {
|
|
6152
|
+
// setInitialError(error);
|
|
6153
|
+
// },
|
|
6154
|
+
// });
|
|
6155
|
+
// return () => {
|
|
6156
|
+
// fieldErrorSubscription.unsubscribe();
|
|
6157
|
+
// };
|
|
6158
|
+
// });
|
|
6159
|
+
// TODO: END: Improve the approach of handling observables
|
|
5922
6160
|
useEffect(() => {
|
|
5923
6161
|
const fieldErrorSubscription = this.fieldError$
|
|
5924
|
-
.pipe(filter((error) => error !== initialError))
|
|
6162
|
+
.pipe(filter((error) => error !== initialError), take(1) // Take only the first emitted value, then unsubscribe
|
|
6163
|
+
)
|
|
5925
6164
|
.subscribe({
|
|
5926
6165
|
next: (error) => {
|
|
5927
6166
|
setInitialError(error);
|
|
@@ -5930,7 +6169,7 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
5930
6169
|
return () => {
|
|
5931
6170
|
fieldErrorSubscription.unsubscribe();
|
|
5932
6171
|
};
|
|
5933
|
-
});
|
|
6172
|
+
}, [initialError]); // Add initialError as a dependency to avoid stale closures
|
|
5934
6173
|
const onChange = (payload) => setSelected(payload.selected);
|
|
5935
6174
|
const arrayValue = useMemo(() => {
|
|
5936
6175
|
if (value && value.length > 0) {
|
|
@@ -6817,14 +7056,30 @@ class SelectionFiltersComponent extends ReactWrapperModule {
|
|
|
6817
7056
|
const [selected, setSelected] = useState([]);
|
|
6818
7057
|
const [rootOrgUnits, setRootOrgUnits] = useState();
|
|
6819
7058
|
const [config, setConfig] = useState();
|
|
7059
|
+
// TODO: START::: Improve approach on handling observables
|
|
7060
|
+
// useEffect(() => {
|
|
7061
|
+
// zip(this.getAppConfig(), this.getRootOrgUnits()).subscribe({
|
|
7062
|
+
// next: ([appConfig, rootOrgUnits]) => {
|
|
7063
|
+
// setConfig(appConfig);
|
|
7064
|
+
// setRootOrgUnits(rootOrgUnits);
|
|
7065
|
+
// },
|
|
7066
|
+
// error: (error) => console.error(error),
|
|
7067
|
+
// });
|
|
7068
|
+
// }, []);
|
|
7069
|
+
// TODO: END::: Improve approach on handling observables
|
|
6820
7070
|
useEffect(() => {
|
|
6821
|
-
zip(this.getAppConfig(), this.getRootOrgUnits())
|
|
7071
|
+
const subscription = zip(this.getAppConfig(), this.getRootOrgUnits())
|
|
7072
|
+
.pipe(take(1)) // Ensures only one emission
|
|
7073
|
+
.subscribe({
|
|
6822
7074
|
next: ([appConfig, rootOrgUnits]) => {
|
|
6823
7075
|
setConfig(appConfig);
|
|
6824
7076
|
setRootOrgUnits(rootOrgUnits);
|
|
6825
7077
|
},
|
|
6826
7078
|
error: (error) => console.error(error),
|
|
6827
7079
|
});
|
|
7080
|
+
return () => {
|
|
7081
|
+
subscription.unsubscribe(); // Cleanup to avoid memory leaks
|
|
7082
|
+
};
|
|
6828
7083
|
}, []);
|
|
6829
7084
|
return config ? (React__default.createElement(Provider, { config: config, plugin: false, parentAlertsAdd: undefined, showAlertsInPlugin: false }, React__default.createElement(Modal$1, { position: "middle", large: true },
|
|
6830
7085
|
React__default.createElement(ModalTitle$1, null, "Organisation unit"),
|