@iapps/ng-dhis2-ui 1.2.105 → 1.2.112

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.
@@ -1,13 +1,13 @@
1
- import * as i1$1 from '@angular/common';
1
+ import * as i1 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { NgModule, ContentChild, Input, Directive, Component, EventEmitter, Output, inject, NgZone, input, ChangeDetectionStrategy, Injectable, model, computed, signal, effect, ViewChildren } from '@angular/core';
4
+ import { NgModule, ContentChild, Input, Directive, inject, ElementRef, Component, EventEmitter, Output, NgZone, input, ChangeDetectionStrategy, Injectable, model, computed, signal, effect, ViewChildren } from '@angular/core';
5
5
  import { useDataQuery, useConfig, useAlert, clearSensitiveCaches, DataProvider, useDataEngine, Provider } from '@dhis2/app-runtime';
6
- import * as i1 from '@iapps/ngx-dhis2-http-client';
7
6
  import * as React from 'react';
8
7
  import React__default, { useState, useCallback, useRef, useEffect, createContext, useContext, useMemo } from 'react';
9
8
  import * as ReactDOM from 'react-dom/client';
10
- import { catchError, of, map, zip, firstValueFrom, from, filter, take, Subject, takeUntil } from 'rxjs';
9
+ import { from, map, catchError, of, zip, firstValueFrom, filter, take, Subject, takeUntil } from 'rxjs';
10
+ import parse from 'html-react-parser';
11
11
  import i18n from '@dhis2/d2-i18n';
12
12
  import { colors, theme, spacers } from '@dhis2/ui-constants';
13
13
  import PropTypes from 'prop-types';
@@ -23,7 +23,6 @@ import { Divider } from '@dhis2-ui/divider';
23
23
  import { Layer } from '@dhis2-ui/layer';
24
24
  import { CircularLoader } from '@dhis2-ui/loader';
25
25
  import { MenuItem, MenuDivider } from '@dhis2-ui/menu';
26
- import parse from 'html-react-parser';
27
26
  import { Button as Button$1, IconDimensionOrgUnit16, IconClock16, IconDimensionData16, spacers as spacers$1, colors as colors$1, IconEdit16, theme as theme$1, Tooltip, IconChevronRight16, SingleSelectField, SingleSelectOption, InputField as InputField$1, TabBar, Tab, Transfer, Modal as Modal$1, ModalTitle as ModalTitle$1, ModalContent as ModalContent$1, ModalActions as ModalActions$1, ButtonStrip as ButtonStrip$1, Checkbox, OrganisationUnitTree, MultiSelect, MultiSelectOption, IconWarningFilled16, CircularLoader as CircularLoader$1, Chip, DataTableToolbar, DropdownButton, FlyoutMenu, CalendarInput, TableHead, DataTableRow, DataTableColumnHeader, Layer as Layer$1, Popper, MenuItem as MenuItem$1, IconMore24, DataTableCell, TableBody as TableBody$1, Pagination as Pagination$1, TableFoot, DataTable, FileInputField, FileListItem, MultiSelectField, TextAreaField } from '@dhis2/ui';
28
27
  import { isObject, isString, debounce, sortBy, isArray, find, camelCase, flatten, isUndefined, head, isEmpty } from 'lodash';
29
28
  import cx from 'classnames';
@@ -51,6 +50,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
51
50
  }]
52
51
  }] });
53
52
 
53
+ window.React = React;
54
+ class ReactWrapperModule {
55
+ constructor(elementRef) {
56
+ this.elementRef = elementRef;
57
+ }
58
+ ngAfterViewInit() {
59
+ if (!this.elementRef)
60
+ throw new Error('No element ref');
61
+ this.reactDomRoot = ReactDOM.createRoot(this.elementRef.nativeElement);
62
+ this.render();
63
+ }
64
+ ngOnDestroy() {
65
+ this.reactDomRoot?.unmount();
66
+ }
67
+ render() {
68
+ if (!this.component) {
69
+ console.warn('React component must be supplied');
70
+ }
71
+ else {
72
+ if (!this.reactDomRoot)
73
+ return;
74
+ const jsxContent = this.content?.nativeElement?.outerHTML
75
+ ? parse(this.content?.nativeElement?.outerHTML)
76
+ : undefined;
77
+ this.reactDomRoot.render(React.createElement(this.component, this.props, jsxContent || ''));
78
+ }
79
+ }
80
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ReactWrapperModule, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
81
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.3", type: ReactWrapperModule, isStandalone: true, selector: "ng-dhis2-ui-wrapper", inputs: { props: "props", component: "component" }, queries: [{ propertyName: "content", first: true, predicate: ["ngDhis2UiContent"], descendants: true }], ngImport: i0 }); }
82
+ }
83
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ReactWrapperModule, decorators: [{
84
+ type: Directive,
85
+ args: [{
86
+ selector: 'ng-dhis2-ui-wrapper',
87
+ }]
88
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { props: [{
89
+ type: Input
90
+ }], component: [{
91
+ type: Input
92
+ }], content: [{
93
+ type: ContentChild,
94
+ args: ['ngDhis2UiContent']
95
+ }] } });
96
+
54
97
  // Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
55
98
  // Use of this source code is governed by a BSD-style
56
99
  // license that can be found in the LICENSE file.
@@ -86,15 +129,15 @@ class HeaderBarNotification {
86
129
  // Use of this source code is governed by a BSD-style
87
130
  // license that can be found in the LICENSE file.
88
131
  class HeaderBarData {
89
- constructor(httpClient) {
90
- this.httpClient = httpClient;
132
+ constructor(httpInstance) {
133
+ this.httpInstance = httpInstance;
91
134
  }
92
135
  getApps() {
93
- return this.httpClient
94
- .get('dhis-web-commons/menu/getModules.action', {
136
+ return from(this.httpInstance.get('dhis-web-commons/menu/getModules.action', {
95
137
  useRootUrl: true,
96
- })
97
- .pipe(catchError(() => of({
138
+ })).pipe(map((result) => result.data || {
139
+ modules: [],
140
+ }), catchError(() => of({
98
141
  modules: [],
99
142
  })), map((result) => {
100
143
  return (result?.modules || [])
@@ -103,12 +146,12 @@ class HeaderBarData {
103
146
  }));
104
147
  }
105
148
  getNotifications() {
106
- return this.httpClient
107
- .get('me/dashboard')
108
- .pipe(map((notifications) => notifications ? new HeaderBarNotification(notifications) : null));
149
+ return from(this.httpInstance.get('me/dashboard')).pipe(map((notificationResponse) => notificationResponse?.data
150
+ ? new HeaderBarNotification(notificationResponse?.data)
151
+ : null));
109
152
  }
110
153
  get() {
111
- return zip(this.getApps(), this.httpClient.get('systemSettings/helpPageLink'), this.httpClient.get('me/dashboard'), this.httpClient.get('systemSettings/applicationTitle'), this.httpClient.get('me.json?fields=authorities,avatar,email,name,settings')).pipe(map((response) => {
154
+ return zip(this.getApps(), from(this.httpInstance.get('systemSettings/helpPageLink')).pipe(map((response) => response?.data)), from(this.httpInstance.get('me/dashboard')).pipe(map((response) => response?.data)), from(this.httpInstance.get('systemSettings/applicationTitle')).pipe(map((response) => response?.data)), from(this.httpInstance.get('me.json?fields=authorities,avatar,email,name,settings')).pipe(map((response) => response?.data))).pipe(map((response) => {
112
155
  if (response) {
113
156
  const [apps, help, notifications, title, user] = response;
114
157
  this.apps = apps;
@@ -1017,73 +1060,31 @@ HeaderBar.propTypes = {
1017
1060
  onApplyAvailableUpdate: PropTypes.func,
1018
1061
  };
1019
1062
 
1020
- window.React = React;
1021
- class ReactWrapperModule {
1022
- constructor(elementRef) {
1023
- this.elementRef = elementRef;
1024
- }
1025
- ngAfterViewInit() {
1026
- if (!this.elementRef)
1027
- throw new Error('No element ref');
1028
- this.reactDomRoot = ReactDOM.createRoot(this.elementRef.nativeElement);
1029
- this.render();
1030
- }
1031
- ngOnDestroy() {
1032
- this.reactDomRoot?.unmount();
1033
- }
1034
- render() {
1035
- if (!this.component) {
1036
- console.warn('React component must be supplied');
1037
- }
1038
- else {
1039
- if (!this.reactDomRoot)
1040
- return;
1041
- const jsxContent = this.content?.nativeElement?.outerHTML
1042
- ? parse(this.content?.nativeElement?.outerHTML)
1043
- : undefined;
1044
- this.reactDomRoot.render(React.createElement(this.component, this.props, jsxContent || ''));
1045
- }
1046
- }
1047
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ReactWrapperModule, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1048
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.3", type: ReactWrapperModule, isStandalone: true, selector: "ng-dhis2-ui-wrapper", inputs: { props: "props", component: "component" }, queries: [{ propertyName: "content", first: true, predicate: ["ngDhis2UiContent"], descendants: true }], ngImport: i0 }); }
1049
- }
1050
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ReactWrapperModule, decorators: [{
1051
- type: Directive,
1052
- args: [{
1053
- selector: 'ng-dhis2-ui-wrapper',
1054
- }]
1055
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { props: [{
1056
- type: Input
1057
- }], component: [{
1058
- type: Input
1059
- }], content: [{
1060
- type: ContentChild,
1061
- args: ['ngDhis2UiContent']
1062
- }] } });
1063
-
1064
1063
  class HeaderBarComponent extends ReactWrapperModule {
1065
- constructor(elementRef, httpClient) {
1066
- super(elementRef);
1067
- this.httpClient = httpClient;
1064
+ constructor() {
1065
+ super(inject((ElementRef)));
1068
1066
  }
1069
1067
  async ngAfterViewInit() {
1070
- if (!this.elementRef)
1071
- throw new Error('No element ref');
1072
- this.reactDomRoot = ReactDOM.createRoot(this.elementRef.nativeElement);
1073
- const manifest = await firstValueFrom(this.httpClient.manifest());
1074
- const data = await firstValueFrom(new HeaderBarData(this.httpClient).get());
1075
- this.component = data
1076
- ? () => {
1077
- const headerBarElement = React__default.createElement(HeaderBar, {
1078
- appName: manifest?.name,
1079
- data: data,
1080
- });
1081
- return React__default.createElement(DataProvider, null, headerBarElement);
1082
- }
1083
- : () => React__default.createElement('div', null, 'Something went wrong');
1084
- this.render();
1068
+ const d2 = window?.d2Web;
1069
+ if (d2) {
1070
+ if (!this.elementRef)
1071
+ throw new Error('No element ref');
1072
+ this.reactDomRoot = ReactDOM.createRoot(this.elementRef.nativeElement);
1073
+ const manifest = d2.appManifest;
1074
+ const data = await firstValueFrom(new HeaderBarData(d2.httpInstance).get());
1075
+ this.component = data
1076
+ ? () => {
1077
+ const headerBarElement = React__default.createElement(HeaderBar, {
1078
+ appName: manifest?.name,
1079
+ data: data,
1080
+ });
1081
+ return React__default.createElement(DataProvider, null, headerBarElement);
1082
+ }
1083
+ : () => React__default.createElement('div', null, 'Something went wrong');
1084
+ this.render();
1085
+ }
1085
1086
  }
1086
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: HeaderBarComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }], target: i0.ɵɵFactoryTarget.Component }); }
1087
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: HeaderBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1087
1088
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: HeaderBarComponent, isStandalone: false, selector: "ng-dhis2-ui-header-bar", usesInheritance: true, ngImport: i0, template: `<ng-container></ng-container>`, isInline: true }); }
1088
1089
  }
1089
1090
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: HeaderBarComponent, decorators: [{
@@ -1093,7 +1094,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
1093
1094
  template: `<ng-container></ng-container>`,
1094
1095
  standalone: false,
1095
1096
  }]
1096
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }] });
1097
+ }], ctorParameters: () => [] });
1097
1098
 
1098
1099
  class HeaderBarModule {
1099
1100
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: HeaderBarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
@@ -4088,10 +4089,10 @@ const getTrackedEntityTableData = (response, programId, pager, metaData, searche
4088
4089
  }))
4089
4090
  .filter((col) => searcheableDataElements.includes(col.key)));
4090
4091
  const dataElementColumns = metaData
4091
- .programStages.sort((a, b) => a.sortOrder - b.sortOrder) // Sorts stages by sortOrder
4092
+ .programStages.sort((a, b) => a.sortOrder - b.sortOrder)
4092
4093
  .flatMap((stage) => stage
4093
4094
  .programStageDataElements.filter((psde) => psde.displayInReports)
4094
- .sort((a, b) => a.sortOrder - b.sortOrder) // Sorts data elements within stage
4095
+ .sort((a, b) => a.sortOrder - b.sortOrder)
4095
4096
  .map((psde) => ({
4096
4097
  label: psde.dataElement.name || psde.dataElement.formName || 'default',
4097
4098
  key: psde.dataElement.id,
@@ -4120,94 +4121,204 @@ const getTrackedEntityTableData = (response, programId, pager, metaData, searche
4120
4121
  options: attr.optionSet ?? undefined,
4121
4122
  type: 'attribute',
4122
4123
  }));
4123
- const tableData = teis.map((tei, idx) => {
4124
+ const getOptionColor = (option) => option?.color || option?.style?.color;
4125
+ const formatDate = (value) => {
4126
+ try {
4127
+ return format(parse$1(value, 'yyyy-MM-dd', new Date()), 'dd/MM/yyyy');
4128
+ }
4129
+ catch {
4130
+ return value;
4131
+ }
4132
+ };
4133
+ const trackedEntityAttributeMap = new Map();
4134
+ (metaData.programTrackedEntityAttributes || []).forEach(({ trackedEntityAttribute }) => {
4135
+ if (trackedEntityAttribute?.id) {
4136
+ trackedEntityAttributeMap.set(trackedEntityAttribute.id, trackedEntityAttribute);
4137
+ }
4138
+ });
4139
+ const dataElementOptionMap = new Map();
4140
+ dataElementOptions.forEach((deo) => {
4141
+ if (deo.id) {
4142
+ dataElementOptionMap.set(deo.id, deo);
4143
+ }
4144
+ });
4145
+ const tableData = teis.map((tei, index) => {
4124
4146
  const row = {
4125
4147
  trackedEntityInstance: { value: tei.trackedEntity },
4126
- index: { value: (pager.page - 1) * pager.pageSize + idx + 1 },
4148
+ index: { value: (pager.page - 1) * pager.pageSize + index + 1 },
4127
4149
  };
4128
- const matchingEnrollment = tei.latestEnrollment;
4129
- let attributesData = matchingEnrollment.attributes;
4130
- const dataElementsData = matchingEnrollment.events.flatMap((event) => event.dataValues);
4131
- attributesData = attributesData.map((attr) => {
4132
- if (attr?.valueType?.toLowerCase() === 'date') {
4133
- try {
4134
- return {
4135
- ...attr,
4136
- value: format(parse$1(attr.value, 'yyyy-MM-dd', new Date()), 'dd/MM/yyyy'),
4137
- };
4138
- }
4139
- catch {
4140
- return { ...attr };
4141
- }
4150
+ const enrollment = tei.latestEnrollment;
4151
+ if (!enrollment)
4152
+ return row;
4153
+ const attributes = (enrollment.attributes || []).map((attr) => {
4154
+ if (attr?.valueType?.toLowerCase() === 'date' &&
4155
+ typeof attr.value === 'string') {
4156
+ return { ...attr, value: formatDate(attr.value) };
4142
4157
  }
4143
4158
  return attr;
4144
4159
  });
4145
- // attributesData.forEach((attr: any) => {
4146
- // const attributeMeta = metaData.programTrackedEntityAttributes?.find(
4147
- // (metadata) => metadata.trackedEntityAttribute.id === attr.attribute
4148
- // );
4149
- // if (attributeMeta?.trackedEntityAttribute.optionSetValue) {
4150
- // const optionSet = attributeMeta?.trackedEntityAttribute?.optionSet;
4151
- // const option = optionSet?.options?.find(
4152
- // (option) => option.code === attr.value
4153
- // );
4154
- // row[attr.attribute] = option
4155
- // ? { value: option?.name }
4156
- // : { value: attr.value };
4157
- // } else {
4158
- // row[attr.attribute] = { value: attr.value };
4159
- // }
4160
- // });
4161
- attributesData.forEach((attr) => {
4162
- const attributeMeta = metaData.programTrackedEntityAttributes?.find((metadata) => metadata.trackedEntityAttribute.id === attr.attribute);
4163
- const valueType = attributeMeta?.trackedEntityAttribute?.valueType;
4160
+ attributes.forEach((attr) => {
4161
+ const attributeId = attr?.attribute;
4162
+ const value = attr?.value;
4163
+ if (!attributeId || value == null)
4164
+ return;
4165
+ const attributeMeta = trackedEntityAttributeMap.get(attributeId);
4166
+ const valueType = attributeMeta?.valueType;
4164
4167
  if (valueType === 'ORGANISATION_UNIT') {
4165
- const orgUnitName = orgUnitMap?.get(attr.value);
4166
- row[attr.attribute] = { value: orgUnitName || attr.value };
4167
- }
4168
- else if (attributeMeta?.trackedEntityAttribute.optionSetValue) {
4169
- const optionSet = attributeMeta?.trackedEntityAttribute?.optionSet;
4170
- const option = optionSet?.options?.find((option) => option.code === attr.value);
4171
- row[attr.attribute] = option
4172
- ? { value: option?.name }
4173
- : { value: attr.value };
4168
+ const name = orgUnitMap?.get(value);
4169
+ row[attributeId] = { value: name || value };
4174
4170
  }
4175
- else {
4176
- row[attr.attribute] = { value: attr.value };
4177
- }
4178
- });
4179
- dataElementsData.forEach((element) => {
4180
- // Finds the matching data element in dataElementOptions by ID
4181
- const dataElementOption = dataElementOptions.find((deo) => deo.id === element.dataElement);
4182
- // finds a matching option within that data element's options
4183
- const matchingOption = dataElementOption?.options?.find((opt) => opt.name === element.value);
4184
- // Builds the row entry with value and optional style
4185
- if (matchingOption) {
4186
- row[element.dataElement] = {
4187
- value: element.value,
4188
- style: matchingOption.color,
4171
+ else if (attributeMeta?.optionSetValue &&
4172
+ attributeMeta?.optionSet?.options) {
4173
+ const matchedOption = attributeMeta.optionSet.options.find((opt) => opt.code === value);
4174
+ row[attributeId] = {
4175
+ value: matchedOption?.name || value,
4176
+ ...(getOptionColor(matchedOption) && {
4177
+ style: getOptionColor(matchedOption),
4178
+ }),
4189
4179
  };
4190
4180
  }
4191
4181
  else {
4192
- row[element.dataElement] = {
4193
- value: element.value,
4194
- };
4182
+ row[attributeId] = { value };
4195
4183
  }
4196
4184
  });
4197
- // Includes orgUnit in the row for id access with style
4198
- row['orgUnitId'] = { value: matchingEnrollment.orgUnit };
4199
- row['orgUnit'] = {
4200
- value: orgUnitMap?.get(matchingEnrollment.orgUnit) || '-',
4185
+ const dataValues = enrollment.events?.flatMap((event) => event.dataValues || []) || [];
4186
+ dataValues.forEach((dataValue) => {
4187
+ const dataElementId = dataValue.dataElement;
4188
+ const value = dataValue.value;
4189
+ if (!dataElementId || value == null)
4190
+ return;
4191
+ const dataElementOption = dataElementOptionMap.get(dataElementId);
4192
+ const matchedOption = dataElementOption?.options?.find((opt) => opt.name === value);
4193
+ row[dataElementId] = {
4194
+ value,
4195
+ ...(getOptionColor(matchedOption) && {
4196
+ style: getOptionColor(matchedOption),
4197
+ }),
4198
+ };
4199
+ });
4200
+ const orgUnitId = enrollment.orgUnit;
4201
+ const orgUnitName = orgUnitMap?.get(orgUnitId) || '-';
4202
+ row['orgUnitId'] = { value: orgUnitId || '-' };
4203
+ row['orgUnit'] = { value: orgUnitName };
4204
+ const teiObject = typeof tei.toObject === 'function' ? tei.toObject() : null;
4205
+ row['responseData'] = {
4206
+ value: teiObject || null,
4201
4207
  };
4202
- row['responseData'] = { value: tei.toObject() };
4203
4208
  return row;
4204
4209
  });
4205
4210
  return {
4206
4211
  columns: tableColumns,
4207
4212
  data: tableData,
4208
4213
  filteredEntityColumns: [...tableFilters, ...tableSearcheableDataElements],
4209
- orgUnitLabel: orgUnitLabel,
4214
+ orgUnitLabel,
4210
4215
  };
4216
+ // const tableData = teis.map((tei: TrackedEntityInstance, idx: number) => {
4217
+ // const row: TableRow = {
4218
+ // trackedEntityInstance: { value: tei.trackedEntity },
4219
+ // index: { value: (pager.page - 1) * pager.pageSize + idx + 1 },
4220
+ // };
4221
+ // const matchingEnrollment = tei.latestEnrollment;
4222
+ // let attributesData = matchingEnrollment.attributes;
4223
+ // const dataElementsData = matchingEnrollment!.events.flatMap(
4224
+ // (event) => event.dataValues
4225
+ // );
4226
+ // attributesData = attributesData!.map((attr: any) => {
4227
+ // if (attr?.valueType?.toLowerCase() === 'date') {
4228
+ // try {
4229
+ // return {
4230
+ // ...attr,
4231
+ // value: format(
4232
+ // parse(attr.value, 'yyyy-MM-dd', new Date()),
4233
+ // 'dd/MM/yyyy'
4234
+ // ),
4235
+ // };
4236
+ // } catch {
4237
+ // return { ...attr };
4238
+ // }
4239
+ // }
4240
+ // return attr;
4241
+ // });
4242
+ // // Tracked Entity Instance Attributes
4243
+ // const trackedEntityAttributeMap = new Map<string, any>();
4244
+ // (metaData.programTrackedEntityAttributes || []).forEach(
4245
+ // (programAttribute) => {
4246
+ // const attributeId = programAttribute.trackedEntityAttribute?.id;
4247
+ // if (attributeId) {
4248
+ // trackedEntityAttributeMap.set(
4249
+ // attributeId,
4250
+ // programAttribute.trackedEntityAttribute
4251
+ // );
4252
+ // }
4253
+ // }
4254
+ // );
4255
+ // attributesData.forEach((attributeItem: any) => {
4256
+ // const attributeId = attributeItem?.attribute;
4257
+ // const attributeValue = attributeItem?.value;
4258
+ // if (!attributeId || attributeValue == null) return;
4259
+ // const trackedEntityAttribute = trackedEntityAttributeMap.get(attributeId);
4260
+ // const valueType = trackedEntityAttribute?.valueType;
4261
+ // if (valueType === 'ORGANISATION_UNIT') {
4262
+ // const organisationUnitName = orgUnitMap?.get(attributeValue);
4263
+ // row[attributeId] = {
4264
+ // value: organisationUnitName || attributeValue,
4265
+ // };
4266
+ // } else if (
4267
+ // trackedEntityAttribute?.optionSetValue &&
4268
+ // trackedEntityAttribute?.optionSet?.options
4269
+ // ) {
4270
+ // const matchedOption = trackedEntityAttribute.optionSet.options.find(
4271
+ // (option: any) => option.code === attributeValue
4272
+ // );
4273
+ // const optionColor = matchedOption?.color || matchedOption?.style?.color;
4274
+ // row[attributeId] = {
4275
+ // value: matchedOption?.name || attributeValue,
4276
+ // ...(optionColor && { style: optionColor }),
4277
+ // };
4278
+ // } else {
4279
+ // row[attributeId] = {
4280
+ // value: attributeValue,
4281
+ // };
4282
+ // }
4283
+ // });
4284
+ // // Program Stage Data Elements
4285
+ // const dataElementOptionMap = new Map(
4286
+ // dataElementOptions.map((deo) => [deo.id, deo])
4287
+ // );
4288
+ // dataElementsData.forEach((element: DataValue) => {
4289
+ // if (!element?.dataElement || element.value == null) return;
4290
+ // const dataElementOption = dataElementOptionMap.get(element.dataElement);
4291
+ // const matchingOption: any = dataElementOption?.options?.find(
4292
+ // (opt) => opt.name === element.value
4293
+ // );
4294
+ // const optionColor = matchingOption?.color || matchingOption?.style?.color;
4295
+ // row[element.dataElement] = {
4296
+ // value: element.value,
4297
+ // ...(optionColor && { style: optionColor }),
4298
+ // };
4299
+ // });
4300
+ // const orgUnitId = matchingEnrollment?.orgUnit;
4301
+ // if (orgUnitId) {
4302
+ // row['orgUnitId'] = { value: orgUnitId };
4303
+ // const orgUnitName = orgUnitMap?.get(orgUnitId) || '-';
4304
+ // row['orgUnit'] = { value: orgUnitName };
4305
+ // } else {
4306
+ // row['orgUnitId'] = { value: '-' };
4307
+ // row['orgUnit'] = { value: '-' };
4308
+ // }
4309
+ // const teiObject =
4310
+ // typeof tei?.toObject === 'function' ? tei.toObject() : null;
4311
+ // row['responseData'] = {
4312
+ // value: (teiObject as TrackedEntityInstance) || null,
4313
+ // };
4314
+ // return row;
4315
+ // });
4316
+ // return {
4317
+ // columns: tableColumns,
4318
+ // data: tableData,
4319
+ // filteredEntityColumns: [...tableFilters, ...tableSearcheableDataElements],
4320
+ // orgUnitLabel: orgUnitLabel,
4321
+ // };
4211
4322
  };
4212
4323
  const addActionsColumn = (columns, actionOptions) => {
4213
4324
  return [
@@ -6217,6 +6328,17 @@ class FormValue {
6217
6328
  }
6218
6329
  }
6219
6330
 
6331
+ var OrgUnitLevel;
6332
+ (function (OrgUnitLevel) {
6333
+ OrgUnitLevel["FACILITY"] = "FACILITY";
6334
+ OrgUnitLevel["HAMLET"] = "HAMLET";
6335
+ OrgUnitLevel["STREET"] = "STREET";
6336
+ OrgUnitLevel["WARD"] = "WARD";
6337
+ OrgUnitLevel["COUNCIL"] = "COUNCIL";
6338
+ OrgUnitLevel["REGION"] = "REGION";
6339
+ OrgUnitLevel["NATIONAL"] = "NATIONAL";
6340
+ })(OrgUnitLevel || (OrgUnitLevel = {}));
6341
+
6220
6342
  // Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
6221
6343
  // Use of this source code is governed by a BSD-style
6222
6344
  // license that can be found in the LICENSE file.
@@ -6324,6 +6446,58 @@ const orgUnitFieldStyles = {
6324
6446
  paddingInlineStart: '4px',
6325
6447
  },
6326
6448
  };
6449
+ const FACILITY_KEYWORDS = [
6450
+ 'Hospital',
6451
+ 'Dispensary',
6452
+ 'Health Center',
6453
+ 'Clinic',
6454
+ 'Health Post',
6455
+ 'Medical Center',
6456
+ 'Polyclinic',
6457
+ ];
6458
+ const LOWERCASE_FACILITY_KEYWORDS = FACILITY_KEYWORDS.map((k) => k.toLowerCase());
6459
+ const getFacilityMatch = (name, config) => {
6460
+ if (!name)
6461
+ return null;
6462
+ const cleanedName = name.trim().toLowerCase();
6463
+ if (cleanedName.length < 3)
6464
+ return null;
6465
+ const matchesKeyword = LOWERCASE_FACILITY_KEYWORDS.some((keyword) => cleanedName.includes(keyword));
6466
+ if (!matchesKeyword) {
6467
+ return null;
6468
+ }
6469
+ return {
6470
+ type: config?.level ?? 'UNKNOWN',
6471
+ confidence: config?.confidence ?? 0,
6472
+ };
6473
+ };
6474
+ const flattenChildren = (rootUnits) => {
6475
+ const result = [];
6476
+ const stack = [...rootUnits];
6477
+ while (stack.length > 0) {
6478
+ const current = stack.pop();
6479
+ if (!current)
6480
+ continue;
6481
+ result.push(current);
6482
+ if (Array.isArray(current.children) && current.children.length > 0) {
6483
+ stack.push(...current.children);
6484
+ }
6485
+ }
6486
+ return result;
6487
+ };
6488
+ const buildReadableFullName = (unit) => {
6489
+ const ancestors = (unit.ancestors || [])
6490
+ .map((a) => a.displayName?.trim())
6491
+ .filter(Boolean);
6492
+ const currentName = (unit.displayName || unit.name || '').trim();
6493
+ const pathParts = [];
6494
+ for (const name of [...ancestors, currentName]) {
6495
+ if (name && name !== pathParts[pathParts.length - 1]) {
6496
+ pathParts.push(name);
6497
+ }
6498
+ }
6499
+ return pathParts.join(' / ');
6500
+ };
6327
6501
  const OrgUnitFormField = (props) => {
6328
6502
  // const { onSelectOrgUnit, label, required, selected, disabled, key, customOrgUnitRoots } = props;
6329
6503
  // const d2 = (window as unknown as D2Window)?.d2Web;
@@ -6391,24 +6565,45 @@ const OrgUnitFormField = (props) => {
6391
6565
  if (matchList.length > 0) {
6392
6566
  setUseCustomRoots(true);
6393
6567
  setConfiguredRootsLoading(true);
6394
- Promise.all(matchList.map((entry) => d2.httpInstance
6395
- .get(`organisationUnits/${entry.orgUnit}.json?fields=id,displayName,name,code,path,level`)
6396
- .then((res) => {
6397
- const orgUnitPayload = res.data;
6398
- return {
6399
- id: orgUnitPayload?.id,
6400
- name: orgUnitPayload?.displayName || orgUnitPayload?.name,
6401
- code: orgUnitPayload?.code,
6402
- path: orgUnitPayload?.path,
6403
- level: orgUnitPayload.level,
6404
- };
6405
- })))
6406
- .then((result) => {
6407
- setConfiguredRootInfo(result);
6568
+ Promise.allSettled(matchList.map(async (orgUnitConfig) => {
6569
+ try {
6570
+ const orgUnitResponse = await d2.httpInstance.get(`organisationUnits/${orgUnitConfig.orgUnit}.json?fields=id,displayName,name,code,path,level,ancestors[displayName],children[id,displayName,name,code,path,level,ancestors[displayName],children[id,displayName,name,code,path,level,ancestors[displayName]]]&paging=false`);
6571
+ const rootOrgUnitData = orgUnitResponse.data;
6572
+ const allDescendantOrgUnits = flattenChildren([rootOrgUnitData]);
6573
+ const matchingConfig = customOrgUnitRoots?.find((config) => config.orgUnit === orgUnitConfig.orgUnit);
6574
+ const facilityResults = allDescendantOrgUnits
6575
+ .map((orgUnit) => {
6576
+ const orgUnitName = orgUnit.displayName || orgUnit.name || '';
6577
+ const facilityMatch = getFacilityMatch(orgUnitName, matchingConfig);
6578
+ if (!facilityMatch)
6579
+ return null;
6580
+ return {
6581
+ id: orgUnit.id,
6582
+ name: buildReadableFullName(orgUnit),
6583
+ code: orgUnit.code,
6584
+ path: orgUnit.path,
6585
+ level: orgUnit.level,
6586
+ type: facilityMatch.type,
6587
+ confidence: facilityMatch.confidence,
6588
+ };
6589
+ })
6590
+ .filter((facility) => facility !== null);
6591
+ return facilityResults;
6592
+ }
6593
+ catch (fetchError) {
6594
+ console.warn(`[OrgUnitFormField] Failed to fetch orgUnit ${orgUnitConfig.orgUnit}:`, fetchError);
6595
+ return [];
6596
+ }
6597
+ }))
6598
+ .then((settledResults) => {
6599
+ const allFacilities = settledResults
6600
+ .filter((result) => result.status === 'fulfilled')
6601
+ .flatMap((result) => result.value);
6602
+ setConfiguredRootInfo(allFacilities);
6408
6603
  setConfiguredRootsLoading(false);
6409
6604
  })
6410
- .catch((err) => {
6411
- console.warn(`[OrgUnitFormField] Failed to fetch customOrgUnitRoots:`, err);
6605
+ .catch((unexpectedError) => {
6606
+ console.warn(`[OrgUnitFormField] Unexpected error:`, unexpectedError);
6412
6607
  setConfiguredRootsLoading(false);
6413
6608
  });
6414
6609
  }
@@ -7038,7 +7233,7 @@ class FormFieldComponent {
7038
7233
  this._runtimeOptions = [...options];
7039
7234
  }
7040
7235
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7041
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.3", type: FormFieldComponent, isStandalone: false, selector: "ng-dhis2-ui-form-field", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, fieldConfig: { classPropertyName: "fieldConfig", publicName: "fieldConfig", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: false, isRequired: false, transformFunction: null }, isCheckBoxButton: { classPropertyName: "isCheckBoxButton", publicName: "isCheckBoxButton", isSignal: true, isRequired: false, transformFunction: null }, fieldClass: { classPropertyName: "fieldClass", publicName: "fieldClass", isSignal: true, isRequired: false, transformFunction: null }, programRuleActions: { classPropertyName: "programRuleActions", publicName: "programRuleActions", isSignal: true, isRequired: false, transformFunction: null }, dataEntities: { classPropertyName: "dataEntities", publicName: "dataEntities", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, dataId: { classPropertyName: "dataId", publicName: "dataId", isSignal: true, isRequired: false, transformFunction: null }, customOrgUnitRoots: { classPropertyName: "customOrgUnitRoots", publicName: "customOrgUnitRoots", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fieldUpdate: "fieldUpdate", immediateFieldUpdate: "immediateFieldUpdate", runtimeOptionChange: "runtimeOptionChange" }, usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"field()\" class=\"form-field-item\">\n <ng-dhis2-ui-form-field-item\n [field]=\"field()\"\n [fieldError]=\"runtimeError()\"\n [isValueAssigned]=\"isValueAssigned()\"\n [fieldConfig]=\"fieldConfig()\"\n [(form)]=\"form\"\n [dataId]=\"dataId()\"\n [customOrgUnitRoots]=\"customOrgUnitRoots()\"\n [value]=\"value()\"\n (update)=\"onValueChange()\"\n (immediateUpdate)=\"onImmediateChange($event)\"\n />\n</div>\n", styles: [".form-field-item{margin-bottom:16px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormFieldItemComponent, selector: "ng-dhis2-ui-form-field-item" }] }); }
7236
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.3", type: FormFieldComponent, isStandalone: false, selector: "ng-dhis2-ui-form-field", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, fieldConfig: { classPropertyName: "fieldConfig", publicName: "fieldConfig", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: false, isRequired: false, transformFunction: null }, isCheckBoxButton: { classPropertyName: "isCheckBoxButton", publicName: "isCheckBoxButton", isSignal: true, isRequired: false, transformFunction: null }, fieldClass: { classPropertyName: "fieldClass", publicName: "fieldClass", isSignal: true, isRequired: false, transformFunction: null }, programRuleActions: { classPropertyName: "programRuleActions", publicName: "programRuleActions", isSignal: true, isRequired: false, transformFunction: null }, dataEntities: { classPropertyName: "dataEntities", publicName: "dataEntities", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, dataId: { classPropertyName: "dataId", publicName: "dataId", isSignal: true, isRequired: false, transformFunction: null }, customOrgUnitRoots: { classPropertyName: "customOrgUnitRoots", publicName: "customOrgUnitRoots", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fieldUpdate: "fieldUpdate", immediateFieldUpdate: "immediateFieldUpdate", runtimeOptionChange: "runtimeOptionChange" }, usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"field()\" class=\"form-field-item\">\n <ng-dhis2-ui-form-field-item\n [field]=\"field()\"\n [fieldError]=\"runtimeError()\"\n [isValueAssigned]=\"isValueAssigned()\"\n [fieldConfig]=\"fieldConfig()\"\n [(form)]=\"form\"\n [dataId]=\"dataId()\"\n [customOrgUnitRoots]=\"customOrgUnitRoots()\"\n [value]=\"value()\"\n (update)=\"onValueChange()\"\n (immediateUpdate)=\"onImmediateChange($event)\"\n />\n</div>\n", styles: [".form-field-item{margin-bottom:16px}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormFieldItemComponent, selector: "ng-dhis2-ui-form-field-item" }] }); }
7042
7237
  }
7043
7238
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: FormFieldComponent, decorators: [{
7044
7239
  type: Component,
@@ -7178,7 +7373,7 @@ class FormComponent {
7178
7373
  this.ruleProcessor.destroy();
7179
7374
  }
7180
7375
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: FormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7181
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.3", type: FormComponent, isStandalone: false, selector: "ng-dhis2-ui-form", inputs: { formConfig: { classPropertyName: "formConfig", publicName: "formConfig", isSignal: true, isRequired: false, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, isFormHorizontal: { classPropertyName: "isFormHorizontal", publicName: "isFormHorizontal", isSignal: true, isRequired: false, transformFunction: null }, showSaveButton: { classPropertyName: "showSaveButton", publicName: "showSaveButton", isSignal: true, isRequired: false, transformFunction: null }, fieldsData: { classPropertyName: "fieldsData", publicName: "fieldsData", isSignal: true, isRequired: false, transformFunction: null }, fieldClass: { classPropertyName: "fieldClass", publicName: "fieldClass", isSignal: true, isRequired: false, transformFunction: null }, shouldRenderAsCheckBoxesButton: { classPropertyName: "shouldRenderAsCheckBoxesButton", publicName: "shouldRenderAsCheckBoxesButton", isSignal: true, isRequired: false, transformFunction: null }, programRuleActions: { classPropertyName: "programRuleActions", publicName: "programRuleActions", isSignal: true, isRequired: false, transformFunction: null }, dataEntities: { classPropertyName: "dataEntities", publicName: "dataEntities", isSignal: true, isRequired: false, transformFunction: null }, dataId: { classPropertyName: "dataId", publicName: "dataId", isSignal: true, isRequired: false, transformFunction: null }, customOrgUnitRoots: { classPropertyName: "customOrgUnitRoots", publicName: "customOrgUnitRoots", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { formUpdate: "formUpdate", formValidityUpdate: "formValidityUpdate" }, viewQueries: [{ propertyName: "fieldComponents", predicate: FormFieldComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"form()\" class=\"{{ configuration().directionClassName }}\">\n <!-- form name -->\n <div class=\"form-name\">\n <h2>{{ configuration().formName }}</h2>\n </div>\n <div\n *ngFor=\"let field of sanitizedFields\"\n class=\"form-field-{{ configuration().direction }}\"\n >\n <ng-dhis2-ui-form-field\n [field]=\"field\"\n [fieldConfig]=\"configuration().fieldConfig\"\n [form]=\"form()\"\n [fieldClass]=\"fieldClass()\"\n [dataEntities]=\"dataEntities()\"\n [dataId]=\"dataId()\"\n [customOrgUnitRoots]=\"customOrgUnitRoots()\"\n [programRuleActions]=\"programRuleActions()\"\n [isCheckBoxButton]=\"shouldRenderAsCheckBoxesButton()\"\n (fieldUpdate)=\"onFieldUpdate($event, field)\"\n (runtimeOptionChange)=\"onRunTimeOptionUpdate($event)\"\n />\n </div>\n</form>\n", styles: [".form-horizontal{display:flex;flex-wrap:wrap;gap:16px;width:100%}.hidden-field{display:none}.units-and-ranges span{margin-left:1%;font-weight:600}.for-warning{margin-left:8px}.form-field-vertical{margin-bottom:8px}.form-field-horizontal{flex:1;margin-bottom:8px;width:100%}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FormFieldComponent, selector: "ng-dhis2-ui-form-field", inputs: ["field", "fieldConfig", "form", "isCheckBoxButton", "fieldClass", "programRuleActions", "dataEntities", "minDate", "maxDate", "dataId", "customOrgUnitRoots"], outputs: ["fieldUpdate", "immediateFieldUpdate", "runtimeOptionChange"] }] }); }
7376
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.3", type: FormComponent, isStandalone: false, selector: "ng-dhis2-ui-form", inputs: { formConfig: { classPropertyName: "formConfig", publicName: "formConfig", isSignal: true, isRequired: false, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, isFormHorizontal: { classPropertyName: "isFormHorizontal", publicName: "isFormHorizontal", isSignal: true, isRequired: false, transformFunction: null }, showSaveButton: { classPropertyName: "showSaveButton", publicName: "showSaveButton", isSignal: true, isRequired: false, transformFunction: null }, fieldsData: { classPropertyName: "fieldsData", publicName: "fieldsData", isSignal: true, isRequired: false, transformFunction: null }, fieldClass: { classPropertyName: "fieldClass", publicName: "fieldClass", isSignal: true, isRequired: false, transformFunction: null }, shouldRenderAsCheckBoxesButton: { classPropertyName: "shouldRenderAsCheckBoxesButton", publicName: "shouldRenderAsCheckBoxesButton", isSignal: true, isRequired: false, transformFunction: null }, programRuleActions: { classPropertyName: "programRuleActions", publicName: "programRuleActions", isSignal: true, isRequired: false, transformFunction: null }, dataEntities: { classPropertyName: "dataEntities", publicName: "dataEntities", isSignal: true, isRequired: false, transformFunction: null }, dataId: { classPropertyName: "dataId", publicName: "dataId", isSignal: true, isRequired: false, transformFunction: null }, customOrgUnitRoots: { classPropertyName: "customOrgUnitRoots", publicName: "customOrgUnitRoots", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { formUpdate: "formUpdate", formValidityUpdate: "formValidityUpdate" }, viewQueries: [{ propertyName: "fieldComponents", predicate: FormFieldComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"form()\" class=\"{{ configuration().directionClassName }}\">\n <!-- form name -->\n <div class=\"form-name\">\n <h2>{{ configuration().formName }}</h2>\n </div>\n <div\n *ngFor=\"let field of sanitizedFields\"\n class=\"form-field-{{ configuration().direction }}\"\n >\n <ng-dhis2-ui-form-field\n [field]=\"field\"\n [fieldConfig]=\"configuration().fieldConfig\"\n [form]=\"form()\"\n [fieldClass]=\"fieldClass()\"\n [dataEntities]=\"dataEntities()\"\n [dataId]=\"dataId()\"\n [customOrgUnitRoots]=\"customOrgUnitRoots()\"\n [programRuleActions]=\"programRuleActions()\"\n [isCheckBoxButton]=\"shouldRenderAsCheckBoxesButton()\"\n (fieldUpdate)=\"onFieldUpdate($event, field)\"\n (runtimeOptionChange)=\"onRunTimeOptionUpdate($event)\"\n />\n </div>\n</form>\n", styles: [".form-horizontal{display:flex;flex-wrap:wrap;gap:16px;width:100%}.hidden-field{display:none}.units-and-ranges span{margin-left:1%;font-weight:600}.for-warning{margin-left:8px}.form-field-vertical{margin-bottom:8px}.form-field-horizontal{flex:1;margin-bottom:8px;width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FormFieldComponent, selector: "ng-dhis2-ui-form-field", inputs: ["field", "fieldConfig", "form", "isCheckBoxButton", "fieldClass", "programRuleActions", "dataEntities", "minDate", "maxDate", "dataId", "customOrgUnitRoots"], outputs: ["fieldUpdate", "immediateFieldUpdate", "runtimeOptionChange"] }] }); }
7182
7377
  }
7183
7378
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: FormComponent, decorators: [{
7184
7379
  type: Component,
@@ -7370,7 +7565,7 @@ class SectionFormComponent {
7370
7565
  return valueValidity || repeatableDataValidity;
7371
7566
  }
7372
7567
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SectionFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7373
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: SectionFormComponent, isStandalone: false, selector: "ng-dhis2-ui-section-form", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, formMetaData: { classPropertyName: "formMetaData", publicName: "formMetaData", isSignal: true, isRequired: true, transformFunction: null }, dataValueEntities: { classPropertyName: "dataValueEntities", publicName: "dataValueEntities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { save: "save", formUpdate: "formUpdate", cancel: "cancel", formValidityUpdate: "formValidityUpdate" }, ngImport: i0, template: "<ng-container *ngIf=\"formMetaData()\">\n <ng-container *ngFor=\"let formSection of formMetaData().sections\">\n @if(formSection?.name; as sectionName) {\n <div class=\"form__section-name\">\n {{ sectionName }}\n </div>\n }\n <div class=\"form__section-content\">\n <ng-container *ngIf=\"formSection\">\n <div *ngFor=\"let fieldGroup of formSection?.fieldGroups\">\n <ng-container *ngIf=\"formGroups[fieldGroup.id] as formGroup\">\n <div\n *ngIf=\"fieldGroup.name && !fieldGroup.repeatableStage\"\n class=\"form__field-group-name\"\n >\n {{ fieldGroup?.name }}\n </div>\n <div *ngIf=\"fieldGroup.fields\">\n <!-- Single stage form section -->\n <ng-container *ngIf=\"!fieldGroup.repeatableStage\">\n <ng-dhis2-ui-form\n *ngIf=\"fieldGroup.fields.length > 0\"\n [fields]=\"fieldGroup.fields\"\n [form]=\"formGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [programRuleActions]=\"ruleActions()\"\n [isFormHorizontal]=\"fieldGroup.isFormHorizontal || false\"\n (formUpdate)=\"onFormUpdate($event, fieldGroup.id)\"\n ></ng-dhis2-ui-form>\n </ng-container>\n\n <!-- Repeatable stage form section -->\n <ng-container *ngIf=\"fieldGroup.repeatableStage\">\n @if(fieldGroup.repeatDependentField) {\n\n <ng-container *ngIf=\"fieldGroup.repeatDependentField\">\n <ng-container\n *ngIf=\"{\n numberOfRows:\n dataValueEntities()[fieldGroup.repeatDependentField]\n } as dataParams\"\n >\n <ng-dhis2-ui-repeatable-form\n *ngIf=\"\n dataParams.numberOfRows &&\n dataParams.numberOfRows !== '0'\n \"\n [fieldGroup]=\"fieldGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [form]=\"formGroup\"\n [program]=\"formSection.program || ''\"\n [programStage]=\"fieldGroup.repeatableStage\"\n [programRuleActions]=\"ruleActions()\"\n [numberOfRows]=\"+dataParams.numberOfRows\"\n [repeatDependentField]=\"\n fieldGroup.repeatDependentField || ''\n \"\n [events]=\"dataValueEntities()[fieldGroup.dataKey!]\"\n (repeatableStageUpdate)=\"\n onUpdateRepeatableStage($event, fieldGroup)\n \"\n ></ng-dhis2-ui-repeatable-form\n ></ng-container>\n </ng-container>\n } @else {\n <ng-dhis2-ui-repeatable-form\n [fieldGroup]=\"fieldGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [form]=\"formGroup\"\n [program]=\"formSection.program || ''\"\n [programStage]=\"fieldGroup.repeatableStage\"\n [programRuleActions]=\"ruleActions()\"\n [numberOfRows]=\"1\"\n [repeatDependentField]=\"fieldGroup.repeatDependentField || ''\"\n [events]=\"dataValueEntities()[fieldGroup.dataKey!]\"\n (repeatableStageUpdate)=\"\n onUpdateRepeatableStage($event, fieldGroup)\n \"\n ></ng-dhis2-ui-repeatable-form>\n }\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</ng-container>\n", styles: [".form__section-name{font-size:16px;font-weight:600;margin-bottom:16px}.form__section-content{margin-bottom:24px}.form__field-group-name{font-size:14px;font-weight:500;padding-bottom:8px;border-bottom:solid 1px rgb(232,237,242);margin-bottom:16px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormComponent, selector: "ng-dhis2-ui-form", inputs: ["formConfig", "fields", "form", "isFormHorizontal", "showSaveButton", "fieldsData", "fieldClass", "shouldRenderAsCheckBoxesButton", "programRuleActions", "dataEntities", "dataId", "customOrgUnitRoots"], outputs: ["formUpdate", "formValidityUpdate"] }, { kind: "component", type: RepeatableFormComponent, selector: "ng-dhis2-ui-repeatable-form", inputs: ["formObject", "formData", "fieldGroup", "form", "numberOfRows", "programRuleActions", "events", "program", "programStage", "repeatDependentField", "dataEntities"], outputs: ["eventsChange", "repeatableStageUpdate"] }] }); }
7568
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: SectionFormComponent, isStandalone: false, selector: "ng-dhis2-ui-section-form", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, formMetaData: { classPropertyName: "formMetaData", publicName: "formMetaData", isSignal: true, isRequired: true, transformFunction: null }, dataValueEntities: { classPropertyName: "dataValueEntities", publicName: "dataValueEntities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { save: "save", formUpdate: "formUpdate", cancel: "cancel", formValidityUpdate: "formValidityUpdate" }, ngImport: i0, template: "<ng-container *ngIf=\"formMetaData()\">\n <ng-container *ngFor=\"let formSection of formMetaData().sections\">\n @if(formSection?.name; as sectionName) {\n <div class=\"form__section-name\">\n {{ sectionName }}\n </div>\n }\n <div class=\"form__section-content\">\n <ng-container *ngIf=\"formSection\">\n <div *ngFor=\"let fieldGroup of formSection?.fieldGroups\">\n <ng-container *ngIf=\"formGroups[fieldGroup.id] as formGroup\">\n <div\n *ngIf=\"fieldGroup.name && !fieldGroup.repeatableStage\"\n class=\"form__field-group-name\"\n >\n {{ fieldGroup?.name }}\n </div>\n <div *ngIf=\"fieldGroup.fields\">\n <!-- Single stage form section -->\n <ng-container *ngIf=\"!fieldGroup.repeatableStage\">\n <ng-dhis2-ui-form\n *ngIf=\"fieldGroup.fields.length > 0\"\n [fields]=\"fieldGroup.fields\"\n [form]=\"formGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [programRuleActions]=\"ruleActions()\"\n [isFormHorizontal]=\"fieldGroup.isFormHorizontal || false\"\n (formUpdate)=\"onFormUpdate($event, fieldGroup.id)\"\n ></ng-dhis2-ui-form>\n </ng-container>\n\n <!-- Repeatable stage form section -->\n <ng-container *ngIf=\"fieldGroup.repeatableStage\">\n @if(fieldGroup.repeatDependentField) {\n\n <ng-container *ngIf=\"fieldGroup.repeatDependentField\">\n <ng-container\n *ngIf=\"{\n numberOfRows:\n dataValueEntities()[fieldGroup.repeatDependentField]\n } as dataParams\"\n >\n <ng-dhis2-ui-repeatable-form\n *ngIf=\"\n dataParams.numberOfRows &&\n dataParams.numberOfRows !== '0'\n \"\n [fieldGroup]=\"fieldGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [form]=\"formGroup\"\n [program]=\"formSection.program || ''\"\n [programStage]=\"fieldGroup.repeatableStage\"\n [programRuleActions]=\"ruleActions()\"\n [numberOfRows]=\"+dataParams.numberOfRows\"\n [repeatDependentField]=\"\n fieldGroup.repeatDependentField || ''\n \"\n [events]=\"dataValueEntities()[fieldGroup.dataKey!]\"\n (repeatableStageUpdate)=\"\n onUpdateRepeatableStage($event, fieldGroup)\n \"\n ></ng-dhis2-ui-repeatable-form\n ></ng-container>\n </ng-container>\n } @else {\n <ng-dhis2-ui-repeatable-form\n [fieldGroup]=\"fieldGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [form]=\"formGroup\"\n [program]=\"formSection.program || ''\"\n [programStage]=\"fieldGroup.repeatableStage\"\n [programRuleActions]=\"ruleActions()\"\n [numberOfRows]=\"1\"\n [repeatDependentField]=\"fieldGroup.repeatDependentField || ''\"\n [events]=\"dataValueEntities()[fieldGroup.dataKey!]\"\n (repeatableStageUpdate)=\"\n onUpdateRepeatableStage($event, fieldGroup)\n \"\n ></ng-dhis2-ui-repeatable-form>\n }\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</ng-container>\n", styles: [".form__section-name{font-size:16px;font-weight:600;margin-bottom:16px}.form__section-content{margin-bottom:24px}.form__field-group-name{font-size:14px;font-weight:500;padding-bottom:8px;border-bottom:solid 1px rgb(232,237,242);margin-bottom:16px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormComponent, selector: "ng-dhis2-ui-form", inputs: ["formConfig", "fields", "form", "isFormHorizontal", "showSaveButton", "fieldsData", "fieldClass", "shouldRenderAsCheckBoxesButton", "programRuleActions", "dataEntities", "dataId", "customOrgUnitRoots"], outputs: ["formUpdate", "formValidityUpdate"] }, { kind: "component", type: RepeatableFormComponent, selector: "ng-dhis2-ui-repeatable-form", inputs: ["formObject", "formData", "fieldGroup", "form", "numberOfRows", "programRuleActions", "events", "program", "programStage", "repeatDependentField", "dataEntities"], outputs: ["eventsChange", "repeatableStageUpdate"] }] }); }
7374
7569
  }
7375
7570
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SectionFormComponent, decorators: [{
7376
7571
  type: Component,
@@ -8652,5 +8847,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
8652
8847
  * Generated bundle index. Do not edit.
8653
8848
  */
8654
8849
 
8655
- export { Boolean$1 as Boolean, BreadcrumbComponent, BreadcrumbModule, ButtonComponent, ButtonModule, CheckBox, D2FormModule, DataTableUIComponent, DataTableUIModule, DateField, DateRangeValue, Dropdown, EventFormComponent, EventFormModule, FieldConfig, FieldControlTypeUtil, FieldDropdown, FieldType, FieldUtil, FlatFormComponent, FormComponent, FormConfig, FormField, FormFieldComponent, FormFieldGroup, FormFieldTypeUtil, FormMetaData, FormMetadataSection, FormUtil, FormValue, FormValueUtil, HeaderBarComponent, HeaderBarModule, LineListModule, LineListTableComponent, MetadataRule, MetadataRuleAction, OrganisationUnitSelectionConfig, OrganisationUnitSelectorComponent, OrganisationUnitSelectorModalComponent, OrganisationUnitSelectorModule, PeriodSelectorComponent, PeriodSelectorModalComponent, PeriodSelectorModule, ProgramEntryFormConfig, ProgramEntryFormMetaData, ProgramEntryFormModule, ProgramEntryFormSection, ReactWrapperModule, RepeatableFormComponent, SectionFormComponent, SelectionFiltersComponent, SelectionFiltersUiModule, TrackerFormComponent, TrackerFormModule, TranslationUtil };
8850
+ export { Boolean$1 as Boolean, BreadcrumbComponent, BreadcrumbModule, ButtonComponent, ButtonModule, CheckBox, D2FormModule, DataTableUIComponent, DataTableUIModule, DateField, DateRangeValue, Dropdown, EventFormComponent, EventFormModule, FieldConfig, FieldControlTypeUtil, FieldDropdown, FieldType, FieldUtil, FlatFormComponent, FormComponent, FormConfig, FormField, FormFieldComponent, FormFieldGroup, FormFieldTypeUtil, FormMetaData, FormMetadataSection, FormUtil, FormValue, FormValueUtil, HeaderBarComponent, HeaderBarModule, LineListModule, LineListTableComponent, MetadataRule, MetadataRuleAction, OrgUnitLevel, OrganisationUnitSelectionConfig, OrganisationUnitSelectorComponent, OrganisationUnitSelectorModalComponent, OrganisationUnitSelectorModule, PeriodSelectorComponent, PeriodSelectorModalComponent, PeriodSelectorModule, ProgramEntryFormConfig, ProgramEntryFormMetaData, ProgramEntryFormModule, ProgramEntryFormSection, ReactWrapperModule, RepeatableFormComponent, SectionFormComponent, SelectionFiltersComponent, SelectionFiltersUiModule, TrackerFormComponent, TrackerFormModule, TranslationUtil };
8656
8851
  //# sourceMappingURL=iapps-ng-dhis2-ui.mjs.map