@iapps/ng-dhis2-ui 1.1.1 → 1.1.2

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.
Files changed (29) hide show
  1. package/fesm2022/iapps-ng-dhis2-ui.mjs +436 -232
  2. package/fesm2022/iapps-ng-dhis2-ui.mjs.map +1 -1
  3. package/index.d.ts +2 -1
  4. package/lib/modules/button/button.component.d.ts +2 -2
  5. package/lib/modules/form/components/base-form-field.component.d.ts +2 -2
  6. package/lib/modules/form/containers/repeatable-form/repeatable-form.component.d.ts +11 -4
  7. package/lib/modules/form/containers/section-form/section-form.component.d.ts +10 -9
  8. package/lib/modules/form/form.module.d.ts +3 -2
  9. package/lib/modules/form/interfaces/form-field-group.interface.d.ts +2 -1
  10. package/lib/modules/form/models/form-field-group.model.d.ts +1 -1
  11. package/lib/modules/form/models/form-metadata.model.d.ts +2 -1
  12. package/lib/modules/form/models/form-value.model.d.ts +3 -1
  13. package/lib/modules/form/utils/index.d.ts +1 -0
  14. package/lib/modules/form/utils/translation.util.d.ts +3 -0
  15. package/lib/modules/header-bar/header-bar.component.d.ts +2 -2
  16. package/lib/modules/line-list/containers/line-list.component.d.ts +6 -5
  17. package/lib/modules/line-list/models/line-list.models.d.ts +43 -0
  18. package/lib/modules/line-list/services/line-list.service.d.ts +1 -1
  19. package/lib/modules/organisation-unit-selector/containers/organisation-unit-selector/organisation-unit-selector.component.d.ts +2 -2
  20. package/lib/modules/organisation-unit-selector/containers/organisation-unit-selector-modal/organisation-unit-selector-modal.component-modal.d.ts +2 -2
  21. package/lib/modules/period-selector/containers/period-selector/period-selector.component.d.ts +2 -2
  22. package/lib/modules/period-selector/containers/period-selector-modal/period-selector-modal.component.d.ts +2 -2
  23. package/lib/modules/react-wrapper/react-wrapper.component.d.ts +3 -3
  24. package/lib/modules/tracker-form/index.d.ts +2 -0
  25. package/lib/modules/tracker-form/tracker-form.component.d.ts +15 -0
  26. package/lib/modules/tracker-form/tracker-form.module.d.ts +9 -0
  27. package/package.json +1 -1
  28. package/lib/modules/react-wrapper/index.d.ts +0 -2
  29. package/lib/modules/react-wrapper/react-wrapper.module.d.ts +0 -8
@@ -27,7 +27,7 @@ import { MenuItem, MenuDivider } from '@dhis2-ui/menu';
27
27
  import parse from 'html-react-parser';
28
28
  import { Button as Button$1, IconDimensionData16, IconClock16, IconDimensionOrgUnit16, spacers as spacers$1, colors as colors$1, IconEdit16, theme as theme$1, Tooltip, 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, Layer as Layer$1, Popper, FlyoutMenu, MenuItem as MenuItem$1, IconMore24, CircularLoader as CircularLoader$1, DataTable, TableHead, DataTableRow, DataTableColumnHeader, TableBody, DataTableCell, TableFoot, Pagination, FileInputField, FileListItem, TextAreaField } from '@dhis2/ui';
29
29
  import { getNowInCalendar, generateFixedPeriods } from '@dhis2/multi-calendar-dates';
30
- import { isObject, isString, sortBy, isArray, find, camelCase, flatten, head, range } from 'lodash';
30
+ import { isObject, isString, sortBy, isArray, find, camelCase, flatten, head, isEmpty } from 'lodash';
31
31
  import cx from 'classnames';
32
32
  import { map as map$1, switchMap } from 'rxjs/operators';
33
33
  import * as i2 from '@angular/forms';
@@ -1018,7 +1018,7 @@ HeaderBar.propTypes = {
1018
1018
  };
1019
1019
 
1020
1020
  window.React = React;
1021
- class ReactWrapperComponent {
1021
+ class ReactWrapperModule {
1022
1022
  constructor(elementRef) {
1023
1023
  this.elementRef = elementRef;
1024
1024
  }
@@ -1047,14 +1047,13 @@ class ReactWrapperComponent {
1047
1047
  " "));
1048
1048
  }
1049
1049
  }
1050
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1051
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.8", type: ReactWrapperComponent, isStandalone: false, selector: "ng-dhis2-ui-wrapper", inputs: { props: "props", component: "component" }, queries: [{ propertyName: "content", first: true, predicate: ["ngDhis2UiContent"], descendants: true }], ngImport: i0 }); }
1050
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1051
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.8", 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 }); }
1052
1052
  }
1053
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperComponent, decorators: [{
1053
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, decorators: [{
1054
1054
  type: Directive,
1055
1055
  args: [{
1056
1056
  selector: 'ng-dhis2-ui-wrapper',
1057
- standalone: false,
1058
1057
  }]
1059
1058
  }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { props: [{
1060
1059
  type: Input
@@ -1065,25 +1064,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
1065
1064
  args: ['ngDhis2UiContent']
1066
1065
  }] } });
1067
1066
 
1068
- class ReactWrapperModule {
1069
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1070
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, declarations: [ReactWrapperComponent], imports: [CommonModule], exports: [ReactWrapperComponent] }); }
1071
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, imports: [CommonModule] }); }
1072
- }
1073
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, decorators: [{
1074
- type: NgModule,
1075
- args: [{
1076
- imports: [CommonModule],
1077
- declarations: [ReactWrapperComponent],
1078
- exports: [ReactWrapperComponent],
1079
- }]
1080
- }] });
1081
-
1082
- // Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
1083
- // Use of this source code is governed by a BSD-style
1084
- // license that can be found in the LICENSE file.
1085
-
1086
- class HeaderBarComponent extends ReactWrapperComponent {
1067
+ class HeaderBarComponent extends ReactWrapperModule {
1087
1068
  constructor(elementRef, httpClient) {
1088
1069
  super(elementRef);
1089
1070
  this.httpClient = httpClient;
@@ -1107,7 +1088,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
1107
1088
  args: [{
1108
1089
  selector: 'ng-dhis2-ui-header-bar',
1109
1090
  template: `<ng-container></ng-container>`,
1110
- standalone: false
1091
+ standalone: false,
1111
1092
  }]
1112
1093
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }] });
1113
1094
 
@@ -1129,7 +1110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
1129
1110
  // Use of this source code is governed by a BSD-style
1130
1111
  // license that can be found in the LICENSE file.
1131
1112
 
1132
- class ButtonComponent extends ReactWrapperComponent {
1113
+ class ButtonComponent extends ReactWrapperModule {
1133
1114
  constructor() {
1134
1115
  super(...arguments);
1135
1116
  this.buttonClick = new EventEmitter();
@@ -1164,7 +1145,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
1164
1145
  args: [{
1165
1146
  selector: 'ng-dhis2-ui-button',
1166
1147
  template: '<ng-content></ng-content>',
1167
- standalone: false
1148
+ standalone: false,
1168
1149
  }]
1169
1150
  }], propDecorators: { label: [{
1170
1151
  type: Input
@@ -2251,7 +2232,7 @@ PeriodDimension.defaultProps = {
2251
2232
  selectedPeriods: [],
2252
2233
  };
2253
2234
 
2254
- class PeriodSelectorModalComponent extends ReactWrapperComponent {
2235
+ class PeriodSelectorModalComponent extends ReactWrapperModule {
2255
2236
  constructor(elementRef, httpClient) {
2256
2237
  super(elementRef);
2257
2238
  this.httpClient = httpClient;
@@ -2321,7 +2302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
2321
2302
  type: Output
2322
2303
  }] } });
2323
2304
 
2324
- class PeriodSelectorComponent extends ReactWrapperComponent {
2305
+ class PeriodSelectorComponent extends ReactWrapperModule {
2325
2306
  constructor(elementRef, httpClient, ngZone) {
2326
2307
  super(elementRef);
2327
2308
  this.httpClient = httpClient;
@@ -2758,7 +2739,7 @@ class OrganisationUnitSelectionConfig {
2758
2739
  // Use of this source code is governed by a BSD-style
2759
2740
  // license that can be found in the LICENSE file.
2760
2741
 
2761
- class OrganisationUnitSelectorComponent extends ReactWrapperComponent {
2742
+ class OrganisationUnitSelectorComponent extends ReactWrapperModule {
2762
2743
  constructor(elementRef, httpClient, ngZone) {
2763
2744
  super(elementRef);
2764
2745
  this.httpClient = httpClient;
@@ -2839,7 +2820,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
2839
2820
  type: Output
2840
2821
  }] } });
2841
2822
 
2842
- class OrganisationUnitSelectorModalComponent extends ReactWrapperComponent {
2823
+ class OrganisationUnitSelectorModalComponent extends ReactWrapperModule {
2843
2824
  constructor(elementRef, httpClient) {
2844
2825
  super(elementRef);
2845
2826
  this.httpClient = httpClient;
@@ -2967,6 +2948,102 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
2967
2948
  // Use of this source code is governed by a BSD-style
2968
2949
  // license that can be found in the LICENSE file.
2969
2950
 
2951
+ const dropdownStyles = {
2952
+ layer: {
2953
+ zIndex: '1 !important',
2954
+ },
2955
+ };
2956
+
2957
+ // Helper function to generate a unique class name
2958
+ const generateClassName = (base) => `${base}-${Math.random().toString(36).substr(2, 9)}`;
2959
+ // Helper function to convert camelCased properties to hyphenated CSS properties
2960
+ const convertStylesToCSS = (className, styles) => {
2961
+ let cssString = `.${className} {`;
2962
+ for (const key in styles) {
2963
+ if (typeof styles[key] === "object" && key.startsWith("@media")) {
2964
+ const mediaStyles = convertStylesToCSS(className, styles[key]);
2965
+ cssString += `${key} { ${mediaStyles} }`;
2966
+ }
2967
+ else if (key.startsWith("&:")) {
2968
+ const pseudoClass = key.replace("&", "");
2969
+ cssString += `${pseudoClass} { ${convertStylesToCSS("", styles[key])} }`;
2970
+ }
2971
+ else {
2972
+ const cssKey = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
2973
+ cssString += `${cssKey}: ${styles[key]}; `;
2974
+ }
2975
+ }
2976
+ cssString += "}";
2977
+ return cssString;
2978
+ };
2979
+ // Custom hook for dynamic styles with generics
2980
+ const useDynamicStyles = (stylesObj) => {
2981
+ const [classNames, setClassNames] = useState({});
2982
+ useEffect(() => {
2983
+ const convertedStyles = Object.keys(stylesObj).map((key) => {
2984
+ const className = generateClassName(key);
2985
+ const styleElement = document.createElement("style");
2986
+ styleElement.innerHTML = convertStylesToCSS(className, stylesObj[key]);
2987
+ document.head.appendChild(styleElement);
2988
+ return {
2989
+ key,
2990
+ className,
2991
+ styleElement,
2992
+ };
2993
+ });
2994
+ setClassNames(convertedStyles.reduce((classNameEntity, convertedStyle) => {
2995
+ return {
2996
+ ...classNameEntity,
2997
+ [convertedStyle.key]: convertedStyle.className,
2998
+ };
2999
+ }, {}));
3000
+ return () => {
3001
+ convertedStyles.forEach((convertedStyle) => {
3002
+ document.head.removeChild(convertedStyle.styleElement);
3003
+ });
3004
+ };
3005
+ }, []);
3006
+ return classNames;
3007
+ };
3008
+
3009
+ const useCurrentModal = () => {
3010
+ const [CurrentModal, setCurrentModal] = useState();
3011
+ return [
3012
+ CurrentModal,
3013
+ (Modal) => {
3014
+ // As setState supports functional updates, we can't pass functional
3015
+ // components directly
3016
+ setCurrentModal(() => Modal);
3017
+ },
3018
+ ];
3019
+ };
3020
+ const ContextMenu = (params) => {
3021
+ const { onClose, onMenuClick, anchorRef, dropDownOptions } = params;
3022
+ const [CurrentModal, setCurrentModal] = useCurrentModal();
3023
+ const styles = useDynamicStyles(dropdownStyles);
3024
+ return (React__default.createElement(React__default.Fragment, null,
3025
+ React__default.createElement(Layer$1, { onBackdropClick: (event, data) => onClose(event, data), className: styles.layer },
3026
+ React__default.createElement(Popper, { reference: anchorRef, placement: "bottom-start" },
3027
+ React__default.createElement(FlyoutMenu, null, dropDownOptions.map((dropDownOption, index) => (React__default.createElement(MenuItem$1, { key: index, destructive: dropDownOption.destructive, label: dropDownOption.label, icon: dropDownOption.icon, onClick: () => {
3028
+ onMenuClick(dropDownOption);
3029
+ onClose();
3030
+ }, dense: true })))))),
3031
+ CurrentModal && (React__default.createElement(CurrentModal, { onClose: () => {
3032
+ onClose();
3033
+ setCurrentModal(null);
3034
+ } }))));
3035
+ };
3036
+ const DropdownMenu = (props) => {
3037
+ const ref = useRef();
3038
+ const [visible, setVisible] = useState(false);
3039
+ const { dropdownOptions, onClick } = props;
3040
+ return (React__default.createElement("div", { ref: ref, style: { display: "inline-block" } },
3041
+ React__default.createElement(Button$1, { small: true, secondary: true, icon: React__default.createElement(IconMore24, { color: colors$1.grey600 }), onClick: () => setVisible(true) }),
3042
+ visible && (React__default.createElement(ContextMenu, { dropDownOptions: dropdownOptions, anchorRef: ref, onClose: () => setVisible(false), onMenuClick: (dropDownOption) => {
3043
+ onClick(dropDownOption);
3044
+ } }))));
3045
+ };
3046
+
2970
3047
  // export function buildFilters(filters: AttributeFilter[]): string {
2971
3048
  // return filters
2972
3049
  // .map(({ attribute, operator, value }) => `filter=${attribute}:${operator}:${value}`)
@@ -3031,12 +3108,13 @@ class LineListService {
3031
3108
  this.httpClient = httpClient;
3032
3109
  }
3033
3110
  getProgramMetadata(programId) {
3034
- return this.httpClient.get(`programs/${programId}.json?fields=programType,programStages[id,name,programStageDataElements[dataElement[id,name]]],organisationUnits[id,name]`);
3111
+ return this.httpClient.get(`programs/${programId}.json?fields=programType,programStages[id,name,programStageDataElements[dataElement[id,name]]],organisationUnits[id,name],*`);
3035
3112
  }
3036
- getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
3113
+ getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters = [], startDate, endDate, ouMode) {
3037
3114
  const filterParams = buildFilters(filters);
3038
3115
  const dateFilter = startDate && endDate ? `&programStartDate=${startDate}&programEndDate=${endDate}` : '';
3039
- return this.httpClient.get(`trackedEntityInstances.json?program=${programId}&ou=${orgUnit}&page=${page}&pageSize=${pageSize}&fields=trackedEntityInstance,attributes[*],enrollments[*]&totalPages=true&${filterParams}${dateFilter}`).pipe(map$1((response) => {
3116
+ const ouModeIdentifier = ouMode ? `&ouMode=${ouMode}` : ``;
3117
+ return this.httpClient.get(`trackedEntityInstances.json?program=${programId}&ou=${orgUnit}${ouModeIdentifier}&page=${page}&pageSize=${pageSize}&fields=trackedEntityInstance,attributes[*,displayInList],enrollments[*]&totalPages=true&${filterParams}${dateFilter}`).pipe(map$1((response) => {
3040
3118
  response.trackedEntityInstances.forEach((tei) => {
3041
3119
  // Filter attributes to only include those with displayInList=true
3042
3120
  tei.attributes = tei.attributes.filter((attr) => attr.displayInList);
@@ -3044,32 +3122,34 @@ class LineListService {
3044
3122
  return response;
3045
3123
  }));
3046
3124
  }
3047
- getEvents(programId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
3125
+ getEvents(programId, orgUnit, page, pageSize, filters = [], startDate, endDate, ouMode) {
3048
3126
  const filterParams = buildFilters(filters);
3049
3127
  const dateFilter = startDate && endDate ? `&startDate=${startDate}&endDate=${endDate}` : '';
3050
- return this.httpClient.get(`events.json?program=${programId}&orgUnit=${orgUnit}&page=${page}&pageSize=${pageSize}&fields=*&totalPages=true&${filterParams}${dateFilter}`);
3128
+ const ouModeIdentifier = ouMode ? `&ouMode=${ouMode}` : ``;
3129
+ return this.httpClient.get(`events.json?program=${programId}&orgUnit=${orgUnit}${ouModeIdentifier}&page=${page}&pageSize=${pageSize}&fields=*&totalPages=true&${filterParams}${dateFilter}`);
3051
3130
  }
3052
- getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
3131
+ getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters = [], startDate, endDate, ouMode) {
3053
3132
  const filterParams = buildFilters(filters);
3054
3133
  const dateFilter = startDate && endDate ? `&startDate=${startDate}&endDate=${endDate}` : '';
3055
- return this.httpClient.get(`events.json?programStage=${programStageId}&orgUnit=${orgUnit}&page=${page}&pageSize=${pageSize}&fields=*&totalPages=true&${filterParams}${dateFilter}`);
3134
+ const ouModeIdentifier = ouMode ? `&ouMode=${ouMode}` : ``;
3135
+ return this.httpClient.get(`events.json?programStage=${programStageId}&orgUnit=${orgUnit}${ouModeIdentifier}&page=${page}&pageSize=${pageSize}&fields=*&totalPages=true&${filterParams}${dateFilter}`);
3056
3136
  }
3057
- getLineListData(programId, orgUnit = '', programStageId, page = 1, pageSize = 10, filters = [], startDate, endDate) {
3137
+ getLineListData(programId, orgUnit = '', programStageId, page = 1, pageSize = 10, filters = [], startDate, endDate, ouMode) {
3058
3138
  return this.getProgramMetadata(programId).pipe(switchMap((programMetadata) => {
3059
3139
  if (programStageId) {
3060
- return this.getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((events) => ({
3140
+ return this.getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters, startDate, endDate, ouMode).pipe(map$1((events) => ({
3061
3141
  metadata: programMetadata,
3062
3142
  data: events,
3063
3143
  })));
3064
3144
  }
3065
3145
  if (programMetadata.programType === 'WITH_REGISTRATION') {
3066
- return this.getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((teis) => ({
3146
+ return this.getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters, startDate, endDate, ouMode).pipe(map$1((teis) => ({
3067
3147
  metadata: programMetadata,
3068
3148
  data: teis,
3069
3149
  })));
3070
3150
  }
3071
3151
  else {
3072
- return this.getEvents(programId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((events) => ({
3152
+ return this.getEvents(programId, orgUnit, page, pageSize, filters, startDate, endDate, ouMode).pipe(map$1((events) => ({
3073
3153
  metadata: programMetadata,
3074
3154
  data: events,
3075
3155
  })));
@@ -3083,102 +3163,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
3083
3163
  type: Injectable
3084
3164
  }], ctorParameters: () => [{ type: i1.NgxDhis2HttpClientService }] });
3085
3165
 
3086
- const dropdownStyles = {
3087
- layer: {
3088
- zIndex: '1 !important',
3089
- },
3090
- };
3091
-
3092
- // Helper function to generate a unique class name
3093
- const generateClassName = (base) => `${base}-${Math.random().toString(36).substr(2, 9)}`;
3094
- // Helper function to convert camelCased properties to hyphenated CSS properties
3095
- const convertStylesToCSS = (className, styles) => {
3096
- let cssString = `.${className} {`;
3097
- for (const key in styles) {
3098
- if (typeof styles[key] === "object" && key.startsWith("@media")) {
3099
- const mediaStyles = convertStylesToCSS(className, styles[key]);
3100
- cssString += `${key} { ${mediaStyles} }`;
3101
- }
3102
- else if (key.startsWith("&:")) {
3103
- const pseudoClass = key.replace("&", "");
3104
- cssString += `${pseudoClass} { ${convertStylesToCSS("", styles[key])} }`;
3105
- }
3106
- else {
3107
- const cssKey = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
3108
- cssString += `${cssKey}: ${styles[key]}; `;
3109
- }
3110
- }
3111
- cssString += "}";
3112
- return cssString;
3113
- };
3114
- // Custom hook for dynamic styles with generics
3115
- const useDynamicStyles = (stylesObj) => {
3116
- const [classNames, setClassNames] = useState({});
3117
- useEffect(() => {
3118
- const convertedStyles = Object.keys(stylesObj).map((key) => {
3119
- const className = generateClassName(key);
3120
- const styleElement = document.createElement("style");
3121
- styleElement.innerHTML = convertStylesToCSS(className, stylesObj[key]);
3122
- document.head.appendChild(styleElement);
3123
- return {
3124
- key,
3125
- className,
3126
- styleElement,
3127
- };
3128
- });
3129
- setClassNames(convertedStyles.reduce((classNameEntity, convertedStyle) => {
3130
- return {
3131
- ...classNameEntity,
3132
- [convertedStyle.key]: convertedStyle.className,
3133
- };
3134
- }, {}));
3135
- return () => {
3136
- convertedStyles.forEach((convertedStyle) => {
3137
- document.head.removeChild(convertedStyle.styleElement);
3138
- });
3139
- };
3140
- }, []);
3141
- return classNames;
3142
- };
3143
-
3144
- const useCurrentModal = () => {
3145
- const [CurrentModal, setCurrentModal] = useState();
3146
- return [
3147
- CurrentModal,
3148
- (Modal) => {
3149
- // As setState supports functional updates, we can't pass functional
3150
- // components directly
3151
- setCurrentModal(() => Modal);
3152
- },
3153
- ];
3154
- };
3155
- const ContextMenu = (params) => {
3156
- const { onClose, onMenuClick, anchorRef, dropDownOptions } = params;
3157
- const [CurrentModal, setCurrentModal] = useCurrentModal();
3158
- const styles = useDynamicStyles(dropdownStyles);
3159
- return (React__default.createElement(React__default.Fragment, null,
3160
- React__default.createElement(Layer$1, { onBackdropClick: (event, data) => onClose(event, data), className: styles.layer },
3161
- React__default.createElement(Popper, { reference: anchorRef, placement: "bottom-start" },
3162
- React__default.createElement(FlyoutMenu, null, dropDownOptions.map((dropDownOption, index) => (React__default.createElement(MenuItem$1, { key: index, destructive: dropDownOption.destructive, label: dropDownOption.label, icon: dropDownOption.icon, onClick: () => {
3163
- onMenuClick(dropDownOption);
3164
- onClose();
3165
- }, dense: true })))))),
3166
- CurrentModal && (React__default.createElement(CurrentModal, { onClose: () => {
3167
- onClose();
3168
- setCurrentModal(null);
3169
- } }))));
3170
- };
3171
- const DropdownMenu = (props) => {
3172
- const ref = useRef();
3173
- const [visible, setVisible] = useState(false);
3174
- const { dropdownOptions, onClick } = props;
3175
- return (React__default.createElement("div", { ref: ref, style: { display: "inline-block" } },
3176
- React__default.createElement(Button$1, { small: true, secondary: true, icon: React__default.createElement(IconMore24, { color: colors$1.grey600 }), onClick: () => setVisible(true) }),
3177
- visible && (React__default.createElement(ContextMenu, { dropDownOptions: dropdownOptions, anchorRef: ref, onClose: () => setVisible(false), onMenuClick: (dropDownOption) => {
3178
- onClick(dropDownOption);
3179
- } }))));
3180
- };
3181
-
3182
3166
  const getProgramStageData = (response, programStageId, pager) => {
3183
3167
  const events = response.data.events;
3184
3168
  const allDataElements = new Set();
@@ -3207,6 +3191,14 @@ const getProgramStageData = (response, programStageId, pager) => {
3207
3191
  const getTrackedEntityData = (response, programId, pager, filters) => {
3208
3192
  let teis = response.data
3209
3193
  .trackedEntityInstances;
3194
+ let programMetaData = response.metadata.programTrackedEntityAttributes;
3195
+ const programAttributesMap = programMetaData.reduce((acc, attribute) => {
3196
+ if (attribute.displayInList) {
3197
+ acc[attribute.id] = attribute.displayName;
3198
+ }
3199
+ return acc;
3200
+ }, {});
3201
+ console.log('metadata', programAttributesMap);
3210
3202
  if (filters) {
3211
3203
  teis = getFilteredTrackedEntityInstances(teis, filters);
3212
3204
  }
@@ -3218,7 +3210,12 @@ const getTrackedEntityData = (response, programId, pager, filters) => {
3218
3210
  : tei.attributes;
3219
3211
  attributes.forEach((attr) => allAttributes.add(attr.attribute));
3220
3212
  });
3221
- const entityColumns = Array.from(allAttributes).map((attrId) => {
3213
+ console.log('all of the attributes', allAttributes);
3214
+ // const filteredAttributes = new Set(
3215
+ // [...allAttributes].filter((attributeId) => programAttributesMap[attributeId])
3216
+ // );
3217
+ // console.log('Filtered All Attributes:', filteredAttributes);
3218
+ let entityColumns = Array.from(allAttributes).map((attrId) => {
3222
3219
  const foundAttribute = teis
3223
3220
  .flatMap((tei) => {
3224
3221
  const matchingEnrollment = tei.enrollments.find((enrollment) => enrollment.program === programId);
@@ -3232,6 +3229,10 @@ const getTrackedEntityData = (response, programId, pager, filters) => {
3232
3229
  key: attrId,
3233
3230
  };
3234
3231
  });
3232
+ entityColumns = entityColumns.filter((column) => {
3233
+ // Check if the column label is part of any value in programAttributesMap
3234
+ return Object.values(programAttributesMap).some((value) => value.includes(column.label));
3235
+ });
3235
3236
  const attributesData = teis.map((tei, idx) => {
3236
3237
  let row = {
3237
3238
  trackedEntityInstance: tei.trackedEntityInstance,
@@ -3278,7 +3279,7 @@ const addActionsColumn = (columns, actionOptions) => {
3278
3279
  };
3279
3280
 
3280
3281
  // src/app/line-list-table.component.ts
3281
- class LineListTableComponent extends ReactWrapperComponent {
3282
+ class LineListTableComponent extends ReactWrapperModule {
3282
3283
  constructor() {
3283
3284
  super(...arguments);
3284
3285
  this.actionSelected = new EventEmitter();
@@ -3332,7 +3333,7 @@ class LineListTableComponent extends ReactWrapperComponent {
3332
3333
  useEffect(() => {
3333
3334
  setLoading(true);
3334
3335
  this.lineListService
3335
- .getLineListData(this.programId, this.orgUnit, this.programStageId, pager.page, pager.pageSize, this.attributeFilters, this.startDate, this.endDate)
3336
+ .getLineListData(this.programId, this.orgUnit, this.programStageId, pager.page, pager.pageSize, this.attributeFilters, this.startDate, this.endDate, this.ouMode)
3336
3337
  .subscribe((response) => {
3337
3338
  let entityColumns = [];
3338
3339
  let responsePager;
@@ -3384,23 +3385,31 @@ class LineListTableComponent extends ReactWrapperComponent {
3384
3385
  },
3385
3386
  }));
3386
3387
  };
3387
- return (React__default.createElement("div", null, loading ? (React__default.createElement(CircularLoader$1, null)) :
3388
- (React__default.createElement(DataTable, null,
3389
- React__default.createElement(TableHead, null,
3390
- React__default.createElement(DataTableRow, null, columns.map((col) => (React__default.createElement(DataTableColumnHeader, { key: col.key }, col.label))))),
3391
- React__default.createElement(TableBody, null, data.map((row) => (React__default.createElement(DataTableRow, { key: row.index }, columns.map((col) => (React__default.createElement(DataTableCell, { key: col.key }, col.key === 'actions' ? (React__default.createElement(DropdownMenu, { dropdownOptions: getDropdownOptions(row), onClick: (option) => option.onClick?.() })) : (row[col.key])))))))),
3392
- React__default.createElement(TableFoot, null,
3393
- React__default.createElement(DataTableRow, null,
3394
- React__default.createElement(DataTableCell, { colSpan: columns.length.toString() },
3395
- React__default.createElement("div", null,
3396
- React__default.createElement(Pagination, { page: pager.page, pageCount: pager.pageCount, pageSize: pager.pageSize, total: pager.total, onPageChange: (page) => setPager((prev) => ({ ...prev, page })), onPageSizeChange: (pageSize) => {
3397
- const newPageSize = Number(pageSize);
3398
- setPager((prev) => ({
3399
- ...prev,
3400
- page: 1,
3401
- pageSize: newPageSize,
3402
- }));
3403
- }, pageSizes: ['5', '10', '20', '50'] })))))))));
3388
+ return (React__default.createElement("div", null, loading ? (React__default.createElement("div", { style: {
3389
+ display: 'flex',
3390
+ alignItems: 'center',
3391
+ gap: 8,
3392
+ padding: 8,
3393
+ } },
3394
+ React__default.createElement(CircularLoader$1, { small: true }),
3395
+ React__default.createElement("div", { style: {
3396
+ fontSize: 14,
3397
+ } }, "Loading"))) : (React__default.createElement(DataTable, null,
3398
+ React__default.createElement(TableHead, null,
3399
+ React__default.createElement(DataTableRow, null, columns.map((col) => (React__default.createElement(DataTableColumnHeader, { key: col.key }, col.label))))),
3400
+ React__default.createElement(TableBody, null, data.map((row) => (React__default.createElement(DataTableRow, { key: row.index }, columns.map((col) => (React__default.createElement(DataTableCell, { key: col.key }, col.key === 'actions' ? (React__default.createElement(DropdownMenu, { dropdownOptions: getDropdownOptions(row), onClick: (option) => option.onClick?.() })) : (row[col.key])))))))),
3401
+ React__default.createElement(TableFoot, null,
3402
+ React__default.createElement(DataTableRow, null,
3403
+ React__default.createElement(DataTableCell, { colSpan: columns.length.toString() },
3404
+ React__default.createElement("div", null,
3405
+ React__default.createElement(Pagination, { page: pager.page, pageCount: pager.pageCount, pageSize: pager.pageSize, total: pager.total, onPageChange: (page) => setPager((prev) => ({ ...prev, page })), onPageSizeChange: (pageSize) => {
3406
+ const newPageSize = Number(pageSize);
3407
+ setPager((prev) => ({
3408
+ ...prev,
3409
+ page: 1,
3410
+ pageSize: newPageSize,
3411
+ }));
3412
+ }, pageSizes: ['5', '10', '20', '50'] })))))))));
3404
3413
  };
3405
3414
  }
3406
3415
  ngOnChanges(changes) {
@@ -3433,7 +3442,7 @@ class LineListTableComponent extends ReactWrapperComponent {
3433
3442
  this.render();
3434
3443
  }
3435
3444
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListTableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3436
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: LineListTableComponent, isStandalone: false, selector: "app-line-list", inputs: { programId: "programId", orgUnit: "orgUnit", programStageId: "programStageId", actionOptions: "actionOptions", attributeFilters: "attributeFilters", startDate: "startDate", endDate: "endDate", filters: "filters" }, outputs: { actionSelected: "actionSelected" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: ["[data-test=dhis2-uiwidgets-pagination]{display:flex!important;flex-direction:row!important;justify-content:space-between!important;align-items:center!important}\n"] }); }
3445
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: LineListTableComponent, isStandalone: false, selector: "app-line-list", inputs: { programId: "programId", orgUnit: "orgUnit", programStageId: "programStageId", actionOptions: "actionOptions", attributeFilters: "attributeFilters", startDate: "startDate", endDate: "endDate", filters: "filters", ouMode: "ouMode" }, outputs: { actionSelected: "actionSelected" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: ["[data-test=dhis2-uiwidgets-pagination]{display:flex!important;flex-direction:row!important;justify-content:space-between!important;align-items:center!important}\n"] }); }
3437
3446
  }
3438
3447
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListTableComponent, decorators: [{
3439
3448
  type: Component,
@@ -3454,6 +3463,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
3454
3463
  type: Input
3455
3464
  }], filters: [{
3456
3465
  type: Input
3466
+ }], ouMode: [{
3467
+ type: Input
3457
3468
  }], actionSelected: [{
3458
3469
  type: Output
3459
3470
  }] } });
@@ -3911,6 +3922,13 @@ class FormValueUtil {
3911
3922
  }
3912
3923
  }
3913
3924
 
3925
+ class TranslationUtil {
3926
+ static getTranslatedFormName(field, locale = 'sw') {
3927
+ const translation = (field['translations'] || []).find((translation) => translation['locale'] == locale && translation['property'] == 'NAME');
3928
+ return (translation ? translation['value'] : field['formName'] || field['name']);
3929
+ }
3930
+ }
3931
+
3914
3932
  // Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
3915
3933
  // Use of this source code is governed by a BSD-style
3916
3934
  // license that can be found in the LICENSE file.
@@ -3922,6 +3940,9 @@ class FormFieldGroup {
3922
3940
  const fields = this.params.formFieldGroup?.fields || [];
3923
3941
  return fields
3924
3942
  .map((field) => {
3943
+ if (field instanceof FormField) {
3944
+ return field;
3945
+ }
3925
3946
  const fieldMetaData = this.params.fieldMetaData.find((attribute) => attribute['id'] === field.id);
3926
3947
  if (!fieldMetaData) {
3927
3948
  return null;
@@ -3964,7 +3985,7 @@ class FormFieldGroup {
3964
3985
  toJson() {
3965
3986
  return {
3966
3987
  id: this.params.formFieldGroup?.id,
3967
- name: this.params.formFieldGroup?.name,
3988
+ name: TranslationUtil.getTranslatedFormName(this.params.formFieldGroup, this.params.locale),
3968
3989
  isFormHorizontal: this.params.formFieldGroup?.isFormHorizontal,
3969
3990
  repeatDependentField: this.params.formFieldGroup?.repeatDependentField,
3970
3991
  dataKey: this.params.formFieldGroup?.dataKey,
@@ -4071,7 +4092,11 @@ class FormMetaData {
4071
4092
  this.params = params;
4072
4093
  }
4073
4094
  get sections() {
4074
- return (this.params.formMetaData.sections || [])
4095
+ const customSections = this.params.customFormMetaData?.sections;
4096
+ if (!customSections) {
4097
+ return this.#getSectionFromPrograms(this.params.programs);
4098
+ }
4099
+ return (this.params.customFormMetaData?.sections || [])
4075
4100
  .map((section) => {
4076
4101
  const program = this.params.programs.find((program) => section.program === program['id']);
4077
4102
  if (!program) {
@@ -4091,7 +4116,7 @@ class FormMetaData {
4091
4116
  get rules() {
4092
4117
  let ruleVariables = [];
4093
4118
  return [
4094
- ...(this.params.formMetaData.rules || []),
4119
+ ...(this.params.customFormMetaData?.rules || []),
4095
4120
  ...(flatten(this.params.programs.map((program) => {
4096
4121
  ruleVariables = [
4097
4122
  ...ruleVariables,
@@ -4101,10 +4126,131 @@ class FormMetaData {
4101
4126
  })) || []).map((rule) => new MetadataRule(rule, ruleVariables).toJson()),
4102
4127
  ];
4103
4128
  }
4129
+ #getSectionFromPrograms(programs) {
4130
+ const sections = flatten(programs.map((program) => {
4131
+ return [
4132
+ this.#getReportingDetailsSection(program),
4133
+ new FormMetadataSection({
4134
+ section: {
4135
+ id: 'registration',
4136
+ name: 'Registration',
4137
+ fieldGroups: (program.programSections || []).length > 0
4138
+ ? program.programSections.map((programSection) => {
4139
+ return {
4140
+ id: programSection.id,
4141
+ name: programSection.name,
4142
+ sortOrder: programSection.sortOrder,
4143
+ fields: programSection.trackedEntityAttributes,
4144
+ };
4145
+ })
4146
+ : [
4147
+ {
4148
+ id: 'registration',
4149
+ name: '',
4150
+ sortOrder: 1,
4151
+ fields: (program.programTrackedEntityAttributes || []).map((programTrackedEntityAttribute) => {
4152
+ return {
4153
+ id: programTrackedEntityAttribute
4154
+ .trackedEntityAttribute?.id,
4155
+ };
4156
+ }),
4157
+ },
4158
+ ],
4159
+ },
4160
+ program,
4161
+ locale: this.params.locale,
4162
+ }).toJson(),
4163
+ ...(program.programStages || []).map((programStage) => {
4164
+ return new FormMetadataSection({
4165
+ section: {
4166
+ id: programStage.id,
4167
+ name: programStage.name,
4168
+ fieldGroups: (programStage.programStageSections || []).length > 0
4169
+ ? programStage.programStageSections.map((programStageSection) => {
4170
+ return {
4171
+ id: programStageSection.id,
4172
+ name: programStageSection.name,
4173
+ dataKey: camelCase(programStage.code),
4174
+ repeatableStage: programStage.repeatable
4175
+ ? programStage.id
4176
+ : undefined,
4177
+ sortOrder: programStageSection.sortOrder,
4178
+ fields: programStageSection.dataElements,
4179
+ };
4180
+ })
4181
+ : [
4182
+ {
4183
+ id: programStage.id,
4184
+ dataKey: camelCase(programStage.code),
4185
+ repeatableStage: programStage.repeatable
4186
+ ? programStage.id
4187
+ : undefined,
4188
+ fields: (programStage.programStageDataElements || []).map((programStageDataElement) => {
4189
+ return {
4190
+ id: programStageDataElement.dataElement?.id,
4191
+ };
4192
+ }),
4193
+ },
4194
+ ],
4195
+ },
4196
+ program,
4197
+ locale: this.params.locale,
4198
+ }).toJson();
4199
+ }),
4200
+ ];
4201
+ }));
4202
+ if (sections.length === 0) {
4203
+ return [];
4204
+ }
4205
+ return sections;
4206
+ }
4207
+ #getReportingDetailsSection(program) {
4208
+ return new FormMetadataSection({
4209
+ section: {
4210
+ id: 'reporting_details',
4211
+ name: 'Reporting details',
4212
+ fieldGroups: [
4213
+ {
4214
+ id: 'reporting_details',
4215
+ sortOrder: 1,
4216
+ isFormHorizontal: true,
4217
+ fields: [
4218
+ new FormField({
4219
+ id: 'orgUnit',
4220
+ key: 'orgUnit',
4221
+ label: 'Organisation unit',
4222
+ code: 'orgUnit',
4223
+ required: true,
4224
+ controlType: 'org-unit',
4225
+ }),
4226
+ new DateField({
4227
+ id: 'enrollmentDate',
4228
+ label: program.enrollmentDateLabel || 'Enrollment date',
4229
+ code: 'enrollmentDate',
4230
+ key: 'enrollmentDate',
4231
+ required: true,
4232
+ }),
4233
+ program.displayIncidentDate
4234
+ ? new DateField({
4235
+ id: 'incidentDate',
4236
+ label: program.incidentDateLabel || 'Incident date',
4237
+ code: 'incidentDate',
4238
+ key: 'incidentDate',
4239
+ required: true,
4240
+ })
4241
+ : null,
4242
+ ].filter((field) => field),
4243
+ },
4244
+ ],
4245
+ },
4246
+ program,
4247
+ locale: this.params.locale,
4248
+ }).toJson();
4249
+ }
4104
4250
  toJson() {
4105
4251
  return {
4106
- id: this.params.formMetaData?.id,
4107
- name: this.params.formMetaData?.name,
4252
+ id: this.params.customFormMetaData?.id,
4253
+ name: TranslationUtil.getTranslatedFormName(this.params.customFormMetaData || {}, this.params.locale),
4108
4254
  fields: this.fields,
4109
4255
  sections: this.sections,
4110
4256
  rules: this.rules,
@@ -4124,16 +4270,18 @@ class FormValue {
4124
4270
  clear() {
4125
4271
  this.form.reset();
4126
4272
  }
4127
- getValues() {
4273
+ getValues(options) {
4128
4274
  const newValues = {};
4129
4275
  const formValues = this.form?.getRawValue();
4276
+ if (options?.valueOnly) {
4277
+ return formValues;
4278
+ }
4130
4279
  Object.keys(formValues).forEach((key) => {
4131
4280
  const field = find(this.fields, ['key', key]);
4132
4281
  if (field) {
4133
4282
  newValues[key] = {
4134
- id: field.id,
4283
+ ...field,
4135
4284
  value: formValues[key],
4136
- options: field.options,
4137
4285
  };
4138
4286
  }
4139
4287
  });
@@ -4148,7 +4296,7 @@ class FormValue {
4148
4296
  // Copyright 2024 UDSM DHIS2 Lab. All rights reserved.
4149
4297
  // Use of this source code is governed by a BSD-style
4150
4298
  // license that can be found in the LICENSE file.
4151
- class BaseFormFieldComponent extends ReactWrapperComponent {
4299
+ class BaseFormFieldComponent extends ReactWrapperModule {
4152
4300
  constructor() {
4153
4301
  super(...arguments);
4154
4302
  this.ngZone = inject(NgZone);
@@ -4774,12 +4922,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
4774
4922
  }] } });
4775
4923
 
4776
4924
  class RepeatableFormComponent {
4925
+ #eventFormValue$;
4926
+ #showForm$;
4927
+ #events$;
4777
4928
  constructor() {
4929
+ this.ngZone = inject(NgZone);
4778
4930
  this.fieldGroup = input.required();
4931
+ this.events = model();
4779
4932
  this.dataEntities = input.required();
4780
4933
  this.repeatableEvents = [];
4781
4934
  this.repeatableData = {};
4782
4935
  this.repeatableStageUpdate = new EventEmitter();
4936
+ this.eventFormValue = signal(null);
4937
+ this.showForm = signal(false);
4938
+ this.eventIndex = signal(0);
4939
+ this.#eventFormValue$ = toObservable(this.eventFormValue);
4940
+ this.#showForm$ = toObservable(this.showForm);
4941
+ this.#events$ = toObservable(this.events);
4783
4942
  }
4784
4943
  get isValid() {
4785
4944
  return !Object.keys(this.repeatableData).some((index) => {
@@ -4788,9 +4947,9 @@ class RepeatableFormComponent {
4788
4947
  });
4789
4948
  }
4790
4949
  ngOnInit() {
4791
- this.repeatableEvents = (this.events?.length > 0
4792
- ? this.events
4793
- : range(this.numberOfRows).map(() => ({}))).map((event, index) => {
4950
+ this.eventForm = FormUtil.getFormGroup(this.fieldGroup().fields, {});
4951
+ this.eventFormValue.set(new FormValue(this.eventForm, this.fieldGroup().fields));
4952
+ this.repeatableEvents = (this.events() || []).map((event, index) => {
4794
4953
  const fieldControls = (this.fieldGroup().fields || []).reduce((fieldObject, field) => {
4795
4954
  const value = (event.dataValueEntities || {})[field.key] || '';
4796
4955
  return {
@@ -4804,19 +4963,20 @@ class RepeatableFormComponent {
4804
4963
  });
4805
4964
  this.repeatableStageUpdate.emit(this.repeatableData);
4806
4965
  }
4807
- onFormUpdate(formValue, eventIndex) {
4808
- this.repeatableData = { ...this.repeatableData, [eventIndex]: formValue };
4809
- if (this.isValid) {
4810
- this.repeatableStageUpdate.emit(this.repeatableData);
4811
- }
4966
+ onFormUpdate(formValue) {
4967
+ this.eventFormValue.set(formValue);
4968
+ this.repeatableData = {
4969
+ ...this.repeatableData,
4970
+ [this.eventIndex()]: formValue,
4971
+ };
4812
4972
  }
4813
4973
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: RepeatableFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4814
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.1.8", type: RepeatableFormComponent, isStandalone: false, selector: "ng-dhis2-ui-repeatable-form", inputs: { formObject: { classPropertyName: "formObject", publicName: "formObject", isSignal: false, isRequired: false, transformFunction: null }, formData: { classPropertyName: "formData", publicName: "formData", isSignal: false, isRequired: false, transformFunction: null }, fieldGroup: { classPropertyName: "fieldGroup", publicName: "fieldGroup", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: false, isRequired: false, transformFunction: null }, numberOfRows: { classPropertyName: "numberOfRows", publicName: "numberOfRows", isSignal: false, isRequired: false, transformFunction: null }, programRuleActions: { classPropertyName: "programRuleActions", publicName: "programRuleActions", isSignal: false, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: false, isRequired: false, transformFunction: null }, program: { classPropertyName: "program", publicName: "program", isSignal: false, isRequired: false, transformFunction: null }, programStage: { classPropertyName: "programStage", publicName: "programStage", isSignal: false, isRequired: false, transformFunction: null }, repeatDependentField: { classPropertyName: "repeatDependentField", publicName: "repeatDependentField", isSignal: false, isRequired: false, transformFunction: null }, dataEntities: { classPropertyName: "dataEntities", publicName: "dataEntities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { repeatableStageUpdate: "repeatableStageUpdate" }, ngImport: i0, template: "<div>\n <div\n *ngFor=\"let repeatableEvent of repeatableEvents; let i = index\"\n class=\"card p-3 mb-2\"\n >\n <div class=\"font-weight-bold h6\">{{ fieldGroup().name }}: #{{ i + 1 }}</div>\n <ng-dhis2-ui-form\n [fields]=\"fieldGroup().fields || []\"\n [form]=\"repeatableEvent.form\"\n [programRuleActions]=\"programRuleActions\"\n [dataEntities]=\"repeatableEvent\"\n [isFormHorizontal]=\"true\"\n (formUpdate)=\"onFormUpdate($event, i)\"\n />\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: FormComponent, selector: "ng-dhis2-ui-form", inputs: ["formConfig", "fields", "form", "isFormHorizontal", "showSaveButton", "fieldsData", "fieldClass", "shouldRenderAsCheckBoxesButton", "programRuleActions", "dataEntities"], outputs: ["formUpdate"] }] }); }
4974
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.8", type: RepeatableFormComponent, isStandalone: false, selector: "ng-dhis2-ui-repeatable-form", inputs: { formObject: { classPropertyName: "formObject", publicName: "formObject", isSignal: false, isRequired: false, transformFunction: null }, formData: { classPropertyName: "formData", publicName: "formData", isSignal: false, isRequired: false, transformFunction: null }, fieldGroup: { classPropertyName: "fieldGroup", publicName: "fieldGroup", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: false, isRequired: false, transformFunction: null }, numberOfRows: { classPropertyName: "numberOfRows", publicName: "numberOfRows", isSignal: false, isRequired: false, transformFunction: null }, programRuleActions: { classPropertyName: "programRuleActions", publicName: "programRuleActions", isSignal: false, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, program: { classPropertyName: "program", publicName: "program", isSignal: false, isRequired: false, transformFunction: null }, programStage: { classPropertyName: "programStage", publicName: "programStage", isSignal: false, isRequired: false, transformFunction: null }, repeatDependentField: { classPropertyName: "repeatDependentField", publicName: "repeatDependentField", isSignal: false, isRequired: false, transformFunction: null }, dataEntities: { classPropertyName: "dataEntities", publicName: "dataEntities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { events: "eventsChange", repeatableStageUpdate: "repeatableStageUpdate" }, ngImport: i0, template: "<div class=\"form__repeatable-stage-container\">\n <!-- <ng-dhis2-ui-wrapper [component]=\"EventTable()\"></ng-dhis2-ui-wrapper> -->\n @if(showForm()) {\n <div class=\"form__repeatable-stage-form\">\n <ng-dhis2-ui-form\n [fields]=\"fieldGroup().fields || []\"\n [form]=\"eventForm\"\n [programRuleActions]=\"programRuleActions\"\n [dataEntities]=\"{}\"\n [isFormHorizontal]=\"false\"\n (formUpdate)=\"onFormUpdate($event)\"\n >\n </ng-dhis2-ui-form>\n\n <!-- <ng-dhis2-ui-wrapper [component]=\"FormActionButtons\"></ng-dhis2-ui-wrapper> -->\n </div>\n }\n</div>\n", styles: [".form__repeatable-stage-container{margin-top:16px}.form__repeatable-stage-form{border:solid 1px rgb(232,237,242);border-top-style:none;background-color:#fff;padding:16px}\n"], dependencies: [{ kind: "component", type: FormComponent, selector: "ng-dhis2-ui-form", inputs: ["formConfig", "fields", "form", "isFormHorizontal", "showSaveButton", "fieldsData", "fieldClass", "shouldRenderAsCheckBoxesButton", "programRuleActions", "dataEntities"], outputs: ["formUpdate"] }] }); }
4815
4975
  }
4816
4976
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: RepeatableFormComponent, decorators: [{
4817
4977
  type: Component,
4818
- args: [{ selector: 'ng-dhis2-ui-repeatable-form', standalone: false, template: "<div>\n <div\n *ngFor=\"let repeatableEvent of repeatableEvents; let i = index\"\n class=\"card p-3 mb-2\"\n >\n <div class=\"font-weight-bold h6\">{{ fieldGroup().name }}: #{{ i + 1 }}</div>\n <ng-dhis2-ui-form\n [fields]=\"fieldGroup().fields || []\"\n [form]=\"repeatableEvent.form\"\n [programRuleActions]=\"programRuleActions\"\n [dataEntities]=\"repeatableEvent\"\n [isFormHorizontal]=\"true\"\n (formUpdate)=\"onFormUpdate($event, i)\"\n />\n </div>\n</div>\n" }]
4819
- }], propDecorators: { formObject: [{
4978
+ args: [{ selector: 'ng-dhis2-ui-repeatable-form', standalone: false, template: "<div class=\"form__repeatable-stage-container\">\n <!-- <ng-dhis2-ui-wrapper [component]=\"EventTable()\"></ng-dhis2-ui-wrapper> -->\n @if(showForm()) {\n <div class=\"form__repeatable-stage-form\">\n <ng-dhis2-ui-form\n [fields]=\"fieldGroup().fields || []\"\n [form]=\"eventForm\"\n [programRuleActions]=\"programRuleActions\"\n [dataEntities]=\"{}\"\n [isFormHorizontal]=\"false\"\n (formUpdate)=\"onFormUpdate($event)\"\n >\n </ng-dhis2-ui-form>\n\n <!-- <ng-dhis2-ui-wrapper [component]=\"FormActionButtons\"></ng-dhis2-ui-wrapper> -->\n </div>\n }\n</div>\n", styles: [".form__repeatable-stage-container{margin-top:16px}.form__repeatable-stage-form{border:solid 1px rgb(232,237,242);border-top-style:none;background-color:#fff;padding:16px}\n"] }]
4979
+ }], ctorParameters: () => [], propDecorators: { formObject: [{
4820
4980
  type: Input
4821
4981
  }], formData: [{
4822
4982
  type: Input
@@ -4826,8 +4986,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
4826
4986
  type: Input
4827
4987
  }], programRuleActions: [{
4828
4988
  type: Input
4829
- }], events: [{
4830
- type: Input
4831
4989
  }], program: [{
4832
4990
  type: Input
4833
4991
  }], programStage: [{
@@ -4840,8 +4998,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
4840
4998
 
4841
4999
  class SectionFormComponent {
4842
5000
  constructor() {
5001
+ this.ngZone = inject(NgZone);
4843
5002
  this.loading = input();
4844
- this.isLabResulst = false;
4845
5003
  this.formMetaData = input.required();
4846
5004
  this.dataValueEntities = input.required();
4847
5005
  this.formGroups = {};
@@ -4851,43 +5009,27 @@ class SectionFormComponent {
4851
5009
  this.save = new EventEmitter();
4852
5010
  this.formUpdate = new EventEmitter();
4853
5011
  this.cancel = new EventEmitter();
4854
- }
4855
- get inValid() {
4856
- const valueValidity = Object.keys(this.formValueEntity)
4857
- .map((key) => {
4858
- return (this.formValueEntity[key] || {}).isValid;
4859
- })
4860
- .some((validity) => !validity);
4861
- const repeatableDataValidity = Object.keys(this.repeatableFormValueEntity)
4862
- .map((key) => {
4863
- return Object.keys(this.repeatableFormValueEntity[key]).some((valueIndex) => {
4864
- return ((this.repeatableFormValueEntity[key] || {})[+valueIndex] || {}).isValid;
4865
- });
4866
- })
4867
- .some((validity) => !validity);
4868
- return valueValidity && repeatableDataValidity;
5012
+ this.inValid = signal(true);
5013
+ this.inValid$ = toObservable(this.inValid);
4869
5014
  }
4870
5015
  ngOnInit() {
4871
5016
  if (this.formMetaData().sections) {
4872
5017
  (this.formMetaData().sections || []).forEach((formSection) => {
4873
5018
  (formSection.fieldGroups || []).forEach((fieldGroup) => {
4874
5019
  const formGroup = FormUtil.getFormGroup(fieldGroup.fields, this.dataValueEntities());
4875
- // Set bookingId as default value for `travelerReferenceId` after search refLabNum
4876
- const refLabNum = formGroup.get('refLabNum');
4877
- const travelerReferenceIdControl = formGroup.get('travelerReferenceId');
4878
- if (travelerReferenceIdControl) {
4879
- const defaultValue = this.clientId ? this.clientId : '';
4880
- travelerReferenceIdControl.setValue(defaultValue);
4881
- }
4882
- else if (refLabNum) {
4883
- const defaultValue = this.labNumber ? this.labNumber : '';
4884
- refLabNum.setValue(defaultValue);
4885
- }
4886
5020
  const formValue = new FormValue(formGroup, fieldGroup.fields);
4887
- this.formValueEntity[fieldGroup.id] = formValue;
4888
5021
  this.formGroups[fieldGroup.id] = formGroup;
5022
+ if (!fieldGroup.repeatableStage) {
5023
+ this.formValueEntity[fieldGroup.id] = formValue;
5024
+ }
5025
+ else {
5026
+ this.repeatableFormValueEntity[fieldGroup.dataKey || fieldGroup.id] = {
5027
+ 0: formValue,
5028
+ };
5029
+ }
4889
5030
  });
4890
5031
  });
5032
+ this.inValid.set(this.checkIfInValid());
4891
5033
  this.ruleActions = new ProgramRuleEngine()
4892
5034
  .setRules(this.formMetaData().rules)
4893
5035
  .setDataValues(this.#getDataValue())
@@ -4895,13 +5037,17 @@ class SectionFormComponent {
4895
5037
  }
4896
5038
  }
4897
5039
  onUpdateRepeatableStage(repeatableData, fieldGroup) {
4898
- this.repeatableFormValueEntity[fieldGroup.dataKey || fieldGroup.id] =
4899
- repeatableData;
4900
- const dataValues = this.#getDataValue();
4901
- this.formUpdate.emit(dataValues);
5040
+ if (!isEmpty(repeatableData)) {
5041
+ this.repeatableFormValueEntity[fieldGroup.dataKey || fieldGroup.id] =
5042
+ repeatableData;
5043
+ this.inValid.set(this.checkIfInValid());
5044
+ const dataValues = this.#getDataValue();
5045
+ this.formUpdate.emit(dataValues);
5046
+ }
4902
5047
  }
4903
5048
  onFormUpdate(formValue, fieldGroupId) {
4904
5049
  this.formValueEntity[fieldGroupId] = formValue;
5050
+ this.inValid.set(this.checkIfInValid());
4905
5051
  const dataValues = this.#getDataValue();
4906
5052
  this.ruleActions = new ProgramRuleEngine()
4907
5053
  .setRules(this.formMetaData().rules)
@@ -4909,13 +5055,12 @@ class SectionFormComponent {
4909
5055
  .execute();
4910
5056
  this.formUpdate.emit(dataValues);
4911
5057
  }
4912
- onSubmit(event) {
4913
- event.stopPropagation();
5058
+ onSubmit() {
4914
5059
  const dataValues = this.#getDataValue();
4915
5060
  this.save.emit(dataValues);
4916
5061
  }
4917
5062
  onCancel(event) {
4918
- event.stopPropagation();
5063
+ event?.stopPropagation();
4919
5064
  this.cancel.emit();
4920
5065
  }
4921
5066
  #getDataValue() {
@@ -4934,21 +5079,28 @@ class SectionFormComponent {
4934
5079
  }, {});
4935
5080
  return { ...dataValues, ...repeatableValues };
4936
5081
  }
5082
+ checkIfInValid() {
5083
+ const valueValidity = Object.keys(this.formValueEntity)
5084
+ .map((key) => {
5085
+ return (this.formValueEntity[key] || {}).isValid;
5086
+ })
5087
+ .some((validity) => !validity);
5088
+ const repeatableDataValidity = Object.keys(this.repeatableFormValueEntity)
5089
+ .map((key) => {
5090
+ return Object.keys(this.repeatableFormValueEntity[key]).some((valueIndex) => {
5091
+ return ((this.repeatableFormValueEntity[key] || {})[+valueIndex] || {}).isValid;
5092
+ });
5093
+ })
5094
+ .some((validity) => !validity);
5095
+ return valueValidity || repeatableDataValidity;
5096
+ }
4937
5097
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SectionFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4938
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.8", type: SectionFormComponent, isStandalone: false, selector: "ng-dhis2-ui-section-form", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, isLab: { classPropertyName: "isLab", publicName: "isLab", isSignal: false, isRequired: false, transformFunction: null }, isLabResulst: { classPropertyName: "isLabResulst", publicName: "isLabResulst", isSignal: false, isRequired: false, transformFunction: null }, clientId: { classPropertyName: "clientId", publicName: "clientId", isSignal: false, isRequired: false, transformFunction: null }, labNumber: { classPropertyName: "labNumber", publicName: "labNumber", isSignal: false, 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" }, 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=\"pt-3 pb-3 font-weight-bold text-left\">\n {{ sectionName }}\n </div>\n }\n <div class=\"p-2\">\n <ng-container *ngIf=\"formSection\">\n <div class=\"row\" *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=\"col-12\"\n >\n <div class=\"pt-2 pb-3 font-weight-bold text-left\">\n {{ fieldGroup?.name }}\n </div>\n </div>\n <div class=\"col-12\" *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 />\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-container>\n </ng-container>\n } @else { Normal event form }\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <div class=\"flex gap-2 m-2\">\n <button mat-stroked-button (click)=\"onCancel($event)\">\n {{ 'cancel' }}\n </button>\n <button\n mat-flat-button\n color=\"primary\"\n [disabled]=\"inValid\"\n (click)=\"onSubmit($event)\"\n *ngIf=\"!isLab || isLabResulst\"\n >\n <div *ngIf=\"isloading\" class=\"p-1\">\n <!-- <mat-spinner diameter=\"30\" strokeWidth=\"2\"></mat-spinner> -->\n </div>\n <span *ngIf=\"!loading()\">{{ 'submit' }}</span>\n <div class=\"p-1\" *ngIf=\"loading()\">\n <!-- <mat-spinner diameter=\"30\" strokeWidth=\"2\"></mat-spinner> -->\n </div>\n </button>\n <button\n mat-flat-button\n color=\"primary\"\n [disabled]=\"inValid\"\n (click)=\"onSubmit($event)\"\n *ngIf=\"isLab && !isLabResulst\"\n >\n <span *ngIf=\"!loading()\">{{ 'Save & Add sample' }}</span>\n <div class=\"p-1\" *ngIf=\"loading()\">\n <!-- <mat-spinner diameter=\"30\" strokeWidth=\"2\"></mat-spinner> -->\n </div>\n </button>\n <button\n mat-flat-button\n color=\"primary\"\n [disabled]=\"inValid\"\n (click)=\"onSubmit($event)\"\n *ngIf=\"isLab && !isLabResulst\"\n >\n <span *ngIf=\"!loading()\">{{ 'Save & Exit' }}</span>\n <div class=\"p-1\" *ngIf=\"loading()\">\n <!-- <mat-spinner diameter=\"30\" strokeWidth=\"2\"></mat-spinner> -->\n </div>\n </button>\n </div>\n</ng-container>\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"], outputs: ["formUpdate"] }, { kind: "component", type: RepeatableFormComponent, selector: "ng-dhis2-ui-repeatable-form", inputs: ["formObject", "formData", "fieldGroup", "form", "numberOfRows", "programRuleActions", "events", "program", "programStage", "repeatDependentField", "dataEntities"], outputs: ["repeatableStageUpdate"] }] }); }
5098
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.8", 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" }, 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"], outputs: ["formUpdate"] }, { 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"] }] }); }
4939
5099
  }
4940
5100
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SectionFormComponent, decorators: [{
4941
5101
  type: Component,
4942
- args: [{ selector: 'ng-dhis2-ui-section-form', standalone: false, template: "<ng-container *ngIf=\"formMetaData()\">\n <ng-container *ngFor=\"let formSection of formMetaData().sections\">\n @if(formSection?.name; as sectionName) {\n <div class=\"pt-3 pb-3 font-weight-bold text-left\">\n {{ sectionName }}\n </div>\n }\n <div class=\"p-2\">\n <ng-container *ngIf=\"formSection\">\n <div class=\"row\" *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=\"col-12\"\n >\n <div class=\"pt-2 pb-3 font-weight-bold text-left\">\n {{ fieldGroup?.name }}\n </div>\n </div>\n <div class=\"col-12\" *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 />\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-container>\n </ng-container>\n } @else { Normal event form }\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <div class=\"flex gap-2 m-2\">\n <button mat-stroked-button (click)=\"onCancel($event)\">\n {{ 'cancel' }}\n </button>\n <button\n mat-flat-button\n color=\"primary\"\n [disabled]=\"inValid\"\n (click)=\"onSubmit($event)\"\n *ngIf=\"!isLab || isLabResulst\"\n >\n <div *ngIf=\"isloading\" class=\"p-1\">\n <!-- <mat-spinner diameter=\"30\" strokeWidth=\"2\"></mat-spinner> -->\n </div>\n <span *ngIf=\"!loading()\">{{ 'submit' }}</span>\n <div class=\"p-1\" *ngIf=\"loading()\">\n <!-- <mat-spinner diameter=\"30\" strokeWidth=\"2\"></mat-spinner> -->\n </div>\n </button>\n <button\n mat-flat-button\n color=\"primary\"\n [disabled]=\"inValid\"\n (click)=\"onSubmit($event)\"\n *ngIf=\"isLab && !isLabResulst\"\n >\n <span *ngIf=\"!loading()\">{{ 'Save & Add sample' }}</span>\n <div class=\"p-1\" *ngIf=\"loading()\">\n <!-- <mat-spinner diameter=\"30\" strokeWidth=\"2\"></mat-spinner> -->\n </div>\n </button>\n <button\n mat-flat-button\n color=\"primary\"\n [disabled]=\"inValid\"\n (click)=\"onSubmit($event)\"\n *ngIf=\"isLab && !isLabResulst\"\n >\n <span *ngIf=\"!loading()\">{{ 'Save & Exit' }}</span>\n <div class=\"p-1\" *ngIf=\"loading()\">\n <!-- <mat-spinner diameter=\"30\" strokeWidth=\"2\"></mat-spinner> -->\n </div>\n </button>\n </div>\n</ng-container>\n" }]
4943
- }], propDecorators: { isLab: [{
4944
- type: Input
4945
- }], isLabResulst: [{
4946
- type: Input
4947
- }], clientId: [{
4948
- type: Input
4949
- }], labNumber: [{
4950
- type: Input
4951
- }], save: [{
5102
+ args: [{ selector: 'ng-dhis2-ui-section-form', standalone: false, 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"] }]
5103
+ }], ctorParameters: () => [], propDecorators: { save: [{
4952
5104
  type: Output
4953
5105
  }], formUpdate: [{
4954
5106
  type: Output
@@ -4962,11 +5114,16 @@ class D2FormModule {
4962
5114
  FormComponent,
4963
5115
  RepeatableFormComponent,
4964
5116
  SectionFormComponent,
4965
- FormFieldItemComponent], imports: [CommonModule, ReactiveFormsModule, OrganisationUnitSelectorModule], exports: [FormFieldComponent,
5117
+ FormFieldItemComponent], imports: [CommonModule,
5118
+ ReactiveFormsModule,
5119
+ ReactWrapperModule,
5120
+ OrganisationUnitSelectorModule], exports: [FormFieldComponent,
4966
5121
  FormComponent,
4967
5122
  RepeatableFormComponent,
4968
5123
  SectionFormComponent] }); }
4969
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, imports: [CommonModule, ReactiveFormsModule, OrganisationUnitSelectorModule] }); }
5124
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, imports: [CommonModule,
5125
+ ReactiveFormsModule,
5126
+ OrganisationUnitSelectorModule] }); }
4970
5127
  }
4971
5128
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, decorators: [{
4972
5129
  type: NgModule,
@@ -4978,7 +5135,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
4978
5135
  SectionFormComponent,
4979
5136
  FormFieldItemComponent,
4980
5137
  ],
4981
- imports: [CommonModule, ReactiveFormsModule, OrganisationUnitSelectorModule],
5138
+ imports: [
5139
+ CommonModule,
5140
+ ReactiveFormsModule,
5141
+ ReactWrapperModule,
5142
+ OrganisationUnitSelectorModule,
5143
+ ],
4982
5144
  exports: [
4983
5145
  FormFieldComponent,
4984
5146
  FormComponent,
@@ -4992,9 +5154,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
4992
5154
  // Use of this source code is governed by a BSD-style
4993
5155
  // license that can be found in the LICENSE file.
4994
5156
 
5157
+ class TrackerFormComponent {
5158
+ constructor() {
5159
+ this.program = input.required();
5160
+ this.d2 = window.d2Web;
5161
+ }
5162
+ async ngOnInit() {
5163
+ this.trackerQuery = this.d2.trackerModule.trackedEntity.setProgram(this.program());
5164
+ const program = await this.trackerQuery.getMetaData();
5165
+ if (program) {
5166
+ this.formMetaData = new FormMetaData({
5167
+ programs: [program],
5168
+ }).toJson();
5169
+ }
5170
+ }
5171
+ onSave(event) { }
5172
+ onCancel() { }
5173
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5174
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.8", type: TrackerFormComponent, isStandalone: false, selector: "ng-dhis2-ui-tracker-form", inputs: { program: { classPropertyName: "program", publicName: "program", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@if(formMetaData) {\n<ng-dhis2-ui-section-form\n [formMetaData]=\"formMetaData\"\n [dataValueEntities]=\"{}\"\n (save)=\"onSave($event)\"\n (cancel)=\"onCancel()\"\n/>\n}\n", dependencies: [{ kind: "component", type: SectionFormComponent, selector: "ng-dhis2-ui-section-form", inputs: ["loading", "formMetaData", "dataValueEntities"], outputs: ["save", "formUpdate", "cancel"] }] }); }
5175
+ }
5176
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormComponent, decorators: [{
5177
+ type: Component,
5178
+ args: [{ selector: 'ng-dhis2-ui-tracker-form', standalone: false, template: "@if(formMetaData) {\n<ng-dhis2-ui-section-form\n [formMetaData]=\"formMetaData\"\n [dataValueEntities]=\"{}\"\n (save)=\"onSave($event)\"\n (cancel)=\"onCancel()\"\n/>\n}\n" }]
5179
+ }] });
5180
+
5181
+ class TrackerFormModule {
5182
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
5183
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, declarations: [TrackerFormComponent], imports: [CommonModule, D2FormModule], exports: [TrackerFormComponent] }); }
5184
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, imports: [CommonModule, D2FormModule] }); }
5185
+ }
5186
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, decorators: [{
5187
+ type: NgModule,
5188
+ args: [{
5189
+ imports: [CommonModule, D2FormModule],
5190
+ declarations: [TrackerFormComponent],
5191
+ exports: [TrackerFormComponent],
5192
+ }]
5193
+ }] });
5194
+
5195
+ // Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
5196
+ // Use of this source code is governed by a BSD-style
5197
+ // license that can be found in the LICENSE file.
5198
+
4995
5199
  /**
4996
5200
  * Generated bundle index. Do not edit.
4997
5201
  */
4998
5202
 
4999
- export { Boolean$1 as Boolean, ButtonComponent, ButtonModule, CheckBox, D2FormModule, DateField, DateRangeValue, Dropdown, FieldConfig, FieldControlTypeUtil, FieldDropdown, FieldType, FieldUtil, FormComponent, FormConfig, FormField, FormFieldComponent, FormFieldGroup, FormFieldTypeUtil, FormMetaData, FormMetadataSection, FormUtil, FormValue, FormValueUtil, HeaderBarComponent, HeaderBarModule, LineListModule, LineListTableComponent, MetadataRule, MetadataRuleAction, OrganisationUnitSelectionConfig, OrganisationUnitSelectorComponent, OrganisationUnitSelectorModalComponent, OrganisationUnitSelectorModule, PeriodSelectorComponent, PeriodSelectorModalComponent, PeriodSelectorModule, ReactWrapperComponent, ReactWrapperModule, RepeatableFormComponent, SectionFormComponent };
5203
+ export { Boolean$1 as Boolean, ButtonComponent, ButtonModule, CheckBox, D2FormModule, DateField, DateRangeValue, Dropdown, FieldConfig, FieldControlTypeUtil, FieldDropdown, FieldType, FieldUtil, FormComponent, FormConfig, FormField, FormFieldComponent, FormFieldGroup, FormFieldTypeUtil, FormMetaData, FormMetadataSection, FormUtil, FormValue, FormValueUtil, HeaderBarComponent, HeaderBarModule, LineListModule, LineListTableComponent, MetadataRule, MetadataRuleAction, OrganisationUnitSelectionConfig, OrganisationUnitSelectorComponent, OrganisationUnitSelectorModalComponent, OrganisationUnitSelectorModule, PeriodSelectorComponent, PeriodSelectorModalComponent, PeriodSelectorModule, ReactWrapperModule, RepeatableFormComponent, SectionFormComponent, TrackerFormComponent, TrackerFormModule, TranslationUtil };
5000
5204
  //# sourceMappingURL=iapps-ng-dhis2-ui.mjs.map