@iapps/ng-dhis2-ui 1.0.9 → 1.1.1

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 (55) hide show
  1. package/fesm2022/iapps-ng-dhis2-ui.mjs +1947 -292
  2. package/fesm2022/iapps-ng-dhis2-ui.mjs.map +1 -1
  3. package/index.d.ts +1 -0
  4. package/lib/modules/form/components/base-form-field.component.d.ts +53 -0
  5. package/lib/modules/form/components/form-field-item.component.d.ts +6 -0
  6. package/lib/modules/form/containers/form/form.component.d.ts +32 -0
  7. package/lib/modules/form/containers/form-field/form-field.component.d.ts +50 -0
  8. package/lib/modules/form/containers/repeatable-form/repeatable-form.component.d.ts +31 -0
  9. package/lib/modules/form/containers/section-form/section-form.component.d.ts +31 -0
  10. package/lib/modules/form/form.module.d.ts +14 -0
  11. package/lib/modules/form/index.d.ts +8 -0
  12. package/lib/modules/form/interfaces/field-control-type.interface.d.ts +1 -0
  13. package/lib/modules/form/interfaces/field-dropdown.interface.d.ts +7 -0
  14. package/lib/modules/form/interfaces/field-type.interface.d.ts +15 -0
  15. package/lib/modules/form/interfaces/form-configuration.model.d.ts +63 -0
  16. package/lib/modules/form/interfaces/form-field-group.interface.d.ts +14 -0
  17. package/lib/modules/form/interfaces/form-field-meta-type.interface.d.ts +1 -0
  18. package/lib/modules/form/interfaces/form-field.interface.d.ts +40 -0
  19. package/lib/modules/form/interfaces/form-metadata-section.interface.d.ts +10 -0
  20. package/lib/modules/form/interfaces/form-metadata.interface.d.ts +11 -0
  21. package/lib/modules/form/interfaces/index.d.ts +9 -0
  22. package/lib/modules/form/models/boolean.model.d.ts +5 -0
  23. package/lib/modules/form/models/check-box.model.d.ts +5 -0
  24. package/lib/modules/form/models/date-field.model.d.ts +7 -0
  25. package/lib/modules/form/models/date-range-value.model.d.ts +4 -0
  26. package/lib/modules/form/models/dropdown-option.model.d.ts +6 -0
  27. package/lib/modules/form/models/dropdown.model.d.ts +5 -0
  28. package/lib/modules/form/models/field-config.model.d.ts +5 -0
  29. package/lib/modules/form/models/field-dropdown.model.d.ts +10 -0
  30. package/lib/modules/form/models/fields-data.model.d.ts +8 -0
  31. package/lib/modules/form/models/form-config.model.d.ts +10 -0
  32. package/lib/modules/form/models/form-field-group.model.d.ts +21 -0
  33. package/lib/modules/form/models/form-field.model.d.ts +41 -0
  34. package/lib/modules/form/models/form-metadata-rule.model.d.ts +28 -0
  35. package/lib/modules/form/models/form-metadata-section.model.d.ts +28 -0
  36. package/lib/modules/form/models/form-metadata.model.d.ts +20 -0
  37. package/lib/modules/form/models/form-value.model.d.ts +17 -0
  38. package/lib/modules/form/models/form.model.d.ts +14 -0
  39. package/lib/modules/form/models/index.d.ts +17 -0
  40. package/lib/modules/form/utils/field-control-type.util.d.ts +4 -0
  41. package/lib/modules/form/utils/field-type.util.d.ts +3 -0
  42. package/lib/modules/form/utils/field.util.d.ts +9 -0
  43. package/lib/modules/form/utils/form-value.util.d.ts +4 -0
  44. package/lib/modules/form/utils/form.util.d.ts +8 -0
  45. package/lib/modules/form/utils/index.d.ts +5 -0
  46. package/lib/modules/line-list/containers/line-list.component.d.ts +12 -1
  47. package/lib/modules/line-list/models/attribute-filter.model.d.ts +2 -1
  48. package/lib/modules/line-list/models/filter-config.model.d.ts +6 -0
  49. package/lib/modules/line-list/models/line-list.models.d.ts +73 -14
  50. package/lib/modules/line-list/utils/filter-builder.d.ts +3 -0
  51. package/lib/modules/line-list/utils/line-list-utils.d.ts +2 -1
  52. package/lib/modules/react-wrapper/react-wrapper.component.d.ts +2 -3
  53. package/lib/shared/components/index.d.ts +1 -2
  54. package/package.json +1 -1
  55. /package/lib/shared/components/{TransferOption.d.ts → transfer-option.component.d.ts} +0 -0
@@ -1,17 +1,17 @@
1
+ import * as i1$1 from '@angular/common';
1
2
  import { CommonModule } from '@angular/common';
2
3
  import * as i0 from '@angular/core';
3
- import { NgModule, Directive, Input, ContentChild, Component, EventEmitter, Output, Injectable, inject } from '@angular/core';
4
- import { IconEdit16, spacers, colors, theme, Tooltip, Button as Button$1, IconDimensionData16, IconClock16, IconDimensionOrgUnit16, 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, DataTable, TableHead, DataTableRow, DataTableColumnHeader, TableBody, DataTableCell, TableFoot, Pagination } from '@dhis2/ui';
5
- import cx from 'classnames';
6
- import PropTypes from 'prop-types';
7
- import * as React from 'react';
8
- import React__default, { useState, useCallback, useRef, useEffect, createContext, useContext, useMemo } from 'react';
4
+ import { NgModule, Directive, Input, ContentChild, Component, EventEmitter, Output, Injectable, inject, NgZone, input, model, signal, computed, ViewChildren } from '@angular/core';
9
5
  import { useDataQuery, useConfig, useAlert, clearSensitiveCaches, DataProvider, useDataEngine, Provider } from '@dhis2/app-runtime';
10
6
  import * as i1 from '@iapps/ngx-dhis2-http-client';
7
+ import { NgxDhis2HttpClientService } from '@iapps/ngx-dhis2-http-client';
8
+ import * as React from 'react';
9
+ import React__default, { useState, useCallback, useRef, useEffect, createContext, useContext, useMemo } from 'react';
11
10
  import * as ReactDOM from 'react-dom/client';
12
- import { catchError, of, map, zip, firstValueFrom } from 'rxjs';
11
+ import { catchError, of, map, zip, firstValueFrom, Subject, takeUntil } from 'rxjs';
13
12
  import i18n from '@dhis2/d2-i18n';
14
- import { colors as colors$1, theme as theme$1, spacers as spacers$1 } from '@dhis2/ui-constants';
13
+ import { colors, theme, spacers } from '@dhis2/ui-constants';
14
+ import PropTypes from 'prop-types';
15
15
  import { Card } from '@dhis2-ui/card';
16
16
  import { InputField } from '@dhis2-ui/input';
17
17
  import { IconSettings24, IconApps24, IconMessages24, IconMail24, IconUser24, IconQuestion24, IconInfo24, IconLogOut24 } from '@dhis2/ui-icons';
@@ -25,152 +25,29 @@ import { Layer } from '@dhis2-ui/layer';
25
25
  import { CircularLoader } from '@dhis2-ui/loader';
26
26
  import { MenuItem, MenuDivider } from '@dhis2-ui/menu';
27
27
  import parse from 'html-react-parser';
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';
28
29
  import { getNowInCalendar, generateFixedPeriods } from '@dhis2/multi-calendar-dates';
29
- import { isObject, isString } from 'lodash';
30
- import { switchMap, map as map$1 } from 'rxjs/operators';
31
-
32
- const TransferOption = ({ disabled, label, highlighted, selected, onClick, onDoubleClick, value, icon, active, tooltipText, dataTest, onEditClick, }) => {
33
- const renderContent = () => (React__default.createElement("div", { className: cx('chip', {
34
- highlighted,
35
- disabled,
36
- selected,
37
- inactive: active !== undefined && !active,
38
- }), "data-test": `${dataTest}-content`, onClick: (event) => {
39
- if (disabled) {
40
- return;
41
- }
42
- onClick({ label, value }, event);
43
- }, onDoubleClick: (event) => {
44
- if (disabled) {
45
- return;
46
- }
47
- onDoubleClick({ label, value }, event);
48
- } },
49
- React__default.createElement("span", { className: "icon" }, icon),
50
- React__default.createElement("span", { className: "label" }, label),
51
- onEditClick && (React__default.createElement("span", { className: "edit", onClick: (e) => {
52
- e.stopPropagation();
53
- onEditClick();
54
- }, "data-test": `${dataTest}-edit-button` },
55
- React__default.createElement(IconEdit16, null))),
56
- React__default.createElement("style", { jsx: true }, `
57
- .wrapper:last-child {
58
- margin-bottom: ${spacers.dp4};
59
- }
60
- .chip {
61
- display: inline-flex;
62
- background: ${colors.grey200};
63
- font-size: 14px;
64
- line-height: 16px;
65
- padding: 2px ${spacers.dp8} 2px ${spacers.dp4};
66
- margin: ${spacers.dp4} ${spacers.dp8} 0 ${spacers.dp8};
67
- border-radius: 3px;
68
- user-select: none;
69
- }
70
-
71
- .chip:hover {
72
- background: ${colors.grey300};
73
- }
74
-
75
- .selected {
76
- background: ${theme.secondary100};
77
- color: ${theme.secondary900};
78
- }
79
-
80
- .selected :global(.icon path) {
81
- fill: ${theme.secondary700};
82
- }
83
-
84
- .selected:hover {
85
- background: #c9edeb;
86
- }
87
-
88
- .highlighted,
89
- .highlighted:hover {
90
- background: ${theme.secondary800};
91
- color: ${colors.white};
92
- }
93
-
94
- .highlighted :global(.icon path) {
95
- fill: ${colors.white};
96
- }
97
-
98
- .disabled {
99
- opacity: 0.3;
100
- cursor: not-allowed;
101
- }
102
-
103
- .inactive {
104
- opacity: 0.3;
105
- }
106
-
107
- .icon,
108
- .label {
109
- line-height: 18px;
110
- }
111
-
112
- .icon {
113
- margin-right: ${spacers.dp4};
114
- display: inline-flex;
115
- vertical-align: text-bottom;
116
- padding-top: 1px;
117
- }
118
-
119
- .label {
120
- font-size: 14px;
121
- }
122
-
123
- .edit {
124
- height: 16px;
125
- margin-top: 1px;
126
- margin-left: ${spacers.dp8};
127
- cursor: pointer;
128
- }
129
-
130
- .edit:hover {
131
- background-color: rgba(0, 0, 0, 0.12);
132
- outline: 1px solid rgba(0, 0, 0, 0.12);
133
- border-radius: 3px;
134
- }
135
-
136
- .highlighted .edit:hover {
137
- background-color: rgba(255, 255, 255, 0.12);
138
- outline: 1px solid rgba(255, 255, 255, 0.12);
139
- }
140
- `)));
141
- return (React__default.createElement("div", { "data-value": value, "data-test": dataTest, className: "wrapper" }, tooltipText ? (React__default.createElement(Tooltip, { key: `${value}`, content: tooltipText, placement: 'top', openDelay: 750, closeDelay: 150 }, renderContent())) : (renderContent())));
142
- };
143
- TransferOption.propTypes = {
144
- label: PropTypes.string.isRequired,
145
- value: PropTypes.string.isRequired,
146
- active: PropTypes.bool,
147
- dataTest: PropTypes.string,
148
- disabled: PropTypes.bool,
149
- highlighted: PropTypes.bool,
150
- icon: PropTypes.node,
151
- selected: PropTypes.bool,
152
- tooltipText: PropTypes.string,
153
- onClick: PropTypes.func,
154
- onDoubleClick: PropTypes.func,
155
- onEditClick: PropTypes.func,
156
- };
157
-
158
- // Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
159
- // Use of this source code is governed by a BSD-style
160
- // license that can be found in the LICENSE file.
161
- const sharedComponents = [];
30
+ import { isObject, isString, sortBy, isArray, find, camelCase, flatten, head, range } from 'lodash';
31
+ import cx from 'classnames';
32
+ import { map as map$1, switchMap } from 'rxjs/operators';
33
+ import * as i2 from '@angular/forms';
34
+ import { Validators, UntypedFormControl, UntypedFormGroup, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
35
+ import { toObservable } from '@angular/core/rxjs-interop';
36
+ import { format } from 'date-fns';
37
+ import moment from 'moment';
38
+ import { ProgramRuleEngine } from '@iapps/d2-web-sdk';
162
39
 
163
40
  class SharedDhis2UiModule {
164
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: SharedDhis2UiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
165
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.7", ngImport: i0, type: SharedDhis2UiModule, imports: [CommonModule] }); }
166
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: SharedDhis2UiModule, imports: [CommonModule] }); }
41
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SharedDhis2UiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
42
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: SharedDhis2UiModule, imports: [CommonModule] }); }
43
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SharedDhis2UiModule, imports: [CommonModule] }); }
167
44
  }
168
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: SharedDhis2UiModule, decorators: [{
45
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SharedDhis2UiModule, decorators: [{
169
46
  type: NgModule,
170
47
  args: [{
171
48
  imports: [CommonModule],
172
- declarations: [...sharedComponents],
173
- exports: [...sharedComponents],
49
+ declarations: [],
50
+ exports: [],
174
51
  }]
175
52
  }] });
176
53
 
@@ -270,7 +147,7 @@ function Search({ value, onChange, baseUrl }) {
270
147
  React__default.createElement(InputField, { value: value, name: "filter", placeholder: i18n.t('Search apps'), onChange: onChange, initialFocus: true })),
271
148
  React__default.createElement("span", { className: "headerbar-apps-search-icon" },
272
149
  React__default.createElement("a", { href: joinPath(baseUrl, 'dhis-web-menu-management') },
273
- React__default.createElement(IconSettings24, { color: colors$1.grey700 }))),
150
+ React__default.createElement(IconSettings24, { color: colors.grey700 }))),
274
151
  React__default.createElement("style", { jsx: true }, `
275
152
  .headerbar-apps-search {
276
153
  display: flex;
@@ -328,7 +205,7 @@ function Item({ name, path, img }) {
328
205
 
329
206
  .headerbar-app-item-logo:hover,
330
207
  .headerbar-app-item-logo:focus {
331
- background-color: ${theme$1.primary050};
208
+ background-color: ${theme.primary050};
332
209
  cursor: pointer;
333
210
  }
334
211
 
@@ -433,13 +310,13 @@ const Apps = ({ apps, baseUrl }) => {
433
310
  }, [onDocClick]);
434
311
  return (React__default.createElement("div", { className: "headerbar-apps", ref: containerEl, "data-test": "headerbar-apps" },
435
312
  React__default.createElement("button", { onClick: handleVisibilityToggle, "data-test": "headerbar-apps-icon" },
436
- React__default.createElement(IconApps24, { color: colors$1.white })),
313
+ React__default.createElement(IconApps24, { color: colors.white })),
437
314
  show ? (React__default.createElement(AppMenu, { apps: apps, filter: filter, baseUrl: baseUrl, onFilterChange: handleFilterChange })) : null,
438
315
  React__default.createElement("style", { jsx: true }, `
439
316
  .headerbar-apps button {
440
317
  display: block;
441
318
  background: transparent;
442
- padding: ${spacers$1.dp4} ${spacers$1.dp12} 0;
319
+ padding: ${spacers.dp4} ${spacers.dp12} 0;
443
320
  border: 0;
444
321
  cursor: pointer;
445
322
  height: 100%;
@@ -553,10 +430,10 @@ const Logo = ({ baseUrl }) => {
553
430
 
554
431
  function icon(kind) {
555
432
  if (kind === 'message') {
556
- return React__default.createElement(IconMessages24, { color: colors$1.white });
433
+ return React__default.createElement(IconMessages24, { color: colors.white });
557
434
  }
558
435
  else {
559
- return React__default.createElement(IconMail24, { color: colors$1.white });
436
+ return React__default.createElement(IconMail24, { color: colors.white });
560
437
  }
561
438
  }
562
439
  const NotificationIcon = (params) => {
@@ -570,7 +447,7 @@ const NotificationIcon = (params) => {
570
447
  position: relative;
571
448
  margin: 0;
572
449
  cursor: pointer;
573
- padding: 0 ${spacers$1.dp12};
450
+ padding: 0 ${spacers.dp12};
574
451
  height: 100%;
575
452
  display: flex;
576
453
  align-items: center;
@@ -598,17 +475,17 @@ const NotificationIcon = (params) => {
598
475
  right: 2px;
599
476
  min-width: 18px;
600
477
  min-height: 18px;
601
- border-radius: ${spacers$1.dp12};
478
+ border-radius: ${spacers.dp12};
602
479
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1),
603
480
  0 1px 2px 0 rgba(0, 0, 0, 0.06);
604
- background-color: ${theme$1.secondary500};
605
- color: ${colors$1.white};
481
+ background-color: ${theme.secondary500};
482
+ color: ${colors.white};
606
483
  font-size: 13px;
607
484
  font-weight: 600;
608
485
  line-height: 15px;
609
486
  text-align: center;
610
487
  cursor: inherit;
611
- padding: 0 ${spacers$1.dp4};
488
+ padding: 0 ${spacers.dp4};
612
489
  }
613
490
  `)));
614
491
  };
@@ -688,7 +565,7 @@ function DebugInfoTable() {
688
565
  white-space: pre-wrap;
689
566
  font-size: 14px;
690
567
  line-height: 1.2;
691
- color: ${colors$1.grey700};
568
+ color: ${colors.grey700};
692
569
  font-famile: Menlo, Courier, monospace !important;
693
570
  }
694
571
  td {
@@ -748,7 +625,7 @@ const DebugInfoMenuItem = (params) => {
748
625
  : i18n.t('App version unknown')),
749
626
  React__default.createElement("style", { jsx: true }, `
750
627
  .root {
751
- color: ${colors$1.grey700};
628
+ color: ${colors.grey700};
752
629
  font-style: italic;
753
630
  font-size: 14px;
754
631
  line-height: 17px;
@@ -902,7 +779,7 @@ function UpdateNotification(params) {
902
779
  height: 12px;
903
780
  margin: 0 8px;
904
781
  border-radius: 6px;
905
- background-color: ${colors$1.blue600};
782
+ background-color: ${colors.blue600};
906
783
  }
907
784
  .spacer {
908
785
  display: inline-block;
@@ -930,10 +807,10 @@ const ProfileContents = (params) => {
930
807
  React__default.createElement(ProfileHeader, { name: name, email: email, avatarId: avatarId }),
931
808
  React__default.createElement(Divider, { margin: "13px 0 7px 0" }),
932
809
  React__default.createElement("ul", { "data-test": "headerbar-profile-menu" },
933
- React__default.createElement(MenuItem, { href: joinPath(baseUrl, 'dhis-web-user-profile/#/settings'), label: i18n.t('Settings'), value: "settings", icon: React__default.createElement(IconSettings24, { color: colors$1.grey700 }) }),
934
- React__default.createElement(MenuItem, { href: joinPath(baseUrl, 'dhis-web-user-profile/#/account'), label: i18n.t('Account'), value: "account", icon: React__default.createElement(IconUser24, { color: colors$1.grey700 }) }),
935
- helpUrl && (React__default.createElement(MenuItem, { href: helpUrl, label: i18n.t('Help'), value: "help", icon: React__default.createElement(IconQuestion24, { color: colors$1.grey700 }) })),
936
- React__default.createElement(MenuItem, { href: joinPath(baseUrl, 'dhis-web-user-profile/#/aboutPage'), label: i18n.t('About DHIS2'), value: "about", icon: React__default.createElement(IconInfo24, { color: colors$1.grey700 }) }),
810
+ React__default.createElement(MenuItem, { href: joinPath(baseUrl, 'dhis-web-user-profile/#/settings'), label: i18n.t('Settings'), value: "settings", icon: React__default.createElement(IconSettings24, { color: colors.grey700 }) }),
811
+ React__default.createElement(MenuItem, { href: joinPath(baseUrl, 'dhis-web-user-profile/#/account'), label: i18n.t('Account'), value: "account", icon: React__default.createElement(IconUser24, { color: colors.grey700 }) }),
812
+ helpUrl && (React__default.createElement(MenuItem, { href: helpUrl, label: i18n.t('Help'), value: "help", icon: React__default.createElement(IconQuestion24, { color: colors.grey700 }) })),
813
+ React__default.createElement(MenuItem, { href: joinPath(baseUrl, 'dhis-web-user-profile/#/aboutPage'), label: i18n.t('About DHIS2'), value: "about", icon: React__default.createElement(IconInfo24, { color: colors.grey700 }) }),
937
814
  React__default.createElement(MenuItem, { href: joinPath(baseUrl, 'dhis-web-commons-security/logout.action'),
938
815
  // NB: By MenuItem implementation, this callback
939
816
  // overwrites default navigation behavior but maintains
@@ -943,7 +820,7 @@ const ProfileContents = (params) => {
943
820
  await clearSensitiveCaches();
944
821
  setLoading(false);
945
822
  window.location.assign(joinPath(baseUrl, 'dhis-web-commons-security/logout.action'));
946
- }, label: i18n.t('Logout'), value: "logout", icon: React__default.createElement(IconLogOut24, { color: colors$1.grey700 }) }),
823
+ }, label: i18n.t('Logout'), value: "logout", icon: React__default.createElement(IconLogOut24, { color: colors.grey700 }) }),
947
824
  React__default.createElement(MenuDivider, { dense: true }),
948
825
  React__default.createElement(DebugInfoMenuItem, { hideProfileMenu: hideProfileMenu, showDebugInfoModal: showDebugInfoModal }),
949
826
  React__default.createElement(UpdateNotification, { hideProfileMenu: hideProfileMenu }))),
@@ -1124,7 +1001,7 @@ const HeaderBar = ({ appName, data, className }) => {
1124
1001
  align-items: center;
1125
1002
  justify-content: space-between;
1126
1003
  background-color: #2c6693;
1127
- color: ${colors$1.white};
1004
+ color: ${colors.white};
1128
1005
  height: 48px;
1129
1006
  }
1130
1007
  .right-control-spacer {
@@ -1151,9 +1028,6 @@ class ReactWrapperComponent {
1151
1028
  this.reactDomRoot = ReactDOM.createRoot(this.elementRef.nativeElement);
1152
1029
  this.render();
1153
1030
  }
1154
- ngOnChanges() {
1155
- // if (this.elementRef) this.render();
1156
- }
1157
1031
  ngOnDestroy() {
1158
1032
  this.reactDomRoot?.unmount();
1159
1033
  }
@@ -1173,10 +1047,10 @@ class ReactWrapperComponent {
1173
1047
  " "));
1174
1048
  }
1175
1049
  }
1176
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ReactWrapperComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1177
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.7", type: ReactWrapperComponent, isStandalone: false, selector: "ng-dhis2-ui-wrapper", inputs: { props: "props", component: "component" }, queries: [{ propertyName: "content", first: true, predicate: ["ngDhis2UiContent"], descendants: true }], usesOnChanges: true, ngImport: i0 }); }
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 }); }
1178
1052
  }
1179
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ReactWrapperComponent, decorators: [{
1053
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperComponent, decorators: [{
1180
1054
  type: Directive,
1181
1055
  args: [{
1182
1056
  selector: 'ng-dhis2-ui-wrapper',
@@ -1192,11 +1066,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
1192
1066
  }] } });
1193
1067
 
1194
1068
  class ReactWrapperModule {
1195
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ReactWrapperModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1196
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.7", ngImport: i0, type: ReactWrapperModule, declarations: [ReactWrapperComponent], imports: [CommonModule], exports: [ReactWrapperComponent] }); }
1197
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ReactWrapperModule, imports: [CommonModule] }); }
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] }); }
1198
1072
  }
1199
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ReactWrapperModule, decorators: [{
1073
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, decorators: [{
1200
1074
  type: NgModule,
1201
1075
  args: [{
1202
1076
  imports: [CommonModule],
@@ -1225,10 +1099,10 @@ class HeaderBarComponent extends ReactWrapperComponent {
1225
1099
  : () => React__default.createElement("div", null, "Something went wrong");
1226
1100
  this.render();
1227
1101
  }
1228
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: HeaderBarComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }], target: i0.ɵɵFactoryTarget.Component }); }
1229
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.7", type: HeaderBarComponent, isStandalone: false, selector: "ng-dhis2-ui-header-bar", usesInheritance: true, ngImport: i0, template: `<ng-container></ng-container>`, isInline: true }); }
1102
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }], target: i0.ɵɵFactoryTarget.Component }); }
1103
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: HeaderBarComponent, isStandalone: false, selector: "ng-dhis2-ui-header-bar", usesInheritance: true, ngImport: i0, template: `<ng-container></ng-container>`, isInline: true }); }
1230
1104
  }
1231
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: HeaderBarComponent, decorators: [{
1105
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarComponent, decorators: [{
1232
1106
  type: Component,
1233
1107
  args: [{
1234
1108
  selector: 'ng-dhis2-ui-header-bar',
@@ -1238,11 +1112,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
1238
1112
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }] });
1239
1113
 
1240
1114
  class HeaderBarModule {
1241
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: HeaderBarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1242
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.7", ngImport: i0, type: HeaderBarModule, declarations: [HeaderBarComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [HeaderBarComponent] }); }
1243
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: HeaderBarModule, imports: [CommonModule, SharedDhis2UiModule] }); }
1115
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1116
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarModule, declarations: [HeaderBarComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [HeaderBarComponent] }); }
1117
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarModule, imports: [CommonModule, SharedDhis2UiModule] }); }
1244
1118
  }
1245
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: HeaderBarModule, decorators: [{
1119
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarModule, decorators: [{
1246
1120
  type: NgModule,
1247
1121
  args: [{
1248
1122
  imports: [CommonModule, SharedDhis2UiModule],
@@ -1282,10 +1156,10 @@ class ButtonComponent extends ReactWrapperComponent {
1282
1156
  onButtonClick(event) {
1283
1157
  this.buttonClick.emit(event);
1284
1158
  }
1285
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ButtonComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1286
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.7", type: ButtonComponent, isStandalone: false, selector: "ng-dhis2-ui-button", inputs: { label: "label", primary: "primary", secondary: "secondary", destructive: "destructive", disabled: "disabled", small: "small", large: "large" }, outputs: { buttonClick: "buttonClick" }, usesInheritance: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true }); }
1159
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ButtonComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1160
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: ButtonComponent, isStandalone: false, selector: "ng-dhis2-ui-button", inputs: { label: "label", primary: "primary", secondary: "secondary", destructive: "destructive", disabled: "disabled", small: "small", large: "large" }, outputs: { buttonClick: "buttonClick" }, usesInheritance: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true }); }
1287
1161
  }
1288
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ButtonComponent, decorators: [{
1162
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ButtonComponent, decorators: [{
1289
1163
  type: Component,
1290
1164
  args: [{
1291
1165
  selector: 'ng-dhis2-ui-button',
@@ -1311,11 +1185,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
1311
1185
  }] } });
1312
1186
 
1313
1187
  class ButtonModule {
1314
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1315
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.7", ngImport: i0, type: ButtonModule, declarations: [ButtonComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [ButtonComponent] }); }
1316
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ButtonModule, imports: [CommonModule, SharedDhis2UiModule] }); }
1188
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1189
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: ButtonModule, declarations: [ButtonComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [ButtonComponent] }); }
1190
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ButtonModule, imports: [CommonModule, SharedDhis2UiModule] }); }
1317
1191
  }
1318
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ButtonModule, decorators: [{
1192
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ButtonModule, decorators: [{
1319
1193
  type: NgModule,
1320
1194
  args: [{
1321
1195
  declarations: [ButtonComponent],
@@ -1540,38 +1414,38 @@ const dimensionGetItems = (dimension) => dimensionIsValid(dimension, { requireIt
1540
1414
  var styles$1 = `
1541
1415
  .filterContainer {
1542
1416
  display: flex;
1543
- margin-bottom: ${spacers.dp12};
1544
- margin-top: ${spacers.dp8};
1417
+ margin-bottom: ${spacers$1.dp12};
1418
+ margin-top: ${spacers$1.dp8};
1545
1419
  }
1546
1420
  .emptyList {
1547
1421
  text-align: center;
1548
1422
  font-size: 14px;
1549
1423
  line-height: 16px;
1550
- margin: ${spacers.dp24} 0 0;
1551
- color: ${colors.grey700};
1424
+ margin: ${spacers$1.dp24} 0 0;
1425
+ color: ${colors$1.grey700};
1552
1426
  }
1553
1427
  .rightHeader {
1554
1428
  font-size: 14px;
1555
1429
  font-weight: 400;
1556
1430
  }
1557
1431
  .leftHeader {
1558
- padding: ${spacers.dp12} ${spacers.dp4};
1432
+ padding: ${spacers$1.dp12} ${spacers$1.dp4};
1559
1433
  }
1560
1434
  .info-container {
1561
1435
  display: flex;
1562
- margin-bottom: ${spacers.dp8};
1563
- padding: ${spacers.dp8};
1564
- background-color: ${colors.grey200};
1436
+ margin-bottom: ${spacers$1.dp8};
1437
+ padding: ${spacers$1.dp8};
1438
+ background-color: ${colors$1.grey200};
1565
1439
  border-radius: 3px;
1566
1440
  }
1567
1441
  .info-text {
1568
- padding-left: ${spacers.dp8};
1569
- color: ${colors.grey900};
1442
+ padding-left: ${spacers$1.dp8};
1443
+ color: ${colors$1.grey900};
1570
1444
  font-size: 12px;
1571
1445
  line-height: 16px;
1572
1446
  }
1573
1447
  .calculation-button {
1574
- margin: ${spacers.dp8} 0;
1448
+ margin: ${spacers$1.dp8} 0;
1575
1449
  }
1576
1450
  `;
1577
1451
 
@@ -1579,6 +1453,136 @@ var styles$1 = `
1579
1453
  // Use of this source code is governed by a BSD-style
1580
1454
  // license that can be found in the LICENSE file.
1581
1455
 
1456
+ const TransferOption = ({ disabled, label, highlighted, selected, onClick, onDoubleClick, value, icon, active, tooltipText, dataTest, onEditClick, }) => {
1457
+ const renderContent = () => (React__default.createElement("div", { className: cx('chip', {
1458
+ highlighted,
1459
+ disabled,
1460
+ selected,
1461
+ inactive: active !== undefined && !active,
1462
+ }), "data-test": `${dataTest}-content`, onClick: (event) => {
1463
+ if (disabled) {
1464
+ return;
1465
+ }
1466
+ onClick({ label, value }, event);
1467
+ }, onDoubleClick: (event) => {
1468
+ if (disabled) {
1469
+ return;
1470
+ }
1471
+ onDoubleClick({ label, value }, event);
1472
+ } },
1473
+ React__default.createElement("span", { className: "icon" }, icon),
1474
+ React__default.createElement("span", { className: "label" }, label),
1475
+ onEditClick && (React__default.createElement("span", { className: "edit", onClick: (e) => {
1476
+ e.stopPropagation();
1477
+ onEditClick();
1478
+ }, "data-test": `${dataTest}-edit-button` },
1479
+ React__default.createElement(IconEdit16, null))),
1480
+ React__default.createElement("style", { jsx: true }, `
1481
+ .wrapper:last-child {
1482
+ margin-bottom: ${spacers$1.dp4};
1483
+ }
1484
+ .chip {
1485
+ display: inline-flex;
1486
+ background: ${colors$1.grey200};
1487
+ font-size: 14px;
1488
+ line-height: 16px;
1489
+ padding: 2px ${spacers$1.dp8} 2px ${spacers$1.dp4};
1490
+ margin: ${spacers$1.dp4} ${spacers$1.dp8} 0 ${spacers$1.dp8};
1491
+ border-radius: 3px;
1492
+ user-select: none;
1493
+ }
1494
+
1495
+ .chip:hover {
1496
+ background: ${colors$1.grey300};
1497
+ }
1498
+
1499
+ .selected {
1500
+ background: ${theme$1.secondary100};
1501
+ color: ${theme$1.secondary900};
1502
+ }
1503
+
1504
+ .selected :global(.icon path) {
1505
+ fill: ${theme$1.secondary700};
1506
+ }
1507
+
1508
+ .selected:hover {
1509
+ background: #c9edeb;
1510
+ }
1511
+
1512
+ .highlighted,
1513
+ .highlighted:hover {
1514
+ background: ${theme$1.secondary800};
1515
+ color: ${colors$1.white};
1516
+ }
1517
+
1518
+ .highlighted :global(.icon path) {
1519
+ fill: ${colors$1.white};
1520
+ }
1521
+
1522
+ .disabled {
1523
+ opacity: 0.3;
1524
+ cursor: not-allowed;
1525
+ }
1526
+
1527
+ .inactive {
1528
+ opacity: 0.3;
1529
+ }
1530
+
1531
+ .icon,
1532
+ .label {
1533
+ line-height: 18px;
1534
+ }
1535
+
1536
+ .icon {
1537
+ margin-right: ${spacers$1.dp4};
1538
+ display: inline-flex;
1539
+ vertical-align: text-bottom;
1540
+ padding-top: 1px;
1541
+ }
1542
+
1543
+ .label {
1544
+ font-size: 14px;
1545
+ }
1546
+
1547
+ .edit {
1548
+ height: 16px;
1549
+ margin-top: 1px;
1550
+ margin-left: ${spacers$1.dp8};
1551
+ cursor: pointer;
1552
+ }
1553
+
1554
+ .edit:hover {
1555
+ background-color: rgba(0, 0, 0, 0.12);
1556
+ outline: 1px solid rgba(0, 0, 0, 0.12);
1557
+ border-radius: 3px;
1558
+ }
1559
+
1560
+ .highlighted .edit:hover {
1561
+ background-color: rgba(255, 255, 255, 0.12);
1562
+ outline: 1px solid rgba(255, 255, 255, 0.12);
1563
+ }
1564
+ `)));
1565
+ return (React__default.createElement("div", { "data-value": value, "data-test": dataTest, className: "wrapper" }, tooltipText ? (React__default.createElement(Tooltip, { key: `${value}`, content: tooltipText, placement: 'top', openDelay: 750, closeDelay: 150 }, renderContent())) : (renderContent())));
1566
+ };
1567
+ TransferOption.propTypes = {
1568
+ label: PropTypes.string.isRequired,
1569
+ value: PropTypes.string.isRequired,
1570
+ active: PropTypes.bool,
1571
+ dataTest: PropTypes.string,
1572
+ disabled: PropTypes.bool,
1573
+ highlighted: PropTypes.bool,
1574
+ icon: PropTypes.node,
1575
+ selected: PropTypes.bool,
1576
+ tooltipText: PropTypes.string,
1577
+ onClick: PropTypes.func,
1578
+ onDoubleClick: PropTypes.func,
1579
+ onEditClick: PropTypes.func,
1580
+ };
1581
+
1582
+ // Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
1583
+ // Use of this source code is governed by a BSD-style
1584
+ // license that can be found in the LICENSE file.
1585
+
1582
1586
  // Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
1583
1587
  // Use of this source code is governed by a BSD-style
1584
1588
  // license that can be found in the LICENSE file.
@@ -2071,7 +2075,7 @@ const FixedPeriodFilter = ({ allowedPeriodTypes, excludedPeriodTypes, currentPer
2071
2075
  }
2072
2076
  .rightSection {
2073
2077
  width: 120px;
2074
- margin-left: ${spacers.dp8};
2078
+ margin-left: ${spacers$1.dp8};
2075
2079
  }
2076
2080
  `)));
2077
2081
  };
@@ -2100,7 +2104,7 @@ const RelativePeriodFilter = ({ currentFilter, onSelectFilter, dataTest, exclude
2100
2104
  }
2101
2105
  .rightSection {
2102
2106
  width: 120px;
2103
- margin-left: ${spacers.dp8};
2107
+ margin-left: ${spacers$1.dp8};
2104
2108
  }
2105
2109
  `)));
2106
2110
  RelativePeriodFilter.propTypes = {
@@ -2303,10 +2307,10 @@ class PeriodSelectorModalComponent extends ReactWrapperComponent {
2303
2307
  onConfirm(selectedItems) {
2304
2308
  this.confirm.emit(selectedItems);
2305
2309
  }
2306
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: PeriodSelectorModalComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }], target: i0.ɵɵFactoryTarget.Component }); }
2307
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.7", type: PeriodSelectorModalComponent, isStandalone: false, selector: "ng-dhis2-ui-period-selector-modal", inputs: { selectedPeriods: "selectedPeriods" }, outputs: { cancel: "cancel", confirm: "confirm" }, usesInheritance: true, ngImport: i0, template: `<ng-container></ng-container>`, isInline: true, styles: ["::ng-deep .layer{z-index:2!important}\n"] }); }
2310
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorModalComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }], target: i0.ɵɵFactoryTarget.Component }); }
2311
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: PeriodSelectorModalComponent, isStandalone: false, selector: "ng-dhis2-ui-period-selector-modal", inputs: { selectedPeriods: "selectedPeriods" }, outputs: { cancel: "cancel", confirm: "confirm" }, usesInheritance: true, ngImport: i0, template: `<ng-container></ng-container>`, isInline: true, styles: ["::ng-deep .layer{z-index:2!important}\n"] }); }
2308
2312
  }
2309
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: PeriodSelectorModalComponent, decorators: [{
2313
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorModalComponent, decorators: [{
2310
2314
  type: Component,
2311
2315
  args: [{ selector: 'ng-dhis2-ui-period-selector-modal', template: `<ng-container></ng-container>`, standalone: false, styles: ["::ng-deep .layer{z-index:2!important}\n"] }]
2312
2316
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }], propDecorators: { selectedPeriods: [{
@@ -2363,10 +2367,10 @@ class PeriodSelectorComponent extends ReactWrapperComponent {
2363
2367
  onSelectItems(selectionEvent) {
2364
2368
  this.selectPeriods.emit(selectionEvent.items);
2365
2369
  }
2366
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: PeriodSelectorComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
2367
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.7", type: PeriodSelectorComponent, isStandalone: false, selector: "ng-dhis2-ui-period-selector", inputs: { selectedPeriods: "selectedPeriods" }, outputs: { selectPeriods: "selectPeriods" }, usesInheritance: true, ngImport: i0, template: `<ng-container></ng-container>`, isInline: true, styles: ["::ng-deep .content-container{z-index:0!important}\n"] }); }
2370
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
2371
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: PeriodSelectorComponent, isStandalone: false, selector: "ng-dhis2-ui-period-selector", inputs: { selectedPeriods: "selectedPeriods" }, outputs: { selectPeriods: "selectPeriods" }, usesInheritance: true, ngImport: i0, template: `<ng-container></ng-container>`, isInline: true, styles: ["::ng-deep .content-container{z-index:0!important}\n"] }); }
2368
2372
  }
2369
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: PeriodSelectorComponent, decorators: [{
2373
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorComponent, decorators: [{
2370
2374
  type: Component,
2371
2375
  args: [{ selector: 'ng-dhis2-ui-period-selector', template: `<ng-container></ng-container>`, standalone: false, styles: ["::ng-deep .content-container{z-index:0!important}\n"] }]
2372
2376
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }, { type: i0.NgZone }], propDecorators: { selectedPeriods: [{
@@ -2376,11 +2380,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2376
2380
  }] } });
2377
2381
 
2378
2382
  class PeriodSelectorModule {
2379
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: PeriodSelectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2380
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.7", ngImport: i0, type: PeriodSelectorModule, declarations: [PeriodSelectorComponent, PeriodSelectorModalComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [PeriodSelectorComponent, PeriodSelectorModalComponent] }); }
2381
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: PeriodSelectorModule, imports: [CommonModule, SharedDhis2UiModule] }); }
2383
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2384
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorModule, declarations: [PeriodSelectorComponent, PeriodSelectorModalComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [PeriodSelectorComponent, PeriodSelectorModalComponent] }); }
2385
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorModule, imports: [CommonModule, SharedDhis2UiModule] }); }
2382
2386
  }
2383
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: PeriodSelectorModule, decorators: [{
2387
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorModule, decorators: [{
2384
2388
  type: NgModule,
2385
2389
  args: [{
2386
2390
  imports: [CommonModule, SharedDhis2UiModule],
@@ -2472,20 +2476,20 @@ const styles = `
2472
2476
 
2473
2477
  .userOrgUnitsWrapper {
2474
2478
  display: flex;
2475
- background: ${colors.grey200};
2476
- padding: ${spacers.dp8} ${spacers.dp8} ${spacers.dp8} ${spacers.dp24};
2477
- margin-bottom: ${spacers.dp12};
2479
+ background: ${colors$1.grey200};
2480
+ padding: ${spacers$1.dp8} ${spacers$1.dp8} ${spacers$1.dp8} ${spacers$1.dp24};
2481
+ margin-bottom: ${spacers$1.dp12};
2478
2482
  }
2479
2483
 
2480
2484
  .userOrgUnitsWrapper > :global(*) {
2481
- margin-right: ${spacers.dp48};
2485
+ margin-right: ${spacers$1.dp48};
2482
2486
  }
2483
2487
 
2484
2488
  .selectsWrapper {
2485
2489
  display: flex;
2486
2490
  align-items: flex-start;
2487
- gap: ${spacers.dp8};
2488
- margin-top: ${spacers.dp12};
2491
+ gap: ${spacers$1.dp8};
2492
+ margin-top: ${spacers$1.dp12};
2489
2493
  }
2490
2494
 
2491
2495
  .selectsWrapper.hidden {
@@ -2499,7 +2503,7 @@ const styles = `
2499
2503
  .summaryWrapper {
2500
2504
  display: inline-flex;
2501
2505
  align-items: center;
2502
- margin-top: ${spacers.dp8};
2506
+ margin-top: ${spacers$1.dp8};
2503
2507
  }
2504
2508
 
2505
2509
  .warningWrapper {
@@ -2508,21 +2512,21 @@ const styles = `
2508
2512
  }
2509
2513
 
2510
2514
  .warningText {
2511
- margin-left: ${spacers.dp8};
2515
+ margin-left: ${spacers$1.dp8};
2512
2516
  font-size: 14px;
2513
2517
  line-height: 18px;
2514
- color: ${colors.red600};
2518
+ color: ${colors$1.red600};
2515
2519
  }
2516
2520
 
2517
2521
  .summaryText {
2518
2522
  font-size: 14px;
2519
2523
  line-height: 18px;
2520
- color: ${colors.grey700};
2524
+ color: ${colors$1.grey700};
2521
2525
  }
2522
2526
 
2523
2527
  .deselectButton {
2524
2528
  display: inline-block;
2525
- margin-left: ${spacers.dp8};
2529
+ margin-left: ${spacers$1.dp8};
2526
2530
  }
2527
2531
  `;
2528
2532
 
@@ -2537,7 +2541,6 @@ const OrgUnitDimension = ({ roots, selected, onSelect, hideGroupSelect, hideLeve
2537
2541
  const [selectedItems, setSelectedItems] = useState(selected);
2538
2542
  const dataEngine = useDataEngine();
2539
2543
  const onSelectItems = (selectedItem) => {
2540
- console.log('WE ARE SELECTING HERE', selectedItem);
2541
2544
  const { id, checked, displayName, path } = selectedItem;
2542
2545
  let result = [...selectedItems];
2543
2546
  if (checked && DYNAMIC_ORG_UNITS.includes(id)) {
@@ -2706,7 +2709,7 @@ const OrgUnitDimension = ({ roots, selected, onSelect, hideGroupSelect, hideLeve
2706
2709
  : [], onChange: ({ selected }) => onGroupChange(selected), placeholder: i18n.t('Select a group'), loading: !ouGroups.length, dense: true, dataTest: 'org-unit-group-select' }, ouGroups.map((group) => (React__default.createElement(MultiSelectOption, { key: group.id, value: group.id, label: group.displayName, dataTest: `org-unit-group-select-option-${group.id}` })))))),
2707
2710
  React__default.createElement("div", { className: "summaryWrapper" },
2708
2711
  warning ? (React__default.createElement("div", { className: "warningWrapper" },
2709
- React__default.createElement(IconWarningFilled16, { color: colors.red500 }),
2712
+ React__default.createElement(IconWarningFilled16, { color: colors$1.red500 }),
2710
2713
  React__default.createElement("span", { className: "warningText" }, warning))) : (React__default.createElement("span", { className: "summaryText" }, getSummary())),
2711
2714
  React__default.createElement("div", { className: "deselectButton" },
2712
2715
  React__default.createElement(Button$1, { secondary: true, small: true, onClick: clearSelection, disabled: !selectedItems.length }, i18n.t('Deselect all')))),
@@ -2818,10 +2821,10 @@ class OrganisationUnitSelectorComponent extends ReactWrapperComponent {
2818
2821
  onSelectItems(selectionEvent) {
2819
2822
  this.selectOrgUnits.emit(selectionEvent.items);
2820
2823
  }
2821
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: OrganisationUnitSelectorComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
2822
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.7", type: OrganisationUnitSelectorComponent, isStandalone: false, selector: "ng-dhis2-ui-org-unit-selector", inputs: { selectedOrgUnits: "selectedOrgUnits", orgUnitSelectionConfig: "orgUnitSelectionConfig" }, outputs: { selectOrgUnits: "selectOrgUnits" }, usesInheritance: true, ngImport: i0, template: '<ng-container><ng-container>', isInline: true }); }
2824
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
2825
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: OrganisationUnitSelectorComponent, isStandalone: false, selector: "ng-dhis2-ui-org-unit-selector", inputs: { selectedOrgUnits: "selectedOrgUnits", orgUnitSelectionConfig: "orgUnitSelectionConfig" }, outputs: { selectOrgUnits: "selectOrgUnits" }, usesInheritance: true, ngImport: i0, template: '<ng-container><ng-container>', isInline: true }); }
2823
2826
  }
2824
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: OrganisationUnitSelectorComponent, decorators: [{
2827
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorComponent, decorators: [{
2825
2828
  type: Component,
2826
2829
  args: [{
2827
2830
  selector: 'ng-dhis2-ui-org-unit-selector',
@@ -2920,10 +2923,10 @@ class OrganisationUnitSelectorModalComponent extends ReactWrapperComponent {
2920
2923
  onSelectItems(selectionEvent) {
2921
2924
  this.selectOrgUnits.emit(selectionEvent.items);
2922
2925
  }
2923
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: OrganisationUnitSelectorModalComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }], target: i0.ɵɵFactoryTarget.Component }); }
2924
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.7", type: OrganisationUnitSelectorModalComponent, isStandalone: false, selector: "ng-dhis2-ui-org-unit-selector-modal", inputs: { selectedOrgUnits: "selectedOrgUnits", orgUnitSelectionConfig: "orgUnitSelectionConfig" }, outputs: { selectOrgUnits: "selectOrgUnits", cancel: "cancel", confirm: "confirm" }, usesInheritance: true, ngImport: i0, template: '<ng-container><ng-container>', isInline: true, styles: ["::ng-deep .layer{z-index:2!important}\n"] }); }
2926
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModalComponent, deps: [{ token: i0.ElementRef }, { token: i1.NgxDhis2HttpClientService }], target: i0.ɵɵFactoryTarget.Component }); }
2927
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: OrganisationUnitSelectorModalComponent, isStandalone: false, selector: "ng-dhis2-ui-org-unit-selector-modal", inputs: { selectedOrgUnits: "selectedOrgUnits", orgUnitSelectionConfig: "orgUnitSelectionConfig" }, outputs: { selectOrgUnits: "selectOrgUnits", cancel: "cancel", confirm: "confirm" }, usesInheritance: true, ngImport: i0, template: '<ng-container><ng-container>', isInline: true, styles: ["::ng-deep .layer{z-index:2!important}\n"] }); }
2925
2928
  }
2926
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: OrganisationUnitSelectorModalComponent, decorators: [{
2929
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModalComponent, decorators: [{
2927
2930
  type: Component,
2928
2931
  args: [{ selector: 'ng-dhis2-ui-org-unit-selector-modal', template: '<ng-container><ng-container>', standalone: false, styles: ["::ng-deep .layer{z-index:2!important}\n"] }]
2929
2932
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }], propDecorators: { selectedOrgUnits: [{
@@ -2939,13 +2942,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2939
2942
  }] } });
2940
2943
 
2941
2944
  class OrganisationUnitSelectorModule {
2942
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: OrganisationUnitSelectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2943
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.7", ngImport: i0, type: OrganisationUnitSelectorModule, declarations: [OrganisationUnitSelectorComponent,
2945
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2946
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModule, declarations: [OrganisationUnitSelectorComponent,
2944
2947
  OrganisationUnitSelectorModalComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [OrganisationUnitSelectorComponent,
2945
2948
  OrganisationUnitSelectorModalComponent] }); }
2946
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: OrganisationUnitSelectorModule, imports: [CommonModule, SharedDhis2UiModule] }); }
2949
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModule, imports: [CommonModule, SharedDhis2UiModule] }); }
2947
2950
  }
2948
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: OrganisationUnitSelectorModule, decorators: [{
2951
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModule, decorators: [{
2949
2952
  type: NgModule,
2950
2953
  args: [{
2951
2954
  imports: [CommonModule, SharedDhis2UiModule],
@@ -2964,34 +2967,97 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2964
2967
  // Use of this source code is governed by a BSD-style
2965
2968
  // license that can be found in the LICENSE file.
2966
2969
 
2970
+ // export function buildFilters(filters: AttributeFilter[]): string {
2971
+ // return filters
2972
+ // .map(({ attribute, operator, value }) => `filter=${attribute}:${operator}:${value}`)
2973
+ // .join('&');
2974
+ // }
2967
2975
  function buildFilters(filters) {
2968
2976
  return filters
2969
- .map(({ attribute, operator, value }) => `filter=${attribute}:${operator}:${value}`)
2977
+ .map(({ attribute, dataElement, operator, value }) => {
2978
+ // Check if attribute is defined, otherwise use dataElement
2979
+ const field = attribute || dataElement;
2980
+ return field ? `filter=${field}:${operator}:${value}` : '';
2981
+ })
2982
+ .filter(Boolean) // Remove any empty strings
2970
2983
  .join('&');
2971
2984
  }
2972
-
2973
- class LineListService {
2974
- constructor(httpClient) {
2975
- this.httpClient = httpClient;
2976
- }
2985
+ const matchesCondition = (eventValue, operator, filterValue) => {
2986
+ if (typeof eventValue === 'number' && typeof filterValue === 'number') {
2987
+ switch (operator) {
2988
+ case '=':
2989
+ return eventValue === filterValue;
2990
+ case '!=':
2991
+ return eventValue !== filterValue;
2992
+ case '>':
2993
+ return eventValue > filterValue;
2994
+ case '<':
2995
+ return eventValue < filterValue;
2996
+ case '>=':
2997
+ return eventValue >= filterValue;
2998
+ case '<=':
2999
+ return eventValue <= filterValue;
3000
+ default:
3001
+ return false;
3002
+ }
3003
+ }
3004
+ const strEventValue = String(eventValue);
3005
+ const strFilterValue = String(filterValue);
3006
+ switch (operator) {
3007
+ case '=':
3008
+ return strEventValue === strFilterValue;
3009
+ case '!=':
3010
+ return strEventValue !== strFilterValue;
3011
+ case 'contains':
3012
+ return strEventValue.includes(strFilterValue);
3013
+ case 'startsWith':
3014
+ return strEventValue.startsWith(strFilterValue);
3015
+ case 'endsWith':
3016
+ return strEventValue.endsWith(strFilterValue);
3017
+ case 'regex':
3018
+ return new RegExp(strFilterValue).test(strEventValue);
3019
+ default:
3020
+ return false;
3021
+ }
3022
+ };
3023
+ const getFilteredTrackedEntityInstances = (trackedEntityInstance, filters) => {
3024
+ return trackedEntityInstance.filter((trackedEntityInstance) => trackedEntityInstance.enrollments.some((enrollment) => enrollment.events.some((event) => filters.every((filter) => event.programStage === filter.programStage &&
3025
+ event.dataValues.some((dataValue) => dataValue.dataElement === filter.dataElement &&
3026
+ matchesCondition(dataValue.value, filter.operator, filter.value))))));
3027
+ };
3028
+
3029
+ class LineListService {
3030
+ constructor(httpClient) {
3031
+ this.httpClient = httpClient;
3032
+ }
2977
3033
  getProgramMetadata(programId) {
2978
3034
  return this.httpClient.get(`programs/${programId}.json?fields=programType,programStages[id,name,programStageDataElements[dataElement[id,name]]],organisationUnits[id,name]`);
2979
3035
  }
2980
3036
  getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
2981
3037
  const filterParams = buildFilters(filters);
2982
3038
  const dateFilter = startDate && endDate ? `&programStartDate=${startDate}&programEndDate=${endDate}` : '';
2983
- return this.httpClient.get(`trackedEntityInstances.json?program=${programId}&ou=${orgUnit}&page=${page}&pageSize=${pageSize}&fields=trackedEntityInstance,attributes[*],enrollments[*]&totalPages=true&${filterParams}${dateFilter}`);
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) => {
3040
+ response.trackedEntityInstances.forEach((tei) => {
3041
+ // Filter attributes to only include those with displayInList=true
3042
+ tei.attributes = tei.attributes.filter((attr) => attr.displayInList);
3043
+ });
3044
+ return response;
3045
+ }));
2984
3046
  }
2985
- getEvents(programId, orgUnit, page, pageSize) {
2986
- return this.httpClient.get(`events.json?program=${programId}&orgUnit=${orgUnit}&page=${page}&pageSize=${pageSize}&fields=event,programStage,dataValues[dataElement,value]&totalPages=true`);
3047
+ getEvents(programId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
3048
+ const filterParams = buildFilters(filters);
3049
+ 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}`);
2987
3051
  }
2988
- getEventsByProgramStage(programStageId, orgUnit, page, pageSize) {
2989
- return this.httpClient.get(`events.json?programStage=${programStageId}&orgUnit=${orgUnit}&page=${page}&pageSize=${pageSize}&fields=event,dataValues[dataElement,value]&totalPages=true`);
3052
+ getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
3053
+ const filterParams = buildFilters(filters);
3054
+ 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}`);
2990
3056
  }
2991
3057
  getLineListData(programId, orgUnit = '', programStageId, page = 1, pageSize = 10, filters = [], startDate, endDate) {
2992
3058
  return this.getProgramMetadata(programId).pipe(switchMap((programMetadata) => {
2993
3059
  if (programStageId) {
2994
- return this.getEventsByProgramStage(programStageId, orgUnit, page, pageSize).pipe(map$1((events) => ({
3060
+ return this.getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((events) => ({
2995
3061
  metadata: programMetadata,
2996
3062
  data: events,
2997
3063
  })));
@@ -3003,17 +3069,17 @@ class LineListService {
3003
3069
  })));
3004
3070
  }
3005
3071
  else {
3006
- return this.getEvents(programId, orgUnit, page, pageSize).pipe(map$1((events) => ({
3072
+ return this.getEvents(programId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((events) => ({
3007
3073
  metadata: programMetadata,
3008
3074
  data: events,
3009
3075
  })));
3010
3076
  }
3011
3077
  }));
3012
3078
  }
3013
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: LineListService, deps: [{ token: i1.NgxDhis2HttpClientService }], target: i0.ɵɵFactoryTarget.Injectable }); }
3014
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: LineListService }); }
3079
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListService, deps: [{ token: i1.NgxDhis2HttpClientService }], target: i0.ɵɵFactoryTarget.Injectable }); }
3080
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListService }); }
3015
3081
  }
3016
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: LineListService, decorators: [{
3082
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListService, decorators: [{
3017
3083
  type: Injectable
3018
3084
  }], ctorParameters: () => [{ type: i1.NgxDhis2HttpClientService }] });
3019
3085
 
@@ -3091,11 +3157,11 @@ const ContextMenu = (params) => {
3091
3157
  const [CurrentModal, setCurrentModal] = useCurrentModal();
3092
3158
  const styles = useDynamicStyles(dropdownStyles);
3093
3159
  return (React__default.createElement(React__default.Fragment, null,
3094
- React__default.createElement(Layer$1, { onBackdropClick: onClose, className: styles.layer },
3160
+ React__default.createElement(Layer$1, { onBackdropClick: (event, data) => onClose(event, data), className: styles.layer },
3095
3161
  React__default.createElement(Popper, { reference: anchorRef, placement: "bottom-start" },
3096
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: () => {
3097
- // onMenuClick(dropDownOption);
3098
- //onClose();
3163
+ onMenuClick(dropDownOption);
3164
+ onClose();
3099
3165
  }, dense: true })))))),
3100
3166
  CurrentModal && (React__default.createElement(CurrentModal, { onClose: () => {
3101
3167
  onClose();
@@ -3107,7 +3173,7 @@ const DropdownMenu = (props) => {
3107
3173
  const [visible, setVisible] = useState(false);
3108
3174
  const { dropdownOptions, onClick } = props;
3109
3175
  return (React__default.createElement("div", { ref: ref, style: { display: "inline-block" } },
3110
- React__default.createElement(Button$1, { small: true, secondary: true, icon: React__default.createElement(IconMore24, { color: colors.grey600 }), onClick: () => setVisible(true) }),
3176
+ React__default.createElement(Button$1, { small: true, secondary: true, icon: React__default.createElement(IconMore24, { color: colors$1.grey600 }), onClick: () => setVisible(true) }),
3111
3177
  visible && (React__default.createElement(ContextMenu, { dropDownOptions: dropdownOptions, anchorRef: ref, onClose: () => setVisible(false), onMenuClick: (dropDownOption) => {
3112
3178
  onClick(dropDownOption);
3113
3179
  } }))));
@@ -3138,8 +3204,12 @@ const getProgramStageData = (response, programStageId, pager) => {
3138
3204
  });
3139
3205
  return { columns: entityColumns, data: dataElementsData };
3140
3206
  };
3141
- const getTrackedEntityData = (response, programId, pager) => {
3142
- const teis = response.data.trackedEntityInstances;
3207
+ const getTrackedEntityData = (response, programId, pager, filters) => {
3208
+ let teis = response.data
3209
+ .trackedEntityInstances;
3210
+ if (filters) {
3211
+ teis = getFilteredTrackedEntityInstances(teis, filters);
3212
+ }
3143
3213
  const allAttributes = new Set();
3144
3214
  teis.forEach((tei) => {
3145
3215
  const matchingEnrollment = tei.enrollments.find((enrollment) => enrollment.program === programId);
@@ -3207,9 +3277,15 @@ const addActionsColumn = (columns, actionOptions) => {
3207
3277
  ];
3208
3278
  };
3209
3279
 
3280
+ // src/app/line-list-table.component.ts
3210
3281
  class LineListTableComponent extends ReactWrapperComponent {
3211
3282
  constructor() {
3212
3283
  super(...arguments);
3284
+ this.actionSelected = new EventEmitter();
3285
+ this.reactStateUpdaters = null;
3286
+ this.setReactStateUpdaters = (updaters) => {
3287
+ this.reactStateUpdaters = updaters;
3288
+ };
3213
3289
  this.lineListService = inject(LineListService);
3214
3290
  this.LineList = () => {
3215
3291
  const [columns, setColumns] = useState([]);
@@ -3221,20 +3297,40 @@ class LineListTableComponent extends ReactWrapperComponent {
3221
3297
  pageCount: 1,
3222
3298
  });
3223
3299
  const paginationRef = useRef(null);
3300
+ const [programIdState, setProgramIdState] = useState(this.programId);
3301
+ const [orgUnitState, setOrgUnitState] = useState(this.orgUnit);
3302
+ const [programStageIdState, setProgramStageIdState] = useState(this.programStageId);
3303
+ const [attributeFiltersState, setAttributeFiltersState] = useState(this.attributeFilters);
3304
+ const [startDateState, setStartDateState] = useState(this.startDate);
3305
+ const [endDateState, setEndDateState] = useState(this.endDate);
3306
+ const [loading, setLoading] = useState(false);
3307
+ // Store updaters in refs for Angular to access
3308
+ const updateRefs = useRef({
3309
+ setProgramIdState,
3310
+ setOrgUnitState,
3311
+ setProgramStageIdState,
3312
+ setAttributeFiltersState,
3313
+ setStartDateState,
3314
+ setEndDateState,
3315
+ });
3224
3316
  useEffect(() => {
3225
- setTimeout(() => {
3226
- const paginationContainer = document.querySelector('[data-test="dhis2-uiwidgets-pagination"]');
3227
- if (paginationContainer) {
3228
- paginationContainer.style.setProperty('display', 'flex', 'important');
3229
- paginationContainer.style.setProperty('flex-direction', 'row', 'important');
3230
- paginationContainer.style.setProperty('justify-content', 'space-between', 'important');
3231
- paginationContainer.style.setProperty('align-items', 'center', 'important');
3232
- }
3233
- }, 1000);
3234
- if (paginationRef.current) {
3235
- paginationRef.current.style.setProperty('display', 'flex', 'important');
3236
- paginationRef.current.style.setProperty('flex-direction', 'row', 'important');
3317
+ this.setReactStateUpdaters?.(updateRefs.current);
3318
+ }, []);
3319
+ useEffect(() => {
3320
+ if (!loading) {
3321
+ setTimeout(() => {
3322
+ const paginationContainer = document.querySelector('[data-test="dhis2-uiwidgets-pagination"]');
3323
+ if (paginationContainer) {
3324
+ paginationContainer.style.display = 'flex';
3325
+ paginationContainer.style.flexDirection = 'row';
3326
+ paginationContainer.style.justifyContent = 'space-between';
3327
+ paginationContainer.style.alignItems = 'center';
3328
+ }
3329
+ }, 500); // Short delay to ensure styles apply after data renders
3237
3330
  }
3331
+ }, [loading]);
3332
+ useEffect(() => {
3333
+ setLoading(true);
3238
3334
  this.lineListService
3239
3335
  .getLineListData(this.programId, this.orgUnit, this.programStageId, pager.page, pager.pageSize, this.attributeFilters, this.startDate, this.endDate)
3240
3336
  .subscribe((response) => {
@@ -3250,7 +3346,7 @@ class LineListTableComponent extends ReactWrapperComponent {
3250
3346
  else if ('trackedEntityInstances' in response.data) {
3251
3347
  responsePager = response.data
3252
3348
  .pager;
3253
- const { columns, data } = getTrackedEntityData(response, this.programId, pager);
3349
+ const { columns, data } = getTrackedEntityData(response, this.programId, pager, this.filters);
3254
3350
  entityColumns = columns;
3255
3351
  entityData = data;
3256
3352
  }
@@ -3261,27 +3357,41 @@ class LineListTableComponent extends ReactWrapperComponent {
3261
3357
  entityData = data;
3262
3358
  }
3263
3359
  const finalColumns = addActionsColumn([{ label: '#', key: 'index' }, ...entityColumns], this.actionOptions);
3264
- setColumns(finalColumns);
3265
- setData(entityData);
3266
- setPager(responsePager);
3360
+ setLoading(false);
3361
+ console.log('hey');
3362
+ setColumns(...[finalColumns]);
3363
+ setData(...[entityData]);
3364
+ setPager(...[responsePager]);
3365
+ console.log('columns', columns);
3366
+ console.log('data', data);
3267
3367
  });
3268
- }, [pager.page, pager.pageSize]);
3269
- console.log('columns', columns);
3270
- console.log('data', data);
3368
+ }, [
3369
+ programIdState,
3370
+ orgUnitState,
3371
+ programStageIdState,
3372
+ attributeFiltersState,
3373
+ startDateState,
3374
+ endDateState,
3375
+ pager.page,
3376
+ pager.pageSize,
3377
+ ]);
3271
3378
  const getDropdownOptions = (row) => {
3272
3379
  return (this.actionOptions || []).map((option) => ({
3273
3380
  ...option,
3274
- onClick: () => option.onClick?.(row),
3381
+ onClick: () => {
3382
+ option.onClick?.(row);
3383
+ this.actionSelected.emit({ action: option.label, row });
3384
+ },
3275
3385
  }));
3276
3386
  };
3277
- return (React__default.createElement("div", null,
3278
- React__default.createElement(DataTable, null,
3387
+ return (React__default.createElement("div", null, loading ? (React__default.createElement(CircularLoader$1, null)) :
3388
+ (React__default.createElement(DataTable, null,
3279
3389
  React__default.createElement(TableHead, null,
3280
3390
  React__default.createElement(DataTableRow, null, columns.map((col) => (React__default.createElement(DataTableColumnHeader, { key: col.key }, col.label))))),
3281
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])))))))),
3282
3392
  React__default.createElement(TableFoot, null,
3283
3393
  React__default.createElement(DataTableRow, null,
3284
- React__default.createElement(DataTableCell, { colSpan: columns.length },
3394
+ React__default.createElement(DataTableCell, { colSpan: columns.length.toString() },
3285
3395
  React__default.createElement("div", null,
3286
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) => {
3287
3397
  const newPageSize = Number(pageSize);
@@ -3290,9 +3400,31 @@ class LineListTableComponent extends ReactWrapperComponent {
3290
3400
  page: 1,
3291
3401
  pageSize: newPageSize,
3292
3402
  }));
3293
- }, pageSizes: ['5', '10', '20', '50'] }))))))));
3403
+ }, pageSizes: ['5', '10', '20', '50'] })))))))));
3294
3404
  };
3295
3405
  }
3406
+ ngOnChanges(changes) {
3407
+ if (this.reactStateUpdaters) {
3408
+ if (changes['programId']) {
3409
+ this.reactStateUpdaters.setProgramIdState(this.programId);
3410
+ }
3411
+ if (changes['orgUnit']) {
3412
+ this.reactStateUpdaters.setOrgUnitState(this.orgUnit);
3413
+ }
3414
+ if (changes['programStageId']) {
3415
+ this.reactStateUpdaters.setProgramStageIdState(this.programStageId);
3416
+ }
3417
+ if (changes['attributeFilters']) {
3418
+ this.reactStateUpdaters.setAttributeFiltersState(this.attributeFilters);
3419
+ }
3420
+ if (changes['startDate']) {
3421
+ this.reactStateUpdaters.setStartDateState(this.startDate);
3422
+ }
3423
+ if (changes['endDate']) {
3424
+ this.reactStateUpdaters.setEndDateState(this.endDate);
3425
+ }
3426
+ }
3427
+ }
3296
3428
  async ngAfterViewInit() {
3297
3429
  if (!this.elementRef)
3298
3430
  throw new Error('No element ref');
@@ -3300,12 +3432,12 @@ class LineListTableComponent extends ReactWrapperComponent {
3300
3432
  this.component = this.LineList;
3301
3433
  this.render();
3302
3434
  }
3303
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: LineListTableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3304
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.7", type: LineListTableComponent, isStandalone: false, selector: "app-line-list", inputs: { programId: "programId", orgUnit: "orgUnit", programStageId: "programStageId", actionOptions: "actionOptions", attributeFilters: "attributeFilters", startDate: "startDate", endDate: "endDate" }, usesInheritance: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [""] }); }
3435
+ 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"] }); }
3305
3437
  }
3306
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: LineListTableComponent, decorators: [{
3438
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListTableComponent, decorators: [{
3307
3439
  type: Component,
3308
- args: [{ selector: 'app-line-list', template: '<ng-content></ng-content>', standalone: false }]
3440
+ args: [{ selector: 'app-line-list', template: '<ng-content></ng-content>', standalone: false, styles: ["[data-test=dhis2-uiwidgets-pagination]{display:flex!important;flex-direction:row!important;justify-content:space-between!important;align-items:center!important}\n"] }]
3309
3441
  }], propDecorators: { programId: [{
3310
3442
  type: Input
3311
3443
  }], orgUnit: [{
@@ -3320,14 +3452,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
3320
3452
  type: Input
3321
3453
  }], endDate: [{
3322
3454
  type: Input
3455
+ }], filters: [{
3456
+ type: Input
3457
+ }], actionSelected: [{
3458
+ type: Output
3323
3459
  }] } });
3324
3460
 
3325
3461
  class LineListModule {
3326
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: LineListModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3327
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.7", ngImport: i0, type: LineListModule, declarations: [LineListTableComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [LineListTableComponent] }); }
3328
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: LineListModule, providers: [LineListService], imports: [CommonModule, SharedDhis2UiModule] }); }
3462
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3463
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: LineListModule, declarations: [LineListTableComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [LineListTableComponent] }); }
3464
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListModule, providers: [LineListService], imports: [CommonModule, SharedDhis2UiModule] }); }
3329
3465
  }
3330
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: LineListModule, decorators: [{
3466
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListModule, decorators: [{
3331
3467
  type: NgModule,
3332
3468
  args: [{
3333
3469
  declarations: [LineListTableComponent],
@@ -3337,9 +3473,1528 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
3337
3473
  }]
3338
3474
  }] });
3339
3475
 
3476
+ class FormField {
3477
+ constructor(options = {}) {
3478
+ this.value = options.value || '';
3479
+ this.key = options.key || '';
3480
+ this.referenceKey = options.referenceKey || '';
3481
+ this.id = options.id || '';
3482
+ this.code = options.code || '';
3483
+ this.label = options.label || '';
3484
+ this.required = !!options.required;
3485
+ this.order = options.order === undefined ? 1 : options.order;
3486
+ this.controlType = options.controlType;
3487
+ this.type = options.type || '';
3488
+ this.options = options.options || [];
3489
+ this.disabled = options.disabled || false;
3490
+ this.placeholder = options.placeholder || '';
3491
+ this.min = options.min;
3492
+ this.max =
3493
+ options.max || (this.controlType === 'date' ? new Date() : undefined);
3494
+ this.maxLength = options.maxLength;
3495
+ this.hidden = options.hidden || false;
3496
+ this.isDataElement = options.isDataElement;
3497
+ this.isAttribute = options.isAttribute;
3498
+ this.isOrgUnit = options.isOrgUnit;
3499
+ this.isEnrollmentDate = options.isEnrollmentDate;
3500
+ this.event = options.event;
3501
+ this.programStage = options.programStage;
3502
+ this.program = options.program;
3503
+ this.trackedEntityInstance = options.trackedEntityInstance;
3504
+ this.hasOptions = options.hasOptions;
3505
+ this.dependentField = options.dependentField;
3506
+ this.displayInList = options.displayInList;
3507
+ this.displayInReports = options.displayInReports;
3508
+ this.searchable = options.searchable;
3509
+ this.unique = options.unique;
3510
+ this.metaType = options.metaType;
3511
+ this.stepId = options.stepId;
3512
+ this.availableOptionsLabel =
3513
+ options.availableOptionsLabel ?? 'Available options';
3514
+ this.selectedOptionsLabel =
3515
+ options.availableOptionsLabel ?? 'Selected options';
3516
+ }
3517
+ }
3518
+
3519
+ let Boolean$1 = class Boolean extends FormField {
3520
+ constructor() {
3521
+ super(...arguments);
3522
+ this.controlType = 'boolean';
3523
+ }
3524
+ };
3525
+
3526
+ class CheckBox extends FormField {
3527
+ constructor() {
3528
+ super(...arguments);
3529
+ this.controlType = 'checkbox';
3530
+ }
3531
+ }
3532
+
3533
+ class DateField extends FormField {
3534
+ constructor(field) {
3535
+ super(field);
3536
+ this.controlType = 'date';
3537
+ this.type = 'date';
3538
+ this.max = field.max ?? format(new Date(), 'yyyy-MM-dd');
3539
+ }
3540
+ }
3541
+
3542
+ class Dropdown extends FormField {
3543
+ constructor() {
3544
+ super(...arguments);
3545
+ this.controlType = 'dropdown';
3546
+ }
3547
+ }
3548
+
3549
+ // Copyright 2024 UDSM DHIS2 Lab. All rights reserved.
3550
+ // Use of this source code is governed by a BSD-style
3551
+ // license that can be found in the LICENSE file.
3552
+ class FieldConfig {
3553
+ constructor(config) {
3554
+ this.hideLabel = config?.hideLabel ?? false;
3555
+ this.inputWidth = config?.inputWidth || '100%';
3556
+ }
3557
+ }
3558
+
3559
+ // Copyright 2024 UDSM DHIS2 Lab. All rights reserved.
3560
+ // Use of this source code is governed by a BSD-style
3561
+ // license that can be found in the LICENSE file.
3562
+ class DateRangeValue {
3563
+ }
3564
+
3565
+ var FieldType;
3566
+ (function (FieldType) {
3567
+ FieldType["TEXT"] = "TEXT";
3568
+ FieldType["TRUE_ONLY"] = "TRUE_ONLY";
3569
+ FieldType["LONG_TEXT"] = "LONG_TEXT";
3570
+ FieldType["BOOLEAN"] = "BOOLEAN";
3571
+ FieldType["NUMBER"] = "NUMBER";
3572
+ FieldType["INTEGER_ZERO_OR_POSITIVE"] = "INTEGER_ZERO_OR_POSITIVE";
3573
+ FieldType["IMAGE"] = "IMAGE";
3574
+ FieldType["FILE_RESOURCE"] = "FILE_RESOURCE";
3575
+ FieldType["DATE"] = "DATE";
3576
+ FieldType["DATE_TIME"] = "DATETIME";
3577
+ FieldType["ORG_UNIT"] = "ORGANISATION_UNIT";
3578
+ FieldType["PHONE_NUMBER"] = "PHONE_NUMBER";
3579
+ FieldType["EMAIL"] = "EMAIL";
3580
+ })(FieldType || (FieldType = {}));
3581
+
3582
+ // Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
3583
+ // Use of this source code is governed by a BSD-style
3584
+ // license that can be found in the LICENSE file.
3585
+
3586
+ class FieldDropdown {
3587
+ constructor(params) {
3588
+ this.key = params.key;
3589
+ this.value = params.value;
3590
+ this.label = params.label;
3591
+ this.order = params.order;
3592
+ }
3593
+ toJson() {
3594
+ return {
3595
+ key: this.key,
3596
+ value: this.value,
3597
+ label: this.label,
3598
+ order: this.order,
3599
+ };
3600
+ }
3601
+ static getDropdownOptions(field, locale) {
3602
+ if (field?.valueType === FieldType.BOOLEAN) {
3603
+ return [
3604
+ {
3605
+ key: 'Yes',
3606
+ value: 'true',
3607
+ label: 'Yes',
3608
+ order: 1,
3609
+ },
3610
+ {
3611
+ key: 'No',
3612
+ value: 'false',
3613
+ label: 'No',
3614
+ order: 2,
3615
+ },
3616
+ ].map((dropdown) => new FieldDropdown(dropdown));
3617
+ }
3618
+ return sortBy((field?.optionSet?.options || []).map((option) => {
3619
+ return new FieldDropdown({
3620
+ key: option.id,
3621
+ value: option.code,
3622
+ label: option.name,
3623
+ order: option.sortOrder,
3624
+ });
3625
+ }), 'order');
3626
+ }
3627
+ }
3628
+
3629
+ class FormConfig {
3630
+ constructor(config) {
3631
+ this.direction = config?.direction || 'vertical';
3632
+ this.showSaveButton = config?.showSaveButton ?? true;
3633
+ this.fieldConfig = config?.fieldConfig || new FieldConfig();
3634
+ this.formName = config?.formName;
3635
+ }
3636
+ get directionClassName() {
3637
+ return this.direction === 'vertical' ? 'form-vertical' : 'form-horizontal';
3638
+ }
3639
+ }
3640
+
3641
+ class FieldUtil {
3642
+ static getFieldDropdownOptions(field) {
3643
+ if (field.valueType === FieldType.BOOLEAN) {
3644
+ return [
3645
+ {
3646
+ key: 'Yes',
3647
+ value: 'true',
3648
+ label: 'Yes',
3649
+ order: 1,
3650
+ },
3651
+ {
3652
+ key: 'No',
3653
+ value: 'false',
3654
+ label: 'No',
3655
+ order: 2,
3656
+ },
3657
+ ];
3658
+ }
3659
+ return FieldUtil.sanitizeOptions(field.optionSet?.options || []);
3660
+ }
3661
+ static sanitizeOptions(options) {
3662
+ return sortBy((options || []).map((option) => ({
3663
+ key: option.id,
3664
+ value: option.code,
3665
+ label: option.name,
3666
+ order: option.sortOrder,
3667
+ color: option.style?.color,
3668
+ attributeValues: option.attributeValues,
3669
+ options: FieldUtil.sanitizeOptions(option.options),
3670
+ })), 'order');
3671
+ }
3672
+ static getFieldType(valueType) {
3673
+ switch (valueType) {
3674
+ case FieldType.NUMBER:
3675
+ return 'number';
3676
+ case FieldType.PHONE_NUMBER:
3677
+ return 'tel';
3678
+ case FieldType.ORG_UNIT:
3679
+ return 'org-unit';
3680
+ case FieldType.DATE:
3681
+ return 'date';
3682
+ case FieldType.FILE_RESOURCE:
3683
+ return 'file';
3684
+ default:
3685
+ return 'text';
3686
+ }
3687
+ }
3688
+ static getFieldControlType(valueType, hasOptions) {
3689
+ if (hasOptions) {
3690
+ return 'dropdown';
3691
+ }
3692
+ switch (valueType) {
3693
+ case FieldType.TEXT:
3694
+ return 'textbox';
3695
+ case FieldType.LONG_TEXT:
3696
+ return 'textarea';
3697
+ case FieldType.TRUE_ONLY:
3698
+ return 'checkbox';
3699
+ case FieldType.NUMBER:
3700
+ return 'textbox';
3701
+ case FieldType.PHONE_NUMBER:
3702
+ return 'textbox';
3703
+ case FieldType.ORG_UNIT:
3704
+ return 'org-unit';
3705
+ case FieldType.DATE:
3706
+ return 'date';
3707
+ case FieldType.DATE_TIME:
3708
+ return 'date-time';
3709
+ case FieldType.IMAGE:
3710
+ return 'image';
3711
+ case FieldType.FILE_RESOURCE:
3712
+ return 'file';
3713
+ default:
3714
+ return 'textbox';
3715
+ }
3716
+ }
3717
+ static getOptionEntities(options) {
3718
+ return (options || []).reduce((entity, option) => {
3719
+ return { ...entity, [option.value]: option.label };
3720
+ }, {});
3721
+ }
3722
+ }
3723
+
3724
+ class FieldControlTypeUtil {
3725
+ static getFieldControlType(valueType, hasOptions) {
3726
+ if (hasOptions) {
3727
+ return 'dropdown';
3728
+ }
3729
+ switch (valueType) {
3730
+ case FieldType.TEXT:
3731
+ return 'textbox';
3732
+ case FieldType.BOOLEAN:
3733
+ return 'dropdown';
3734
+ case FieldType.LONG_TEXT:
3735
+ return 'textarea';
3736
+ case FieldType.TRUE_ONLY:
3737
+ return 'checkbox';
3738
+ case FieldType.NUMBER:
3739
+ return 'textbox';
3740
+ case FieldType.INTEGER_ZERO_OR_POSITIVE:
3741
+ return 'textbox';
3742
+ case FieldType.ORG_UNIT:
3743
+ return 'org-unit';
3744
+ case FieldType.DATE:
3745
+ return 'date';
3746
+ case FieldType.DATE_TIME:
3747
+ return 'date-time';
3748
+ case FieldType.IMAGE:
3749
+ return 'image';
3750
+ case FieldType.FILE_RESOURCE:
3751
+ return 'file';
3752
+ default:
3753
+ return 'textbox';
3754
+ }
3755
+ }
3756
+ }
3757
+
3758
+ class FormFieldTypeUtil {
3759
+ static getFieldType(valueType) {
3760
+ switch (valueType) {
3761
+ case FieldType.NUMBER:
3762
+ return 'number';
3763
+ case FieldType.INTEGER_ZERO_OR_POSITIVE:
3764
+ return 'number';
3765
+ case FieldType.ORG_UNIT:
3766
+ return 'org-unit';
3767
+ case FieldType.IMAGE:
3768
+ return 'image';
3769
+ case FieldType.FILE_RESOURCE:
3770
+ return 'file';
3771
+ default:
3772
+ return 'text';
3773
+ }
3774
+ }
3775
+ }
3776
+
3777
+ class FormUtil {
3778
+ static getFormGroup(fields, dataEntities) {
3779
+ const group = {};
3780
+ (fields || []).forEach((field) => {
3781
+ if (field) {
3782
+ const value = FormUtil.getFieldValue(field, dataEntities);
3783
+ const minValidators = field.min
3784
+ ? [Validators.min(field.min)]
3785
+ : [];
3786
+ const maxValidators = field.max
3787
+ ? [Validators.max(field.max)]
3788
+ : [];
3789
+ const phoneNumberValidator = field.type === 'tel'
3790
+ ? [Validators.pattern('\\+255[6-7][1-9][0-9]{7}$')]
3791
+ : [];
3792
+ group[field.key] = field.required
3793
+ ? new UntypedFormControl({ value, disabled: field.disabled }, {
3794
+ validators: [
3795
+ Validators.required,
3796
+ ...minValidators,
3797
+ ...maxValidators,
3798
+ ...phoneNumberValidator,
3799
+ ],
3800
+ updateOn: 'change',
3801
+ })
3802
+ : new UntypedFormControl({ value, disabled: field.disabled }, {
3803
+ validators: [
3804
+ ...minValidators,
3805
+ ...maxValidators,
3806
+ ...phoneNumberValidator,
3807
+ ],
3808
+ });
3809
+ if (field.referenceKey) {
3810
+ const value = dataEntities
3811
+ ? dataEntities[field.referenceKey] || ''
3812
+ : '';
3813
+ group[field.referenceKey] = field.required
3814
+ ? new UntypedFormControl({ value, disabled: field.disabled }, {
3815
+ validators: [
3816
+ Validators.required,
3817
+ ...minValidators,
3818
+ ...maxValidators,
3819
+ ...phoneNumberValidator,
3820
+ ],
3821
+ updateOn: 'change',
3822
+ })
3823
+ : new UntypedFormControl({ value, disabled: field.disabled }, {
3824
+ validators: [
3825
+ ...minValidators,
3826
+ ...maxValidators,
3827
+ ...phoneNumberValidator,
3828
+ ],
3829
+ });
3830
+ }
3831
+ }
3832
+ });
3833
+ return new UntypedFormGroup(group);
3834
+ }
3835
+ static getFieldValue(field, dataEntities) {
3836
+ const fieldValue = dataEntities
3837
+ ? dataEntities[field.id] || dataEntities[field.key] || ''
3838
+ : '';
3839
+ return isArray(fieldValue) ? JSON.stringify(fieldValue) : fieldValue;
3840
+ }
3841
+ static getFormFields(fields) {
3842
+ return (fields || []).map((field) => {
3843
+ const options = FieldUtil.getFieldDropdownOptions(field);
3844
+ const dependentField = find(fields, ['id', field.fieldOptionsDependsOn]);
3845
+ const label = field.formName || field.name || field.displayName;
3846
+ return new FormField({
3847
+ id: field.id,
3848
+ label,
3849
+ code: field.code,
3850
+ key: camelCase(field.code) || field.id,
3851
+ referenceKey: field.referenceKey,
3852
+ required: field.mandatory && !field.generated,
3853
+ displayInList: field.displayInList,
3854
+ type: FieldUtil.getFieldType(field.valueType),
3855
+ controlType: FieldUtil.getFieldControlType(field.valueType, options?.length > 0 || field.hasOptions),
3856
+ options,
3857
+ isDataElement: field.isDataElement,
3858
+ isAttribute: field.isAttribute,
3859
+ isOrgUnit: field.isOrgUnit,
3860
+ isEnrollmentDate: field.isEnrollmentDate,
3861
+ programStage: field.stageId,
3862
+ event: field.event,
3863
+ trackedEntityInstance: field.trackedEntityInstance,
3864
+ disabled: field.disabled || field.generated,
3865
+ dependentField: dependentField,
3866
+ min: field.min,
3867
+ max: field.max,
3868
+ maxLength: field.maxLength,
3869
+ });
3870
+ });
3871
+ }
3872
+ static createField(id, label, required, controlType, disabled, placeholder, options) {
3873
+ return new FormField({
3874
+ id,
3875
+ code: id,
3876
+ key: id,
3877
+ label,
3878
+ required,
3879
+ controlType,
3880
+ type: 'text',
3881
+ options: options ?? [],
3882
+ disabled: disabled ?? false,
3883
+ placeholder: placeholder,
3884
+ });
3885
+ }
3886
+ }
3887
+
3888
+ class FormValueUtil {
3889
+ static getFormDataEntities(formValueEntities) {
3890
+ const formValueKeys = Object.keys(formValueEntities);
3891
+ return formValueKeys.reduce((entity, key) => {
3892
+ const formValue = formValueEntities[key];
3893
+ const formRawValues = formValue.form.getRawValue() || {};
3894
+ const dataValueEntities = Object.keys(formRawValues).reduce((valueObject, key) => {
3895
+ const field = formValue.fields.find((field) => field.id === key);
3896
+ if (!field) {
3897
+ return valueObject;
3898
+ }
3899
+ return {
3900
+ ...valueObject,
3901
+ [key]: {
3902
+ ...field,
3903
+ value: formRawValues[key],
3904
+ attribute: field?.isAttribute ? field.id : undefined,
3905
+ dataElement: field?.isDataElement ? field.id : undefined,
3906
+ },
3907
+ };
3908
+ }, {});
3909
+ return { ...entity, ...dataValueEntities };
3910
+ }, {});
3911
+ }
3912
+ }
3913
+
3914
+ // Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
3915
+ // Use of this source code is governed by a BSD-style
3916
+ // license that can be found in the LICENSE file.
3917
+ class FormFieldGroup {
3918
+ constructor(params) {
3919
+ this.params = params;
3920
+ }
3921
+ get fields() {
3922
+ const fields = this.params.formFieldGroup?.fields || [];
3923
+ return fields
3924
+ .map((field) => {
3925
+ const fieldMetaData = this.params.fieldMetaData.find((attribute) => attribute['id'] === field.id);
3926
+ if (!fieldMetaData) {
3927
+ return null;
3928
+ }
3929
+ const dependentField = find(fields, [
3930
+ 'id',
3931
+ field?.fieldOptionsDependsOn,
3932
+ ]);
3933
+ const options = FieldDropdown.getDropdownOptions(fieldMetaData, this.params.locale);
3934
+ const hasOptions = (options?.length > 0 ||
3935
+ dependentField !== undefined ||
3936
+ fieldMetaData['hasOptions']);
3937
+ return new FormField({
3938
+ ...(fieldMetaData || {}),
3939
+ ...field,
3940
+ id: field.id,
3941
+ code: fieldMetaData['code'],
3942
+ label: (fieldMetaData['formName'] ?? field['label']),
3943
+ key: camelCase(fieldMetaData['code']) || field.id,
3944
+ required: (fieldMetaData['mandatory'] ??
3945
+ fieldMetaData['required']),
3946
+ type: FieldUtil.getFieldType(fieldMetaData['valueType']),
3947
+ dependentField,
3948
+ options,
3949
+ disabled: field.disabled ?? fieldMetaData['disabled'],
3950
+ min: field.min ?? fieldMetaData['min'],
3951
+ max: field.max ?? fieldMetaData['max'],
3952
+ order: field.order ??
3953
+ (fieldMetaData['order'] ?? fieldMetaData['sortOrder']),
3954
+ hidden: field.hidden ?? fieldMetaData['hidden'],
3955
+ fieldOptionsDependsOn: field.fieldOptionsDependsOn,
3956
+ hasOptions,
3957
+ controlType: FieldUtil.getFieldControlType(fieldMetaData['valueType'], hasOptions),
3958
+ metaType: fieldMetaData['metaType'],
3959
+ stepId: fieldMetaData['stepId'],
3960
+ });
3961
+ })
3962
+ .filter((field) => field);
3963
+ }
3964
+ toJson() {
3965
+ return {
3966
+ id: this.params.formFieldGroup?.id,
3967
+ name: this.params.formFieldGroup?.name,
3968
+ isFormHorizontal: this.params.formFieldGroup?.isFormHorizontal,
3969
+ repeatDependentField: this.params.formFieldGroup?.repeatDependentField,
3970
+ dataKey: this.params.formFieldGroup?.dataKey,
3971
+ repeatableStage: this.params.formFieldGroup?.repeatableStage,
3972
+ fields: this.fields,
3973
+ };
3974
+ }
3975
+ }
3976
+
3977
+ class MetadataRuleAction {
3978
+ constructor(ruleAction) {
3979
+ this.ruleAction = ruleAction;
3980
+ }
3981
+ get field() {
3982
+ return (this.ruleAction.dataElement?.id ||
3983
+ this.ruleAction.trackedEntityAttribute?.id);
3984
+ }
3985
+ get actionType() {
3986
+ return this.ruleAction.programRuleActionType;
3987
+ }
3988
+ toJson() {
3989
+ return {
3990
+ field: this.field,
3991
+ actionType: this.actionType,
3992
+ };
3993
+ }
3994
+ }
3995
+ class MetadataRule {
3996
+ constructor(rule, ruleVariables) {
3997
+ this.rule = rule;
3998
+ this.ruleVariables = ruleVariables;
3999
+ }
4000
+ get actions() {
4001
+ return (this.rule?.programRuleActions || []).map((action) => new MetadataRuleAction(action));
4002
+ }
4003
+ get condition() {
4004
+ const regex = /(A|#)\{([^}]+)\}/g;
4005
+ return this.rule?.condition?.replace(regex, (match, _, ruleVariable) => {
4006
+ const ruleVariableObject = this.ruleVariables?.find((variable) => variable.name === ruleVariable);
4007
+ const code = camelCase(ruleVariableObject?.dataElement?.code) ||
4008
+ ruleVariableObject?.dataElement?.id ||
4009
+ camelCase(ruleVariableObject?.trackedEntityAttribute?.code) ||
4010
+ ruleVariableObject?.trackedEntityAttribute?.id;
4011
+ return `{${code}}`;
4012
+ });
4013
+ }
4014
+ toJson() {
4015
+ return {
4016
+ actions: this.actions.map((action) => action.toJson()),
4017
+ condition: this.condition,
4018
+ };
4019
+ }
4020
+ }
4021
+
4022
+ class FormMetadataSection {
4023
+ constructor(params) {
4024
+ this.params = params;
4025
+ }
4026
+ get attributes() {
4027
+ return (this.params.program['programTrackedEntityAttributes'] || []).map((programTrackedEntityAttribute) => {
4028
+ return {
4029
+ ...programTrackedEntityAttribute['trackedEntityAttribute'],
4030
+ formName: (programTrackedEntityAttribute['trackedEntityAttribute'] || {})['name'],
4031
+ sortOrder: programTrackedEntityAttribute['sortOrder'],
4032
+ mandatory: programTrackedEntityAttribute['mandatory'],
4033
+ metaType: 'ATTRIBUTE',
4034
+ };
4035
+ });
4036
+ }
4037
+ get dataElements() {
4038
+ return flatten((this.params.program['programStages'] ||
4039
+ []).map((programStage) => {
4040
+ return (programStage['programStageDataElements'] || []).map((stageDataElement) => {
4041
+ return {
4042
+ ...(stageDataElement['dataElement'] ||
4043
+ {}),
4044
+ mandatory: stageDataElement['compulsory'],
4045
+ stepId: programStage['id'],
4046
+ metaType: 'DATA_ELEMENT',
4047
+ };
4048
+ });
4049
+ }));
4050
+ }
4051
+ get fieldGroups() {
4052
+ return (this.params.section.fieldGroups || []).map((formFieldGroup) => {
4053
+ return new FormFieldGroup({
4054
+ formFieldGroup,
4055
+ fieldMetaData: [...this.attributes, ...this.dataElements],
4056
+ locale: this.params.locale,
4057
+ }).toJson();
4058
+ });
4059
+ }
4060
+ toJson() {
4061
+ return {
4062
+ id: this.params.section?.id,
4063
+ name: this.params.section?.name,
4064
+ fieldGroups: this.fieldGroups,
4065
+ };
4066
+ }
4067
+ }
4068
+
4069
+ class FormMetaData {
4070
+ constructor(params) {
4071
+ this.params = params;
4072
+ }
4073
+ get sections() {
4074
+ return (this.params.formMetaData.sections || [])
4075
+ .map((section) => {
4076
+ const program = this.params.programs.find((program) => section.program === program['id']);
4077
+ if (!program) {
4078
+ return null;
4079
+ }
4080
+ return new FormMetadataSection({
4081
+ section,
4082
+ program,
4083
+ locale: this.params.locale,
4084
+ }).toJson();
4085
+ })
4086
+ .filter((section) => section !== null);
4087
+ }
4088
+ get fields() {
4089
+ return flatten(flatten(this.sections.map((section) => section.fieldGroups.map((fieldGroup) => fieldGroup.fields || []))));
4090
+ }
4091
+ get rules() {
4092
+ let ruleVariables = [];
4093
+ return [
4094
+ ...(this.params.formMetaData.rules || []),
4095
+ ...(flatten(this.params.programs.map((program) => {
4096
+ ruleVariables = [
4097
+ ...ruleVariables,
4098
+ ...program.programRuleVariables,
4099
+ ];
4100
+ return program.programRules;
4101
+ })) || []).map((rule) => new MetadataRule(rule, ruleVariables).toJson()),
4102
+ ];
4103
+ }
4104
+ toJson() {
4105
+ return {
4106
+ id: this.params.formMetaData?.id,
4107
+ name: this.params.formMetaData?.name,
4108
+ fields: this.fields,
4109
+ sections: this.sections,
4110
+ rules: this.rules,
4111
+ };
4112
+ }
4113
+ }
4114
+
4115
+ class FormValue {
4116
+ constructor(form, fields, changedField) {
4117
+ this.form = form;
4118
+ this.fields = fields;
4119
+ this.changedField = changedField;
4120
+ }
4121
+ get isValid() {
4122
+ return this.form.valid;
4123
+ }
4124
+ clear() {
4125
+ this.form.reset();
4126
+ }
4127
+ getValues() {
4128
+ const newValues = {};
4129
+ const formValues = this.form?.getRawValue();
4130
+ Object.keys(formValues).forEach((key) => {
4131
+ const field = find(this.fields, ['key', key]);
4132
+ if (field) {
4133
+ newValues[key] = {
4134
+ id: field.id,
4135
+ value: formValues[key],
4136
+ options: field.options,
4137
+ };
4138
+ }
4139
+ });
4140
+ return newValues;
4141
+ }
4142
+ }
4143
+
4144
+ // Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
4145
+ // Use of this source code is governed by a BSD-style
4146
+ // license that can be found in the LICENSE file.
4147
+
4148
+ // Copyright 2024 UDSM DHIS2 Lab. All rights reserved.
4149
+ // Use of this source code is governed by a BSD-style
4150
+ // license that can be found in the LICENSE file.
4151
+ class BaseFormFieldComponent extends ReactWrapperComponent {
4152
+ constructor() {
4153
+ super(...arguments);
4154
+ this.ngZone = inject(NgZone);
4155
+ this.httpClient = inject(NgxDhis2HttpClientService);
4156
+ this.fieldType = 'textbox';
4157
+ this.field = input.required();
4158
+ this.fieldConfig = input(new FieldConfig());
4159
+ this.form = model.required();
4160
+ this.isValid = input();
4161
+ this.uploadedFiles = [];
4162
+ this.value = model();
4163
+ this.value$ = toObservable(this.value);
4164
+ this.FieldOrgUnitSelector = (props) => {
4165
+ const { onSelectOrgUnit, onCancelOrgUnit } = props;
4166
+ const [selected, setSelected] = useState([]);
4167
+ const [rootOrgUnits, setRootOrgUnits] = useState();
4168
+ const [config, setConfig] = useState();
4169
+ useEffect(() => {
4170
+ zip(this.getAppConfig(), this.getRootOrgUnits()).subscribe({
4171
+ next: ([appConfig, rootOrgUnits]) => {
4172
+ setConfig(appConfig);
4173
+ setRootOrgUnits(rootOrgUnits);
4174
+ },
4175
+ error: (error) => console.error(error),
4176
+ });
4177
+ }, []);
4178
+ return config ? (React__default.createElement(Provider, { config: config, plugin: false, parentAlertsAdd: undefined, showAlertsInPlugin: false }, React__default.createElement(Modal$1, { position: "middle", large: true },
4179
+ React__default.createElement(ModalTitle$1, null, "Organisation unit"),
4180
+ React__default.createElement(ModalContent$1, null,
4181
+ React__default.createElement(OrgUnitDimension, { selected: selected, hideGroupSelect: this.orgUnitSelectionConfig.hideGroupSelect, hideLevelSelect: this.orgUnitSelectionConfig.hideLevelSelect, hideUserOrgUnits: this.orgUnitSelectionConfig.hideUserOrgUnits, onSelect: (selectionEvent) => {
4182
+ setSelected(selectionEvent.items);
4183
+ }, orgUnitGroupPromise: this.getOrgUnitGroups(), orgUnitLevelPromise: this.getOrgUnitLevels(), roots: rootOrgUnits })),
4184
+ React__default.createElement(ModalActions$1, null,
4185
+ React__default.createElement(ButtonStrip$1, { end: true },
4186
+ React__default.createElement(Button$1, { onClick: () => {
4187
+ onCancelOrgUnit();
4188
+ } }, "Cancel"),
4189
+ React__default.createElement(Button$1, { primary: true, disabled: selected.length === 0, onClick: () => {
4190
+ onSelectOrgUnit(selected);
4191
+ } }, "Confirm")))))) : (React__default.createElement(CircularLoader$1, { small: true }));
4192
+ };
4193
+ this.showOrgUnitTree = signal(false);
4194
+ this.orgUnitSelectionConfig = {
4195
+ hideGroupSelect: true,
4196
+ hideLevelSelect: true,
4197
+ hideUserOrgUnits: true,
4198
+ allowSingleSelection: true,
4199
+ usageType: 'DATA_ENTRY',
4200
+ };
4201
+ this.selectedOrgUnit = signal(null);
4202
+ this.selectedOrgUnit$ = toObservable(this.selectedOrgUnit);
4203
+ this.label = computed(() => {
4204
+ return !this.fieldConfig()?.hideLabel ? this.field().label : undefined;
4205
+ });
4206
+ this.placeholder = computed(() => {
4207
+ return (this.field()?.placeholder || `Enter ${this.field()?.label || 'value'}`);
4208
+ });
4209
+ this.InputField = this.#getInputField();
4210
+ this.update = new EventEmitter();
4211
+ this.immediateUpdate = new EventEmitter();
4212
+ }
4213
+ async ngAfterViewInit() {
4214
+ if (!this.elementRef)
4215
+ throw new Error('No element ref');
4216
+ this.reactDomRoot = ReactDOM.createRoot(this.elementRef.nativeElement);
4217
+ this.component = this.InputField;
4218
+ this.render();
4219
+ }
4220
+ ngOnChanges(changes) {
4221
+ if (!(changes['field'] || {})?.firstChange) {
4222
+ this.InputField = this.#getInputField();
4223
+ this.component = this.#getInputField();
4224
+ this.render();
4225
+ }
4226
+ }
4227
+ #getInputField() {
4228
+ return () => {
4229
+ const [value, setValue] = useState(this.form().get(this.field().id)?.value ||
4230
+ this.form().get(this.field().key)?.value);
4231
+ const [displayValue, setDisplayValue] = useState(null);
4232
+ const [selected, setSelected] = useState();
4233
+ const [touched, setTouched] = useState(false);
4234
+ const [showOrgUnit, setShowOrgUnit] = useState(false);
4235
+ const onChange = (payload) => setSelected(payload.selected);
4236
+ const hasError = useMemo(() => {
4237
+ return (touched &&
4238
+ (this.form().get(this.field().id) ||
4239
+ this.form().get(this.field().key))?.invalid);
4240
+ }, [value, touched]);
4241
+ const validationError = useMemo(() => {
4242
+ if (!touched) {
4243
+ return undefined;
4244
+ }
4245
+ const field = this.field();
4246
+ const error = (this.form().get(field.id) || this.form().get(field.key))
4247
+ ?.errors;
4248
+ if (!error) {
4249
+ return undefined;
4250
+ }
4251
+ if (error['min']) {
4252
+ return `${this.label() || 'Value'} should not be less than ${error['min'].min}!`;
4253
+ }
4254
+ else if (error['max']) {
4255
+ return `${this.label() || 'Value'} should not be greater than ${error['max'].max}!`;
4256
+ }
4257
+ else if (error['pattern']) {
4258
+ if (field.type === 'email') {
4259
+ return `The email address provided is not valid`;
4260
+ }
4261
+ else if (field.type === 'tel') {
4262
+ return 'Phone number provided is not valid';
4263
+ }
4264
+ else {
4265
+ return `${this.label() || 'Value'} should have appropriate format`;
4266
+ }
4267
+ }
4268
+ return error['required']
4269
+ ? `${this.label() || 'Value'} is required`
4270
+ : undefined;
4271
+ }, [hasError]);
4272
+ switch (this.field().controlType) {
4273
+ case 'textarea':
4274
+ return (React__default.createElement(TextAreaField, { error: hasError, validationText: validationError, type: this.field().type, inputWidth: this.fieldConfig()?.inputWidth, required: this.field().required, name: this.field().id, label: this.label(), min: this.field().min?.toString(), max: this.field().max?.toString(), placeholder: this.placeholder(), value: value, onChange: (event) => {
4275
+ this.ngZone.run(() => {
4276
+ (this.form().get(this.field().id) ||
4277
+ this.form().get(this.field().key))?.setValue(event.value);
4278
+ this.immediateUpdate.emit({
4279
+ form: this.form(),
4280
+ value: event.value,
4281
+ });
4282
+ });
4283
+ setValue(event.value);
4284
+ setTouched(true);
4285
+ }, onBlur: () => {
4286
+ this.ngZone.run(() => {
4287
+ this.update.emit({ form: this.form(), value });
4288
+ });
4289
+ } }));
4290
+ case 'org-unit':
4291
+ return (React__default.createElement(React__default.Fragment, null,
4292
+ React__default.createElement(InputField$1, { error: hasError, validationText: validationError, type: this.field().type, prefixIcon: React__default.createElement(IconDimensionOrgUnit16, null), required: this.field().required, name: this.field().id, label: this.label(), placeholder: this.placeholder(), value: displayValue, readOnly: false, onFocus: () => {
4293
+ setShowOrgUnit(true);
4294
+ }, onBlur: () => {
4295
+ this.ngZone.run(() => {
4296
+ this.update.emit({ form: this.form(), value });
4297
+ });
4298
+ setTouched(true);
4299
+ } }),
4300
+ showOrgUnit && (React__default.createElement(this.FieldOrgUnitSelector, { onCancelOrgUnit: () => {
4301
+ setShowOrgUnit(false);
4302
+ setTouched(true);
4303
+ }, onSelectOrgUnit: (selectedOrgUnits) => {
4304
+ if ((selectedOrgUnits || [])[0]) {
4305
+ const selectedOrgUnit = selectedOrgUnits[0];
4306
+ setDisplayValue(selectedOrgUnit.name);
4307
+ setValue(selectedOrgUnit.id);
4308
+ setShowOrgUnit(false);
4309
+ setTouched(true);
4310
+ this.ngZone.run(() => {
4311
+ (this.form().get(this.field().id) ||
4312
+ this.form().get(this.field().key))?.setValue(selectedOrgUnit.id);
4313
+ this.immediateUpdate.emit({
4314
+ form: this.form(),
4315
+ value: selectedOrgUnit.id,
4316
+ });
4317
+ });
4318
+ }
4319
+ } }))));
4320
+ case 'transfer':
4321
+ return (React__default.createElement(Transfer, { filterable: true, filterPlaceholder: "Search", selected: selected, error: hasError, validationText: validationError, type: this.field().type, inputWidth: this.fieldConfig()?.inputWidth, required: this.field().required, name: this.field().id, label: this.label(), placeholder: this.placeholder(), value: selected, leftHeader: React__default.createElement("div", { style: {
4322
+ fontSize: 14,
4323
+ padding: '8px 4px',
4324
+ } }, this.field().availableOptionsLabel), rightHeader: React__default.createElement("div", { style: {
4325
+ fontSize: 14,
4326
+ padding: '8px 4px',
4327
+ } }, this.field().selectedOptionsLabel), options: this.field().options, onChange: (event) => {
4328
+ onChange({ selected: event.selected });
4329
+ this.ngZone.run(() => {
4330
+ (this.form().get(this.field().id) ||
4331
+ this.form().get(this.field().key))?.setValue(event.selected);
4332
+ });
4333
+ setValue(event.selected);
4334
+ setTouched(true);
4335
+ this.update.emit({ form: this.form(), value });
4336
+ } }));
4337
+ case 'checkbox':
4338
+ return (React__default.createElement(Checkbox, { checked: Boolean(value), error: hasError, label: this.label(), name: this.field().id, onChange: (event) => {
4339
+ this.ngZone.run(() => {
4340
+ (this.form().get(this.field().id) ||
4341
+ this.form().get(this.field().key))?.setValue(event.checked);
4342
+ });
4343
+ setValue(event.checked);
4344
+ setTouched(true);
4345
+ }, onBlur: () => {
4346
+ this.ngZone.run(() => {
4347
+ this.update.emit({ form: this.form(), value });
4348
+ });
4349
+ } }));
4350
+ case 'dropdown':
4351
+ return (React__default.createElement(SingleSelectField, { filterable: (this.field().options || []).length > 5, clearable: true, error: hasError, validationText: validationError, inputWidth: this.fieldConfig()?.inputWidth, required: this.field().required, name: this.field().id, className: "select", label: this.label(), selected: value, onChange: (event) => {
4352
+ this.ngZone.run(() => {
4353
+ (this.form().get(this.field().id) ||
4354
+ this.form().get(this.field().key))?.setValue(event.selected);
4355
+ this.update.emit({
4356
+ form: this.form(),
4357
+ value: event.selected,
4358
+ });
4359
+ });
4360
+ setValue(event.selected);
4361
+ setTouched(true);
4362
+ } }, (this.field().options || []).map((option) => (React__default.createElement(SingleSelectOption, { key: option.key, label: option.label, value: option.value })))));
4363
+ case 'file':
4364
+ return (React__default.createElement(FileInputField, { accept: "*", buttonLabel: "Upload a file", label: this.label(), name: this.field().id, files: this.uploadedFiles, onChange: (event) => {
4365
+ this.uploadedFiles.push((event?.files || [])[0]);
4366
+ this.ngZone.run(() => {
4367
+ this.form().get(this.field().id) ||
4368
+ this.form()
4369
+ .get(this.field().key)
4370
+ ?.setValue((event?.files || [])[0]);
4371
+ this.update.emit({
4372
+ form: this.form(),
4373
+ value: (event?.files || [])[0],
4374
+ });
4375
+ });
4376
+ setValue((event?.files || [])[0]);
4377
+ setTouched(true);
4378
+ } }, this.uploadedFiles.map((file, index) => (React__default.createElement(FileListItem, { key: index, cancelText: "Cancel", label: file.name, onCancel: () => { }, onRemove: () => {
4379
+ this.ngZone.run(() => {
4380
+ this.uploadedFiles.splice(index, 1);
4381
+ setValue(this.uploadedFiles);
4382
+ setTouched(true);
4383
+ });
4384
+ }, removeText: "Remove" })))));
4385
+ default:
4386
+ return (React__default.createElement(InputField$1, { error: hasError, validationText: validationError, type: this.field().type, inputWidth: this.fieldConfig()?.inputWidth, required: this.field().required, name: this.field().id, label: this.label(), min: this.field().min?.toString(), max: this.field().max?.toString(), placeholder: this.placeholder(), value: value, readOnly: this.field().disabled, onChange: (event) => {
4387
+ this.ngZone.run(() => {
4388
+ (this.form().get(this.field().id) ||
4389
+ this.form().get(this.field().key))?.setValue(event.value);
4390
+ this.immediateUpdate.emit({
4391
+ form: this.form(),
4392
+ value: event.value,
4393
+ });
4394
+ });
4395
+ setValue(event.value);
4396
+ setTouched(true);
4397
+ }, onBlur: () => {
4398
+ this.ngZone.run(() => {
4399
+ this.update.emit({ form: this.form(), value });
4400
+ });
4401
+ } }));
4402
+ }
4403
+ };
4404
+ }
4405
+ onChange(event) {
4406
+ this.value.set(event);
4407
+ }
4408
+ onSelectOrgUnit(selectedOrgUnits) {
4409
+ this.showOrgUnitTree.set(false);
4410
+ if ((selectedOrgUnits || [])[0]) {
4411
+ this.selectedOrgUnit.set(selectedOrgUnits[0]);
4412
+ }
4413
+ }
4414
+ onCancelOrgUnit() {
4415
+ this.showOrgUnitTree.set(false);
4416
+ }
4417
+ getAppConfig() {
4418
+ return this.httpClient.systemInfo().pipe(map((response) => {
4419
+ const systemInfo = response;
4420
+ return {
4421
+ baseUrl: (document?.location?.host?.includes('localhost')
4422
+ ? `${document.location.protocol}//${document.location.host}`
4423
+ : systemInfo['contextPath']),
4424
+ apiVersion: Number(((systemInfo['version'] || '')?.split('.') || [])[1]),
4425
+ };
4426
+ }));
4427
+ }
4428
+ getOrgUnitAttributeByUsage(usageType) {
4429
+ switch (usageType) {
4430
+ case 'DATA_ENTRY':
4431
+ return 'organisationUnits';
4432
+ case 'DATA_VIEW':
4433
+ return 'dataViewOrganisationUnits';
4434
+ default:
4435
+ return 'organisationUnits';
4436
+ }
4437
+ }
4438
+ getRootOrgUnits() {
4439
+ const orgUnitAttribute = this.getOrgUnitAttributeByUsage(this.orgUnitSelectionConfig.usageType);
4440
+ return this.httpClient
4441
+ .me()
4442
+ .pipe(map((user) => (user ? user[orgUnitAttribute] : []).map((orgUnit) => orgUnit.id)));
4443
+ }
4444
+ getOrgUnitGroups() {
4445
+ return firstValueFrom(this.httpClient
4446
+ .get('organisationUnitGroups.json?fields=id,displayName,name&paging=false')
4447
+ .pipe(map((res) => res?.['organisationUnitGroups'])));
4448
+ }
4449
+ getOrgUnitLevels() {
4450
+ return firstValueFrom(this.httpClient
4451
+ .get('organisationUnitLevels.json?fields=id,level,displayName,name&paging=false')
4452
+ .pipe(map((res) => res?.['organisationUnitLevels'])));
4453
+ }
4454
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: BaseFormFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
4455
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.1.8", type: BaseFormFieldComponent, isStandalone: true, inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, fieldConfig: { classPropertyName: "fieldConfig", publicName: "fieldConfig", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, isValid: { classPropertyName: "isValid", publicName: "isValid", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { form: "formChange", value: "valueChange", update: "update", immediateUpdate: "immediateUpdate" }, usesInheritance: true, usesOnChanges: true, ngImport: i0 }); }
4456
+ }
4457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: BaseFormFieldComponent, decorators: [{
4458
+ type: Directive
4459
+ }], propDecorators: { update: [{
4460
+ type: Output
4461
+ }], immediateUpdate: [{
4462
+ type: Output
4463
+ }] } });
4464
+
4465
+ class FormFieldItemComponent extends BaseFormFieldComponent {
4466
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormFieldItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
4467
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: FormFieldItemComponent, isStandalone: false, selector: "ng-dhis2-ui-form-field-item", usesInheritance: true, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true }); }
4468
+ }
4469
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormFieldItemComponent, decorators: [{
4470
+ type: Component,
4471
+ args: [{
4472
+ selector: 'ng-dhis2-ui-form-field-item',
4473
+ template: `<ng-content></ng-content>`,
4474
+ standalone: false,
4475
+ }]
4476
+ }] });
4477
+
4478
+ class FormFieldComponent {
4479
+ constructor() {
4480
+ this.field = input.required();
4481
+ this.maxDate = new Date();
4482
+ this.color = 'primary';
4483
+ this.fieldUpdate = new EventEmitter();
4484
+ this.immediateFieldUpdate = new EventEmitter();
4485
+ this.runtimeOptionChange = new EventEmitter();
4486
+ this.value = signal('');
4487
+ this._runtimeOptions = [];
4488
+ this.runtimeOptions = [];
4489
+ this.fieldFilterControl = new FormControl();
4490
+ this._onDestroy = new Subject();
4491
+ }
4492
+ ngOnChanges(changes) {
4493
+ if (changes && changes['dataEntities'] && this.field()?.dependentField) {
4494
+ if (this._runtimeOptions?.length === 0) {
4495
+ const parentOption = find(this.field()?.dependentField?.optionSet?.options, ['code', (this.form?.value || {})[this.field()?.dependentField?.id]]);
4496
+ this.runtimeOptions = parentOption?.options || [];
4497
+ this.runtimeOptionChange.emit({
4498
+ field: this.field(),
4499
+ options: this.runtimeOptions,
4500
+ });
4501
+ }
4502
+ else {
4503
+ this.runtimeOptions = this._runtimeOptions;
4504
+ }
4505
+ }
4506
+ }
4507
+ ngOnInit() {
4508
+ this.value.set(this.form?.get(this.field()?.id)?.value);
4509
+ this.fieldFilterControl.valueChanges
4510
+ .pipe(takeUntil(this._onDestroy))
4511
+ .subscribe(() => {
4512
+ this.optionSearchTerm = this.fieldFilterControl.value;
4513
+ });
4514
+ }
4515
+ ngOnDestroy() {
4516
+ this._onDestroy.next();
4517
+ this._onDestroy.complete();
4518
+ }
4519
+ get isValid() {
4520
+ return this.form?.controls[this.field().id]?.valid;
4521
+ }
4522
+ get fieldError() {
4523
+ const error = this.form?.controls[this.field()?.id]?.errors;
4524
+ if (!error) {
4525
+ return undefined;
4526
+ }
4527
+ if (error['min']) {
4528
+ return `${this.field().label} should not be less than ${error['min'].min}!`;
4529
+ }
4530
+ else if (error['max']) {
4531
+ return `${this.field().label} should not be greater than ${error['max'].max}!`;
4532
+ }
4533
+ else if (error['pattern']) {
4534
+ if (this.field().type === 'email') {
4535
+ return `The email address provided is not valid`;
4536
+ }
4537
+ else if (this.field().type === 'tel') {
4538
+ return 'Phone number provided is not valid';
4539
+ }
4540
+ else {
4541
+ return `${this.field().label} should have appropriate format`;
4542
+ }
4543
+ }
4544
+ return error['required'] ? `${this.field()?.label} is required` : undefined;
4545
+ }
4546
+ get minErrorText() {
4547
+ const minError = this.form?.controls[this.field()?.id]?.errors?.['min'];
4548
+ return minError ? `${this.field()?.label} is min` : undefined;
4549
+ }
4550
+ get maxErrorText() {
4551
+ const maxError = this.form?.controls[this.field()?.id]?.errors?.['max'];
4552
+ return maxError ? `${this.field()?.label} is required` : undefined;
4553
+ }
4554
+ get isInvalid() {
4555
+ return (this.form?.controls[this.field().id]?.invalid &&
4556
+ !this.form?.controls[this.field().id].pristine);
4557
+ }
4558
+ get isDate() {
4559
+ return this.field().controlType === 'date';
4560
+ }
4561
+ get isDateTime() {
4562
+ return this.field().controlType === 'date-time';
4563
+ }
4564
+ get isBoolean() {
4565
+ return this.field().controlType === 'boolean';
4566
+ }
4567
+ get isCheckbox() {
4568
+ return this.field()?.controlType === 'checkbox';
4569
+ }
4570
+ get isCommonField() {
4571
+ return !this.isCheckbox && !this.isDate && !this.isDateTime;
4572
+ }
4573
+ get fieldId() {
4574
+ return this.field()?.id;
4575
+ }
4576
+ onValueChange() {
4577
+ this.fieldUpdate.emit(this.form);
4578
+ }
4579
+ onImmediateChange(event) {
4580
+ this.immediateFieldUpdate.emit({ value: event?.value || '' });
4581
+ }
4582
+ onFieldUpdate(e, isDate, isDateTime) {
4583
+ if (e && e.value) {
4584
+ const dateValue = new Date(e.value);
4585
+ if (isDate) {
4586
+ const dateValue = new Date(e.value);
4587
+ const formattedDate = moment(e.value).format('YYYY-MM-DD');
4588
+ let dateTimeString = formattedDate;
4589
+ if (isDateTime) {
4590
+ const hours = dateValue.getHours() < 10
4591
+ ? '0' + dateValue.getHours()
4592
+ : dateValue.getHours();
4593
+ const minutes = dateValue.getMinutes() < 10
4594
+ ? '0' + dateValue.getMinutes()
4595
+ : dateValue.getMinutes();
4596
+ const seconds = dateValue.getSeconds() < 10
4597
+ ? '0' + dateValue.getSeconds()
4598
+ : dateValue.getSeconds();
4599
+ const timeValue = `${hours}:${minutes}:${seconds}`;
4600
+ dateTimeString = `${formattedDate}T${timeValue}`;
4601
+ }
4602
+ const formControl = this.form.get(this.field().key);
4603
+ if (formControl) {
4604
+ formControl.setValue(dateTimeString);
4605
+ }
4606
+ }
4607
+ else {
4608
+ const formControl = this.form.get(this.field().key);
4609
+ if (formControl) {
4610
+ formControl.setValue(e.value);
4611
+ }
4612
+ }
4613
+ }
4614
+ this.fieldUpdate.emit(this.form);
4615
+ }
4616
+ onUpdateRuntimeOptions(options) {
4617
+ this._runtimeOptions = [...options];
4618
+ }
4619
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4620
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.1.8", 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: false, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: false, isRequired: false, transformFunction: null }, isCheckBoxButton: { classPropertyName: "isCheckBoxButton", publicName: "isCheckBoxButton", isSignal: false, isRequired: false, transformFunction: null }, fieldClass: { classPropertyName: "fieldClass", publicName: "fieldClass", isSignal: false, isRequired: false, transformFunction: null }, programRuleActions: { classPropertyName: "programRuleActions", publicName: "programRuleActions", isSignal: false, isRequired: false, transformFunction: null }, dataEntities: { classPropertyName: "dataEntities", publicName: "dataEntities", isSignal: false, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: false, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: false, 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 [fieldConfig]=\"fieldConfig\"\n [(form)]=\"form\"\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" }] }); }
4621
+ }
4622
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormFieldComponent, decorators: [{
4623
+ type: Component,
4624
+ args: [{ selector: 'ng-dhis2-ui-form-field', standalone: false, template: "<div *ngIf=\"field()\" class=\"form-field-item\">\n <ng-dhis2-ui-form-field-item\n [field]=\"field()\"\n [fieldConfig]=\"fieldConfig\"\n [(form)]=\"form\"\n [value]=\"value()\"\n (update)=\"onValueChange()\"\n (immediateUpdate)=\"onImmediateChange($event)\"\n />\n</div>\n", styles: [".form-field-item{margin-bottom:16px}\n"] }]
4625
+ }], propDecorators: { fieldConfig: [{
4626
+ type: Input
4627
+ }], form: [{
4628
+ type: Input
4629
+ }], isCheckBoxButton: [{
4630
+ type: Input
4631
+ }], fieldClass: [{
4632
+ type: Input
4633
+ }], programRuleActions: [{
4634
+ type: Input
4635
+ }], dataEntities: [{
4636
+ type: Input
4637
+ }], minDate: [{
4638
+ type: Input
4639
+ }], maxDate: [{
4640
+ type: Input
4641
+ }], fieldUpdate: [{
4642
+ type: Output
4643
+ }], immediateFieldUpdate: [{
4644
+ type: Output
4645
+ }], runtimeOptionChange: [{
4646
+ type: Output
4647
+ }] } });
4648
+
4649
+ class FormComponent {
4650
+ constructor() {
4651
+ this.formConfig = input();
4652
+ this.configuration = computed(() => {
4653
+ if (!this.formConfig()) {
4654
+ return new FormConfig({
4655
+ direction: this.isFormHorizontal ? 'horizontal' : 'vertical',
4656
+ });
4657
+ }
4658
+ return this.formConfig();
4659
+ });
4660
+ this.formUpdate = new EventEmitter();
4661
+ }
4662
+ get sanitizedFields() {
4663
+ return (this.fields || []).filter((field) => {
4664
+ if (field.hidden) {
4665
+ return false;
4666
+ }
4667
+ const type = field.isDataElement
4668
+ ? 'dataElement'
4669
+ : 'trackedEntityAttribute';
4670
+ const elementItem = field[type] || field;
4671
+ if (!elementItem) {
4672
+ return true;
4673
+ }
4674
+ const availableRule = head((this.programRuleActions || []).filter((ruleAction) => {
4675
+ const fieldId = ruleAction.field || ruleAction[type]?.id;
4676
+ return (fieldId === elementItem.id &&
4677
+ (ruleAction.programRuleActionType === 'HIDEFIELD' ||
4678
+ ruleAction.actionType === 'HIDEFIELD'));
4679
+ }));
4680
+ if (!availableRule) {
4681
+ return true;
4682
+ }
4683
+ const actionType = availableRule?.programRuleActionType || availableRule?.actionType;
4684
+ return actionType !== 'HIDEFIELD';
4685
+ });
4686
+ }
4687
+ get layoutCssClass() {
4688
+ if (!this.isFormHorizontal) {
4689
+ return 'col-12';
4690
+ }
4691
+ const numberOfFields = this.sanitizedFields.length;
4692
+ if (numberOfFields === 2) {
4693
+ return 'col-sm-6';
4694
+ }
4695
+ if (numberOfFields === 1) {
4696
+ return 'col-12';
4697
+ }
4698
+ return 'col-sm-4';
4699
+ }
4700
+ onUpdateFields(programRuleActions) {
4701
+ this.fields = (this.fields || []).filter((field) => {
4702
+ const type = field.isDataElement
4703
+ ? 'dataElement'
4704
+ : 'trackedEntityAttribute';
4705
+ const elementItem = field[type] || field;
4706
+ if (!elementItem) {
4707
+ return true;
4708
+ }
4709
+ const availableRule = head((programRuleActions || []).filter((rule) => {
4710
+ return (rule[type] &&
4711
+ rule[type].id === elementItem.id &&
4712
+ rule.programRuleActionType === 'HIDEFIELD');
4713
+ }));
4714
+ if (!availableRule) {
4715
+ return true;
4716
+ }
4717
+ return (availableRule && availableRule.programRuleActionType !== 'HIDEFIELD');
4718
+ });
4719
+ }
4720
+ ngOnChanges() {
4721
+ this.values = this.form.getRawValue();
4722
+ }
4723
+ onSubmit() {
4724
+ this.formUpdate.emit(this.form.getRawValue());
4725
+ }
4726
+ onFieldUpdate(form, field) {
4727
+ if (!this.showSaveButton && form) {
4728
+ this.formUpdate.emit(new FormValue(this.form, this.fields, field));
4729
+ this.values = form.getRawValue();
4730
+ }
4731
+ }
4732
+ onClear() {
4733
+ this.form.reset();
4734
+ }
4735
+ isFormInValid() {
4736
+ return this.form.invalid;
4737
+ }
4738
+ onRunTimeOptionUpdate(result) {
4739
+ if (this.fieldComponents) {
4740
+ const fieldToUpdate = this.fieldComponents.find((fieldComponent) => fieldComponent?.field()?.dependentField?.id === result?.field?.id);
4741
+ const parentOption = result?.options.find((option) => option.code === this.form?.value[result?.field?.id]);
4742
+ fieldToUpdate?.onUpdateRuntimeOptions(parentOption?.options || []);
4743
+ }
4744
+ }
4745
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4746
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.1.8", 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: false, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: false, isRequired: false, transformFunction: null }, isFormHorizontal: { classPropertyName: "isFormHorizontal", publicName: "isFormHorizontal", isSignal: false, isRequired: false, transformFunction: null }, showSaveButton: { classPropertyName: "showSaveButton", publicName: "showSaveButton", isSignal: false, isRequired: false, transformFunction: null }, fieldsData: { classPropertyName: "fieldsData", publicName: "fieldsData", isSignal: false, isRequired: false, transformFunction: null }, fieldClass: { classPropertyName: "fieldClass", publicName: "fieldClass", isSignal: false, isRequired: false, transformFunction: null }, shouldRenderAsCheckBoxesButton: { classPropertyName: "shouldRenderAsCheckBoxesButton", publicName: "shouldRenderAsCheckBoxesButton", isSignal: false, isRequired: false, transformFunction: null }, programRuleActions: { classPropertyName: "programRuleActions", publicName: "programRuleActions", isSignal: false, isRequired: false, transformFunction: null }, dataEntities: { classPropertyName: "dataEntities", publicName: "dataEntities", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { formUpdate: "formUpdate" }, 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 [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"], outputs: ["fieldUpdate", "immediateFieldUpdate", "runtimeOptionChange"] }] }); }
4747
+ }
4748
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormComponent, decorators: [{
4749
+ type: Component,
4750
+ args: [{ selector: 'ng-dhis2-ui-form', standalone: false, 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 [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"] }]
4751
+ }], propDecorators: { fields: [{
4752
+ type: Input
4753
+ }], form: [{
4754
+ type: Input
4755
+ }], isFormHorizontal: [{
4756
+ type: Input
4757
+ }], showSaveButton: [{
4758
+ type: Input
4759
+ }], fieldsData: [{
4760
+ type: Input
4761
+ }], fieldClass: [{
4762
+ type: Input
4763
+ }], shouldRenderAsCheckBoxesButton: [{
4764
+ type: Input
4765
+ }], programRuleActions: [{
4766
+ type: Input
4767
+ }], dataEntities: [{
4768
+ type: Input
4769
+ }], formUpdate: [{
4770
+ type: Output
4771
+ }], fieldComponents: [{
4772
+ type: ViewChildren,
4773
+ args: [FormFieldComponent]
4774
+ }] } });
4775
+
4776
+ class RepeatableFormComponent {
4777
+ constructor() {
4778
+ this.fieldGroup = input.required();
4779
+ this.dataEntities = input.required();
4780
+ this.repeatableEvents = [];
4781
+ this.repeatableData = {};
4782
+ this.repeatableStageUpdate = new EventEmitter();
4783
+ }
4784
+ get isValid() {
4785
+ return !Object.keys(this.repeatableData).some((index) => {
4786
+ const formValue = this.repeatableData[index];
4787
+ return !formValue?.isValid;
4788
+ });
4789
+ }
4790
+ ngOnInit() {
4791
+ this.repeatableEvents = (this.events?.length > 0
4792
+ ? this.events
4793
+ : range(this.numberOfRows).map(() => ({}))).map((event, index) => {
4794
+ const fieldControls = (this.fieldGroup().fields || []).reduce((fieldObject, field) => {
4795
+ const value = (event.dataValueEntities || {})[field.key] || '';
4796
+ return {
4797
+ ...fieldObject,
4798
+ [field.key]: new FormControl(value, field.required ? [Validators.required] : []),
4799
+ };
4800
+ }, {});
4801
+ const form = new FormGroup(fieldControls);
4802
+ this.repeatableData[index] = new FormValue(form, this.fieldGroup().fields || []);
4803
+ return { ...event, form };
4804
+ });
4805
+ this.repeatableStageUpdate.emit(this.repeatableData);
4806
+ }
4807
+ onFormUpdate(formValue, eventIndex) {
4808
+ this.repeatableData = { ...this.repeatableData, [eventIndex]: formValue };
4809
+ if (this.isValid) {
4810
+ this.repeatableStageUpdate.emit(this.repeatableData);
4811
+ }
4812
+ }
4813
+ 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"] }] }); }
4815
+ }
4816
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: RepeatableFormComponent, decorators: [{
4817
+ 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: [{
4820
+ type: Input
4821
+ }], formData: [{
4822
+ type: Input
4823
+ }], form: [{
4824
+ type: Input
4825
+ }], numberOfRows: [{
4826
+ type: Input
4827
+ }], programRuleActions: [{
4828
+ type: Input
4829
+ }], events: [{
4830
+ type: Input
4831
+ }], program: [{
4832
+ type: Input
4833
+ }], programStage: [{
4834
+ type: Input
4835
+ }], repeatDependentField: [{
4836
+ type: Input
4837
+ }], repeatableStageUpdate: [{
4838
+ type: Output
4839
+ }] } });
4840
+
4841
+ class SectionFormComponent {
4842
+ constructor() {
4843
+ this.loading = input();
4844
+ this.isLabResulst = false;
4845
+ this.formMetaData = input.required();
4846
+ this.dataValueEntities = input.required();
4847
+ this.formGroups = {};
4848
+ this.formValueEntity = {};
4849
+ this.repeatableFormValueEntity = {};
4850
+ this.ruleActions = [];
4851
+ this.save = new EventEmitter();
4852
+ this.formUpdate = new EventEmitter();
4853
+ 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;
4869
+ }
4870
+ ngOnInit() {
4871
+ if (this.formMetaData().sections) {
4872
+ (this.formMetaData().sections || []).forEach((formSection) => {
4873
+ (formSection.fieldGroups || []).forEach((fieldGroup) => {
4874
+ 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
+ const formValue = new FormValue(formGroup, fieldGroup.fields);
4887
+ this.formValueEntity[fieldGroup.id] = formValue;
4888
+ this.formGroups[fieldGroup.id] = formGroup;
4889
+ });
4890
+ });
4891
+ this.ruleActions = new ProgramRuleEngine()
4892
+ .setRules(this.formMetaData().rules)
4893
+ .setDataValues(this.#getDataValue())
4894
+ .execute();
4895
+ }
4896
+ }
4897
+ onUpdateRepeatableStage(repeatableData, fieldGroup) {
4898
+ this.repeatableFormValueEntity[fieldGroup.dataKey || fieldGroup.id] =
4899
+ repeatableData;
4900
+ const dataValues = this.#getDataValue();
4901
+ this.formUpdate.emit(dataValues);
4902
+ }
4903
+ onFormUpdate(formValue, fieldGroupId) {
4904
+ this.formValueEntity[fieldGroupId] = formValue;
4905
+ const dataValues = this.#getDataValue();
4906
+ this.ruleActions = new ProgramRuleEngine()
4907
+ .setRules(this.formMetaData().rules)
4908
+ .setDataValues(dataValues)
4909
+ .execute();
4910
+ this.formUpdate.emit(dataValues);
4911
+ }
4912
+ onSubmit(event) {
4913
+ event.stopPropagation();
4914
+ const dataValues = this.#getDataValue();
4915
+ this.save.emit(dataValues);
4916
+ }
4917
+ onCancel(event) {
4918
+ event.stopPropagation();
4919
+ this.cancel.emit();
4920
+ }
4921
+ #getDataValue() {
4922
+ const dataValues = Object.keys(this.formValueEntity).reduce((valueObject, key) => {
4923
+ const values = this.formValueEntity[key]?.form?.getRawValue();
4924
+ return { ...valueObject, ...(values || {}) };
4925
+ }, {});
4926
+ const repeatableValues = Object.keys(this.repeatableFormValueEntity).reduce((repeatableObject, key) => {
4927
+ const formValueEntity = this.repeatableFormValueEntity[key];
4928
+ const values = Object.keys(formValueEntity)
4929
+ .map((valueIndex) => {
4930
+ return (formValueEntity[+valueIndex] || {}).form?.getRawValue();
4931
+ })
4932
+ .filter((value) => value);
4933
+ return { ...repeatableObject, [key]: values };
4934
+ }, {});
4935
+ return { ...dataValues, ...repeatableValues };
4936
+ }
4937
+ 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"] }] }); }
4939
+ }
4940
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SectionFormComponent, decorators: [{
4941
+ 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: [{
4952
+ type: Output
4953
+ }], formUpdate: [{
4954
+ type: Output
4955
+ }], cancel: [{
4956
+ type: Output
4957
+ }] } });
4958
+
4959
+ class D2FormModule {
4960
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
4961
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, declarations: [FormFieldComponent,
4962
+ FormComponent,
4963
+ RepeatableFormComponent,
4964
+ SectionFormComponent,
4965
+ FormFieldItemComponent], imports: [CommonModule, ReactiveFormsModule, OrganisationUnitSelectorModule], exports: [FormFieldComponent,
4966
+ FormComponent,
4967
+ RepeatableFormComponent,
4968
+ SectionFormComponent] }); }
4969
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, imports: [CommonModule, ReactiveFormsModule, OrganisationUnitSelectorModule] }); }
4970
+ }
4971
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, decorators: [{
4972
+ type: NgModule,
4973
+ args: [{
4974
+ declarations: [
4975
+ FormFieldComponent,
4976
+ FormComponent,
4977
+ RepeatableFormComponent,
4978
+ SectionFormComponent,
4979
+ FormFieldItemComponent,
4980
+ ],
4981
+ imports: [CommonModule, ReactiveFormsModule, OrganisationUnitSelectorModule],
4982
+ exports: [
4983
+ FormFieldComponent,
4984
+ FormComponent,
4985
+ RepeatableFormComponent,
4986
+ SectionFormComponent,
4987
+ ],
4988
+ }]
4989
+ }] });
4990
+
4991
+ // Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
4992
+ // Use of this source code is governed by a BSD-style
4993
+ // license that can be found in the LICENSE file.
4994
+
3340
4995
  /**
3341
4996
  * Generated bundle index. Do not edit.
3342
4997
  */
3343
4998
 
3344
- export { ButtonComponent, ButtonModule, HeaderBarComponent, HeaderBarModule, LineListModule, LineListTableComponent, OrganisationUnitSelectionConfig, OrganisationUnitSelectorComponent, OrganisationUnitSelectorModalComponent, OrganisationUnitSelectorModule, PeriodSelectorComponent, PeriodSelectorModalComponent, PeriodSelectorModule, ReactWrapperComponent, ReactWrapperModule };
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 };
3345
5000
  //# sourceMappingURL=iapps-ng-dhis2-ui.mjs.map