@iapps/ng-dhis2-ui 1.2.165 → 1.2.166
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.
- package/fesm2022/iapps-ng-dhis2-ui.mjs +297 -75
- package/fesm2022/iapps-ng-dhis2-ui.mjs.map +1 -1
- package/index.d.ts +20 -6
- package/package.json +1 -1
|
@@ -4670,6 +4670,141 @@ const getEvents = (response, programStageId, pager, metaData, columnNameSource =
|
|
|
4670
4670
|
return { columns: entityColumns, data: dataElementsData };
|
|
4671
4671
|
};
|
|
4672
4672
|
|
|
4673
|
+
const getCellValue = (cell) => {
|
|
4674
|
+
if (cell === null || cell === undefined)
|
|
4675
|
+
return '';
|
|
4676
|
+
if (typeof cell === 'object') {
|
|
4677
|
+
if ('value' in cell)
|
|
4678
|
+
return cell.value;
|
|
4679
|
+
return JSON.stringify(cell);
|
|
4680
|
+
}
|
|
4681
|
+
return cell;
|
|
4682
|
+
};
|
|
4683
|
+
const getExportColumns = (columns) => columns.filter((column) => column.label !== 'Actions');
|
|
4684
|
+
const downloadLineListExcel = (columns, data, fileName = 'records') => {
|
|
4685
|
+
const exportColumns = getExportColumns(columns);
|
|
4686
|
+
const header = exportColumns.map((column) => column.label);
|
|
4687
|
+
const rows = data.map((row) => exportColumns.map((column) => getCellValue(row[column.key])));
|
|
4688
|
+
const worksheet = XLSX.utils.aoa_to_sheet([header, ...rows]);
|
|
4689
|
+
const workbook = XLSX.utils.book_new();
|
|
4690
|
+
XLSX.utils.book_append_sheet(workbook, worksheet, 'LineListData');
|
|
4691
|
+
XLSX.writeFile(workbook, `${fileName}.xlsx`);
|
|
4692
|
+
};
|
|
4693
|
+
const downloadLineListCsv = (columns, data, fileName = 'records') => {
|
|
4694
|
+
const exportColumns = getExportColumns(columns);
|
|
4695
|
+
const escapeCsvValue = (value) => `"${String(getCellValue(value)).replace(/"/g, '""')}"`;
|
|
4696
|
+
const header = exportColumns.map((column) => escapeCsvValue(column.label));
|
|
4697
|
+
const rows = data.map((row) => exportColumns.map((column) => escapeCsvValue(row[column.key])));
|
|
4698
|
+
const csvContent = [header, ...rows].map((row) => row.join(',')).join('\n');
|
|
4699
|
+
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
|
4700
|
+
const url = URL.createObjectURL(blob);
|
|
4701
|
+
const link = document.createElement('a');
|
|
4702
|
+
link.href = url;
|
|
4703
|
+
link.setAttribute('download', `${fileName}.csv`);
|
|
4704
|
+
document.body.appendChild(link);
|
|
4705
|
+
link.click();
|
|
4706
|
+
document.body.removeChild(link);
|
|
4707
|
+
URL.revokeObjectURL(url);
|
|
4708
|
+
};
|
|
4709
|
+
|
|
4710
|
+
const applyDownloadColumnFilter = (columns, filterableColumnIds) => {
|
|
4711
|
+
if (!Array.isArray(filterableColumnIds) || filterableColumnIds.length === 0) {
|
|
4712
|
+
return columns;
|
|
4713
|
+
}
|
|
4714
|
+
const filterableColumnIdsSet = new Set(filterableColumnIds);
|
|
4715
|
+
return columns.filter((column) => filterableColumnIdsSet.has(column.key));
|
|
4716
|
+
};
|
|
4717
|
+
const fetchLineListDownloadRows = async ({ d2, metaData, programId, programStageId, orgUnit, ouMode, startDate, endDate, dataQueryFilters, enrollmentStatus, eventStatus, filterableColumnIds, searcheableDataElements, customDisplayInReportsIds, columnNameSource, fetchOrgUnits, }) => {
|
|
4718
|
+
if (!metaData) {
|
|
4719
|
+
return { columns: [], data: [] };
|
|
4720
|
+
}
|
|
4721
|
+
const isTracker = metaData.programType === 'WITH_REGISTRATION';
|
|
4722
|
+
const isEvent = metaData.programType === 'WITHOUT_REGISTRATION';
|
|
4723
|
+
const downloadPager = new Pager({ paging: false });
|
|
4724
|
+
const resolvedEndDate = endDate ?? format(addDays(new Date(), 1), 'yyyy-MM-dd');
|
|
4725
|
+
if (programStageId || isEvent) {
|
|
4726
|
+
const eventQuery = d2.eventModule.event
|
|
4727
|
+
.setEndDate(resolvedEndDate)
|
|
4728
|
+
.setStartDate(startDate)
|
|
4729
|
+
.setProgram(programId)
|
|
4730
|
+
.setOrgUnit(orgUnit)
|
|
4731
|
+
.setOuMode(ouMode)
|
|
4732
|
+
.setPagination(downloadPager);
|
|
4733
|
+
if (programStageId) {
|
|
4734
|
+
eventQuery.setProgramStage(programStageId);
|
|
4735
|
+
}
|
|
4736
|
+
const response = await eventQuery.get();
|
|
4737
|
+
const events = Array.isArray(response.data)
|
|
4738
|
+
? response.data
|
|
4739
|
+
: response.data
|
|
4740
|
+
? [response.data]
|
|
4741
|
+
: [];
|
|
4742
|
+
const eventsResponse = {
|
|
4743
|
+
events,
|
|
4744
|
+
pager: new Pager({
|
|
4745
|
+
page: 1,
|
|
4746
|
+
pageSize: events.length || 1,
|
|
4747
|
+
}),
|
|
4748
|
+
};
|
|
4749
|
+
const downloadRows = getEvents({ data: eventsResponse }, programStageId || '', eventsResponse.pager, metaData, columnNameSource);
|
|
4750
|
+
return {
|
|
4751
|
+
columns: applyDownloadColumnFilter(downloadRows.columns, filterableColumnIds),
|
|
4752
|
+
data: downloadRows.data,
|
|
4753
|
+
};
|
|
4754
|
+
}
|
|
4755
|
+
if (isTracker) {
|
|
4756
|
+
const trackerQuery = d2.trackerModule.trackedEntity
|
|
4757
|
+
.setEndDate(resolvedEndDate)
|
|
4758
|
+
.setStartDate(startDate)
|
|
4759
|
+
.setProgram(programId)
|
|
4760
|
+
.setOrgUnit(orgUnit)
|
|
4761
|
+
.setOuMode(ouMode)
|
|
4762
|
+
.setStatus(enrollmentStatus)
|
|
4763
|
+
.setFilters(dataQueryFilters)
|
|
4764
|
+
.setPagination(downloadPager)
|
|
4765
|
+
.setOrderCriterias([
|
|
4766
|
+
new DataOrderCriteria().setField('createdAt').setOrder('desc'),
|
|
4767
|
+
]);
|
|
4768
|
+
if (eventStatus?.status && eventStatus?.programStage) {
|
|
4769
|
+
trackerQuery.setEventStatus(eventStatus.status, eventStatus.programStage);
|
|
4770
|
+
}
|
|
4771
|
+
if (programStageId) {
|
|
4772
|
+
trackerQuery.setProgramStage(programStageId);
|
|
4773
|
+
}
|
|
4774
|
+
const response = await trackerQuery.get();
|
|
4775
|
+
const trackedEntityInstances = Array.isArray(response.data)
|
|
4776
|
+
? response.data
|
|
4777
|
+
: response.data
|
|
4778
|
+
? [response.data]
|
|
4779
|
+
: [];
|
|
4780
|
+
const uniqueOrgUnitIds = Array.from(new Set(trackedEntityInstances
|
|
4781
|
+
.flatMap((tei) => [
|
|
4782
|
+
tei.latestEnrollment?.orgUnit,
|
|
4783
|
+
...(tei.attributes
|
|
4784
|
+
?.filter((attr) => attr.valueType === 'ORGANISATION_UNIT')
|
|
4785
|
+
.map((attr) => attr.value) || []),
|
|
4786
|
+
])
|
|
4787
|
+
.filter((orgUnitId) => !!orgUnitId)));
|
|
4788
|
+
const fetchedOrgUnits = uniqueOrgUnitIds.length > 0
|
|
4789
|
+
? await firstValueFrom(fetchOrgUnits(uniqueOrgUnitIds))
|
|
4790
|
+
: new Map();
|
|
4791
|
+
const trackedEntityResponse = {
|
|
4792
|
+
trackedEntityInstances,
|
|
4793
|
+
pager: new Pager({
|
|
4794
|
+
page: 1,
|
|
4795
|
+
pageSize: trackedEntityInstances.length || 1,
|
|
4796
|
+
}),
|
|
4797
|
+
orgUnitsMap: fetchedOrgUnits,
|
|
4798
|
+
};
|
|
4799
|
+
const downloadRows = getTrackedEntityTableData({ data: trackedEntityResponse }, programId, trackedEntityResponse.pager, metaData, searcheableDataElements, customDisplayInReportsIds, columnNameSource);
|
|
4800
|
+
return {
|
|
4801
|
+
columns: applyDownloadColumnFilter(downloadRows.columns, filterableColumnIds),
|
|
4802
|
+
data: downloadRows.data,
|
|
4803
|
+
};
|
|
4804
|
+
}
|
|
4805
|
+
return { columns: [], data: [] };
|
|
4806
|
+
};
|
|
4807
|
+
|
|
4673
4808
|
class LineListTableComponent extends ReactWrapperModule {
|
|
4674
4809
|
constructor() {
|
|
4675
4810
|
super(...arguments);
|
|
@@ -4718,6 +4853,7 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
4718
4853
|
const [endDateState, setEndDateState] = useState(this.endDate);
|
|
4719
4854
|
const [tempEndDateState, setTempEndDateState] = useState(this.endDate);
|
|
4720
4855
|
const [loading, setLoading] = useState(false);
|
|
4856
|
+
const [downloadLoading, setDownloadLoading] = useState(false);
|
|
4721
4857
|
const [filteredColumns, setFilteredColumns] = useState();
|
|
4722
4858
|
const [inputValues, setInputValues] = useState({});
|
|
4723
4859
|
const [orgUnitLabel, setOrgUnitLabel] = useState('');
|
|
@@ -4941,47 +5077,41 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
4941
5077
|
triggerRefetch,
|
|
4942
5078
|
triggerTokenState,
|
|
4943
5079
|
]);
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
const
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
:
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
return JSON.stringify(value);
|
|
5080
|
+
//TODO: ADD DOWNLOADING SUPPORT USING ANALYTICS
|
|
5081
|
+
const handleDownload = async (format) => {
|
|
5082
|
+
try {
|
|
5083
|
+
setDownloadLoading(true);
|
|
5084
|
+
const { columns, data } = await fetchLineListDownloadRows({
|
|
5085
|
+
d2,
|
|
5086
|
+
metaData,
|
|
5087
|
+
programId: programIdState,
|
|
5088
|
+
programStageId: programStageIdState,
|
|
5089
|
+
orgUnit: orgUnitState,
|
|
5090
|
+
ouMode: this.ouMode,
|
|
5091
|
+
startDate: startDateState,
|
|
5092
|
+
endDate: endDateState,
|
|
5093
|
+
dataQueryFilters: dataQueryFiltersState,
|
|
5094
|
+
enrollmentStatus: this.enrollmentStatus,
|
|
5095
|
+
eventStatus: this.eventStatus,
|
|
5096
|
+
filterableColumnIds: this.filterableColumnIds,
|
|
5097
|
+
searcheableDataElements: this.searcheableDataElements,
|
|
5098
|
+
customDisplayInReportsIds: this.customDisplayInReportsIds,
|
|
5099
|
+
columnNameSource: this.columnNameSource,
|
|
5100
|
+
fetchOrgUnits: (orgUnitIds) => this.lineListService.fetchOrgUnits(orgUnitIds),
|
|
5101
|
+
});
|
|
5102
|
+
if (format === 'CSV') {
|
|
5103
|
+
downloadLineListCsv(columns, data);
|
|
5104
|
+
return;
|
|
4970
5105
|
}
|
|
4971
|
-
|
|
4972
|
-
}
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
link.href = url;
|
|
4981
|
-
link.setAttribute('download', 'records.csv');
|
|
4982
|
-
document.body.appendChild(link);
|
|
4983
|
-
link.click();
|
|
4984
|
-
document.body.removeChild(link);
|
|
5106
|
+
downloadLineListExcel(columns, data);
|
|
5107
|
+
}
|
|
5108
|
+
catch (error) {
|
|
5109
|
+
console.error('Failed to download line list data:', error);
|
|
5110
|
+
setError('Could not download records. Please try again.');
|
|
5111
|
+
}
|
|
5112
|
+
finally {
|
|
5113
|
+
setDownloadLoading(false);
|
|
5114
|
+
}
|
|
4985
5115
|
};
|
|
4986
5116
|
const handleInputChange = (key, value, type) => {
|
|
4987
5117
|
setInputValues((prevValues) => ({
|
|
@@ -5117,7 +5247,7 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
5117
5247
|
// Returns black for light backgrounds, white for dark backgrounds
|
|
5118
5248
|
return yiq >= 128 ? colors$1.grey700 : '#FFFFFF';
|
|
5119
5249
|
}
|
|
5120
|
-
return React__default.createElement('div',
|
|
5250
|
+
return React__default.createElement('div', { className: 'line-list-root' }, loading
|
|
5121
5251
|
? React__default.createElement('div', {
|
|
5122
5252
|
style: {
|
|
5123
5253
|
display: 'flex',
|
|
@@ -5132,22 +5262,26 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
5132
5262
|
}, 'Loading'))
|
|
5133
5263
|
: React__default.createElement('div', null, this.showDownloadButton &&
|
|
5134
5264
|
React__default.createElement('div', {
|
|
5265
|
+
className: 'line-list-download-toolbar',
|
|
5135
5266
|
style: {
|
|
5136
5267
|
paddingBottom: '1rem',
|
|
5137
|
-
display: 'flex',
|
|
5138
|
-
justifyContent: 'flex-end',
|
|
5139
5268
|
},
|
|
5140
5269
|
}, React__default.createElement(DropdownButton, {
|
|
5141
5270
|
name: 'Download',
|
|
5271
|
+
disabled: downloadLoading,
|
|
5142
5272
|
component: React__default.createElement('span', null, ' ', React__default.createElement(MenuItem$1, {
|
|
5143
|
-
label: '
|
|
5144
|
-
|
|
5273
|
+
label: 'CSV',
|
|
5274
|
+
disabled: downloadLoading,
|
|
5275
|
+
onClick: () => handleDownload('CSV'),
|
|
5145
5276
|
}), React__default.createElement(MenuItem$1, {
|
|
5146
|
-
label: '
|
|
5147
|
-
|
|
5277
|
+
label: 'Excel',
|
|
5278
|
+
disabled: downloadLoading,
|
|
5279
|
+
onClick: () => handleDownload('XLSX'),
|
|
5148
5280
|
})),
|
|
5149
5281
|
value: 'Download',
|
|
5150
|
-
},
|
|
5282
|
+
}, downloadLoading
|
|
5283
|
+
? React__default.createElement(CircularLoader$1, { small: true })
|
|
5284
|
+
: 'Download')), orgUnitModalVisible &&
|
|
5151
5285
|
React__default.createElement(OrgUnitSelector, {
|
|
5152
5286
|
hide: hide,
|
|
5153
5287
|
setHide: setHide,
|
|
@@ -5200,7 +5334,7 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
5200
5334
|
prevSelectedOrgUnit: prevSelectedOrgUnit,
|
|
5201
5335
|
setPrevSelectedOrgUnit: setPrevSelectedOrgUnit,
|
|
5202
5336
|
// filteredFilters: filteredFilters
|
|
5203
|
-
}), React__default.createElement(LineListTable, {
|
|
5337
|
+
}), React__default.createElement('div', { className: 'line-list-table-scroll' }, React__default.createElement(LineListTable, {
|
|
5204
5338
|
columns: columns,
|
|
5205
5339
|
data: data,
|
|
5206
5340
|
pager: pager,
|
|
@@ -5214,7 +5348,7 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
5214
5348
|
rowsSelected: this.rowsSelected,
|
|
5215
5349
|
showActionButtons: showActionButtons,
|
|
5216
5350
|
error: error,
|
|
5217
|
-
})));
|
|
5351
|
+
}))));
|
|
5218
5352
|
};
|
|
5219
5353
|
}
|
|
5220
5354
|
ngOnChanges(changes) {
|
|
@@ -5263,11 +5397,11 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
5263
5397
|
this.render();
|
|
5264
5398
|
}
|
|
5265
5399
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LineListTableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
5266
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: LineListTableComponent, isStandalone: false, selector: "ng-dhis2-ui-line-list", inputs: { triggerToken: "triggerToken", programId: "programId", orgUnit: "orgUnit", programStageId: "programStageId", actionOptions: "actionOptions", actionOptionOrientation: "actionOptionOrientation", attributeFilters: "attributeFilters", useOuModeWithOlderDHIS2Instance: "useOuModeWithOlderDHIS2Instance", startDate: "startDate", endDate: "endDate", dataQueryFilters: "dataQueryFilters", lineListRowActionFilterConfig: "lineListRowActionFilterConfig", hydrateForActionFiltering: "hydrateForActionFiltering", ouMode: "ouMode", isButtonLoading: "isButtonLoading", buttonFilter: "buttonFilter", filterRootOrgUnit: "filterRootOrgUnit", showFilters: "showFilters", isOptionSetNameVisible: "isOptionSetNameVisible", allowRowsSelection: "allowRowsSelection", enrollmentStatus: "enrollmentStatus", filterableColumnIds: "filterableColumnIds", triggerRefetch: "triggerRefetch", eventStatus: "eventStatus", showActionButtons: "showActionButtons", showEnrollmentDates: "showEnrollmentDates", showDownloadButton: "showDownloadButton", searcheableDataElements: "searcheableDataElements", columnNameSource: "columnNameSource", customDisplayInReportsIds: "customDisplayInReportsIds" }, outputs: { actionSelected: "actionSelected", rowsSelected: "rowsSelected" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: ["@charset \"UTF-8\";::ng-deep .custom-input{display:flex!important;gap:4px!important;align-items:center!important;border:1px solid #9fadba!important;border-radius:4px!important;margin:0;padding:0 0 0 8px;background-color:#fff!important}::ng-deep .custom-input div{margin:0!important}::ng-deep .custom-input label{font-size:12px;padding-right:0}::ng-deep .custom-input input{border:none!important;font-size:12px!important;display:flex;align-items:center;padding-left:4px;height:40px;outline:none!important;box-shadow:none!important}::ng-deep .custom-input input:focus{border:none!important;box-shadow:none!important}::ng-deep .custom-input [data-test=calendar-clear-button]{background-color:#f2f2f2!important;color:#870808!important;border-radius:6px!important;padding:4px 10px!important;font-size:0!important}::ng-deep .custom-input [data-test=calendar-clear-button]:before{content:\"\\2715\";font-size:14px;color:#870808}::ng-deep .custom-input [data-test=calendar-clear-button]:hover{background-color:#ddd}::ng-deep .calendar-input-wrapper{position:relative}::ng-deep .calendar-input-wrapper .custom-input{position:relative;width:100%;display:flex;align-items:center}::ng-deep .calendar-input-wrapper [data-test=calendar-clear-button]{right:8px;bottom:14px;margin:auto;display:flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:0!important;background-color:#a0adba!important;border-radius:50%;padding:2px;cursor:pointer}::ng-deep .calendar-input-wrapper [data-test=calendar-clear-button]:before{content:\"\\2715\";font-size:10px;color:#f0f0f0}::ng-deep .calendar-input-wrapper input{padding-right:40px!important;height:40px;line-height:40px;box-sizing:border-box}::ng-deep .custom-input label{color:gray!important;opacity:1}::ng-deep .table-top-toolbar{background-color:var(--colors-grey100)!important;color:var(--colors-grey900)!important}::ng-deep .custom-select-input{display:flex!important;gap:4px!important;align-items:center!important;border:1px solid #9fadba!important;border-radius:4px!important;margin:0;padding:0 0 0 8px;background-color:#fff!important}::ng-deep .custom-select-input div{margin:0!important}::ng-deep .custom-select-input [data-test=dhis2-uiwidgets-singleselectfield-label]{font-size:12px;color:gray!important}::ng-deep .custom-select-input [data-test=dhis2-uicore-select-input]{border:none!important;font-size:12px!important;display:flex;align-items:center;padding-left:4px;height:40px;outline:none!important;box-shadow:none!important}::ng-deep .custom-select-input [data-test=dhis2-uicore-select-input]:focus-within{box-shadow:none!important}::ng-deep .custom-select-input input:focus{border:none!important;box-shadow:none!important}\n"] }); }
|
|
5400
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: LineListTableComponent, isStandalone: false, selector: "ng-dhis2-ui-line-list", inputs: { triggerToken: "triggerToken", programId: "programId", orgUnit: "orgUnit", programStageId: "programStageId", actionOptions: "actionOptions", actionOptionOrientation: "actionOptionOrientation", attributeFilters: "attributeFilters", useOuModeWithOlderDHIS2Instance: "useOuModeWithOlderDHIS2Instance", startDate: "startDate", endDate: "endDate", dataQueryFilters: "dataQueryFilters", lineListRowActionFilterConfig: "lineListRowActionFilterConfig", hydrateForActionFiltering: "hydrateForActionFiltering", ouMode: "ouMode", isButtonLoading: "isButtonLoading", buttonFilter: "buttonFilter", filterRootOrgUnit: "filterRootOrgUnit", showFilters: "showFilters", isOptionSetNameVisible: "isOptionSetNameVisible", allowRowsSelection: "allowRowsSelection", enrollmentStatus: "enrollmentStatus", filterableColumnIds: "filterableColumnIds", triggerRefetch: "triggerRefetch", eventStatus: "eventStatus", showActionButtons: "showActionButtons", showEnrollmentDates: "showEnrollmentDates", showDownloadButton: "showDownloadButton", searcheableDataElements: "searcheableDataElements", columnNameSource: "columnNameSource", customDisplayInReportsIds: "customDisplayInReportsIds" }, outputs: { actionSelected: "actionSelected", rowsSelected: "rowsSelected" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: ["@charset \"UTF-8\";::ng-deep .line-list-root{width:100%;max-width:100%;min-width:0}::ng-deep .line-list-download-toolbar{position:sticky;left:0;z-index:2;display:flex;justify-content:flex-end;width:100%;max-width:100%;box-sizing:border-box;background:#fff}::ng-deep .line-list-table-scroll{width:100%;max-width:100%;overflow-x:auto}::ng-deep .custom-input{display:flex!important;gap:4px!important;align-items:center!important;border:1px solid #9fadba!important;border-radius:4px!important;margin:0;padding:0 0 0 8px;background-color:#fff!important}::ng-deep .custom-input div{margin:0!important}::ng-deep .custom-input label{font-size:12px;padding-right:0}::ng-deep .custom-input input{border:none!important;font-size:12px!important;display:flex;align-items:center;padding-left:4px;height:40px;outline:none!important;box-shadow:none!important}::ng-deep .custom-input input:focus{border:none!important;box-shadow:none!important}::ng-deep .custom-input [data-test=calendar-clear-button]{background-color:#f2f2f2!important;color:#870808!important;border-radius:6px!important;padding:4px 10px!important;font-size:0!important}::ng-deep .custom-input [data-test=calendar-clear-button]:before{content:\"\\2715\";font-size:14px;color:#870808}::ng-deep .custom-input [data-test=calendar-clear-button]:hover{background-color:#ddd}::ng-deep .calendar-input-wrapper{position:relative}::ng-deep .calendar-input-wrapper .custom-input{position:relative;width:100%;display:flex;align-items:center}::ng-deep .calendar-input-wrapper [data-test=calendar-clear-button]{right:8px;bottom:14px;margin:auto;display:flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:0!important;background-color:#a0adba!important;border-radius:50%;padding:2px;cursor:pointer}::ng-deep .calendar-input-wrapper [data-test=calendar-clear-button]:before{content:\"\\2715\";font-size:10px;color:#f0f0f0}::ng-deep .calendar-input-wrapper input{padding-right:40px!important;height:40px;line-height:40px;box-sizing:border-box}::ng-deep .custom-input label{color:gray!important;opacity:1}::ng-deep .table-top-toolbar{background-color:var(--colors-grey100)!important;color:var(--colors-grey900)!important}::ng-deep .custom-select-input{display:flex!important;gap:4px!important;align-items:center!important;border:1px solid #9fadba!important;border-radius:4px!important;margin:0;padding:0 0 0 8px;background-color:#fff!important}::ng-deep .custom-select-input div{margin:0!important}::ng-deep .custom-select-input [data-test=dhis2-uiwidgets-singleselectfield-label]{font-size:12px;color:gray!important}::ng-deep .custom-select-input [data-test=dhis2-uicore-select-input]{border:none!important;font-size:12px!important;display:flex;align-items:center;padding-left:4px;height:40px;outline:none!important;box-shadow:none!important}::ng-deep .custom-select-input [data-test=dhis2-uicore-select-input]:focus-within{box-shadow:none!important}::ng-deep .custom-select-input input:focus{border:none!important;box-shadow:none!important}\n"] }); }
|
|
5267
5401
|
}
|
|
5268
5402
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LineListTableComponent, decorators: [{
|
|
5269
5403
|
type: Component,
|
|
5270
|
-
args: [{ selector: 'ng-dhis2-ui-line-list', template: '<ng-content></ng-content>', standalone: false, styles: ["@charset \"UTF-8\";::ng-deep .custom-input{display:flex!important;gap:4px!important;align-items:center!important;border:1px solid #9fadba!important;border-radius:4px!important;margin:0;padding:0 0 0 8px;background-color:#fff!important}::ng-deep .custom-input div{margin:0!important}::ng-deep .custom-input label{font-size:12px;padding-right:0}::ng-deep .custom-input input{border:none!important;font-size:12px!important;display:flex;align-items:center;padding-left:4px;height:40px;outline:none!important;box-shadow:none!important}::ng-deep .custom-input input:focus{border:none!important;box-shadow:none!important}::ng-deep .custom-input [data-test=calendar-clear-button]{background-color:#f2f2f2!important;color:#870808!important;border-radius:6px!important;padding:4px 10px!important;font-size:0!important}::ng-deep .custom-input [data-test=calendar-clear-button]:before{content:\"\\2715\";font-size:14px;color:#870808}::ng-deep .custom-input [data-test=calendar-clear-button]:hover{background-color:#ddd}::ng-deep .calendar-input-wrapper{position:relative}::ng-deep .calendar-input-wrapper .custom-input{position:relative;width:100%;display:flex;align-items:center}::ng-deep .calendar-input-wrapper [data-test=calendar-clear-button]{right:8px;bottom:14px;margin:auto;display:flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:0!important;background-color:#a0adba!important;border-radius:50%;padding:2px;cursor:pointer}::ng-deep .calendar-input-wrapper [data-test=calendar-clear-button]:before{content:\"\\2715\";font-size:10px;color:#f0f0f0}::ng-deep .calendar-input-wrapper input{padding-right:40px!important;height:40px;line-height:40px;box-sizing:border-box}::ng-deep .custom-input label{color:gray!important;opacity:1}::ng-deep .table-top-toolbar{background-color:var(--colors-grey100)!important;color:var(--colors-grey900)!important}::ng-deep .custom-select-input{display:flex!important;gap:4px!important;align-items:center!important;border:1px solid #9fadba!important;border-radius:4px!important;margin:0;padding:0 0 0 8px;background-color:#fff!important}::ng-deep .custom-select-input div{margin:0!important}::ng-deep .custom-select-input [data-test=dhis2-uiwidgets-singleselectfield-label]{font-size:12px;color:gray!important}::ng-deep .custom-select-input [data-test=dhis2-uicore-select-input]{border:none!important;font-size:12px!important;display:flex;align-items:center;padding-left:4px;height:40px;outline:none!important;box-shadow:none!important}::ng-deep .custom-select-input [data-test=dhis2-uicore-select-input]:focus-within{box-shadow:none!important}::ng-deep .custom-select-input input:focus{border:none!important;box-shadow:none!important}\n"] }]
|
|
5404
|
+
args: [{ selector: 'ng-dhis2-ui-line-list', template: '<ng-content></ng-content>', standalone: false, styles: ["@charset \"UTF-8\";::ng-deep .line-list-root{width:100%;max-width:100%;min-width:0}::ng-deep .line-list-download-toolbar{position:sticky;left:0;z-index:2;display:flex;justify-content:flex-end;width:100%;max-width:100%;box-sizing:border-box;background:#fff}::ng-deep .line-list-table-scroll{width:100%;max-width:100%;overflow-x:auto}::ng-deep .custom-input{display:flex!important;gap:4px!important;align-items:center!important;border:1px solid #9fadba!important;border-radius:4px!important;margin:0;padding:0 0 0 8px;background-color:#fff!important}::ng-deep .custom-input div{margin:0!important}::ng-deep .custom-input label{font-size:12px;padding-right:0}::ng-deep .custom-input input{border:none!important;font-size:12px!important;display:flex;align-items:center;padding-left:4px;height:40px;outline:none!important;box-shadow:none!important}::ng-deep .custom-input input:focus{border:none!important;box-shadow:none!important}::ng-deep .custom-input [data-test=calendar-clear-button]{background-color:#f2f2f2!important;color:#870808!important;border-radius:6px!important;padding:4px 10px!important;font-size:0!important}::ng-deep .custom-input [data-test=calendar-clear-button]:before{content:\"\\2715\";font-size:14px;color:#870808}::ng-deep .custom-input [data-test=calendar-clear-button]:hover{background-color:#ddd}::ng-deep .calendar-input-wrapper{position:relative}::ng-deep .calendar-input-wrapper .custom-input{position:relative;width:100%;display:flex;align-items:center}::ng-deep .calendar-input-wrapper [data-test=calendar-clear-button]{right:8px;bottom:14px;margin:auto;display:flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:0!important;background-color:#a0adba!important;border-radius:50%;padding:2px;cursor:pointer}::ng-deep .calendar-input-wrapper [data-test=calendar-clear-button]:before{content:\"\\2715\";font-size:10px;color:#f0f0f0}::ng-deep .calendar-input-wrapper input{padding-right:40px!important;height:40px;line-height:40px;box-sizing:border-box}::ng-deep .custom-input label{color:gray!important;opacity:1}::ng-deep .table-top-toolbar{background-color:var(--colors-grey100)!important;color:var(--colors-grey900)!important}::ng-deep .custom-select-input{display:flex!important;gap:4px!important;align-items:center!important;border:1px solid #9fadba!important;border-radius:4px!important;margin:0;padding:0 0 0 8px;background-color:#fff!important}::ng-deep .custom-select-input div{margin:0!important}::ng-deep .custom-select-input [data-test=dhis2-uiwidgets-singleselectfield-label]{font-size:12px;color:gray!important}::ng-deep .custom-select-input [data-test=dhis2-uicore-select-input]{border:none!important;font-size:12px!important;display:flex;align-items:center;padding-left:4px;height:40px;outline:none!important;box-shadow:none!important}::ng-deep .custom-select-input [data-test=dhis2-uicore-select-input]:focus-within{box-shadow:none!important}::ng-deep .custom-select-input input:focus{border:none!important;box-shadow:none!important}\n"] }]
|
|
5271
5405
|
}], propDecorators: { triggerToken: [{
|
|
5272
5406
|
type: Input
|
|
5273
5407
|
}], programId: [{
|
|
@@ -9067,6 +9201,42 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
9067
9201
|
// ----------------------------
|
|
9068
9202
|
useEffect(() => {
|
|
9069
9203
|
const cascade = this.#resolveCascadeForCurrentField();
|
|
9204
|
+
const dependentField = field.dependentField;
|
|
9205
|
+
if (dependentField) {
|
|
9206
|
+
const parentCtrl = this.#getControl(fg, dependentField.key || dependentField.id);
|
|
9207
|
+
if (!parentCtrl) {
|
|
9208
|
+
setFilteredOptions([]);
|
|
9209
|
+
setDisabled(baseDisabled);
|
|
9210
|
+
return undefined;
|
|
9211
|
+
}
|
|
9212
|
+
const parentOptions = dependentField.options?.length > 0
|
|
9213
|
+
? dependentField.options
|
|
9214
|
+
: dependentField.optionSet?.options ?? [];
|
|
9215
|
+
const applyDependentOptions = (parentValue) => {
|
|
9216
|
+
const parentOption = parentOptions.find((option) => {
|
|
9217
|
+
const optionValue = option?.value ?? option?.code ?? option?.key;
|
|
9218
|
+
return optionValue === parentValue;
|
|
9219
|
+
});
|
|
9220
|
+
const nextOptions = parentOption?.options ?? [];
|
|
9221
|
+
const childCtrl = this.#getCurrentFieldControl(fg);
|
|
9222
|
+
const currentChildValue = String(childCtrl?.value ?? '').trim();
|
|
9223
|
+
if (currentChildValue) {
|
|
9224
|
+
const stillValid = nextOptions.some((option) => {
|
|
9225
|
+
const optionValue = String(option?.value ?? option?.code ?? option?.key ?? '');
|
|
9226
|
+
return optionValue === currentChildValue;
|
|
9227
|
+
});
|
|
9228
|
+
if (!stillValid) {
|
|
9229
|
+
childCtrl?.setValue(null, { emitEvent: true });
|
|
9230
|
+
setValue('');
|
|
9231
|
+
}
|
|
9232
|
+
}
|
|
9233
|
+
setFilteredOptions(nextOptions);
|
|
9234
|
+
setDisabled(baseDisabled || !parentValue);
|
|
9235
|
+
};
|
|
9236
|
+
applyDependentOptions(parentCtrl.value);
|
|
9237
|
+
const sub = parentCtrl.valueChanges.subscribe((value) => applyDependentOptions(value));
|
|
9238
|
+
return () => sub.unsubscribe();
|
|
9239
|
+
}
|
|
9070
9240
|
if (!cascade || cascade.kind !== 'OPTIONS_PATH') {
|
|
9071
9241
|
setFilteredOptions(field.options ?? []);
|
|
9072
9242
|
setDisabled(baseDisabled);
|
|
@@ -9905,7 +10075,8 @@ class FormComponent {
|
|
|
9905
10075
|
if (fieldToRemove) {
|
|
9906
10076
|
const form = this.form();
|
|
9907
10077
|
const currentValue = form.get(fieldToRemove.key)?.value;
|
|
9908
|
-
|
|
10078
|
+
const shouldPreserveValue = fieldToRemove.disabled || fieldToRemove.generated;
|
|
10079
|
+
if (currentValue != null && !shouldPreserveValue) {
|
|
9909
10080
|
form.get(fieldToRemove.key)?.setValue(null);
|
|
9910
10081
|
this.onFieldUpdate(form, fieldToRemove);
|
|
9911
10082
|
}
|
|
@@ -10013,6 +10184,7 @@ class FormField {
|
|
|
10013
10184
|
this.trackedEntityType = options.trackedEntityType;
|
|
10014
10185
|
this.hasOptions = options.hasOptions;
|
|
10015
10186
|
this.dependentField = options.dependentField;
|
|
10187
|
+
this.fieldOptionsDependsOn = options.fieldOptionsDependsOn;
|
|
10016
10188
|
this.displayInList = options.displayInList;
|
|
10017
10189
|
this.displayInReports = options.displayInReports;
|
|
10018
10190
|
this.searchable = options.searchable;
|
|
@@ -10098,10 +10270,13 @@ var FieldType;
|
|
|
10098
10270
|
|
|
10099
10271
|
class FieldDropdown {
|
|
10100
10272
|
constructor(params) {
|
|
10101
|
-
|
|
10102
|
-
this.
|
|
10103
|
-
this.
|
|
10104
|
-
this.
|
|
10273
|
+
const rawParams = params;
|
|
10274
|
+
this.key = params.key ?? rawParams.id ?? rawParams.code ?? rawParams.name;
|
|
10275
|
+
this.value = params.value ?? rawParams.code ?? rawParams.name;
|
|
10276
|
+
this.label =
|
|
10277
|
+
params.label ?? rawParams.name ?? rawParams.displayName ?? rawParams.code;
|
|
10278
|
+
this.order = params.order ?? rawParams.sortOrder;
|
|
10279
|
+
this.options = params.options?.map((option) => new FieldDropdown(option));
|
|
10105
10280
|
}
|
|
10106
10281
|
toJson() {
|
|
10107
10282
|
return {
|
|
@@ -10109,6 +10284,7 @@ class FieldDropdown {
|
|
|
10109
10284
|
value: this.value,
|
|
10110
10285
|
label: this.label,
|
|
10111
10286
|
order: this.order,
|
|
10287
|
+
options: this.options?.map((option) => option.toJson()),
|
|
10112
10288
|
};
|
|
10113
10289
|
}
|
|
10114
10290
|
static getDropdownOptions(field, locale, extension) {
|
|
@@ -10140,10 +10316,11 @@ class FieldDropdown {
|
|
|
10140
10316
|
}
|
|
10141
10317
|
return sortBy((field?.optionSet?.options || []).map((option) => {
|
|
10142
10318
|
return new FieldDropdown({
|
|
10143
|
-
key: option.id,
|
|
10144
|
-
value: option.code,
|
|
10145
|
-
label: option.name,
|
|
10319
|
+
key: option.id ?? option.code ?? option.name,
|
|
10320
|
+
value: option.code ?? option.value ?? option.name,
|
|
10321
|
+
label: option.name ?? option.label ?? option.code,
|
|
10146
10322
|
order: option.sortOrder,
|
|
10323
|
+
options: option.options,
|
|
10147
10324
|
});
|
|
10148
10325
|
}), 'order');
|
|
10149
10326
|
}
|
|
@@ -12345,9 +12522,10 @@ class ProgramStageEntryFormSectionUtil {
|
|
|
12345
12522
|
// }
|
|
12346
12523
|
class ProgramEntryFormSectionUtil {
|
|
12347
12524
|
#sortedCanonicalFieldsCache = null;
|
|
12348
|
-
constructor(program, config) {
|
|
12525
|
+
constructor(program, config, customFieldConfigurations = {}) {
|
|
12349
12526
|
this.program = program;
|
|
12350
12527
|
this.config = config;
|
|
12528
|
+
this.customFieldConfigurations = customFieldConfigurations;
|
|
12351
12529
|
this.fieldUtil = new ProgramEntryFormFieldUtil(program, config);
|
|
12352
12530
|
}
|
|
12353
12531
|
// get programEntryFormSections(): IProgramEntryFormSection[] {
|
|
@@ -12570,7 +12748,12 @@ class ProgramEntryFormSectionUtil {
|
|
|
12570
12748
|
sortOrder: programTrackedEntityAttribute.sortOrder,
|
|
12571
12749
|
optionSet: tea.optionSet,
|
|
12572
12750
|
};
|
|
12573
|
-
const
|
|
12751
|
+
const customConfiguration = this.customFieldConfigurations?.[iTrackedEntityFormFieldBase.id];
|
|
12752
|
+
const fieldWithCustomConfiguration = {
|
|
12753
|
+
...iTrackedEntityFormFieldBase,
|
|
12754
|
+
...(customConfiguration || {}),
|
|
12755
|
+
};
|
|
12756
|
+
const options = FieldDropdown.getDropdownOptions(fieldWithCustomConfiguration);
|
|
12574
12757
|
const hasOptions = (options?.length ?? 0) > 0;
|
|
12575
12758
|
const fieldExtension = this.config.formFieldExtensions?.find((formFieldExtension) => formFieldExtension?.id === iTrackedEntityFormFieldBase.id);
|
|
12576
12759
|
const autoAssignedValue = this.#getAutoAssignedValue(iTrackedEntityFormFieldBase);
|
|
@@ -12579,22 +12762,24 @@ class ProgramEntryFormSectionUtil {
|
|
|
12579
12762
|
return null;
|
|
12580
12763
|
}
|
|
12581
12764
|
return new FormField({
|
|
12582
|
-
id:
|
|
12583
|
-
code:
|
|
12584
|
-
label:
|
|
12585
|
-
|
|
12586
|
-
key:
|
|
12587
|
-
? camelCase(
|
|
12588
|
-
:
|
|
12589
|
-
required:
|
|
12590
|
-
type: FieldUtil.getFieldType(
|
|
12765
|
+
id: fieldWithCustomConfiguration.id,
|
|
12766
|
+
code: fieldWithCustomConfiguration.code,
|
|
12767
|
+
label: fieldWithCustomConfiguration.formName ||
|
|
12768
|
+
fieldWithCustomConfiguration.name,
|
|
12769
|
+
key: fieldWithCustomConfiguration.code
|
|
12770
|
+
? camelCase(fieldWithCustomConfiguration.code)
|
|
12771
|
+
: fieldWithCustomConfiguration.id,
|
|
12772
|
+
required: fieldWithCustomConfiguration.mandatory,
|
|
12773
|
+
type: FieldUtil.getFieldType(fieldWithCustomConfiguration.valueType),
|
|
12591
12774
|
options,
|
|
12592
12775
|
hasOptions,
|
|
12593
|
-
disabled: this.#getDisabledStatus(iTrackedEntityFormFieldBase) ||
|
|
12594
|
-
|
|
12595
|
-
|
|
12776
|
+
disabled: this.#getDisabledStatus(iTrackedEntityFormFieldBase) ||
|
|
12777
|
+
!!tea.generated,
|
|
12778
|
+
order: fieldWithCustomConfiguration.sortOrder,
|
|
12779
|
+
controlType: FieldUtil.getFieldControlType(fieldWithCustomConfiguration.valueType, hasOptions),
|
|
12596
12780
|
allowFutureDate: programTrackedEntityAttribute.allowFutureDate === true,
|
|
12597
12781
|
extension: fieldExtension,
|
|
12782
|
+
fieldOptionsDependsOn: fieldWithCustomConfiguration.fieldOptionsDependsOn,
|
|
12598
12783
|
generated: !!tea.generated,
|
|
12599
12784
|
unique: !!tea.unique,
|
|
12600
12785
|
pattern: tea.pattern,
|
|
@@ -12618,6 +12803,18 @@ class ProgramEntryFormSectionUtil {
|
|
|
12618
12803
|
continue;
|
|
12619
12804
|
fieldsByAttributeId.set(canonicalField.id, canonicalField);
|
|
12620
12805
|
}
|
|
12806
|
+
for (const [fieldId, field] of fieldsByAttributeId.entries()) {
|
|
12807
|
+
if (!field.fieldOptionsDependsOn)
|
|
12808
|
+
continue;
|
|
12809
|
+
const dependentField = fieldsByAttributeId.get(field.fieldOptionsDependsOn);
|
|
12810
|
+
if (!dependentField)
|
|
12811
|
+
continue;
|
|
12812
|
+
fieldsByAttributeId.set(fieldId, new FormField({
|
|
12813
|
+
...field,
|
|
12814
|
+
dependentField,
|
|
12815
|
+
controlType: 'dropdown',
|
|
12816
|
+
}));
|
|
12817
|
+
}
|
|
12621
12818
|
return fieldsByAttributeId;
|
|
12622
12819
|
}
|
|
12623
12820
|
}
|
|
@@ -12628,6 +12825,7 @@ class ProgramEntryFormSectionUtil {
|
|
|
12628
12825
|
class ProgramEntryFormMetaData {
|
|
12629
12826
|
constructor() {
|
|
12630
12827
|
this.d2 = window?.d2Web;
|
|
12828
|
+
this.customFieldConfigurations = {};
|
|
12631
12829
|
}
|
|
12632
12830
|
setConfig(config) {
|
|
12633
12831
|
this.config = config;
|
|
@@ -12826,7 +13024,7 @@ class ProgramEntryFormMetaData {
|
|
|
12826
13024
|
if (displayType !== 'FLAT') {
|
|
12827
13025
|
return [];
|
|
12828
13026
|
}
|
|
12829
|
-
const baseSections = new ProgramEntryFormSectionUtil(this.program, this.config).programEntryFormSections;
|
|
13027
|
+
const baseSections = new ProgramEntryFormSectionUtil(this.program, this.config, this.customFieldConfigurations).programEntryFormSections;
|
|
12830
13028
|
const autoAssigned = this.config?.autoAssignedValues;
|
|
12831
13029
|
if (!autoAssigned?.length) {
|
|
12832
13030
|
return baseSections;
|
|
@@ -12908,13 +13106,37 @@ class ProgramEntryFormMetaData {
|
|
|
12908
13106
|
sections,
|
|
12909
13107
|
programStageSections,
|
|
12910
13108
|
rules: this.rules,
|
|
13109
|
+
customFieldConfigurations: this.customFieldConfigurations,
|
|
12911
13110
|
};
|
|
12912
13111
|
}
|
|
13112
|
+
async #getCustomFieldConfigurations() {
|
|
13113
|
+
try {
|
|
13114
|
+
const response = await this.d2.httpInstance.get('dataStore/field-extensions?fields=id,fieldOptionsDependsOn,optionSet&paging=false');
|
|
13115
|
+
const entries = response?.data?.['entries'];
|
|
13116
|
+
if (!Array.isArray(entries)) {
|
|
13117
|
+
return {};
|
|
13118
|
+
}
|
|
13119
|
+
return entries.reduce((fieldConfigurations, fieldConfiguration) => {
|
|
13120
|
+
if (!fieldConfiguration?.id) {
|
|
13121
|
+
return fieldConfigurations;
|
|
13122
|
+
}
|
|
13123
|
+
return {
|
|
13124
|
+
...fieldConfigurations,
|
|
13125
|
+
[fieldConfiguration.id]: fieldConfiguration,
|
|
13126
|
+
};
|
|
13127
|
+
}, {});
|
|
13128
|
+
}
|
|
13129
|
+
catch {
|
|
13130
|
+
return {};
|
|
13131
|
+
}
|
|
13132
|
+
}
|
|
12913
13133
|
async get() {
|
|
12914
13134
|
try {
|
|
12915
13135
|
const program = await this.#getProgramMetaData();
|
|
12916
13136
|
if (program) {
|
|
12917
13137
|
this.program = program;
|
|
13138
|
+
this.customFieldConfigurations =
|
|
13139
|
+
await this.#getCustomFieldConfigurations();
|
|
12918
13140
|
if (this.config?.formFieldExtensions &&
|
|
12919
13141
|
this.config.formFieldExtensions.length > 0 &&
|
|
12920
13142
|
this.config.formFieldExtensions[0]?.optionsSourceCode) {
|