@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.
- package/fesm2022/iapps-ng-dhis2-ui.mjs +1947 -292
- package/fesm2022/iapps-ng-dhis2-ui.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/modules/form/components/base-form-field.component.d.ts +53 -0
- package/lib/modules/form/components/form-field-item.component.d.ts +6 -0
- package/lib/modules/form/containers/form/form.component.d.ts +32 -0
- package/lib/modules/form/containers/form-field/form-field.component.d.ts +50 -0
- package/lib/modules/form/containers/repeatable-form/repeatable-form.component.d.ts +31 -0
- package/lib/modules/form/containers/section-form/section-form.component.d.ts +31 -0
- package/lib/modules/form/form.module.d.ts +14 -0
- package/lib/modules/form/index.d.ts +8 -0
- package/lib/modules/form/interfaces/field-control-type.interface.d.ts +1 -0
- package/lib/modules/form/interfaces/field-dropdown.interface.d.ts +7 -0
- package/lib/modules/form/interfaces/field-type.interface.d.ts +15 -0
- package/lib/modules/form/interfaces/form-configuration.model.d.ts +63 -0
- package/lib/modules/form/interfaces/form-field-group.interface.d.ts +14 -0
- package/lib/modules/form/interfaces/form-field-meta-type.interface.d.ts +1 -0
- package/lib/modules/form/interfaces/form-field.interface.d.ts +40 -0
- package/lib/modules/form/interfaces/form-metadata-section.interface.d.ts +10 -0
- package/lib/modules/form/interfaces/form-metadata.interface.d.ts +11 -0
- package/lib/modules/form/interfaces/index.d.ts +9 -0
- package/lib/modules/form/models/boolean.model.d.ts +5 -0
- package/lib/modules/form/models/check-box.model.d.ts +5 -0
- package/lib/modules/form/models/date-field.model.d.ts +7 -0
- package/lib/modules/form/models/date-range-value.model.d.ts +4 -0
- package/lib/modules/form/models/dropdown-option.model.d.ts +6 -0
- package/lib/modules/form/models/dropdown.model.d.ts +5 -0
- package/lib/modules/form/models/field-config.model.d.ts +5 -0
- package/lib/modules/form/models/field-dropdown.model.d.ts +10 -0
- package/lib/modules/form/models/fields-data.model.d.ts +8 -0
- package/lib/modules/form/models/form-config.model.d.ts +10 -0
- package/lib/modules/form/models/form-field-group.model.d.ts +21 -0
- package/lib/modules/form/models/form-field.model.d.ts +41 -0
- package/lib/modules/form/models/form-metadata-rule.model.d.ts +28 -0
- package/lib/modules/form/models/form-metadata-section.model.d.ts +28 -0
- package/lib/modules/form/models/form-metadata.model.d.ts +20 -0
- package/lib/modules/form/models/form-value.model.d.ts +17 -0
- package/lib/modules/form/models/form.model.d.ts +14 -0
- package/lib/modules/form/models/index.d.ts +17 -0
- package/lib/modules/form/utils/field-control-type.util.d.ts +4 -0
- package/lib/modules/form/utils/field-type.util.d.ts +3 -0
- package/lib/modules/form/utils/field.util.d.ts +9 -0
- package/lib/modules/form/utils/form-value.util.d.ts +4 -0
- package/lib/modules/form/utils/form.util.d.ts +8 -0
- package/lib/modules/form/utils/index.d.ts +5 -0
- package/lib/modules/line-list/containers/line-list.component.d.ts +12 -1
- package/lib/modules/line-list/models/attribute-filter.model.d.ts +2 -1
- package/lib/modules/line-list/models/filter-config.model.d.ts +6 -0
- package/lib/modules/line-list/models/line-list.models.d.ts +73 -14
- package/lib/modules/line-list/utils/filter-builder.d.ts +3 -0
- package/lib/modules/line-list/utils/line-list-utils.d.ts +2 -1
- package/lib/modules/react-wrapper/react-wrapper.component.d.ts +2 -3
- package/lib/shared/components/index.d.ts +1 -2
- package/package.json +1 -1
- /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
|
|
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
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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.
|
|
165
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
166
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
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.
|
|
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: [
|
|
173
|
-
exports: [
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
433
|
+
return React__default.createElement(IconMessages24, { color: colors.white });
|
|
557
434
|
}
|
|
558
435
|
else {
|
|
559
|
-
return React__default.createElement(IconMail24, { color: colors
|
|
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
|
|
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
|
|
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
|
|
605
|
-
color: ${colors
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
935
|
-
helpUrl && (React__default.createElement(MenuItem, { href: helpUrl, label: i18n.t('Help'), value: "help", icon: React__default.createElement(IconQuestion24, { color: colors
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
1177
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.
|
|
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.
|
|
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.
|
|
1196
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
1197
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
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.
|
|
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.
|
|
1229
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
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.
|
|
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.
|
|
1242
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
1243
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
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.
|
|
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.
|
|
1286
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
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.
|
|
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.
|
|
1315
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
1316
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
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.
|
|
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.
|
|
2307
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
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.
|
|
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.
|
|
2367
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
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.
|
|
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.
|
|
2380
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
2381
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
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.
|
|
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.
|
|
2822
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
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.
|
|
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.
|
|
2924
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
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.
|
|
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.
|
|
2943
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
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.
|
|
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.
|
|
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 }) =>
|
|
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
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
3014
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.
|
|
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.
|
|
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
|
-
|
|
3098
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
paginationContainer.
|
|
3231
|
-
paginationContainer
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
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
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
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
|
-
}, [
|
|
3269
|
-
|
|
3270
|
-
|
|
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: () =>
|
|
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.
|
|
3304
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
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.
|
|
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.
|
|
3327
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
3328
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
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.
|
|
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
|