@iapps/ng-dhis2-ui 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/iapps-ng-dhis2-ui.mjs +2198 -469
- package/fesm2022/iapps-ng-dhis2-ui.mjs.map +1 -1
- package/index.d.ts +3 -1
- package/lib/modules/button/button.component.d.ts +2 -2
- 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 +38 -0
- package/lib/modules/form/containers/section-form/section-form.component.d.ts +32 -0
- package/lib/modules/form/form.module.d.ts +15 -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 +15 -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 +21 -0
- package/lib/modules/form/models/form-value.model.d.ts +19 -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 +6 -0
- package/lib/modules/form/utils/translation.util.d.ts +3 -0
- package/lib/modules/header-bar/header-bar.component.d.ts +2 -2
- package/lib/modules/line-list/containers/line-list.component.d.ts +6 -5
- package/lib/modules/line-list/models/line-list.models.d.ts +43 -0
- package/lib/modules/line-list/services/line-list.service.d.ts +1 -1
- package/lib/modules/organisation-unit-selector/containers/organisation-unit-selector/organisation-unit-selector.component.d.ts +2 -2
- package/lib/modules/organisation-unit-selector/containers/organisation-unit-selector-modal/organisation-unit-selector-modal.component-modal.d.ts +2 -2
- package/lib/modules/period-selector/containers/period-selector/period-selector.component.d.ts +2 -2
- package/lib/modules/period-selector/containers/period-selector-modal/period-selector-modal.component.d.ts +2 -2
- package/lib/modules/react-wrapper/react-wrapper.component.d.ts +3 -3
- package/lib/modules/tracker-form/index.d.ts +2 -0
- package/lib/modules/tracker-form/tracker-form.component.d.ts +15 -0
- package/lib/modules/tracker-form/tracker-form.module.d.ts +9 -0
- package/lib/shared/components/index.d.ts +1 -2
- package/lib/shared/utils/predefinedDimensions.d.ts +6 -6
- package/package.json +1 -1
- package/lib/modules/react-wrapper/index.d.ts +0 -2
- package/lib/modules/react-wrapper/react-wrapper.module.d.ts +0 -8
- /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, CircularLoader as CircularLoader$1, 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 { isObject, isString, sortBy, isArray, find, camelCase, flatten, head, isEmpty } from 'lodash';
|
|
31
|
+
import cx from 'classnames';
|
|
30
32
|
import { map as map$1, switchMap } from 'rxjs/operators';
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
inactive: active !== undefined && !active,
|
|
38
|
-
}), "data-test": `${dataTest}-content`, onClick: (event) => {
|
|
39
|
-
if (disabled) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
onClick({ label, value }, event);
|
|
43
|
-
}, onDoubleClick: (event) => {
|
|
44
|
-
if (disabled) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
onDoubleClick({ label, value }, event);
|
|
48
|
-
} },
|
|
49
|
-
React__default.createElement("span", { className: "icon" }, icon),
|
|
50
|
-
React__default.createElement("span", { className: "label" }, label),
|
|
51
|
-
onEditClick && (React__default.createElement("span", { className: "edit", onClick: (e) => {
|
|
52
|
-
e.stopPropagation();
|
|
53
|
-
onEditClick();
|
|
54
|
-
}, "data-test": `${dataTest}-edit-button` },
|
|
55
|
-
React__default.createElement(IconEdit16, null))),
|
|
56
|
-
React__default.createElement("style", { jsx: true }, `
|
|
57
|
-
.wrapper:last-child {
|
|
58
|
-
margin-bottom: ${spacers.dp4};
|
|
59
|
-
}
|
|
60
|
-
.chip {
|
|
61
|
-
display: inline-flex;
|
|
62
|
-
background: ${colors.grey200};
|
|
63
|
-
font-size: 14px;
|
|
64
|
-
line-height: 16px;
|
|
65
|
-
padding: 2px ${spacers.dp8} 2px ${spacers.dp4};
|
|
66
|
-
margin: ${spacers.dp4} ${spacers.dp8} 0 ${spacers.dp8};
|
|
67
|
-
border-radius: 3px;
|
|
68
|
-
user-select: none;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.chip:hover {
|
|
72
|
-
background: ${colors.grey300};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.selected {
|
|
76
|
-
background: ${theme.secondary100};
|
|
77
|
-
color: ${theme.secondary900};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.selected :global(.icon path) {
|
|
81
|
-
fill: ${theme.secondary700};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.selected:hover {
|
|
85
|
-
background: #c9edeb;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.highlighted,
|
|
89
|
-
.highlighted:hover {
|
|
90
|
-
background: ${theme.secondary800};
|
|
91
|
-
color: ${colors.white};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.highlighted :global(.icon path) {
|
|
95
|
-
fill: ${colors.white};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
.disabled {
|
|
99
|
-
opacity: 0.3;
|
|
100
|
-
cursor: not-allowed;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.inactive {
|
|
104
|
-
opacity: 0.3;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.icon,
|
|
108
|
-
.label {
|
|
109
|
-
line-height: 18px;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
.icon {
|
|
113
|
-
margin-right: ${spacers.dp4};
|
|
114
|
-
display: inline-flex;
|
|
115
|
-
vertical-align: text-bottom;
|
|
116
|
-
padding-top: 1px;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
.label {
|
|
120
|
-
font-size: 14px;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.edit {
|
|
124
|
-
height: 16px;
|
|
125
|
-
margin-top: 1px;
|
|
126
|
-
margin-left: ${spacers.dp8};
|
|
127
|
-
cursor: pointer;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
.edit:hover {
|
|
131
|
-
background-color: rgba(0, 0, 0, 0.12);
|
|
132
|
-
outline: 1px solid rgba(0, 0, 0, 0.12);
|
|
133
|
-
border-radius: 3px;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
.highlighted .edit:hover {
|
|
137
|
-
background-color: rgba(255, 255, 255, 0.12);
|
|
138
|
-
outline: 1px solid rgba(255, 255, 255, 0.12);
|
|
139
|
-
}
|
|
140
|
-
`)));
|
|
141
|
-
return (React__default.createElement("div", { "data-value": value, "data-test": dataTest, className: "wrapper" }, tooltipText ? (React__default.createElement(Tooltip, { key: `${value}`, content: tooltipText, placement: 'top', openDelay: 750, closeDelay: 150 }, renderContent())) : (renderContent())));
|
|
142
|
-
};
|
|
143
|
-
TransferOption.propTypes = {
|
|
144
|
-
label: PropTypes.string.isRequired,
|
|
145
|
-
value: PropTypes.string.isRequired,
|
|
146
|
-
active: PropTypes.bool,
|
|
147
|
-
dataTest: PropTypes.string,
|
|
148
|
-
disabled: PropTypes.bool,
|
|
149
|
-
highlighted: PropTypes.bool,
|
|
150
|
-
icon: PropTypes.node,
|
|
151
|
-
selected: PropTypes.bool,
|
|
152
|
-
tooltipText: PropTypes.string,
|
|
153
|
-
onClick: PropTypes.func,
|
|
154
|
-
onDoubleClick: PropTypes.func,
|
|
155
|
-
onEditClick: PropTypes.func,
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
// Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
|
|
159
|
-
// Use of this source code is governed by a BSD-style
|
|
160
|
-
// license that can be found in the LICENSE file.
|
|
161
|
-
const sharedComponents = [];
|
|
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 {
|
|
@@ -1141,7 +1018,7 @@ HeaderBar.propTypes = {
|
|
|
1141
1018
|
};
|
|
1142
1019
|
|
|
1143
1020
|
window.React = React;
|
|
1144
|
-
class
|
|
1021
|
+
class ReactWrapperModule {
|
|
1145
1022
|
constructor(elementRef) {
|
|
1146
1023
|
this.elementRef = elementRef;
|
|
1147
1024
|
}
|
|
@@ -1170,14 +1047,13 @@ class ReactWrapperComponent {
|
|
|
1170
1047
|
" "));
|
|
1171
1048
|
}
|
|
1172
1049
|
}
|
|
1173
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
1174
|
-
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: ReactWrapperModule, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1051
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.8", type: ReactWrapperModule, isStandalone: true, selector: "ng-dhis2-ui-wrapper", inputs: { props: "props", component: "component" }, queries: [{ propertyName: "content", first: true, predicate: ["ngDhis2UiContent"], descendants: true }], ngImport: i0 }); }
|
|
1175
1052
|
}
|
|
1176
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1053
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, decorators: [{
|
|
1177
1054
|
type: Directive,
|
|
1178
1055
|
args: [{
|
|
1179
1056
|
selector: 'ng-dhis2-ui-wrapper',
|
|
1180
|
-
standalone: false,
|
|
1181
1057
|
}]
|
|
1182
1058
|
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { props: [{
|
|
1183
1059
|
type: Input
|
|
@@ -1188,25 +1064,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
1188
1064
|
args: ['ngDhis2UiContent']
|
|
1189
1065
|
}] } });
|
|
1190
1066
|
|
|
1191
|
-
class ReactWrapperModule {
|
|
1192
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ReactWrapperModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1193
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.7", ngImport: i0, type: ReactWrapperModule, declarations: [ReactWrapperComponent], imports: [CommonModule], exports: [ReactWrapperComponent] }); }
|
|
1194
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ReactWrapperModule, imports: [CommonModule] }); }
|
|
1195
|
-
}
|
|
1196
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ReactWrapperModule, decorators: [{
|
|
1197
|
-
type: NgModule,
|
|
1198
|
-
args: [{
|
|
1199
|
-
imports: [CommonModule],
|
|
1200
|
-
declarations: [ReactWrapperComponent],
|
|
1201
|
-
exports: [ReactWrapperComponent],
|
|
1202
|
-
}]
|
|
1203
|
-
}] });
|
|
1204
|
-
|
|
1205
|
-
// Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
|
|
1206
|
-
// Use of this source code is governed by a BSD-style
|
|
1207
|
-
// license that can be found in the LICENSE file.
|
|
1208
|
-
|
|
1209
|
-
class HeaderBarComponent extends ReactWrapperComponent {
|
|
1067
|
+
class HeaderBarComponent extends ReactWrapperModule {
|
|
1210
1068
|
constructor(elementRef, httpClient) {
|
|
1211
1069
|
super(elementRef);
|
|
1212
1070
|
this.httpClient = httpClient;
|
|
@@ -1222,24 +1080,24 @@ class HeaderBarComponent extends ReactWrapperComponent {
|
|
|
1222
1080
|
: () => React__default.createElement("div", null, "Something went wrong");
|
|
1223
1081
|
this.render();
|
|
1224
1082
|
}
|
|
1225
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
1226
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
1083
|
+
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 }); }
|
|
1084
|
+
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 }); }
|
|
1227
1085
|
}
|
|
1228
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1086
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarComponent, decorators: [{
|
|
1229
1087
|
type: Component,
|
|
1230
1088
|
args: [{
|
|
1231
1089
|
selector: 'ng-dhis2-ui-header-bar',
|
|
1232
1090
|
template: `<ng-container></ng-container>`,
|
|
1233
|
-
standalone: false
|
|
1091
|
+
standalone: false,
|
|
1234
1092
|
}]
|
|
1235
1093
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }] });
|
|
1236
1094
|
|
|
1237
1095
|
class HeaderBarModule {
|
|
1238
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
1239
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
1240
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
1096
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1097
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarModule, declarations: [HeaderBarComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [HeaderBarComponent] }); }
|
|
1098
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarModule, imports: [CommonModule, SharedDhis2UiModule] }); }
|
|
1241
1099
|
}
|
|
1242
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1100
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: HeaderBarModule, decorators: [{
|
|
1243
1101
|
type: NgModule,
|
|
1244
1102
|
args: [{
|
|
1245
1103
|
imports: [CommonModule, SharedDhis2UiModule],
|
|
@@ -1252,7 +1110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
1252
1110
|
// Use of this source code is governed by a BSD-style
|
|
1253
1111
|
// license that can be found in the LICENSE file.
|
|
1254
1112
|
|
|
1255
|
-
class ButtonComponent extends
|
|
1113
|
+
class ButtonComponent extends ReactWrapperModule {
|
|
1256
1114
|
constructor() {
|
|
1257
1115
|
super(...arguments);
|
|
1258
1116
|
this.buttonClick = new EventEmitter();
|
|
@@ -1279,15 +1137,15 @@ class ButtonComponent extends ReactWrapperComponent {
|
|
|
1279
1137
|
onButtonClick(event) {
|
|
1280
1138
|
this.buttonClick.emit(event);
|
|
1281
1139
|
}
|
|
1282
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
1283
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
1140
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ButtonComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1141
|
+
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 }); }
|
|
1284
1142
|
}
|
|
1285
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1143
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
1286
1144
|
type: Component,
|
|
1287
1145
|
args: [{
|
|
1288
1146
|
selector: 'ng-dhis2-ui-button',
|
|
1289
1147
|
template: '<ng-content></ng-content>',
|
|
1290
|
-
standalone: false
|
|
1148
|
+
standalone: false,
|
|
1291
1149
|
}]
|
|
1292
1150
|
}], propDecorators: { label: [{
|
|
1293
1151
|
type: Input
|
|
@@ -1308,11 +1166,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
1308
1166
|
}] } });
|
|
1309
1167
|
|
|
1310
1168
|
class ButtonModule {
|
|
1311
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
1312
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
1313
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
1169
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1170
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: ButtonModule, declarations: [ButtonComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [ButtonComponent] }); }
|
|
1171
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ButtonModule, imports: [CommonModule, SharedDhis2UiModule] }); }
|
|
1314
1172
|
}
|
|
1315
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1173
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ButtonModule, decorators: [{
|
|
1316
1174
|
type: NgModule,
|
|
1317
1175
|
args: [{
|
|
1318
1176
|
declarations: [ButtonComponent],
|
|
@@ -1537,38 +1395,38 @@ const dimensionGetItems = (dimension) => dimensionIsValid(dimension, { requireIt
|
|
|
1537
1395
|
var styles$1 = `
|
|
1538
1396
|
.filterContainer {
|
|
1539
1397
|
display: flex;
|
|
1540
|
-
margin-bottom: ${spacers.dp12};
|
|
1541
|
-
margin-top: ${spacers.dp8};
|
|
1398
|
+
margin-bottom: ${spacers$1.dp12};
|
|
1399
|
+
margin-top: ${spacers$1.dp8};
|
|
1542
1400
|
}
|
|
1543
1401
|
.emptyList {
|
|
1544
1402
|
text-align: center;
|
|
1545
1403
|
font-size: 14px;
|
|
1546
1404
|
line-height: 16px;
|
|
1547
|
-
margin: ${spacers.dp24} 0 0;
|
|
1548
|
-
color: ${colors.grey700};
|
|
1405
|
+
margin: ${spacers$1.dp24} 0 0;
|
|
1406
|
+
color: ${colors$1.grey700};
|
|
1549
1407
|
}
|
|
1550
1408
|
.rightHeader {
|
|
1551
1409
|
font-size: 14px;
|
|
1552
1410
|
font-weight: 400;
|
|
1553
1411
|
}
|
|
1554
1412
|
.leftHeader {
|
|
1555
|
-
padding: ${spacers.dp12} ${spacers.dp4};
|
|
1413
|
+
padding: ${spacers$1.dp12} ${spacers$1.dp4};
|
|
1556
1414
|
}
|
|
1557
1415
|
.info-container {
|
|
1558
1416
|
display: flex;
|
|
1559
|
-
margin-bottom: ${spacers.dp8};
|
|
1560
|
-
padding: ${spacers.dp8};
|
|
1561
|
-
background-color: ${colors.grey200};
|
|
1417
|
+
margin-bottom: ${spacers$1.dp8};
|
|
1418
|
+
padding: ${spacers$1.dp8};
|
|
1419
|
+
background-color: ${colors$1.grey200};
|
|
1562
1420
|
border-radius: 3px;
|
|
1563
1421
|
}
|
|
1564
1422
|
.info-text {
|
|
1565
|
-
padding-left: ${spacers.dp8};
|
|
1566
|
-
color: ${colors.grey900};
|
|
1423
|
+
padding-left: ${spacers$1.dp8};
|
|
1424
|
+
color: ${colors$1.grey900};
|
|
1567
1425
|
font-size: 12px;
|
|
1568
1426
|
line-height: 16px;
|
|
1569
1427
|
}
|
|
1570
1428
|
.calculation-button {
|
|
1571
|
-
margin: ${spacers.dp8} 0;
|
|
1429
|
+
margin: ${spacers$1.dp8} 0;
|
|
1572
1430
|
}
|
|
1573
1431
|
`;
|
|
1574
1432
|
|
|
@@ -1576,82 +1434,212 @@ var styles$1 = `
|
|
|
1576
1434
|
// Use of this source code is governed by a BSD-style
|
|
1577
1435
|
// license that can be found in the LICENSE file.
|
|
1578
1436
|
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1437
|
+
const TransferOption = ({ disabled, label, highlighted, selected, onClick, onDoubleClick, value, icon, active, tooltipText, dataTest, onEditClick, }) => {
|
|
1438
|
+
const renderContent = () => (React__default.createElement("div", { className: cx('chip', {
|
|
1439
|
+
highlighted,
|
|
1440
|
+
disabled,
|
|
1441
|
+
selected,
|
|
1442
|
+
inactive: active !== undefined && !active,
|
|
1443
|
+
}), "data-test": `${dataTest}-content`, onClick: (event) => {
|
|
1444
|
+
if (disabled) {
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
onClick({ label, value }, event);
|
|
1448
|
+
}, onDoubleClick: (event) => {
|
|
1449
|
+
if (disabled) {
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
onDoubleClick({ label, value }, event);
|
|
1453
|
+
} },
|
|
1454
|
+
React__default.createElement("span", { className: "icon" }, icon),
|
|
1455
|
+
React__default.createElement("span", { className: "label" }, label),
|
|
1456
|
+
onEditClick && (React__default.createElement("span", { className: "edit", onClick: (e) => {
|
|
1457
|
+
e.stopPropagation();
|
|
1458
|
+
onEditClick();
|
|
1459
|
+
}, "data-test": `${dataTest}-edit-button` },
|
|
1460
|
+
React__default.createElement(IconEdit16, null))),
|
|
1461
|
+
React__default.createElement("style", { jsx: true }, `
|
|
1462
|
+
.wrapper:last-child {
|
|
1463
|
+
margin-bottom: ${spacers$1.dp4};
|
|
1464
|
+
}
|
|
1465
|
+
.chip {
|
|
1466
|
+
display: inline-flex;
|
|
1467
|
+
background: ${colors$1.grey200};
|
|
1468
|
+
font-size: 14px;
|
|
1469
|
+
line-height: 16px;
|
|
1470
|
+
padding: 2px ${spacers$1.dp8} 2px ${spacers$1.dp4};
|
|
1471
|
+
margin: ${spacers$1.dp4} ${spacers$1.dp8} 0 ${spacers$1.dp8};
|
|
1472
|
+
border-radius: 3px;
|
|
1473
|
+
user-select: none;
|
|
1474
|
+
}
|
|
1582
1475
|
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
const DAILY = 'DAILY';
|
|
1587
|
-
const WEEKLY = 'WEEKLY';
|
|
1588
|
-
const WEEKLYWED = 'WEEKLYWED';
|
|
1589
|
-
const WEEKLYTHU = 'WEEKLYTHU';
|
|
1590
|
-
const WEEKLYSAT = 'WEEKLYSAT';
|
|
1591
|
-
const WEEKLYSUN = 'WEEKLYSUN';
|
|
1592
|
-
const WEEKS_THIS_YEAR = 'WEEKS_THIS_YEAR';
|
|
1593
|
-
const BIWEEKLY = 'BIWEEKLY';
|
|
1594
|
-
const MONTHLY = 'MONTHLY';
|
|
1595
|
-
const BIMONTHLY = 'BIMONTHLY';
|
|
1596
|
-
const QUARTERLY = 'QUARTERLY';
|
|
1597
|
-
const SIXMONTHLY = 'SIXMONTHLY';
|
|
1598
|
-
const SIXMONTHLYAPR = 'SIXMONTHLYAPR';
|
|
1599
|
-
const YEARLY = 'YEARLY';
|
|
1600
|
-
const FINANCIAL = 'FINANCIAL';
|
|
1601
|
-
const FYNOV = 'FYNOV';
|
|
1602
|
-
const FYOCT = 'FYOCT';
|
|
1603
|
-
const FYJUL = 'FYJUL';
|
|
1604
|
-
const FYAPR = 'FYAPR';
|
|
1476
|
+
.chip:hover {
|
|
1477
|
+
background: ${colors$1.grey300};
|
|
1478
|
+
}
|
|
1605
1479
|
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1480
|
+
.selected {
|
|
1481
|
+
background: ${theme$1.secondary100};
|
|
1482
|
+
color: ${theme$1.secondary900};
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
.selected :global(.icon path) {
|
|
1486
|
+
fill: ${theme$1.secondary700};
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
.selected:hover {
|
|
1490
|
+
background: #c9edeb;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
.highlighted,
|
|
1494
|
+
.highlighted:hover {
|
|
1495
|
+
background: ${theme$1.secondary800};
|
|
1496
|
+
color: ${colors$1.white};
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
.highlighted :global(.icon path) {
|
|
1500
|
+
fill: ${colors$1.white};
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
.disabled {
|
|
1504
|
+
opacity: 0.3;
|
|
1505
|
+
cursor: not-allowed;
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
.inactive {
|
|
1509
|
+
opacity: 0.3;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
.icon,
|
|
1513
|
+
.label {
|
|
1514
|
+
line-height: 18px;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
.icon {
|
|
1518
|
+
margin-right: ${spacers$1.dp4};
|
|
1519
|
+
display: inline-flex;
|
|
1520
|
+
vertical-align: text-bottom;
|
|
1521
|
+
padding-top: 1px;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
.label {
|
|
1525
|
+
font-size: 14px;
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
.edit {
|
|
1529
|
+
height: 16px;
|
|
1530
|
+
margin-top: 1px;
|
|
1531
|
+
margin-left: ${spacers$1.dp8};
|
|
1532
|
+
cursor: pointer;
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
.edit:hover {
|
|
1536
|
+
background-color: rgba(0, 0, 0, 0.12);
|
|
1537
|
+
outline: 1px solid rgba(0, 0, 0, 0.12);
|
|
1538
|
+
border-radius: 3px;
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
.highlighted .edit:hover {
|
|
1542
|
+
background-color: rgba(255, 255, 255, 0.12);
|
|
1543
|
+
outline: 1px solid rgba(255, 255, 255, 0.12);
|
|
1544
|
+
}
|
|
1545
|
+
`)));
|
|
1546
|
+
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())));
|
|
1547
|
+
};
|
|
1548
|
+
TransferOption.propTypes = {
|
|
1549
|
+
label: PropTypes.string.isRequired,
|
|
1550
|
+
value: PropTypes.string.isRequired,
|
|
1551
|
+
active: PropTypes.bool,
|
|
1552
|
+
dataTest: PropTypes.string,
|
|
1553
|
+
disabled: PropTypes.bool,
|
|
1554
|
+
highlighted: PropTypes.bool,
|
|
1555
|
+
icon: PropTypes.node,
|
|
1556
|
+
selected: PropTypes.bool,
|
|
1557
|
+
tooltipText: PropTypes.string,
|
|
1558
|
+
onClick: PropTypes.func,
|
|
1559
|
+
onDoubleClick: PropTypes.func,
|
|
1560
|
+
onEditClick: PropTypes.func,
|
|
1561
|
+
};
|
|
1562
|
+
|
|
1563
|
+
// Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
|
|
1564
|
+
// Use of this source code is governed by a BSD-style
|
|
1565
|
+
// license that can be found in the LICENSE file.
|
|
1566
|
+
|
|
1567
|
+
// Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
|
|
1568
|
+
// Use of this source code is governed by a BSD-style
|
|
1569
|
+
// license that can be found in the LICENSE file.
|
|
1570
|
+
|
|
1571
|
+
// Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
|
|
1572
|
+
// Use of this source code is governed by a BSD-style
|
|
1573
|
+
// license that can be found in the LICENSE file.
|
|
1574
|
+
const DAILY = 'DAILY';
|
|
1575
|
+
const WEEKLY = 'WEEKLY';
|
|
1576
|
+
const WEEKLYWED = 'WEEKLYWED';
|
|
1577
|
+
const WEEKLYTHU = 'WEEKLYTHU';
|
|
1578
|
+
const WEEKLYSAT = 'WEEKLYSAT';
|
|
1579
|
+
const WEEKLYSUN = 'WEEKLYSUN';
|
|
1580
|
+
const WEEKS_THIS_YEAR = 'WEEKS_THIS_YEAR';
|
|
1581
|
+
const BIWEEKLY = 'BIWEEKLY';
|
|
1582
|
+
const MONTHLY = 'MONTHLY';
|
|
1583
|
+
const BIMONTHLY = 'BIMONTHLY';
|
|
1584
|
+
const QUARTERLY = 'QUARTERLY';
|
|
1585
|
+
const SIXMONTHLY = 'SIXMONTHLY';
|
|
1586
|
+
const SIXMONTHLYAPR = 'SIXMONTHLYAPR';
|
|
1587
|
+
const YEARLY = 'YEARLY';
|
|
1588
|
+
const FINANCIAL = 'FINANCIAL';
|
|
1589
|
+
const FYNOV = 'FYNOV';
|
|
1590
|
+
const FYOCT = 'FYOCT';
|
|
1591
|
+
const FYJUL = 'FYJUL';
|
|
1592
|
+
const FYAPR = 'FYAPR';
|
|
1593
|
+
|
|
1594
|
+
const getDaysPeriodType = () => [
|
|
1595
|
+
{ id: 'TODAY', name: i18n.t('Today') },
|
|
1596
|
+
{ id: 'YESTERDAY', name: i18n.t('Yesterday') },
|
|
1597
|
+
{ id: 'LAST_3_DAYS', name: i18n.t('Last 3 days') },
|
|
1598
|
+
{ id: 'LAST_7_DAYS', name: i18n.t('Last 7 days') },
|
|
1599
|
+
{ id: 'LAST_14_DAYS', name: i18n.t('Last 14 days') },
|
|
1600
|
+
{ id: 'LAST_30_DAYS', name: i18n.t('Last 30 days') },
|
|
1601
|
+
{ id: 'LAST_60_DAYS', name: i18n.t('Last 60 days') },
|
|
1602
|
+
{ id: 'LAST_90_DAYS', name: i18n.t('Last 90 days') },
|
|
1603
|
+
{ id: 'LAST_180_DAYS', name: i18n.t('Last 180 days') },
|
|
1604
|
+
];
|
|
1605
|
+
const getWeeksPeriodType = () => [
|
|
1606
|
+
{ id: 'THIS_WEEK', name: i18n.t('This week') },
|
|
1607
|
+
{ id: 'LAST_WEEK', name: i18n.t('Last week') },
|
|
1608
|
+
{ id: 'LAST_4_WEEKS', name: i18n.t('Last 4 weeks') },
|
|
1609
|
+
{ id: 'LAST_12_WEEKS', name: i18n.t('Last 12 weeks') },
|
|
1610
|
+
{ id: 'LAST_52_WEEKS', name: i18n.t('Last 52 weeks') },
|
|
1611
|
+
{ id: WEEKS_THIS_YEAR, name: i18n.t('Weeks this year') },
|
|
1612
|
+
];
|
|
1613
|
+
const getBiWeeksPeriodType = () => [
|
|
1614
|
+
{ id: 'THIS_BIWEEK', name: i18n.t('This bi-week') },
|
|
1615
|
+
{ id: 'LAST_BIWEEK', name: i18n.t('Last bi-week') },
|
|
1616
|
+
{ id: 'LAST_4_BIWEEKS', name: i18n.t('Last 4 bi-weeks') },
|
|
1617
|
+
];
|
|
1618
|
+
const getMonthsPeriodType = () => [
|
|
1619
|
+
{ id: 'THIS_MONTH', name: i18n.t('This month') },
|
|
1620
|
+
{ id: 'LAST_MONTH', name: i18n.t('Last month') },
|
|
1621
|
+
{ id: 'LAST_3_MONTHS', name: i18n.t('Last 3 months') },
|
|
1622
|
+
{ id: 'LAST_6_MONTHS', name: i18n.t('Last 6 months') },
|
|
1623
|
+
{ id: 'LAST_12_MONTHS', name: i18n.t('Last 12 months') },
|
|
1624
|
+
{
|
|
1625
|
+
id: 'MONTHS_THIS_YEAR',
|
|
1626
|
+
name: i18n.t('Months this year'),
|
|
1627
|
+
},
|
|
1628
|
+
];
|
|
1629
|
+
const getBiMonthsPeriodType = () => [
|
|
1630
|
+
{ id: 'THIS_BIMONTH', name: i18n.t('This bi-month') },
|
|
1631
|
+
{ id: 'LAST_BIMONTH', name: i18n.t('Last bi-month') },
|
|
1632
|
+
{
|
|
1633
|
+
id: 'LAST_6_BIMONTHS',
|
|
1634
|
+
name: i18n.t('Last 6 bi-months'),
|
|
1635
|
+
},
|
|
1636
|
+
{
|
|
1637
|
+
id: 'BIMONTHS_THIS_YEAR',
|
|
1638
|
+
name: i18n.t('Bi-months this year'),
|
|
1639
|
+
},
|
|
1640
|
+
];
|
|
1641
|
+
const getQuartersPeriodType = () => [
|
|
1642
|
+
{ id: 'THIS_QUARTER', name: i18n.t('This quarter') },
|
|
1655
1643
|
{ id: 'LAST_QUARTER', name: i18n.t('Last quarter') },
|
|
1656
1644
|
{ id: 'LAST_4_QUARTERS', name: i18n.t('Last 4 quarters') },
|
|
1657
1645
|
{
|
|
@@ -2068,7 +2056,7 @@ const FixedPeriodFilter = ({ allowedPeriodTypes, excludedPeriodTypes, currentPer
|
|
|
2068
2056
|
}
|
|
2069
2057
|
.rightSection {
|
|
2070
2058
|
width: 120px;
|
|
2071
|
-
margin-left: ${spacers.dp8};
|
|
2059
|
+
margin-left: ${spacers$1.dp8};
|
|
2072
2060
|
}
|
|
2073
2061
|
`)));
|
|
2074
2062
|
};
|
|
@@ -2097,7 +2085,7 @@ const RelativePeriodFilter = ({ currentFilter, onSelectFilter, dataTest, exclude
|
|
|
2097
2085
|
}
|
|
2098
2086
|
.rightSection {
|
|
2099
2087
|
width: 120px;
|
|
2100
|
-
margin-left: ${spacers.dp8};
|
|
2088
|
+
margin-left: ${spacers$1.dp8};
|
|
2101
2089
|
}
|
|
2102
2090
|
`)));
|
|
2103
2091
|
RelativePeriodFilter.propTypes = {
|
|
@@ -2244,7 +2232,7 @@ PeriodDimension.defaultProps = {
|
|
|
2244
2232
|
selectedPeriods: [],
|
|
2245
2233
|
};
|
|
2246
2234
|
|
|
2247
|
-
class PeriodSelectorModalComponent extends
|
|
2235
|
+
class PeriodSelectorModalComponent extends ReactWrapperModule {
|
|
2248
2236
|
constructor(elementRef, httpClient) {
|
|
2249
2237
|
super(elementRef);
|
|
2250
2238
|
this.httpClient = httpClient;
|
|
@@ -2300,10 +2288,10 @@ class PeriodSelectorModalComponent extends ReactWrapperComponent {
|
|
|
2300
2288
|
onConfirm(selectedItems) {
|
|
2301
2289
|
this.confirm.emit(selectedItems);
|
|
2302
2290
|
}
|
|
2303
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
2304
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
2291
|
+
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 }); }
|
|
2292
|
+
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"] }); }
|
|
2305
2293
|
}
|
|
2306
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2294
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorModalComponent, decorators: [{
|
|
2307
2295
|
type: Component,
|
|
2308
2296
|
args: [{ selector: 'ng-dhis2-ui-period-selector-modal', template: `<ng-container></ng-container>`, standalone: false, styles: ["::ng-deep .layer{z-index:2!important}\n"] }]
|
|
2309
2297
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }], propDecorators: { selectedPeriods: [{
|
|
@@ -2314,7 +2302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
2314
2302
|
type: Output
|
|
2315
2303
|
}] } });
|
|
2316
2304
|
|
|
2317
|
-
class PeriodSelectorComponent extends
|
|
2305
|
+
class PeriodSelectorComponent extends ReactWrapperModule {
|
|
2318
2306
|
constructor(elementRef, httpClient, ngZone) {
|
|
2319
2307
|
super(elementRef);
|
|
2320
2308
|
this.httpClient = httpClient;
|
|
@@ -2360,10 +2348,10 @@ class PeriodSelectorComponent extends ReactWrapperComponent {
|
|
|
2360
2348
|
onSelectItems(selectionEvent) {
|
|
2361
2349
|
this.selectPeriods.emit(selectionEvent.items);
|
|
2362
2350
|
}
|
|
2363
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
2364
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
2351
|
+
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 }); }
|
|
2352
|
+
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"] }); }
|
|
2365
2353
|
}
|
|
2366
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2354
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorComponent, decorators: [{
|
|
2367
2355
|
type: Component,
|
|
2368
2356
|
args: [{ selector: 'ng-dhis2-ui-period-selector', template: `<ng-container></ng-container>`, standalone: false, styles: ["::ng-deep .content-container{z-index:0!important}\n"] }]
|
|
2369
2357
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }, { type: i0.NgZone }], propDecorators: { selectedPeriods: [{
|
|
@@ -2373,11 +2361,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
2373
2361
|
}] } });
|
|
2374
2362
|
|
|
2375
2363
|
class PeriodSelectorModule {
|
|
2376
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
2377
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
2378
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
2364
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2365
|
+
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] }); }
|
|
2366
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorModule, imports: [CommonModule, SharedDhis2UiModule] }); }
|
|
2379
2367
|
}
|
|
2380
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2368
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: PeriodSelectorModule, decorators: [{
|
|
2381
2369
|
type: NgModule,
|
|
2382
2370
|
args: [{
|
|
2383
2371
|
imports: [CommonModule, SharedDhis2UiModule],
|
|
@@ -2469,20 +2457,20 @@ const styles = `
|
|
|
2469
2457
|
|
|
2470
2458
|
.userOrgUnitsWrapper {
|
|
2471
2459
|
display: flex;
|
|
2472
|
-
background: ${colors.grey200};
|
|
2473
|
-
padding: ${spacers.dp8} ${spacers.dp8} ${spacers.dp8} ${spacers.dp24};
|
|
2474
|
-
margin-bottom: ${spacers.dp12};
|
|
2460
|
+
background: ${colors$1.grey200};
|
|
2461
|
+
padding: ${spacers$1.dp8} ${spacers$1.dp8} ${spacers$1.dp8} ${spacers$1.dp24};
|
|
2462
|
+
margin-bottom: ${spacers$1.dp12};
|
|
2475
2463
|
}
|
|
2476
2464
|
|
|
2477
2465
|
.userOrgUnitsWrapper > :global(*) {
|
|
2478
|
-
margin-right: ${spacers.dp48};
|
|
2466
|
+
margin-right: ${spacers$1.dp48};
|
|
2479
2467
|
}
|
|
2480
2468
|
|
|
2481
2469
|
.selectsWrapper {
|
|
2482
2470
|
display: flex;
|
|
2483
2471
|
align-items: flex-start;
|
|
2484
|
-
gap: ${spacers.dp8};
|
|
2485
|
-
margin-top: ${spacers.dp12};
|
|
2472
|
+
gap: ${spacers$1.dp8};
|
|
2473
|
+
margin-top: ${spacers$1.dp12};
|
|
2486
2474
|
}
|
|
2487
2475
|
|
|
2488
2476
|
.selectsWrapper.hidden {
|
|
@@ -2496,7 +2484,7 @@ const styles = `
|
|
|
2496
2484
|
.summaryWrapper {
|
|
2497
2485
|
display: inline-flex;
|
|
2498
2486
|
align-items: center;
|
|
2499
|
-
margin-top: ${spacers.dp8};
|
|
2487
|
+
margin-top: ${spacers$1.dp8};
|
|
2500
2488
|
}
|
|
2501
2489
|
|
|
2502
2490
|
.warningWrapper {
|
|
@@ -2505,21 +2493,21 @@ const styles = `
|
|
|
2505
2493
|
}
|
|
2506
2494
|
|
|
2507
2495
|
.warningText {
|
|
2508
|
-
margin-left: ${spacers.dp8};
|
|
2496
|
+
margin-left: ${spacers$1.dp8};
|
|
2509
2497
|
font-size: 14px;
|
|
2510
2498
|
line-height: 18px;
|
|
2511
|
-
color: ${colors.red600};
|
|
2499
|
+
color: ${colors$1.red600};
|
|
2512
2500
|
}
|
|
2513
2501
|
|
|
2514
2502
|
.summaryText {
|
|
2515
2503
|
font-size: 14px;
|
|
2516
2504
|
line-height: 18px;
|
|
2517
|
-
color: ${colors.grey700};
|
|
2505
|
+
color: ${colors$1.grey700};
|
|
2518
2506
|
}
|
|
2519
2507
|
|
|
2520
2508
|
.deselectButton {
|
|
2521
2509
|
display: inline-block;
|
|
2522
|
-
margin-left: ${spacers.dp8};
|
|
2510
|
+
margin-left: ${spacers$1.dp8};
|
|
2523
2511
|
}
|
|
2524
2512
|
`;
|
|
2525
2513
|
|
|
@@ -2534,7 +2522,6 @@ const OrgUnitDimension = ({ roots, selected, onSelect, hideGroupSelect, hideLeve
|
|
|
2534
2522
|
const [selectedItems, setSelectedItems] = useState(selected);
|
|
2535
2523
|
const dataEngine = useDataEngine();
|
|
2536
2524
|
const onSelectItems = (selectedItem) => {
|
|
2537
|
-
console.log('WE ARE SELECTING HERE', selectedItem);
|
|
2538
2525
|
const { id, checked, displayName, path } = selectedItem;
|
|
2539
2526
|
let result = [...selectedItems];
|
|
2540
2527
|
if (checked && DYNAMIC_ORG_UNITS.includes(id)) {
|
|
@@ -2703,7 +2690,7 @@ const OrgUnitDimension = ({ roots, selected, onSelect, hideGroupSelect, hideLeve
|
|
|
2703
2690
|
: [], 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}` })))))),
|
|
2704
2691
|
React__default.createElement("div", { className: "summaryWrapper" },
|
|
2705
2692
|
warning ? (React__default.createElement("div", { className: "warningWrapper" },
|
|
2706
|
-
React__default.createElement(IconWarningFilled16, { color: colors.red500 }),
|
|
2693
|
+
React__default.createElement(IconWarningFilled16, { color: colors$1.red500 }),
|
|
2707
2694
|
React__default.createElement("span", { className: "warningText" }, warning))) : (React__default.createElement("span", { className: "summaryText" }, getSummary())),
|
|
2708
2695
|
React__default.createElement("div", { className: "deselectButton" },
|
|
2709
2696
|
React__default.createElement(Button$1, { secondary: true, small: true, onClick: clearSelection, disabled: !selectedItems.length }, i18n.t('Deselect all')))),
|
|
@@ -2752,7 +2739,7 @@ class OrganisationUnitSelectionConfig {
|
|
|
2752
2739
|
// Use of this source code is governed by a BSD-style
|
|
2753
2740
|
// license that can be found in the LICENSE file.
|
|
2754
2741
|
|
|
2755
|
-
class OrganisationUnitSelectorComponent extends
|
|
2742
|
+
class OrganisationUnitSelectorComponent extends ReactWrapperModule {
|
|
2756
2743
|
constructor(elementRef, httpClient, ngZone) {
|
|
2757
2744
|
super(elementRef);
|
|
2758
2745
|
this.httpClient = httpClient;
|
|
@@ -2815,10 +2802,10 @@ class OrganisationUnitSelectorComponent extends ReactWrapperComponent {
|
|
|
2815
2802
|
onSelectItems(selectionEvent) {
|
|
2816
2803
|
this.selectOrgUnits.emit(selectionEvent.items);
|
|
2817
2804
|
}
|
|
2818
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
2819
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
2805
|
+
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 }); }
|
|
2806
|
+
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 }); }
|
|
2820
2807
|
}
|
|
2821
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2808
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorComponent, decorators: [{
|
|
2822
2809
|
type: Component,
|
|
2823
2810
|
args: [{
|
|
2824
2811
|
selector: 'ng-dhis2-ui-org-unit-selector',
|
|
@@ -2833,7 +2820,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
2833
2820
|
type: Output
|
|
2834
2821
|
}] } });
|
|
2835
2822
|
|
|
2836
|
-
class OrganisationUnitSelectorModalComponent extends
|
|
2823
|
+
class OrganisationUnitSelectorModalComponent extends ReactWrapperModule {
|
|
2837
2824
|
constructor(elementRef, httpClient) {
|
|
2838
2825
|
super(elementRef);
|
|
2839
2826
|
this.httpClient = httpClient;
|
|
@@ -2917,10 +2904,10 @@ class OrganisationUnitSelectorModalComponent extends ReactWrapperComponent {
|
|
|
2917
2904
|
onSelectItems(selectionEvent) {
|
|
2918
2905
|
this.selectOrgUnits.emit(selectionEvent.items);
|
|
2919
2906
|
}
|
|
2920
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
2921
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
2907
|
+
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 }); }
|
|
2908
|
+
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"] }); }
|
|
2922
2909
|
}
|
|
2923
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2910
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModalComponent, decorators: [{
|
|
2924
2911
|
type: Component,
|
|
2925
2912
|
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"] }]
|
|
2926
2913
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }], propDecorators: { selectedOrgUnits: [{
|
|
@@ -2936,13 +2923,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
2936
2923
|
}] } });
|
|
2937
2924
|
|
|
2938
2925
|
class OrganisationUnitSelectorModule {
|
|
2939
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
2940
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
2926
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2927
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModule, declarations: [OrganisationUnitSelectorComponent,
|
|
2941
2928
|
OrganisationUnitSelectorModalComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [OrganisationUnitSelectorComponent,
|
|
2942
2929
|
OrganisationUnitSelectorModalComponent] }); }
|
|
2943
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
2930
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModule, imports: [CommonModule, SharedDhis2UiModule] }); }
|
|
2944
2931
|
}
|
|
2945
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2932
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: OrganisationUnitSelectorModule, decorators: [{
|
|
2946
2933
|
type: NgModule,
|
|
2947
2934
|
args: [{
|
|
2948
2935
|
imports: [CommonModule, SharedDhis2UiModule],
|
|
@@ -2961,6 +2948,102 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
2961
2948
|
// Use of this source code is governed by a BSD-style
|
|
2962
2949
|
// license that can be found in the LICENSE file.
|
|
2963
2950
|
|
|
2951
|
+
const dropdownStyles = {
|
|
2952
|
+
layer: {
|
|
2953
|
+
zIndex: '1 !important',
|
|
2954
|
+
},
|
|
2955
|
+
};
|
|
2956
|
+
|
|
2957
|
+
// Helper function to generate a unique class name
|
|
2958
|
+
const generateClassName = (base) => `${base}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2959
|
+
// Helper function to convert camelCased properties to hyphenated CSS properties
|
|
2960
|
+
const convertStylesToCSS = (className, styles) => {
|
|
2961
|
+
let cssString = `.${className} {`;
|
|
2962
|
+
for (const key in styles) {
|
|
2963
|
+
if (typeof styles[key] === "object" && key.startsWith("@media")) {
|
|
2964
|
+
const mediaStyles = convertStylesToCSS(className, styles[key]);
|
|
2965
|
+
cssString += `${key} { ${mediaStyles} }`;
|
|
2966
|
+
}
|
|
2967
|
+
else if (key.startsWith("&:")) {
|
|
2968
|
+
const pseudoClass = key.replace("&", "");
|
|
2969
|
+
cssString += `${pseudoClass} { ${convertStylesToCSS("", styles[key])} }`;
|
|
2970
|
+
}
|
|
2971
|
+
else {
|
|
2972
|
+
const cssKey = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
2973
|
+
cssString += `${cssKey}: ${styles[key]}; `;
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
cssString += "}";
|
|
2977
|
+
return cssString;
|
|
2978
|
+
};
|
|
2979
|
+
// Custom hook for dynamic styles with generics
|
|
2980
|
+
const useDynamicStyles = (stylesObj) => {
|
|
2981
|
+
const [classNames, setClassNames] = useState({});
|
|
2982
|
+
useEffect(() => {
|
|
2983
|
+
const convertedStyles = Object.keys(stylesObj).map((key) => {
|
|
2984
|
+
const className = generateClassName(key);
|
|
2985
|
+
const styleElement = document.createElement("style");
|
|
2986
|
+
styleElement.innerHTML = convertStylesToCSS(className, stylesObj[key]);
|
|
2987
|
+
document.head.appendChild(styleElement);
|
|
2988
|
+
return {
|
|
2989
|
+
key,
|
|
2990
|
+
className,
|
|
2991
|
+
styleElement,
|
|
2992
|
+
};
|
|
2993
|
+
});
|
|
2994
|
+
setClassNames(convertedStyles.reduce((classNameEntity, convertedStyle) => {
|
|
2995
|
+
return {
|
|
2996
|
+
...classNameEntity,
|
|
2997
|
+
[convertedStyle.key]: convertedStyle.className,
|
|
2998
|
+
};
|
|
2999
|
+
}, {}));
|
|
3000
|
+
return () => {
|
|
3001
|
+
convertedStyles.forEach((convertedStyle) => {
|
|
3002
|
+
document.head.removeChild(convertedStyle.styleElement);
|
|
3003
|
+
});
|
|
3004
|
+
};
|
|
3005
|
+
}, []);
|
|
3006
|
+
return classNames;
|
|
3007
|
+
};
|
|
3008
|
+
|
|
3009
|
+
const useCurrentModal = () => {
|
|
3010
|
+
const [CurrentModal, setCurrentModal] = useState();
|
|
3011
|
+
return [
|
|
3012
|
+
CurrentModal,
|
|
3013
|
+
(Modal) => {
|
|
3014
|
+
// As setState supports functional updates, we can't pass functional
|
|
3015
|
+
// components directly
|
|
3016
|
+
setCurrentModal(() => Modal);
|
|
3017
|
+
},
|
|
3018
|
+
];
|
|
3019
|
+
};
|
|
3020
|
+
const ContextMenu = (params) => {
|
|
3021
|
+
const { onClose, onMenuClick, anchorRef, dropDownOptions } = params;
|
|
3022
|
+
const [CurrentModal, setCurrentModal] = useCurrentModal();
|
|
3023
|
+
const styles = useDynamicStyles(dropdownStyles);
|
|
3024
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
3025
|
+
React__default.createElement(Layer$1, { onBackdropClick: (event, data) => onClose(event, data), className: styles.layer },
|
|
3026
|
+
React__default.createElement(Popper, { reference: anchorRef, placement: "bottom-start" },
|
|
3027
|
+
React__default.createElement(FlyoutMenu, null, dropDownOptions.map((dropDownOption, index) => (React__default.createElement(MenuItem$1, { key: index, destructive: dropDownOption.destructive, label: dropDownOption.label, icon: dropDownOption.icon, onClick: () => {
|
|
3028
|
+
onMenuClick(dropDownOption);
|
|
3029
|
+
onClose();
|
|
3030
|
+
}, dense: true })))))),
|
|
3031
|
+
CurrentModal && (React__default.createElement(CurrentModal, { onClose: () => {
|
|
3032
|
+
onClose();
|
|
3033
|
+
setCurrentModal(null);
|
|
3034
|
+
} }))));
|
|
3035
|
+
};
|
|
3036
|
+
const DropdownMenu = (props) => {
|
|
3037
|
+
const ref = useRef();
|
|
3038
|
+
const [visible, setVisible] = useState(false);
|
|
3039
|
+
const { dropdownOptions, onClick } = props;
|
|
3040
|
+
return (React__default.createElement("div", { ref: ref, style: { display: "inline-block" } },
|
|
3041
|
+
React__default.createElement(Button$1, { small: true, secondary: true, icon: React__default.createElement(IconMore24, { color: colors$1.grey600 }), onClick: () => setVisible(true) }),
|
|
3042
|
+
visible && (React__default.createElement(ContextMenu, { dropDownOptions: dropdownOptions, anchorRef: ref, onClose: () => setVisible(false), onMenuClick: (dropDownOption) => {
|
|
3043
|
+
onClick(dropDownOption);
|
|
3044
|
+
} }))));
|
|
3045
|
+
};
|
|
3046
|
+
|
|
2964
3047
|
// export function buildFilters(filters: AttributeFilter[]): string {
|
|
2965
3048
|
// return filters
|
|
2966
3049
|
// .map(({ attribute, operator, value }) => `filter=${attribute}:${operator}:${value}`)
|
|
@@ -3025,12 +3108,13 @@ class LineListService {
|
|
|
3025
3108
|
this.httpClient = httpClient;
|
|
3026
3109
|
}
|
|
3027
3110
|
getProgramMetadata(programId) {
|
|
3028
|
-
return this.httpClient.get(`programs/${programId}.json?fields=programType,programStages[id,name,programStageDataElements[dataElement[id,name]]],organisationUnits[id,name]
|
|
3111
|
+
return this.httpClient.get(`programs/${programId}.json?fields=programType,programStages[id,name,programStageDataElements[dataElement[id,name]]],organisationUnits[id,name],*`);
|
|
3029
3112
|
}
|
|
3030
|
-
getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
|
|
3113
|
+
getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters = [], startDate, endDate, ouMode) {
|
|
3031
3114
|
const filterParams = buildFilters(filters);
|
|
3032
3115
|
const dateFilter = startDate && endDate ? `&programStartDate=${startDate}&programEndDate=${endDate}` : '';
|
|
3033
|
-
|
|
3116
|
+
const ouModeIdentifier = ouMode ? `&ouMode=${ouMode}` : ``;
|
|
3117
|
+
return this.httpClient.get(`trackedEntityInstances.json?program=${programId}&ou=${orgUnit}${ouModeIdentifier}&page=${page}&pageSize=${pageSize}&fields=trackedEntityInstance,attributes[*,displayInList],enrollments[*]&totalPages=true&${filterParams}${dateFilter}`).pipe(map$1((response) => {
|
|
3034
3118
|
response.trackedEntityInstances.forEach((tei) => {
|
|
3035
3119
|
// Filter attributes to only include those with displayInList=true
|
|
3036
3120
|
tei.attributes = tei.attributes.filter((attr) => attr.displayInList);
|
|
@@ -3038,141 +3122,47 @@ class LineListService {
|
|
|
3038
3122
|
return response;
|
|
3039
3123
|
}));
|
|
3040
3124
|
}
|
|
3041
|
-
getEvents(programId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
|
|
3125
|
+
getEvents(programId, orgUnit, page, pageSize, filters = [], startDate, endDate, ouMode) {
|
|
3042
3126
|
const filterParams = buildFilters(filters);
|
|
3043
3127
|
const dateFilter = startDate && endDate ? `&startDate=${startDate}&endDate=${endDate}` : '';
|
|
3044
|
-
|
|
3128
|
+
const ouModeIdentifier = ouMode ? `&ouMode=${ouMode}` : ``;
|
|
3129
|
+
return this.httpClient.get(`events.json?program=${programId}&orgUnit=${orgUnit}${ouModeIdentifier}&page=${page}&pageSize=${pageSize}&fields=*&totalPages=true&${filterParams}${dateFilter}`);
|
|
3045
3130
|
}
|
|
3046
|
-
getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
|
|
3131
|
+
getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters = [], startDate, endDate, ouMode) {
|
|
3047
3132
|
const filterParams = buildFilters(filters);
|
|
3048
3133
|
const dateFilter = startDate && endDate ? `&startDate=${startDate}&endDate=${endDate}` : '';
|
|
3049
|
-
|
|
3134
|
+
const ouModeIdentifier = ouMode ? `&ouMode=${ouMode}` : ``;
|
|
3135
|
+
return this.httpClient.get(`events.json?programStage=${programStageId}&orgUnit=${orgUnit}${ouModeIdentifier}&page=${page}&pageSize=${pageSize}&fields=*&totalPages=true&${filterParams}${dateFilter}`);
|
|
3050
3136
|
}
|
|
3051
|
-
getLineListData(programId, orgUnit = '', programStageId, page = 1, pageSize = 10, filters = [], startDate, endDate) {
|
|
3137
|
+
getLineListData(programId, orgUnit = '', programStageId, page = 1, pageSize = 10, filters = [], startDate, endDate, ouMode) {
|
|
3052
3138
|
return this.getProgramMetadata(programId).pipe(switchMap((programMetadata) => {
|
|
3053
3139
|
if (programStageId) {
|
|
3054
|
-
return this.getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((events) => ({
|
|
3140
|
+
return this.getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters, startDate, endDate, ouMode).pipe(map$1((events) => ({
|
|
3055
3141
|
metadata: programMetadata,
|
|
3056
3142
|
data: events,
|
|
3057
3143
|
})));
|
|
3058
3144
|
}
|
|
3059
3145
|
if (programMetadata.programType === 'WITH_REGISTRATION') {
|
|
3060
|
-
return this.getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((teis) => ({
|
|
3146
|
+
return this.getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters, startDate, endDate, ouMode).pipe(map$1((teis) => ({
|
|
3061
3147
|
metadata: programMetadata,
|
|
3062
3148
|
data: teis,
|
|
3063
3149
|
})));
|
|
3064
3150
|
}
|
|
3065
3151
|
else {
|
|
3066
|
-
return this.getEvents(programId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((events) => ({
|
|
3152
|
+
return this.getEvents(programId, orgUnit, page, pageSize, filters, startDate, endDate, ouMode).pipe(map$1((events) => ({
|
|
3067
3153
|
metadata: programMetadata,
|
|
3068
3154
|
data: events,
|
|
3069
3155
|
})));
|
|
3070
3156
|
}
|
|
3071
3157
|
}));
|
|
3072
3158
|
}
|
|
3073
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
3074
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.
|
|
3159
|
+
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 }); }
|
|
3160
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListService }); }
|
|
3075
3161
|
}
|
|
3076
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
3162
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListService, decorators: [{
|
|
3077
3163
|
type: Injectable
|
|
3078
3164
|
}], ctorParameters: () => [{ type: i1.NgxDhis2HttpClientService }] });
|
|
3079
3165
|
|
|
3080
|
-
const dropdownStyles = {
|
|
3081
|
-
layer: {
|
|
3082
|
-
zIndex: '1 !important',
|
|
3083
|
-
},
|
|
3084
|
-
};
|
|
3085
|
-
|
|
3086
|
-
// Helper function to generate a unique class name
|
|
3087
|
-
const generateClassName = (base) => `${base}-${Math.random().toString(36).substr(2, 9)}`;
|
|
3088
|
-
// Helper function to convert camelCased properties to hyphenated CSS properties
|
|
3089
|
-
const convertStylesToCSS = (className, styles) => {
|
|
3090
|
-
let cssString = `.${className} {`;
|
|
3091
|
-
for (const key in styles) {
|
|
3092
|
-
if (typeof styles[key] === "object" && key.startsWith("@media")) {
|
|
3093
|
-
const mediaStyles = convertStylesToCSS(className, styles[key]);
|
|
3094
|
-
cssString += `${key} { ${mediaStyles} }`;
|
|
3095
|
-
}
|
|
3096
|
-
else if (key.startsWith("&:")) {
|
|
3097
|
-
const pseudoClass = key.replace("&", "");
|
|
3098
|
-
cssString += `${pseudoClass} { ${convertStylesToCSS("", styles[key])} }`;
|
|
3099
|
-
}
|
|
3100
|
-
else {
|
|
3101
|
-
const cssKey = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
3102
|
-
cssString += `${cssKey}: ${styles[key]}; `;
|
|
3103
|
-
}
|
|
3104
|
-
}
|
|
3105
|
-
cssString += "}";
|
|
3106
|
-
return cssString;
|
|
3107
|
-
};
|
|
3108
|
-
// Custom hook for dynamic styles with generics
|
|
3109
|
-
const useDynamicStyles = (stylesObj) => {
|
|
3110
|
-
const [classNames, setClassNames] = useState({});
|
|
3111
|
-
useEffect(() => {
|
|
3112
|
-
const convertedStyles = Object.keys(stylesObj).map((key) => {
|
|
3113
|
-
const className = generateClassName(key);
|
|
3114
|
-
const styleElement = document.createElement("style");
|
|
3115
|
-
styleElement.innerHTML = convertStylesToCSS(className, stylesObj[key]);
|
|
3116
|
-
document.head.appendChild(styleElement);
|
|
3117
|
-
return {
|
|
3118
|
-
key,
|
|
3119
|
-
className,
|
|
3120
|
-
styleElement,
|
|
3121
|
-
};
|
|
3122
|
-
});
|
|
3123
|
-
setClassNames(convertedStyles.reduce((classNameEntity, convertedStyle) => {
|
|
3124
|
-
return {
|
|
3125
|
-
...classNameEntity,
|
|
3126
|
-
[convertedStyle.key]: convertedStyle.className,
|
|
3127
|
-
};
|
|
3128
|
-
}, {}));
|
|
3129
|
-
return () => {
|
|
3130
|
-
convertedStyles.forEach((convertedStyle) => {
|
|
3131
|
-
document.head.removeChild(convertedStyle.styleElement);
|
|
3132
|
-
});
|
|
3133
|
-
};
|
|
3134
|
-
}, []);
|
|
3135
|
-
return classNames;
|
|
3136
|
-
};
|
|
3137
|
-
|
|
3138
|
-
const useCurrentModal = () => {
|
|
3139
|
-
const [CurrentModal, setCurrentModal] = useState();
|
|
3140
|
-
return [
|
|
3141
|
-
CurrentModal,
|
|
3142
|
-
(Modal) => {
|
|
3143
|
-
// As setState supports functional updates, we can't pass functional
|
|
3144
|
-
// components directly
|
|
3145
|
-
setCurrentModal(() => Modal);
|
|
3146
|
-
},
|
|
3147
|
-
];
|
|
3148
|
-
};
|
|
3149
|
-
const ContextMenu = (params) => {
|
|
3150
|
-
const { onClose, onMenuClick, anchorRef, dropDownOptions } = params;
|
|
3151
|
-
const [CurrentModal, setCurrentModal] = useCurrentModal();
|
|
3152
|
-
const styles = useDynamicStyles(dropdownStyles);
|
|
3153
|
-
return (React__default.createElement(React__default.Fragment, null,
|
|
3154
|
-
React__default.createElement(Layer$1, { onBackdropClick: (event, data) => onClose(event, data), className: styles.layer },
|
|
3155
|
-
React__default.createElement(Popper, { reference: anchorRef, placement: "bottom-start" },
|
|
3156
|
-
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: () => {
|
|
3157
|
-
onMenuClick(dropDownOption);
|
|
3158
|
-
onClose();
|
|
3159
|
-
}, dense: true })))))),
|
|
3160
|
-
CurrentModal && (React__default.createElement(CurrentModal, { onClose: () => {
|
|
3161
|
-
onClose();
|
|
3162
|
-
setCurrentModal(null);
|
|
3163
|
-
} }))));
|
|
3164
|
-
};
|
|
3165
|
-
const DropdownMenu = (props) => {
|
|
3166
|
-
const ref = useRef();
|
|
3167
|
-
const [visible, setVisible] = useState(false);
|
|
3168
|
-
const { dropdownOptions, onClick } = props;
|
|
3169
|
-
return (React__default.createElement("div", { ref: ref, style: { display: "inline-block" } },
|
|
3170
|
-
React__default.createElement(Button$1, { small: true, secondary: true, icon: React__default.createElement(IconMore24, { color: colors.grey600 }), onClick: () => setVisible(true) }),
|
|
3171
|
-
visible && (React__default.createElement(ContextMenu, { dropDownOptions: dropdownOptions, anchorRef: ref, onClose: () => setVisible(false), onMenuClick: (dropDownOption) => {
|
|
3172
|
-
onClick(dropDownOption);
|
|
3173
|
-
} }))));
|
|
3174
|
-
};
|
|
3175
|
-
|
|
3176
3166
|
const getProgramStageData = (response, programStageId, pager) => {
|
|
3177
3167
|
const events = response.data.events;
|
|
3178
3168
|
const allDataElements = new Set();
|
|
@@ -3201,6 +3191,14 @@ const getProgramStageData = (response, programStageId, pager) => {
|
|
|
3201
3191
|
const getTrackedEntityData = (response, programId, pager, filters) => {
|
|
3202
3192
|
let teis = response.data
|
|
3203
3193
|
.trackedEntityInstances;
|
|
3194
|
+
let programMetaData = response.metadata.programTrackedEntityAttributes;
|
|
3195
|
+
const programAttributesMap = programMetaData.reduce((acc, attribute) => {
|
|
3196
|
+
if (attribute.displayInList) {
|
|
3197
|
+
acc[attribute.id] = attribute.displayName;
|
|
3198
|
+
}
|
|
3199
|
+
return acc;
|
|
3200
|
+
}, {});
|
|
3201
|
+
console.log('metadata', programAttributesMap);
|
|
3204
3202
|
if (filters) {
|
|
3205
3203
|
teis = getFilteredTrackedEntityInstances(teis, filters);
|
|
3206
3204
|
}
|
|
@@ -3212,7 +3210,12 @@ const getTrackedEntityData = (response, programId, pager, filters) => {
|
|
|
3212
3210
|
: tei.attributes;
|
|
3213
3211
|
attributes.forEach((attr) => allAttributes.add(attr.attribute));
|
|
3214
3212
|
});
|
|
3215
|
-
|
|
3213
|
+
console.log('all of the attributes', allAttributes);
|
|
3214
|
+
// const filteredAttributes = new Set(
|
|
3215
|
+
// [...allAttributes].filter((attributeId) => programAttributesMap[attributeId])
|
|
3216
|
+
// );
|
|
3217
|
+
// console.log('Filtered All Attributes:', filteredAttributes);
|
|
3218
|
+
let entityColumns = Array.from(allAttributes).map((attrId) => {
|
|
3216
3219
|
const foundAttribute = teis
|
|
3217
3220
|
.flatMap((tei) => {
|
|
3218
3221
|
const matchingEnrollment = tei.enrollments.find((enrollment) => enrollment.program === programId);
|
|
@@ -3226,6 +3229,10 @@ const getTrackedEntityData = (response, programId, pager, filters) => {
|
|
|
3226
3229
|
key: attrId,
|
|
3227
3230
|
};
|
|
3228
3231
|
});
|
|
3232
|
+
entityColumns = entityColumns.filter((column) => {
|
|
3233
|
+
// Check if the column label is part of any value in programAttributesMap
|
|
3234
|
+
return Object.values(programAttributesMap).some((value) => value.includes(column.label));
|
|
3235
|
+
});
|
|
3229
3236
|
const attributesData = teis.map((tei, idx) => {
|
|
3230
3237
|
let row = {
|
|
3231
3238
|
trackedEntityInstance: tei.trackedEntityInstance,
|
|
@@ -3272,7 +3279,7 @@ const addActionsColumn = (columns, actionOptions) => {
|
|
|
3272
3279
|
};
|
|
3273
3280
|
|
|
3274
3281
|
// src/app/line-list-table.component.ts
|
|
3275
|
-
class LineListTableComponent extends
|
|
3282
|
+
class LineListTableComponent extends ReactWrapperModule {
|
|
3276
3283
|
constructor() {
|
|
3277
3284
|
super(...arguments);
|
|
3278
3285
|
this.actionSelected = new EventEmitter();
|
|
@@ -3326,7 +3333,7 @@ class LineListTableComponent extends ReactWrapperComponent {
|
|
|
3326
3333
|
useEffect(() => {
|
|
3327
3334
|
setLoading(true);
|
|
3328
3335
|
this.lineListService
|
|
3329
|
-
.getLineListData(this.programId, this.orgUnit, this.programStageId, pager.page, pager.pageSize, this.attributeFilters, this.startDate, this.endDate)
|
|
3336
|
+
.getLineListData(this.programId, this.orgUnit, this.programStageId, pager.page, pager.pageSize, this.attributeFilters, this.startDate, this.endDate, this.ouMode)
|
|
3330
3337
|
.subscribe((response) => {
|
|
3331
3338
|
let entityColumns = [];
|
|
3332
3339
|
let responsePager;
|
|
@@ -3378,23 +3385,31 @@ class LineListTableComponent extends ReactWrapperComponent {
|
|
|
3378
3385
|
},
|
|
3379
3386
|
}));
|
|
3380
3387
|
};
|
|
3381
|
-
return (React__default.createElement("div", null, loading ? (React__default.createElement(
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3388
|
+
return (React__default.createElement("div", null, loading ? (React__default.createElement("div", { style: {
|
|
3389
|
+
display: 'flex',
|
|
3390
|
+
alignItems: 'center',
|
|
3391
|
+
gap: 8,
|
|
3392
|
+
padding: 8,
|
|
3393
|
+
} },
|
|
3394
|
+
React__default.createElement(CircularLoader$1, { small: true }),
|
|
3395
|
+
React__default.createElement("div", { style: {
|
|
3396
|
+
fontSize: 14,
|
|
3397
|
+
} }, "Loading"))) : (React__default.createElement(DataTable, null,
|
|
3398
|
+
React__default.createElement(TableHead, null,
|
|
3399
|
+
React__default.createElement(DataTableRow, null, columns.map((col) => (React__default.createElement(DataTableColumnHeader, { key: col.key }, col.label))))),
|
|
3400
|
+
React__default.createElement(TableBody, null, data.map((row) => (React__default.createElement(DataTableRow, { key: row.index }, columns.map((col) => (React__default.createElement(DataTableCell, { key: col.key }, col.key === 'actions' ? (React__default.createElement(DropdownMenu, { dropdownOptions: getDropdownOptions(row), onClick: (option) => option.onClick?.() })) : (row[col.key])))))))),
|
|
3401
|
+
React__default.createElement(TableFoot, null,
|
|
3402
|
+
React__default.createElement(DataTableRow, null,
|
|
3403
|
+
React__default.createElement(DataTableCell, { colSpan: columns.length.toString() },
|
|
3404
|
+
React__default.createElement("div", null,
|
|
3405
|
+
React__default.createElement(Pagination, { page: pager.page, pageCount: pager.pageCount, pageSize: pager.pageSize, total: pager.total, onPageChange: (page) => setPager((prev) => ({ ...prev, page })), onPageSizeChange: (pageSize) => {
|
|
3406
|
+
const newPageSize = Number(pageSize);
|
|
3407
|
+
setPager((prev) => ({
|
|
3408
|
+
...prev,
|
|
3409
|
+
page: 1,
|
|
3410
|
+
pageSize: newPageSize,
|
|
3411
|
+
}));
|
|
3412
|
+
}, pageSizes: ['5', '10', '20', '50'] })))))))));
|
|
3398
3413
|
};
|
|
3399
3414
|
}
|
|
3400
3415
|
ngOnChanges(changes) {
|
|
@@ -3426,10 +3441,10 @@ class LineListTableComponent extends ReactWrapperComponent {
|
|
|
3426
3441
|
this.component = this.LineList;
|
|
3427
3442
|
this.render();
|
|
3428
3443
|
}
|
|
3429
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
3430
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
3444
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListTableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
3445
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: LineListTableComponent, isStandalone: false, selector: "app-line-list", inputs: { programId: "programId", orgUnit: "orgUnit", programStageId: "programStageId", actionOptions: "actionOptions", attributeFilters: "attributeFilters", startDate: "startDate", endDate: "endDate", filters: "filters", ouMode: "ouMode" }, outputs: { actionSelected: "actionSelected" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: ["[data-test=dhis2-uiwidgets-pagination]{display:flex!important;flex-direction:row!important;justify-content:space-between!important;align-items:center!important}\n"] }); }
|
|
3431
3446
|
}
|
|
3432
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
3447
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListTableComponent, decorators: [{
|
|
3433
3448
|
type: Component,
|
|
3434
3449
|
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"] }]
|
|
3435
3450
|
}], propDecorators: { programId: [{
|
|
@@ -3448,16 +3463,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
3448
3463
|
type: Input
|
|
3449
3464
|
}], filters: [{
|
|
3450
3465
|
type: Input
|
|
3466
|
+
}], ouMode: [{
|
|
3467
|
+
type: Input
|
|
3451
3468
|
}], actionSelected: [{
|
|
3452
3469
|
type: Output
|
|
3453
3470
|
}] } });
|
|
3454
3471
|
|
|
3455
3472
|
class LineListModule {
|
|
3456
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
3457
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
3458
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
3473
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
3474
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: LineListModule, declarations: [LineListTableComponent], imports: [CommonModule, SharedDhis2UiModule], exports: [LineListTableComponent] }); }
|
|
3475
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListModule, providers: [LineListService], imports: [CommonModule, SharedDhis2UiModule] }); }
|
|
3459
3476
|
}
|
|
3460
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
3477
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListModule, decorators: [{
|
|
3461
3478
|
type: NgModule,
|
|
3462
3479
|
args: [{
|
|
3463
3480
|
declarations: [LineListTableComponent],
|
|
@@ -3467,9 +3484,1721 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
3467
3484
|
}]
|
|
3468
3485
|
}] });
|
|
3469
3486
|
|
|
3487
|
+
class FormField {
|
|
3488
|
+
constructor(options = {}) {
|
|
3489
|
+
this.value = options.value || '';
|
|
3490
|
+
this.key = options.key || '';
|
|
3491
|
+
this.referenceKey = options.referenceKey || '';
|
|
3492
|
+
this.id = options.id || '';
|
|
3493
|
+
this.code = options.code || '';
|
|
3494
|
+
this.label = options.label || '';
|
|
3495
|
+
this.required = !!options.required;
|
|
3496
|
+
this.order = options.order === undefined ? 1 : options.order;
|
|
3497
|
+
this.controlType = options.controlType;
|
|
3498
|
+
this.type = options.type || '';
|
|
3499
|
+
this.options = options.options || [];
|
|
3500
|
+
this.disabled = options.disabled || false;
|
|
3501
|
+
this.placeholder = options.placeholder || '';
|
|
3502
|
+
this.min = options.min;
|
|
3503
|
+
this.max =
|
|
3504
|
+
options.max || (this.controlType === 'date' ? new Date() : undefined);
|
|
3505
|
+
this.maxLength = options.maxLength;
|
|
3506
|
+
this.hidden = options.hidden || false;
|
|
3507
|
+
this.isDataElement = options.isDataElement;
|
|
3508
|
+
this.isAttribute = options.isAttribute;
|
|
3509
|
+
this.isOrgUnit = options.isOrgUnit;
|
|
3510
|
+
this.isEnrollmentDate = options.isEnrollmentDate;
|
|
3511
|
+
this.event = options.event;
|
|
3512
|
+
this.programStage = options.programStage;
|
|
3513
|
+
this.program = options.program;
|
|
3514
|
+
this.trackedEntityInstance = options.trackedEntityInstance;
|
|
3515
|
+
this.hasOptions = options.hasOptions;
|
|
3516
|
+
this.dependentField = options.dependentField;
|
|
3517
|
+
this.displayInList = options.displayInList;
|
|
3518
|
+
this.displayInReports = options.displayInReports;
|
|
3519
|
+
this.searchable = options.searchable;
|
|
3520
|
+
this.unique = options.unique;
|
|
3521
|
+
this.metaType = options.metaType;
|
|
3522
|
+
this.stepId = options.stepId;
|
|
3523
|
+
this.availableOptionsLabel =
|
|
3524
|
+
options.availableOptionsLabel ?? 'Available options';
|
|
3525
|
+
this.selectedOptionsLabel =
|
|
3526
|
+
options.availableOptionsLabel ?? 'Selected options';
|
|
3527
|
+
}
|
|
3528
|
+
}
|
|
3529
|
+
|
|
3530
|
+
let Boolean$1 = class Boolean extends FormField {
|
|
3531
|
+
constructor() {
|
|
3532
|
+
super(...arguments);
|
|
3533
|
+
this.controlType = 'boolean';
|
|
3534
|
+
}
|
|
3535
|
+
};
|
|
3536
|
+
|
|
3537
|
+
class CheckBox extends FormField {
|
|
3538
|
+
constructor() {
|
|
3539
|
+
super(...arguments);
|
|
3540
|
+
this.controlType = 'checkbox';
|
|
3541
|
+
}
|
|
3542
|
+
}
|
|
3543
|
+
|
|
3544
|
+
class DateField extends FormField {
|
|
3545
|
+
constructor(field) {
|
|
3546
|
+
super(field);
|
|
3547
|
+
this.controlType = 'date';
|
|
3548
|
+
this.type = 'date';
|
|
3549
|
+
this.max = field.max ?? format(new Date(), 'yyyy-MM-dd');
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
|
|
3553
|
+
class Dropdown extends FormField {
|
|
3554
|
+
constructor() {
|
|
3555
|
+
super(...arguments);
|
|
3556
|
+
this.controlType = 'dropdown';
|
|
3557
|
+
}
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3560
|
+
// Copyright 2024 UDSM DHIS2 Lab. All rights reserved.
|
|
3561
|
+
// Use of this source code is governed by a BSD-style
|
|
3562
|
+
// license that can be found in the LICENSE file.
|
|
3563
|
+
class FieldConfig {
|
|
3564
|
+
constructor(config) {
|
|
3565
|
+
this.hideLabel = config?.hideLabel ?? false;
|
|
3566
|
+
this.inputWidth = config?.inputWidth || '100%';
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
|
|
3570
|
+
// Copyright 2024 UDSM DHIS2 Lab. All rights reserved.
|
|
3571
|
+
// Use of this source code is governed by a BSD-style
|
|
3572
|
+
// license that can be found in the LICENSE file.
|
|
3573
|
+
class DateRangeValue {
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
var FieldType;
|
|
3577
|
+
(function (FieldType) {
|
|
3578
|
+
FieldType["TEXT"] = "TEXT";
|
|
3579
|
+
FieldType["TRUE_ONLY"] = "TRUE_ONLY";
|
|
3580
|
+
FieldType["LONG_TEXT"] = "LONG_TEXT";
|
|
3581
|
+
FieldType["BOOLEAN"] = "BOOLEAN";
|
|
3582
|
+
FieldType["NUMBER"] = "NUMBER";
|
|
3583
|
+
FieldType["INTEGER_ZERO_OR_POSITIVE"] = "INTEGER_ZERO_OR_POSITIVE";
|
|
3584
|
+
FieldType["IMAGE"] = "IMAGE";
|
|
3585
|
+
FieldType["FILE_RESOURCE"] = "FILE_RESOURCE";
|
|
3586
|
+
FieldType["DATE"] = "DATE";
|
|
3587
|
+
FieldType["DATE_TIME"] = "DATETIME";
|
|
3588
|
+
FieldType["ORG_UNIT"] = "ORGANISATION_UNIT";
|
|
3589
|
+
FieldType["PHONE_NUMBER"] = "PHONE_NUMBER";
|
|
3590
|
+
FieldType["EMAIL"] = "EMAIL";
|
|
3591
|
+
})(FieldType || (FieldType = {}));
|
|
3592
|
+
|
|
3593
|
+
// Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
|
|
3594
|
+
// Use of this source code is governed by a BSD-style
|
|
3595
|
+
// license that can be found in the LICENSE file.
|
|
3596
|
+
|
|
3597
|
+
class FieldDropdown {
|
|
3598
|
+
constructor(params) {
|
|
3599
|
+
this.key = params.key;
|
|
3600
|
+
this.value = params.value;
|
|
3601
|
+
this.label = params.label;
|
|
3602
|
+
this.order = params.order;
|
|
3603
|
+
}
|
|
3604
|
+
toJson() {
|
|
3605
|
+
return {
|
|
3606
|
+
key: this.key,
|
|
3607
|
+
value: this.value,
|
|
3608
|
+
label: this.label,
|
|
3609
|
+
order: this.order,
|
|
3610
|
+
};
|
|
3611
|
+
}
|
|
3612
|
+
static getDropdownOptions(field, locale) {
|
|
3613
|
+
if (field?.valueType === FieldType.BOOLEAN) {
|
|
3614
|
+
return [
|
|
3615
|
+
{
|
|
3616
|
+
key: 'Yes',
|
|
3617
|
+
value: 'true',
|
|
3618
|
+
label: 'Yes',
|
|
3619
|
+
order: 1,
|
|
3620
|
+
},
|
|
3621
|
+
{
|
|
3622
|
+
key: 'No',
|
|
3623
|
+
value: 'false',
|
|
3624
|
+
label: 'No',
|
|
3625
|
+
order: 2,
|
|
3626
|
+
},
|
|
3627
|
+
].map((dropdown) => new FieldDropdown(dropdown));
|
|
3628
|
+
}
|
|
3629
|
+
return sortBy((field?.optionSet?.options || []).map((option) => {
|
|
3630
|
+
return new FieldDropdown({
|
|
3631
|
+
key: option.id,
|
|
3632
|
+
value: option.code,
|
|
3633
|
+
label: option.name,
|
|
3634
|
+
order: option.sortOrder,
|
|
3635
|
+
});
|
|
3636
|
+
}), 'order');
|
|
3637
|
+
}
|
|
3638
|
+
}
|
|
3639
|
+
|
|
3640
|
+
class FormConfig {
|
|
3641
|
+
constructor(config) {
|
|
3642
|
+
this.direction = config?.direction || 'vertical';
|
|
3643
|
+
this.showSaveButton = config?.showSaveButton ?? true;
|
|
3644
|
+
this.fieldConfig = config?.fieldConfig || new FieldConfig();
|
|
3645
|
+
this.formName = config?.formName;
|
|
3646
|
+
}
|
|
3647
|
+
get directionClassName() {
|
|
3648
|
+
return this.direction === 'vertical' ? 'form-vertical' : 'form-horizontal';
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
|
|
3652
|
+
class FieldUtil {
|
|
3653
|
+
static getFieldDropdownOptions(field) {
|
|
3654
|
+
if (field.valueType === FieldType.BOOLEAN) {
|
|
3655
|
+
return [
|
|
3656
|
+
{
|
|
3657
|
+
key: 'Yes',
|
|
3658
|
+
value: 'true',
|
|
3659
|
+
label: 'Yes',
|
|
3660
|
+
order: 1,
|
|
3661
|
+
},
|
|
3662
|
+
{
|
|
3663
|
+
key: 'No',
|
|
3664
|
+
value: 'false',
|
|
3665
|
+
label: 'No',
|
|
3666
|
+
order: 2,
|
|
3667
|
+
},
|
|
3668
|
+
];
|
|
3669
|
+
}
|
|
3670
|
+
return FieldUtil.sanitizeOptions(field.optionSet?.options || []);
|
|
3671
|
+
}
|
|
3672
|
+
static sanitizeOptions(options) {
|
|
3673
|
+
return sortBy((options || []).map((option) => ({
|
|
3674
|
+
key: option.id,
|
|
3675
|
+
value: option.code,
|
|
3676
|
+
label: option.name,
|
|
3677
|
+
order: option.sortOrder,
|
|
3678
|
+
color: option.style?.color,
|
|
3679
|
+
attributeValues: option.attributeValues,
|
|
3680
|
+
options: FieldUtil.sanitizeOptions(option.options),
|
|
3681
|
+
})), 'order');
|
|
3682
|
+
}
|
|
3683
|
+
static getFieldType(valueType) {
|
|
3684
|
+
switch (valueType) {
|
|
3685
|
+
case FieldType.NUMBER:
|
|
3686
|
+
return 'number';
|
|
3687
|
+
case FieldType.PHONE_NUMBER:
|
|
3688
|
+
return 'tel';
|
|
3689
|
+
case FieldType.ORG_UNIT:
|
|
3690
|
+
return 'org-unit';
|
|
3691
|
+
case FieldType.DATE:
|
|
3692
|
+
return 'date';
|
|
3693
|
+
case FieldType.FILE_RESOURCE:
|
|
3694
|
+
return 'file';
|
|
3695
|
+
default:
|
|
3696
|
+
return 'text';
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
static getFieldControlType(valueType, hasOptions) {
|
|
3700
|
+
if (hasOptions) {
|
|
3701
|
+
return 'dropdown';
|
|
3702
|
+
}
|
|
3703
|
+
switch (valueType) {
|
|
3704
|
+
case FieldType.TEXT:
|
|
3705
|
+
return 'textbox';
|
|
3706
|
+
case FieldType.LONG_TEXT:
|
|
3707
|
+
return 'textarea';
|
|
3708
|
+
case FieldType.TRUE_ONLY:
|
|
3709
|
+
return 'checkbox';
|
|
3710
|
+
case FieldType.NUMBER:
|
|
3711
|
+
return 'textbox';
|
|
3712
|
+
case FieldType.PHONE_NUMBER:
|
|
3713
|
+
return 'textbox';
|
|
3714
|
+
case FieldType.ORG_UNIT:
|
|
3715
|
+
return 'org-unit';
|
|
3716
|
+
case FieldType.DATE:
|
|
3717
|
+
return 'date';
|
|
3718
|
+
case FieldType.DATE_TIME:
|
|
3719
|
+
return 'date-time';
|
|
3720
|
+
case FieldType.IMAGE:
|
|
3721
|
+
return 'image';
|
|
3722
|
+
case FieldType.FILE_RESOURCE:
|
|
3723
|
+
return 'file';
|
|
3724
|
+
default:
|
|
3725
|
+
return 'textbox';
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3728
|
+
static getOptionEntities(options) {
|
|
3729
|
+
return (options || []).reduce((entity, option) => {
|
|
3730
|
+
return { ...entity, [option.value]: option.label };
|
|
3731
|
+
}, {});
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
|
|
3735
|
+
class FieldControlTypeUtil {
|
|
3736
|
+
static getFieldControlType(valueType, hasOptions) {
|
|
3737
|
+
if (hasOptions) {
|
|
3738
|
+
return 'dropdown';
|
|
3739
|
+
}
|
|
3740
|
+
switch (valueType) {
|
|
3741
|
+
case FieldType.TEXT:
|
|
3742
|
+
return 'textbox';
|
|
3743
|
+
case FieldType.BOOLEAN:
|
|
3744
|
+
return 'dropdown';
|
|
3745
|
+
case FieldType.LONG_TEXT:
|
|
3746
|
+
return 'textarea';
|
|
3747
|
+
case FieldType.TRUE_ONLY:
|
|
3748
|
+
return 'checkbox';
|
|
3749
|
+
case FieldType.NUMBER:
|
|
3750
|
+
return 'textbox';
|
|
3751
|
+
case FieldType.INTEGER_ZERO_OR_POSITIVE:
|
|
3752
|
+
return 'textbox';
|
|
3753
|
+
case FieldType.ORG_UNIT:
|
|
3754
|
+
return 'org-unit';
|
|
3755
|
+
case FieldType.DATE:
|
|
3756
|
+
return 'date';
|
|
3757
|
+
case FieldType.DATE_TIME:
|
|
3758
|
+
return 'date-time';
|
|
3759
|
+
case FieldType.IMAGE:
|
|
3760
|
+
return 'image';
|
|
3761
|
+
case FieldType.FILE_RESOURCE:
|
|
3762
|
+
return 'file';
|
|
3763
|
+
default:
|
|
3764
|
+
return 'textbox';
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3768
|
+
|
|
3769
|
+
class FormFieldTypeUtil {
|
|
3770
|
+
static getFieldType(valueType) {
|
|
3771
|
+
switch (valueType) {
|
|
3772
|
+
case FieldType.NUMBER:
|
|
3773
|
+
return 'number';
|
|
3774
|
+
case FieldType.INTEGER_ZERO_OR_POSITIVE:
|
|
3775
|
+
return 'number';
|
|
3776
|
+
case FieldType.ORG_UNIT:
|
|
3777
|
+
return 'org-unit';
|
|
3778
|
+
case FieldType.IMAGE:
|
|
3779
|
+
return 'image';
|
|
3780
|
+
case FieldType.FILE_RESOURCE:
|
|
3781
|
+
return 'file';
|
|
3782
|
+
default:
|
|
3783
|
+
return 'text';
|
|
3784
|
+
}
|
|
3785
|
+
}
|
|
3786
|
+
}
|
|
3787
|
+
|
|
3788
|
+
class FormUtil {
|
|
3789
|
+
static getFormGroup(fields, dataEntities) {
|
|
3790
|
+
const group = {};
|
|
3791
|
+
(fields || []).forEach((field) => {
|
|
3792
|
+
if (field) {
|
|
3793
|
+
const value = FormUtil.getFieldValue(field, dataEntities);
|
|
3794
|
+
const minValidators = field.min
|
|
3795
|
+
? [Validators.min(field.min)]
|
|
3796
|
+
: [];
|
|
3797
|
+
const maxValidators = field.max
|
|
3798
|
+
? [Validators.max(field.max)]
|
|
3799
|
+
: [];
|
|
3800
|
+
const phoneNumberValidator = field.type === 'tel'
|
|
3801
|
+
? [Validators.pattern('\\+255[6-7][1-9][0-9]{7}$')]
|
|
3802
|
+
: [];
|
|
3803
|
+
group[field.key] = field.required
|
|
3804
|
+
? new UntypedFormControl({ value, disabled: field.disabled }, {
|
|
3805
|
+
validators: [
|
|
3806
|
+
Validators.required,
|
|
3807
|
+
...minValidators,
|
|
3808
|
+
...maxValidators,
|
|
3809
|
+
...phoneNumberValidator,
|
|
3810
|
+
],
|
|
3811
|
+
updateOn: 'change',
|
|
3812
|
+
})
|
|
3813
|
+
: new UntypedFormControl({ value, disabled: field.disabled }, {
|
|
3814
|
+
validators: [
|
|
3815
|
+
...minValidators,
|
|
3816
|
+
...maxValidators,
|
|
3817
|
+
...phoneNumberValidator,
|
|
3818
|
+
],
|
|
3819
|
+
});
|
|
3820
|
+
if (field.referenceKey) {
|
|
3821
|
+
const value = dataEntities
|
|
3822
|
+
? dataEntities[field.referenceKey] || ''
|
|
3823
|
+
: '';
|
|
3824
|
+
group[field.referenceKey] = field.required
|
|
3825
|
+
? new UntypedFormControl({ value, disabled: field.disabled }, {
|
|
3826
|
+
validators: [
|
|
3827
|
+
Validators.required,
|
|
3828
|
+
...minValidators,
|
|
3829
|
+
...maxValidators,
|
|
3830
|
+
...phoneNumberValidator,
|
|
3831
|
+
],
|
|
3832
|
+
updateOn: 'change',
|
|
3833
|
+
})
|
|
3834
|
+
: new UntypedFormControl({ value, disabled: field.disabled }, {
|
|
3835
|
+
validators: [
|
|
3836
|
+
...minValidators,
|
|
3837
|
+
...maxValidators,
|
|
3838
|
+
...phoneNumberValidator,
|
|
3839
|
+
],
|
|
3840
|
+
});
|
|
3841
|
+
}
|
|
3842
|
+
}
|
|
3843
|
+
});
|
|
3844
|
+
return new UntypedFormGroup(group);
|
|
3845
|
+
}
|
|
3846
|
+
static getFieldValue(field, dataEntities) {
|
|
3847
|
+
const fieldValue = dataEntities
|
|
3848
|
+
? dataEntities[field.id] || dataEntities[field.key] || ''
|
|
3849
|
+
: '';
|
|
3850
|
+
return isArray(fieldValue) ? JSON.stringify(fieldValue) : fieldValue;
|
|
3851
|
+
}
|
|
3852
|
+
static getFormFields(fields) {
|
|
3853
|
+
return (fields || []).map((field) => {
|
|
3854
|
+
const options = FieldUtil.getFieldDropdownOptions(field);
|
|
3855
|
+
const dependentField = find(fields, ['id', field.fieldOptionsDependsOn]);
|
|
3856
|
+
const label = field.formName || field.name || field.displayName;
|
|
3857
|
+
return new FormField({
|
|
3858
|
+
id: field.id,
|
|
3859
|
+
label,
|
|
3860
|
+
code: field.code,
|
|
3861
|
+
key: camelCase(field.code) || field.id,
|
|
3862
|
+
referenceKey: field.referenceKey,
|
|
3863
|
+
required: field.mandatory && !field.generated,
|
|
3864
|
+
displayInList: field.displayInList,
|
|
3865
|
+
type: FieldUtil.getFieldType(field.valueType),
|
|
3866
|
+
controlType: FieldUtil.getFieldControlType(field.valueType, options?.length > 0 || field.hasOptions),
|
|
3867
|
+
options,
|
|
3868
|
+
isDataElement: field.isDataElement,
|
|
3869
|
+
isAttribute: field.isAttribute,
|
|
3870
|
+
isOrgUnit: field.isOrgUnit,
|
|
3871
|
+
isEnrollmentDate: field.isEnrollmentDate,
|
|
3872
|
+
programStage: field.stageId,
|
|
3873
|
+
event: field.event,
|
|
3874
|
+
trackedEntityInstance: field.trackedEntityInstance,
|
|
3875
|
+
disabled: field.disabled || field.generated,
|
|
3876
|
+
dependentField: dependentField,
|
|
3877
|
+
min: field.min,
|
|
3878
|
+
max: field.max,
|
|
3879
|
+
maxLength: field.maxLength,
|
|
3880
|
+
});
|
|
3881
|
+
});
|
|
3882
|
+
}
|
|
3883
|
+
static createField(id, label, required, controlType, disabled, placeholder, options) {
|
|
3884
|
+
return new FormField({
|
|
3885
|
+
id,
|
|
3886
|
+
code: id,
|
|
3887
|
+
key: id,
|
|
3888
|
+
label,
|
|
3889
|
+
required,
|
|
3890
|
+
controlType,
|
|
3891
|
+
type: 'text',
|
|
3892
|
+
options: options ?? [],
|
|
3893
|
+
disabled: disabled ?? false,
|
|
3894
|
+
placeholder: placeholder,
|
|
3895
|
+
});
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
class FormValueUtil {
|
|
3900
|
+
static getFormDataEntities(formValueEntities) {
|
|
3901
|
+
const formValueKeys = Object.keys(formValueEntities);
|
|
3902
|
+
return formValueKeys.reduce((entity, key) => {
|
|
3903
|
+
const formValue = formValueEntities[key];
|
|
3904
|
+
const formRawValues = formValue.form.getRawValue() || {};
|
|
3905
|
+
const dataValueEntities = Object.keys(formRawValues).reduce((valueObject, key) => {
|
|
3906
|
+
const field = formValue.fields.find((field) => field.id === key);
|
|
3907
|
+
if (!field) {
|
|
3908
|
+
return valueObject;
|
|
3909
|
+
}
|
|
3910
|
+
return {
|
|
3911
|
+
...valueObject,
|
|
3912
|
+
[key]: {
|
|
3913
|
+
...field,
|
|
3914
|
+
value: formRawValues[key],
|
|
3915
|
+
attribute: field?.isAttribute ? field.id : undefined,
|
|
3916
|
+
dataElement: field?.isDataElement ? field.id : undefined,
|
|
3917
|
+
},
|
|
3918
|
+
};
|
|
3919
|
+
}, {});
|
|
3920
|
+
return { ...entity, ...dataValueEntities };
|
|
3921
|
+
}, {});
|
|
3922
|
+
}
|
|
3923
|
+
}
|
|
3924
|
+
|
|
3925
|
+
class TranslationUtil {
|
|
3926
|
+
static getTranslatedFormName(field, locale = 'sw') {
|
|
3927
|
+
const translation = (field['translations'] || []).find((translation) => translation['locale'] == locale && translation['property'] == 'NAME');
|
|
3928
|
+
return (translation ? translation['value'] : field['formName'] || field['name']);
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3932
|
+
// Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
|
|
3933
|
+
// Use of this source code is governed by a BSD-style
|
|
3934
|
+
// license that can be found in the LICENSE file.
|
|
3935
|
+
class FormFieldGroup {
|
|
3936
|
+
constructor(params) {
|
|
3937
|
+
this.params = params;
|
|
3938
|
+
}
|
|
3939
|
+
get fields() {
|
|
3940
|
+
const fields = this.params.formFieldGroup?.fields || [];
|
|
3941
|
+
return fields
|
|
3942
|
+
.map((field) => {
|
|
3943
|
+
if (field instanceof FormField) {
|
|
3944
|
+
return field;
|
|
3945
|
+
}
|
|
3946
|
+
const fieldMetaData = this.params.fieldMetaData.find((attribute) => attribute['id'] === field.id);
|
|
3947
|
+
if (!fieldMetaData) {
|
|
3948
|
+
return null;
|
|
3949
|
+
}
|
|
3950
|
+
const dependentField = find(fields, [
|
|
3951
|
+
'id',
|
|
3952
|
+
field?.fieldOptionsDependsOn,
|
|
3953
|
+
]);
|
|
3954
|
+
const options = FieldDropdown.getDropdownOptions(fieldMetaData, this.params.locale);
|
|
3955
|
+
const hasOptions = (options?.length > 0 ||
|
|
3956
|
+
dependentField !== undefined ||
|
|
3957
|
+
fieldMetaData['hasOptions']);
|
|
3958
|
+
return new FormField({
|
|
3959
|
+
...(fieldMetaData || {}),
|
|
3960
|
+
...field,
|
|
3961
|
+
id: field.id,
|
|
3962
|
+
code: fieldMetaData['code'],
|
|
3963
|
+
label: (fieldMetaData['formName'] ?? field['label']),
|
|
3964
|
+
key: camelCase(fieldMetaData['code']) || field.id,
|
|
3965
|
+
required: (fieldMetaData['mandatory'] ??
|
|
3966
|
+
fieldMetaData['required']),
|
|
3967
|
+
type: FieldUtil.getFieldType(fieldMetaData['valueType']),
|
|
3968
|
+
dependentField,
|
|
3969
|
+
options,
|
|
3970
|
+
disabled: field.disabled ?? fieldMetaData['disabled'],
|
|
3971
|
+
min: field.min ?? fieldMetaData['min'],
|
|
3972
|
+
max: field.max ?? fieldMetaData['max'],
|
|
3973
|
+
order: field.order ??
|
|
3974
|
+
(fieldMetaData['order'] ?? fieldMetaData['sortOrder']),
|
|
3975
|
+
hidden: field.hidden ?? fieldMetaData['hidden'],
|
|
3976
|
+
fieldOptionsDependsOn: field.fieldOptionsDependsOn,
|
|
3977
|
+
hasOptions,
|
|
3978
|
+
controlType: FieldUtil.getFieldControlType(fieldMetaData['valueType'], hasOptions),
|
|
3979
|
+
metaType: fieldMetaData['metaType'],
|
|
3980
|
+
stepId: fieldMetaData['stepId'],
|
|
3981
|
+
});
|
|
3982
|
+
})
|
|
3983
|
+
.filter((field) => field);
|
|
3984
|
+
}
|
|
3985
|
+
toJson() {
|
|
3986
|
+
return {
|
|
3987
|
+
id: this.params.formFieldGroup?.id,
|
|
3988
|
+
name: TranslationUtil.getTranslatedFormName(this.params.formFieldGroup, this.params.locale),
|
|
3989
|
+
isFormHorizontal: this.params.formFieldGroup?.isFormHorizontal,
|
|
3990
|
+
repeatDependentField: this.params.formFieldGroup?.repeatDependentField,
|
|
3991
|
+
dataKey: this.params.formFieldGroup?.dataKey,
|
|
3992
|
+
repeatableStage: this.params.formFieldGroup?.repeatableStage,
|
|
3993
|
+
fields: this.fields,
|
|
3994
|
+
};
|
|
3995
|
+
}
|
|
3996
|
+
}
|
|
3997
|
+
|
|
3998
|
+
class MetadataRuleAction {
|
|
3999
|
+
constructor(ruleAction) {
|
|
4000
|
+
this.ruleAction = ruleAction;
|
|
4001
|
+
}
|
|
4002
|
+
get field() {
|
|
4003
|
+
return (this.ruleAction.dataElement?.id ||
|
|
4004
|
+
this.ruleAction.trackedEntityAttribute?.id);
|
|
4005
|
+
}
|
|
4006
|
+
get actionType() {
|
|
4007
|
+
return this.ruleAction.programRuleActionType;
|
|
4008
|
+
}
|
|
4009
|
+
toJson() {
|
|
4010
|
+
return {
|
|
4011
|
+
field: this.field,
|
|
4012
|
+
actionType: this.actionType,
|
|
4013
|
+
};
|
|
4014
|
+
}
|
|
4015
|
+
}
|
|
4016
|
+
class MetadataRule {
|
|
4017
|
+
constructor(rule, ruleVariables) {
|
|
4018
|
+
this.rule = rule;
|
|
4019
|
+
this.ruleVariables = ruleVariables;
|
|
4020
|
+
}
|
|
4021
|
+
get actions() {
|
|
4022
|
+
return (this.rule?.programRuleActions || []).map((action) => new MetadataRuleAction(action));
|
|
4023
|
+
}
|
|
4024
|
+
get condition() {
|
|
4025
|
+
const regex = /(A|#)\{([^}]+)\}/g;
|
|
4026
|
+
return this.rule?.condition?.replace(regex, (match, _, ruleVariable) => {
|
|
4027
|
+
const ruleVariableObject = this.ruleVariables?.find((variable) => variable.name === ruleVariable);
|
|
4028
|
+
const code = camelCase(ruleVariableObject?.dataElement?.code) ||
|
|
4029
|
+
ruleVariableObject?.dataElement?.id ||
|
|
4030
|
+
camelCase(ruleVariableObject?.trackedEntityAttribute?.code) ||
|
|
4031
|
+
ruleVariableObject?.trackedEntityAttribute?.id;
|
|
4032
|
+
return `{${code}}`;
|
|
4033
|
+
});
|
|
4034
|
+
}
|
|
4035
|
+
toJson() {
|
|
4036
|
+
return {
|
|
4037
|
+
actions: this.actions.map((action) => action.toJson()),
|
|
4038
|
+
condition: this.condition,
|
|
4039
|
+
};
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
|
|
4043
|
+
class FormMetadataSection {
|
|
4044
|
+
constructor(params) {
|
|
4045
|
+
this.params = params;
|
|
4046
|
+
}
|
|
4047
|
+
get attributes() {
|
|
4048
|
+
return (this.params.program['programTrackedEntityAttributes'] || []).map((programTrackedEntityAttribute) => {
|
|
4049
|
+
return {
|
|
4050
|
+
...programTrackedEntityAttribute['trackedEntityAttribute'],
|
|
4051
|
+
formName: (programTrackedEntityAttribute['trackedEntityAttribute'] || {})['name'],
|
|
4052
|
+
sortOrder: programTrackedEntityAttribute['sortOrder'],
|
|
4053
|
+
mandatory: programTrackedEntityAttribute['mandatory'],
|
|
4054
|
+
metaType: 'ATTRIBUTE',
|
|
4055
|
+
};
|
|
4056
|
+
});
|
|
4057
|
+
}
|
|
4058
|
+
get dataElements() {
|
|
4059
|
+
return flatten((this.params.program['programStages'] ||
|
|
4060
|
+
[]).map((programStage) => {
|
|
4061
|
+
return (programStage['programStageDataElements'] || []).map((stageDataElement) => {
|
|
4062
|
+
return {
|
|
4063
|
+
...(stageDataElement['dataElement'] ||
|
|
4064
|
+
{}),
|
|
4065
|
+
mandatory: stageDataElement['compulsory'],
|
|
4066
|
+
stepId: programStage['id'],
|
|
4067
|
+
metaType: 'DATA_ELEMENT',
|
|
4068
|
+
};
|
|
4069
|
+
});
|
|
4070
|
+
}));
|
|
4071
|
+
}
|
|
4072
|
+
get fieldGroups() {
|
|
4073
|
+
return (this.params.section.fieldGroups || []).map((formFieldGroup) => {
|
|
4074
|
+
return new FormFieldGroup({
|
|
4075
|
+
formFieldGroup,
|
|
4076
|
+
fieldMetaData: [...this.attributes, ...this.dataElements],
|
|
4077
|
+
locale: this.params.locale,
|
|
4078
|
+
}).toJson();
|
|
4079
|
+
});
|
|
4080
|
+
}
|
|
4081
|
+
toJson() {
|
|
4082
|
+
return {
|
|
4083
|
+
id: this.params.section?.id,
|
|
4084
|
+
name: this.params.section?.name,
|
|
4085
|
+
fieldGroups: this.fieldGroups,
|
|
4086
|
+
};
|
|
4087
|
+
}
|
|
4088
|
+
}
|
|
4089
|
+
|
|
4090
|
+
class FormMetaData {
|
|
4091
|
+
constructor(params) {
|
|
4092
|
+
this.params = params;
|
|
4093
|
+
}
|
|
4094
|
+
get sections() {
|
|
4095
|
+
const customSections = this.params.customFormMetaData?.sections;
|
|
4096
|
+
if (!customSections) {
|
|
4097
|
+
return this.#getSectionFromPrograms(this.params.programs);
|
|
4098
|
+
}
|
|
4099
|
+
return (this.params.customFormMetaData?.sections || [])
|
|
4100
|
+
.map((section) => {
|
|
4101
|
+
const program = this.params.programs.find((program) => section.program === program['id']);
|
|
4102
|
+
if (!program) {
|
|
4103
|
+
return null;
|
|
4104
|
+
}
|
|
4105
|
+
return new FormMetadataSection({
|
|
4106
|
+
section,
|
|
4107
|
+
program,
|
|
4108
|
+
locale: this.params.locale,
|
|
4109
|
+
}).toJson();
|
|
4110
|
+
})
|
|
4111
|
+
.filter((section) => section !== null);
|
|
4112
|
+
}
|
|
4113
|
+
get fields() {
|
|
4114
|
+
return flatten(flatten(this.sections.map((section) => section.fieldGroups.map((fieldGroup) => fieldGroup.fields || []))));
|
|
4115
|
+
}
|
|
4116
|
+
get rules() {
|
|
4117
|
+
let ruleVariables = [];
|
|
4118
|
+
return [
|
|
4119
|
+
...(this.params.customFormMetaData?.rules || []),
|
|
4120
|
+
...(flatten(this.params.programs.map((program) => {
|
|
4121
|
+
ruleVariables = [
|
|
4122
|
+
...ruleVariables,
|
|
4123
|
+
...program.programRuleVariables,
|
|
4124
|
+
];
|
|
4125
|
+
return program.programRules;
|
|
4126
|
+
})) || []).map((rule) => new MetadataRule(rule, ruleVariables).toJson()),
|
|
4127
|
+
];
|
|
4128
|
+
}
|
|
4129
|
+
#getSectionFromPrograms(programs) {
|
|
4130
|
+
const sections = flatten(programs.map((program) => {
|
|
4131
|
+
return [
|
|
4132
|
+
this.#getReportingDetailsSection(program),
|
|
4133
|
+
new FormMetadataSection({
|
|
4134
|
+
section: {
|
|
4135
|
+
id: 'registration',
|
|
4136
|
+
name: 'Registration',
|
|
4137
|
+
fieldGroups: (program.programSections || []).length > 0
|
|
4138
|
+
? program.programSections.map((programSection) => {
|
|
4139
|
+
return {
|
|
4140
|
+
id: programSection.id,
|
|
4141
|
+
name: programSection.name,
|
|
4142
|
+
sortOrder: programSection.sortOrder,
|
|
4143
|
+
fields: programSection.trackedEntityAttributes,
|
|
4144
|
+
};
|
|
4145
|
+
})
|
|
4146
|
+
: [
|
|
4147
|
+
{
|
|
4148
|
+
id: 'registration',
|
|
4149
|
+
name: '',
|
|
4150
|
+
sortOrder: 1,
|
|
4151
|
+
fields: (program.programTrackedEntityAttributes || []).map((programTrackedEntityAttribute) => {
|
|
4152
|
+
return {
|
|
4153
|
+
id: programTrackedEntityAttribute
|
|
4154
|
+
.trackedEntityAttribute?.id,
|
|
4155
|
+
};
|
|
4156
|
+
}),
|
|
4157
|
+
},
|
|
4158
|
+
],
|
|
4159
|
+
},
|
|
4160
|
+
program,
|
|
4161
|
+
locale: this.params.locale,
|
|
4162
|
+
}).toJson(),
|
|
4163
|
+
...(program.programStages || []).map((programStage) => {
|
|
4164
|
+
return new FormMetadataSection({
|
|
4165
|
+
section: {
|
|
4166
|
+
id: programStage.id,
|
|
4167
|
+
name: programStage.name,
|
|
4168
|
+
fieldGroups: (programStage.programStageSections || []).length > 0
|
|
4169
|
+
? programStage.programStageSections.map((programStageSection) => {
|
|
4170
|
+
return {
|
|
4171
|
+
id: programStageSection.id,
|
|
4172
|
+
name: programStageSection.name,
|
|
4173
|
+
dataKey: camelCase(programStage.code),
|
|
4174
|
+
repeatableStage: programStage.repeatable
|
|
4175
|
+
? programStage.id
|
|
4176
|
+
: undefined,
|
|
4177
|
+
sortOrder: programStageSection.sortOrder,
|
|
4178
|
+
fields: programStageSection.dataElements,
|
|
4179
|
+
};
|
|
4180
|
+
})
|
|
4181
|
+
: [
|
|
4182
|
+
{
|
|
4183
|
+
id: programStage.id,
|
|
4184
|
+
dataKey: camelCase(programStage.code),
|
|
4185
|
+
repeatableStage: programStage.repeatable
|
|
4186
|
+
? programStage.id
|
|
4187
|
+
: undefined,
|
|
4188
|
+
fields: (programStage.programStageDataElements || []).map((programStageDataElement) => {
|
|
4189
|
+
return {
|
|
4190
|
+
id: programStageDataElement.dataElement?.id,
|
|
4191
|
+
};
|
|
4192
|
+
}),
|
|
4193
|
+
},
|
|
4194
|
+
],
|
|
4195
|
+
},
|
|
4196
|
+
program,
|
|
4197
|
+
locale: this.params.locale,
|
|
4198
|
+
}).toJson();
|
|
4199
|
+
}),
|
|
4200
|
+
];
|
|
4201
|
+
}));
|
|
4202
|
+
if (sections.length === 0) {
|
|
4203
|
+
return [];
|
|
4204
|
+
}
|
|
4205
|
+
return sections;
|
|
4206
|
+
}
|
|
4207
|
+
#getReportingDetailsSection(program) {
|
|
4208
|
+
return new FormMetadataSection({
|
|
4209
|
+
section: {
|
|
4210
|
+
id: 'reporting_details',
|
|
4211
|
+
name: 'Reporting details',
|
|
4212
|
+
fieldGroups: [
|
|
4213
|
+
{
|
|
4214
|
+
id: 'reporting_details',
|
|
4215
|
+
sortOrder: 1,
|
|
4216
|
+
isFormHorizontal: true,
|
|
4217
|
+
fields: [
|
|
4218
|
+
new FormField({
|
|
4219
|
+
id: 'orgUnit',
|
|
4220
|
+
key: 'orgUnit',
|
|
4221
|
+
label: 'Organisation unit',
|
|
4222
|
+
code: 'orgUnit',
|
|
4223
|
+
required: true,
|
|
4224
|
+
controlType: 'org-unit',
|
|
4225
|
+
}),
|
|
4226
|
+
new DateField({
|
|
4227
|
+
id: 'enrollmentDate',
|
|
4228
|
+
label: program.enrollmentDateLabel || 'Enrollment date',
|
|
4229
|
+
code: 'enrollmentDate',
|
|
4230
|
+
key: 'enrollmentDate',
|
|
4231
|
+
required: true,
|
|
4232
|
+
}),
|
|
4233
|
+
program.displayIncidentDate
|
|
4234
|
+
? new DateField({
|
|
4235
|
+
id: 'incidentDate',
|
|
4236
|
+
label: program.incidentDateLabel || 'Incident date',
|
|
4237
|
+
code: 'incidentDate',
|
|
4238
|
+
key: 'incidentDate',
|
|
4239
|
+
required: true,
|
|
4240
|
+
})
|
|
4241
|
+
: null,
|
|
4242
|
+
].filter((field) => field),
|
|
4243
|
+
},
|
|
4244
|
+
],
|
|
4245
|
+
},
|
|
4246
|
+
program,
|
|
4247
|
+
locale: this.params.locale,
|
|
4248
|
+
}).toJson();
|
|
4249
|
+
}
|
|
4250
|
+
toJson() {
|
|
4251
|
+
return {
|
|
4252
|
+
id: this.params.customFormMetaData?.id,
|
|
4253
|
+
name: TranslationUtil.getTranslatedFormName(this.params.customFormMetaData || {}, this.params.locale),
|
|
4254
|
+
fields: this.fields,
|
|
4255
|
+
sections: this.sections,
|
|
4256
|
+
rules: this.rules,
|
|
4257
|
+
};
|
|
4258
|
+
}
|
|
4259
|
+
}
|
|
4260
|
+
|
|
4261
|
+
class FormValue {
|
|
4262
|
+
constructor(form, fields, changedField) {
|
|
4263
|
+
this.form = form;
|
|
4264
|
+
this.fields = fields;
|
|
4265
|
+
this.changedField = changedField;
|
|
4266
|
+
}
|
|
4267
|
+
get isValid() {
|
|
4268
|
+
return this.form.valid;
|
|
4269
|
+
}
|
|
4270
|
+
clear() {
|
|
4271
|
+
this.form.reset();
|
|
4272
|
+
}
|
|
4273
|
+
getValues(options) {
|
|
4274
|
+
const newValues = {};
|
|
4275
|
+
const formValues = this.form?.getRawValue();
|
|
4276
|
+
if (options?.valueOnly) {
|
|
4277
|
+
return formValues;
|
|
4278
|
+
}
|
|
4279
|
+
Object.keys(formValues).forEach((key) => {
|
|
4280
|
+
const field = find(this.fields, ['key', key]);
|
|
4281
|
+
if (field) {
|
|
4282
|
+
newValues[key] = {
|
|
4283
|
+
...field,
|
|
4284
|
+
value: formValues[key],
|
|
4285
|
+
};
|
|
4286
|
+
}
|
|
4287
|
+
});
|
|
4288
|
+
return newValues;
|
|
4289
|
+
}
|
|
4290
|
+
}
|
|
4291
|
+
|
|
4292
|
+
// Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
|
|
4293
|
+
// Use of this source code is governed by a BSD-style
|
|
4294
|
+
// license that can be found in the LICENSE file.
|
|
4295
|
+
|
|
4296
|
+
// Copyright 2024 UDSM DHIS2 Lab. All rights reserved.
|
|
4297
|
+
// Use of this source code is governed by a BSD-style
|
|
4298
|
+
// license that can be found in the LICENSE file.
|
|
4299
|
+
class BaseFormFieldComponent extends ReactWrapperModule {
|
|
4300
|
+
constructor() {
|
|
4301
|
+
super(...arguments);
|
|
4302
|
+
this.ngZone = inject(NgZone);
|
|
4303
|
+
this.httpClient = inject(NgxDhis2HttpClientService);
|
|
4304
|
+
this.fieldType = 'textbox';
|
|
4305
|
+
this.field = input.required();
|
|
4306
|
+
this.fieldConfig = input(new FieldConfig());
|
|
4307
|
+
this.form = model.required();
|
|
4308
|
+
this.isValid = input();
|
|
4309
|
+
this.uploadedFiles = [];
|
|
4310
|
+
this.value = model();
|
|
4311
|
+
this.value$ = toObservable(this.value);
|
|
4312
|
+
this.FieldOrgUnitSelector = (props) => {
|
|
4313
|
+
const { onSelectOrgUnit, onCancelOrgUnit } = props;
|
|
4314
|
+
const [selected, setSelected] = useState([]);
|
|
4315
|
+
const [rootOrgUnits, setRootOrgUnits] = useState();
|
|
4316
|
+
const [config, setConfig] = useState();
|
|
4317
|
+
useEffect(() => {
|
|
4318
|
+
zip(this.getAppConfig(), this.getRootOrgUnits()).subscribe({
|
|
4319
|
+
next: ([appConfig, rootOrgUnits]) => {
|
|
4320
|
+
setConfig(appConfig);
|
|
4321
|
+
setRootOrgUnits(rootOrgUnits);
|
|
4322
|
+
},
|
|
4323
|
+
error: (error) => console.error(error),
|
|
4324
|
+
});
|
|
4325
|
+
}, []);
|
|
4326
|
+
return config ? (React__default.createElement(Provider, { config: config, plugin: false, parentAlertsAdd: undefined, showAlertsInPlugin: false }, React__default.createElement(Modal$1, { position: "middle", large: true },
|
|
4327
|
+
React__default.createElement(ModalTitle$1, null, "Organisation unit"),
|
|
4328
|
+
React__default.createElement(ModalContent$1, null,
|
|
4329
|
+
React__default.createElement(OrgUnitDimension, { selected: selected, hideGroupSelect: this.orgUnitSelectionConfig.hideGroupSelect, hideLevelSelect: this.orgUnitSelectionConfig.hideLevelSelect, hideUserOrgUnits: this.orgUnitSelectionConfig.hideUserOrgUnits, onSelect: (selectionEvent) => {
|
|
4330
|
+
setSelected(selectionEvent.items);
|
|
4331
|
+
}, orgUnitGroupPromise: this.getOrgUnitGroups(), orgUnitLevelPromise: this.getOrgUnitLevels(), roots: rootOrgUnits })),
|
|
4332
|
+
React__default.createElement(ModalActions$1, null,
|
|
4333
|
+
React__default.createElement(ButtonStrip$1, { end: true },
|
|
4334
|
+
React__default.createElement(Button$1, { onClick: () => {
|
|
4335
|
+
onCancelOrgUnit();
|
|
4336
|
+
} }, "Cancel"),
|
|
4337
|
+
React__default.createElement(Button$1, { primary: true, disabled: selected.length === 0, onClick: () => {
|
|
4338
|
+
onSelectOrgUnit(selected);
|
|
4339
|
+
} }, "Confirm")))))) : (React__default.createElement(CircularLoader$1, { small: true }));
|
|
4340
|
+
};
|
|
4341
|
+
this.showOrgUnitTree = signal(false);
|
|
4342
|
+
this.orgUnitSelectionConfig = {
|
|
4343
|
+
hideGroupSelect: true,
|
|
4344
|
+
hideLevelSelect: true,
|
|
4345
|
+
hideUserOrgUnits: true,
|
|
4346
|
+
allowSingleSelection: true,
|
|
4347
|
+
usageType: 'DATA_ENTRY',
|
|
4348
|
+
};
|
|
4349
|
+
this.selectedOrgUnit = signal(null);
|
|
4350
|
+
this.selectedOrgUnit$ = toObservable(this.selectedOrgUnit);
|
|
4351
|
+
this.label = computed(() => {
|
|
4352
|
+
return !this.fieldConfig()?.hideLabel ? this.field().label : undefined;
|
|
4353
|
+
});
|
|
4354
|
+
this.placeholder = computed(() => {
|
|
4355
|
+
return (this.field()?.placeholder || `Enter ${this.field()?.label || 'value'}`);
|
|
4356
|
+
});
|
|
4357
|
+
this.InputField = this.#getInputField();
|
|
4358
|
+
this.update = new EventEmitter();
|
|
4359
|
+
this.immediateUpdate = new EventEmitter();
|
|
4360
|
+
}
|
|
4361
|
+
async ngAfterViewInit() {
|
|
4362
|
+
if (!this.elementRef)
|
|
4363
|
+
throw new Error('No element ref');
|
|
4364
|
+
this.reactDomRoot = ReactDOM.createRoot(this.elementRef.nativeElement);
|
|
4365
|
+
this.component = this.InputField;
|
|
4366
|
+
this.render();
|
|
4367
|
+
}
|
|
4368
|
+
ngOnChanges(changes) {
|
|
4369
|
+
if (!(changes['field'] || {})?.firstChange) {
|
|
4370
|
+
this.InputField = this.#getInputField();
|
|
4371
|
+
this.component = this.#getInputField();
|
|
4372
|
+
this.render();
|
|
4373
|
+
}
|
|
4374
|
+
}
|
|
4375
|
+
#getInputField() {
|
|
4376
|
+
return () => {
|
|
4377
|
+
const [value, setValue] = useState(this.form().get(this.field().id)?.value ||
|
|
4378
|
+
this.form().get(this.field().key)?.value);
|
|
4379
|
+
const [displayValue, setDisplayValue] = useState(null);
|
|
4380
|
+
const [selected, setSelected] = useState();
|
|
4381
|
+
const [touched, setTouched] = useState(false);
|
|
4382
|
+
const [showOrgUnit, setShowOrgUnit] = useState(false);
|
|
4383
|
+
const onChange = (payload) => setSelected(payload.selected);
|
|
4384
|
+
const hasError = useMemo(() => {
|
|
4385
|
+
return (touched &&
|
|
4386
|
+
(this.form().get(this.field().id) ||
|
|
4387
|
+
this.form().get(this.field().key))?.invalid);
|
|
4388
|
+
}, [value, touched]);
|
|
4389
|
+
const validationError = useMemo(() => {
|
|
4390
|
+
if (!touched) {
|
|
4391
|
+
return undefined;
|
|
4392
|
+
}
|
|
4393
|
+
const field = this.field();
|
|
4394
|
+
const error = (this.form().get(field.id) || this.form().get(field.key))
|
|
4395
|
+
?.errors;
|
|
4396
|
+
if (!error) {
|
|
4397
|
+
return undefined;
|
|
4398
|
+
}
|
|
4399
|
+
if (error['min']) {
|
|
4400
|
+
return `${this.label() || 'Value'} should not be less than ${error['min'].min}!`;
|
|
4401
|
+
}
|
|
4402
|
+
else if (error['max']) {
|
|
4403
|
+
return `${this.label() || 'Value'} should not be greater than ${error['max'].max}!`;
|
|
4404
|
+
}
|
|
4405
|
+
else if (error['pattern']) {
|
|
4406
|
+
if (field.type === 'email') {
|
|
4407
|
+
return `The email address provided is not valid`;
|
|
4408
|
+
}
|
|
4409
|
+
else if (field.type === 'tel') {
|
|
4410
|
+
return 'Phone number provided is not valid';
|
|
4411
|
+
}
|
|
4412
|
+
else {
|
|
4413
|
+
return `${this.label() || 'Value'} should have appropriate format`;
|
|
4414
|
+
}
|
|
4415
|
+
}
|
|
4416
|
+
return error['required']
|
|
4417
|
+
? `${this.label() || 'Value'} is required`
|
|
4418
|
+
: undefined;
|
|
4419
|
+
}, [hasError]);
|
|
4420
|
+
switch (this.field().controlType) {
|
|
4421
|
+
case 'textarea':
|
|
4422
|
+
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) => {
|
|
4423
|
+
this.ngZone.run(() => {
|
|
4424
|
+
(this.form().get(this.field().id) ||
|
|
4425
|
+
this.form().get(this.field().key))?.setValue(event.value);
|
|
4426
|
+
this.immediateUpdate.emit({
|
|
4427
|
+
form: this.form(),
|
|
4428
|
+
value: event.value,
|
|
4429
|
+
});
|
|
4430
|
+
});
|
|
4431
|
+
setValue(event.value);
|
|
4432
|
+
setTouched(true);
|
|
4433
|
+
}, onBlur: () => {
|
|
4434
|
+
this.ngZone.run(() => {
|
|
4435
|
+
this.update.emit({ form: this.form(), value });
|
|
4436
|
+
});
|
|
4437
|
+
} }));
|
|
4438
|
+
case 'org-unit':
|
|
4439
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
4440
|
+
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: () => {
|
|
4441
|
+
setShowOrgUnit(true);
|
|
4442
|
+
}, onBlur: () => {
|
|
4443
|
+
this.ngZone.run(() => {
|
|
4444
|
+
this.update.emit({ form: this.form(), value });
|
|
4445
|
+
});
|
|
4446
|
+
setTouched(true);
|
|
4447
|
+
} }),
|
|
4448
|
+
showOrgUnit && (React__default.createElement(this.FieldOrgUnitSelector, { onCancelOrgUnit: () => {
|
|
4449
|
+
setShowOrgUnit(false);
|
|
4450
|
+
setTouched(true);
|
|
4451
|
+
}, onSelectOrgUnit: (selectedOrgUnits) => {
|
|
4452
|
+
if ((selectedOrgUnits || [])[0]) {
|
|
4453
|
+
const selectedOrgUnit = selectedOrgUnits[0];
|
|
4454
|
+
setDisplayValue(selectedOrgUnit.name);
|
|
4455
|
+
setValue(selectedOrgUnit.id);
|
|
4456
|
+
setShowOrgUnit(false);
|
|
4457
|
+
setTouched(true);
|
|
4458
|
+
this.ngZone.run(() => {
|
|
4459
|
+
(this.form().get(this.field().id) ||
|
|
4460
|
+
this.form().get(this.field().key))?.setValue(selectedOrgUnit.id);
|
|
4461
|
+
this.immediateUpdate.emit({
|
|
4462
|
+
form: this.form(),
|
|
4463
|
+
value: selectedOrgUnit.id,
|
|
4464
|
+
});
|
|
4465
|
+
});
|
|
4466
|
+
}
|
|
4467
|
+
} }))));
|
|
4468
|
+
case 'transfer':
|
|
4469
|
+
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: {
|
|
4470
|
+
fontSize: 14,
|
|
4471
|
+
padding: '8px 4px',
|
|
4472
|
+
} }, this.field().availableOptionsLabel), rightHeader: React__default.createElement("div", { style: {
|
|
4473
|
+
fontSize: 14,
|
|
4474
|
+
padding: '8px 4px',
|
|
4475
|
+
} }, this.field().selectedOptionsLabel), options: this.field().options, onChange: (event) => {
|
|
4476
|
+
onChange({ selected: event.selected });
|
|
4477
|
+
this.ngZone.run(() => {
|
|
4478
|
+
(this.form().get(this.field().id) ||
|
|
4479
|
+
this.form().get(this.field().key))?.setValue(event.selected);
|
|
4480
|
+
});
|
|
4481
|
+
setValue(event.selected);
|
|
4482
|
+
setTouched(true);
|
|
4483
|
+
this.update.emit({ form: this.form(), value });
|
|
4484
|
+
} }));
|
|
4485
|
+
case 'checkbox':
|
|
4486
|
+
return (React__default.createElement(Checkbox, { checked: Boolean(value), error: hasError, label: this.label(), name: this.field().id, onChange: (event) => {
|
|
4487
|
+
this.ngZone.run(() => {
|
|
4488
|
+
(this.form().get(this.field().id) ||
|
|
4489
|
+
this.form().get(this.field().key))?.setValue(event.checked);
|
|
4490
|
+
});
|
|
4491
|
+
setValue(event.checked);
|
|
4492
|
+
setTouched(true);
|
|
4493
|
+
}, onBlur: () => {
|
|
4494
|
+
this.ngZone.run(() => {
|
|
4495
|
+
this.update.emit({ form: this.form(), value });
|
|
4496
|
+
});
|
|
4497
|
+
} }));
|
|
4498
|
+
case 'dropdown':
|
|
4499
|
+
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) => {
|
|
4500
|
+
this.ngZone.run(() => {
|
|
4501
|
+
(this.form().get(this.field().id) ||
|
|
4502
|
+
this.form().get(this.field().key))?.setValue(event.selected);
|
|
4503
|
+
this.update.emit({
|
|
4504
|
+
form: this.form(),
|
|
4505
|
+
value: event.selected,
|
|
4506
|
+
});
|
|
4507
|
+
});
|
|
4508
|
+
setValue(event.selected);
|
|
4509
|
+
setTouched(true);
|
|
4510
|
+
} }, (this.field().options || []).map((option) => (React__default.createElement(SingleSelectOption, { key: option.key, label: option.label, value: option.value })))));
|
|
4511
|
+
case 'file':
|
|
4512
|
+
return (React__default.createElement(FileInputField, { accept: "*", buttonLabel: "Upload a file", label: this.label(), name: this.field().id, files: this.uploadedFiles, onChange: (event) => {
|
|
4513
|
+
this.uploadedFiles.push((event?.files || [])[0]);
|
|
4514
|
+
this.ngZone.run(() => {
|
|
4515
|
+
this.form().get(this.field().id) ||
|
|
4516
|
+
this.form()
|
|
4517
|
+
.get(this.field().key)
|
|
4518
|
+
?.setValue((event?.files || [])[0]);
|
|
4519
|
+
this.update.emit({
|
|
4520
|
+
form: this.form(),
|
|
4521
|
+
value: (event?.files || [])[0],
|
|
4522
|
+
});
|
|
4523
|
+
});
|
|
4524
|
+
setValue((event?.files || [])[0]);
|
|
4525
|
+
setTouched(true);
|
|
4526
|
+
} }, this.uploadedFiles.map((file, index) => (React__default.createElement(FileListItem, { key: index, cancelText: "Cancel", label: file.name, onCancel: () => { }, onRemove: () => {
|
|
4527
|
+
this.ngZone.run(() => {
|
|
4528
|
+
this.uploadedFiles.splice(index, 1);
|
|
4529
|
+
setValue(this.uploadedFiles);
|
|
4530
|
+
setTouched(true);
|
|
4531
|
+
});
|
|
4532
|
+
}, removeText: "Remove" })))));
|
|
4533
|
+
default:
|
|
4534
|
+
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) => {
|
|
4535
|
+
this.ngZone.run(() => {
|
|
4536
|
+
(this.form().get(this.field().id) ||
|
|
4537
|
+
this.form().get(this.field().key))?.setValue(event.value);
|
|
4538
|
+
this.immediateUpdate.emit({
|
|
4539
|
+
form: this.form(),
|
|
4540
|
+
value: event.value,
|
|
4541
|
+
});
|
|
4542
|
+
});
|
|
4543
|
+
setValue(event.value);
|
|
4544
|
+
setTouched(true);
|
|
4545
|
+
}, onBlur: () => {
|
|
4546
|
+
this.ngZone.run(() => {
|
|
4547
|
+
this.update.emit({ form: this.form(), value });
|
|
4548
|
+
});
|
|
4549
|
+
} }));
|
|
4550
|
+
}
|
|
4551
|
+
};
|
|
4552
|
+
}
|
|
4553
|
+
onChange(event) {
|
|
4554
|
+
this.value.set(event);
|
|
4555
|
+
}
|
|
4556
|
+
onSelectOrgUnit(selectedOrgUnits) {
|
|
4557
|
+
this.showOrgUnitTree.set(false);
|
|
4558
|
+
if ((selectedOrgUnits || [])[0]) {
|
|
4559
|
+
this.selectedOrgUnit.set(selectedOrgUnits[0]);
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4562
|
+
onCancelOrgUnit() {
|
|
4563
|
+
this.showOrgUnitTree.set(false);
|
|
4564
|
+
}
|
|
4565
|
+
getAppConfig() {
|
|
4566
|
+
return this.httpClient.systemInfo().pipe(map((response) => {
|
|
4567
|
+
const systemInfo = response;
|
|
4568
|
+
return {
|
|
4569
|
+
baseUrl: (document?.location?.host?.includes('localhost')
|
|
4570
|
+
? `${document.location.protocol}//${document.location.host}`
|
|
4571
|
+
: systemInfo['contextPath']),
|
|
4572
|
+
apiVersion: Number(((systemInfo['version'] || '')?.split('.') || [])[1]),
|
|
4573
|
+
};
|
|
4574
|
+
}));
|
|
4575
|
+
}
|
|
4576
|
+
getOrgUnitAttributeByUsage(usageType) {
|
|
4577
|
+
switch (usageType) {
|
|
4578
|
+
case 'DATA_ENTRY':
|
|
4579
|
+
return 'organisationUnits';
|
|
4580
|
+
case 'DATA_VIEW':
|
|
4581
|
+
return 'dataViewOrganisationUnits';
|
|
4582
|
+
default:
|
|
4583
|
+
return 'organisationUnits';
|
|
4584
|
+
}
|
|
4585
|
+
}
|
|
4586
|
+
getRootOrgUnits() {
|
|
4587
|
+
const orgUnitAttribute = this.getOrgUnitAttributeByUsage(this.orgUnitSelectionConfig.usageType);
|
|
4588
|
+
return this.httpClient
|
|
4589
|
+
.me()
|
|
4590
|
+
.pipe(map((user) => (user ? user[orgUnitAttribute] : []).map((orgUnit) => orgUnit.id)));
|
|
4591
|
+
}
|
|
4592
|
+
getOrgUnitGroups() {
|
|
4593
|
+
return firstValueFrom(this.httpClient
|
|
4594
|
+
.get('organisationUnitGroups.json?fields=id,displayName,name&paging=false')
|
|
4595
|
+
.pipe(map((res) => res?.['organisationUnitGroups'])));
|
|
4596
|
+
}
|
|
4597
|
+
getOrgUnitLevels() {
|
|
4598
|
+
return firstValueFrom(this.httpClient
|
|
4599
|
+
.get('organisationUnitLevels.json?fields=id,level,displayName,name&paging=false')
|
|
4600
|
+
.pipe(map((res) => res?.['organisationUnitLevels'])));
|
|
4601
|
+
}
|
|
4602
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: BaseFormFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4603
|
+
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 }); }
|
|
4604
|
+
}
|
|
4605
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: BaseFormFieldComponent, decorators: [{
|
|
4606
|
+
type: Directive
|
|
4607
|
+
}], propDecorators: { update: [{
|
|
4608
|
+
type: Output
|
|
4609
|
+
}], immediateUpdate: [{
|
|
4610
|
+
type: Output
|
|
4611
|
+
}] } });
|
|
4612
|
+
|
|
4613
|
+
class FormFieldItemComponent extends BaseFormFieldComponent {
|
|
4614
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormFieldItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
4615
|
+
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 }); }
|
|
4616
|
+
}
|
|
4617
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormFieldItemComponent, decorators: [{
|
|
4618
|
+
type: Component,
|
|
4619
|
+
args: [{
|
|
4620
|
+
selector: 'ng-dhis2-ui-form-field-item',
|
|
4621
|
+
template: `<ng-content></ng-content>`,
|
|
4622
|
+
standalone: false,
|
|
4623
|
+
}]
|
|
4624
|
+
}] });
|
|
4625
|
+
|
|
4626
|
+
class FormFieldComponent {
|
|
4627
|
+
constructor() {
|
|
4628
|
+
this.field = input.required();
|
|
4629
|
+
this.maxDate = new Date();
|
|
4630
|
+
this.color = 'primary';
|
|
4631
|
+
this.fieldUpdate = new EventEmitter();
|
|
4632
|
+
this.immediateFieldUpdate = new EventEmitter();
|
|
4633
|
+
this.runtimeOptionChange = new EventEmitter();
|
|
4634
|
+
this.value = signal('');
|
|
4635
|
+
this._runtimeOptions = [];
|
|
4636
|
+
this.runtimeOptions = [];
|
|
4637
|
+
this.fieldFilterControl = new FormControl();
|
|
4638
|
+
this._onDestroy = new Subject();
|
|
4639
|
+
}
|
|
4640
|
+
ngOnChanges(changes) {
|
|
4641
|
+
if (changes && changes['dataEntities'] && this.field()?.dependentField) {
|
|
4642
|
+
if (this._runtimeOptions?.length === 0) {
|
|
4643
|
+
const parentOption = find(this.field()?.dependentField?.optionSet?.options, ['code', (this.form?.value || {})[this.field()?.dependentField?.id]]);
|
|
4644
|
+
this.runtimeOptions = parentOption?.options || [];
|
|
4645
|
+
this.runtimeOptionChange.emit({
|
|
4646
|
+
field: this.field(),
|
|
4647
|
+
options: this.runtimeOptions,
|
|
4648
|
+
});
|
|
4649
|
+
}
|
|
4650
|
+
else {
|
|
4651
|
+
this.runtimeOptions = this._runtimeOptions;
|
|
4652
|
+
}
|
|
4653
|
+
}
|
|
4654
|
+
}
|
|
4655
|
+
ngOnInit() {
|
|
4656
|
+
this.value.set(this.form?.get(this.field()?.id)?.value);
|
|
4657
|
+
this.fieldFilterControl.valueChanges
|
|
4658
|
+
.pipe(takeUntil(this._onDestroy))
|
|
4659
|
+
.subscribe(() => {
|
|
4660
|
+
this.optionSearchTerm = this.fieldFilterControl.value;
|
|
4661
|
+
});
|
|
4662
|
+
}
|
|
4663
|
+
ngOnDestroy() {
|
|
4664
|
+
this._onDestroy.next();
|
|
4665
|
+
this._onDestroy.complete();
|
|
4666
|
+
}
|
|
4667
|
+
get isValid() {
|
|
4668
|
+
return this.form?.controls[this.field().id]?.valid;
|
|
4669
|
+
}
|
|
4670
|
+
get fieldError() {
|
|
4671
|
+
const error = this.form?.controls[this.field()?.id]?.errors;
|
|
4672
|
+
if (!error) {
|
|
4673
|
+
return undefined;
|
|
4674
|
+
}
|
|
4675
|
+
if (error['min']) {
|
|
4676
|
+
return `${this.field().label} should not be less than ${error['min'].min}!`;
|
|
4677
|
+
}
|
|
4678
|
+
else if (error['max']) {
|
|
4679
|
+
return `${this.field().label} should not be greater than ${error['max'].max}!`;
|
|
4680
|
+
}
|
|
4681
|
+
else if (error['pattern']) {
|
|
4682
|
+
if (this.field().type === 'email') {
|
|
4683
|
+
return `The email address provided is not valid`;
|
|
4684
|
+
}
|
|
4685
|
+
else if (this.field().type === 'tel') {
|
|
4686
|
+
return 'Phone number provided is not valid';
|
|
4687
|
+
}
|
|
4688
|
+
else {
|
|
4689
|
+
return `${this.field().label} should have appropriate format`;
|
|
4690
|
+
}
|
|
4691
|
+
}
|
|
4692
|
+
return error['required'] ? `${this.field()?.label} is required` : undefined;
|
|
4693
|
+
}
|
|
4694
|
+
get minErrorText() {
|
|
4695
|
+
const minError = this.form?.controls[this.field()?.id]?.errors?.['min'];
|
|
4696
|
+
return minError ? `${this.field()?.label} is min` : undefined;
|
|
4697
|
+
}
|
|
4698
|
+
get maxErrorText() {
|
|
4699
|
+
const maxError = this.form?.controls[this.field()?.id]?.errors?.['max'];
|
|
4700
|
+
return maxError ? `${this.field()?.label} is required` : undefined;
|
|
4701
|
+
}
|
|
4702
|
+
get isInvalid() {
|
|
4703
|
+
return (this.form?.controls[this.field().id]?.invalid &&
|
|
4704
|
+
!this.form?.controls[this.field().id].pristine);
|
|
4705
|
+
}
|
|
4706
|
+
get isDate() {
|
|
4707
|
+
return this.field().controlType === 'date';
|
|
4708
|
+
}
|
|
4709
|
+
get isDateTime() {
|
|
4710
|
+
return this.field().controlType === 'date-time';
|
|
4711
|
+
}
|
|
4712
|
+
get isBoolean() {
|
|
4713
|
+
return this.field().controlType === 'boolean';
|
|
4714
|
+
}
|
|
4715
|
+
get isCheckbox() {
|
|
4716
|
+
return this.field()?.controlType === 'checkbox';
|
|
4717
|
+
}
|
|
4718
|
+
get isCommonField() {
|
|
4719
|
+
return !this.isCheckbox && !this.isDate && !this.isDateTime;
|
|
4720
|
+
}
|
|
4721
|
+
get fieldId() {
|
|
4722
|
+
return this.field()?.id;
|
|
4723
|
+
}
|
|
4724
|
+
onValueChange() {
|
|
4725
|
+
this.fieldUpdate.emit(this.form);
|
|
4726
|
+
}
|
|
4727
|
+
onImmediateChange(event) {
|
|
4728
|
+
this.immediateFieldUpdate.emit({ value: event?.value || '' });
|
|
4729
|
+
}
|
|
4730
|
+
onFieldUpdate(e, isDate, isDateTime) {
|
|
4731
|
+
if (e && e.value) {
|
|
4732
|
+
const dateValue = new Date(e.value);
|
|
4733
|
+
if (isDate) {
|
|
4734
|
+
const dateValue = new Date(e.value);
|
|
4735
|
+
const formattedDate = moment(e.value).format('YYYY-MM-DD');
|
|
4736
|
+
let dateTimeString = formattedDate;
|
|
4737
|
+
if (isDateTime) {
|
|
4738
|
+
const hours = dateValue.getHours() < 10
|
|
4739
|
+
? '0' + dateValue.getHours()
|
|
4740
|
+
: dateValue.getHours();
|
|
4741
|
+
const minutes = dateValue.getMinutes() < 10
|
|
4742
|
+
? '0' + dateValue.getMinutes()
|
|
4743
|
+
: dateValue.getMinutes();
|
|
4744
|
+
const seconds = dateValue.getSeconds() < 10
|
|
4745
|
+
? '0' + dateValue.getSeconds()
|
|
4746
|
+
: dateValue.getSeconds();
|
|
4747
|
+
const timeValue = `${hours}:${minutes}:${seconds}`;
|
|
4748
|
+
dateTimeString = `${formattedDate}T${timeValue}`;
|
|
4749
|
+
}
|
|
4750
|
+
const formControl = this.form.get(this.field().key);
|
|
4751
|
+
if (formControl) {
|
|
4752
|
+
formControl.setValue(dateTimeString);
|
|
4753
|
+
}
|
|
4754
|
+
}
|
|
4755
|
+
else {
|
|
4756
|
+
const formControl = this.form.get(this.field().key);
|
|
4757
|
+
if (formControl) {
|
|
4758
|
+
formControl.setValue(e.value);
|
|
4759
|
+
}
|
|
4760
|
+
}
|
|
4761
|
+
}
|
|
4762
|
+
this.fieldUpdate.emit(this.form);
|
|
4763
|
+
}
|
|
4764
|
+
onUpdateRuntimeOptions(options) {
|
|
4765
|
+
this._runtimeOptions = [...options];
|
|
4766
|
+
}
|
|
4767
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4768
|
+
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" }] }); }
|
|
4769
|
+
}
|
|
4770
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormFieldComponent, decorators: [{
|
|
4771
|
+
type: Component,
|
|
4772
|
+
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"] }]
|
|
4773
|
+
}], propDecorators: { fieldConfig: [{
|
|
4774
|
+
type: Input
|
|
4775
|
+
}], form: [{
|
|
4776
|
+
type: Input
|
|
4777
|
+
}], isCheckBoxButton: [{
|
|
4778
|
+
type: Input
|
|
4779
|
+
}], fieldClass: [{
|
|
4780
|
+
type: Input
|
|
4781
|
+
}], programRuleActions: [{
|
|
4782
|
+
type: Input
|
|
4783
|
+
}], dataEntities: [{
|
|
4784
|
+
type: Input
|
|
4785
|
+
}], minDate: [{
|
|
4786
|
+
type: Input
|
|
4787
|
+
}], maxDate: [{
|
|
4788
|
+
type: Input
|
|
4789
|
+
}], fieldUpdate: [{
|
|
4790
|
+
type: Output
|
|
4791
|
+
}], immediateFieldUpdate: [{
|
|
4792
|
+
type: Output
|
|
4793
|
+
}], runtimeOptionChange: [{
|
|
4794
|
+
type: Output
|
|
4795
|
+
}] } });
|
|
4796
|
+
|
|
4797
|
+
class FormComponent {
|
|
4798
|
+
constructor() {
|
|
4799
|
+
this.formConfig = input();
|
|
4800
|
+
this.configuration = computed(() => {
|
|
4801
|
+
if (!this.formConfig()) {
|
|
4802
|
+
return new FormConfig({
|
|
4803
|
+
direction: this.isFormHorizontal ? 'horizontal' : 'vertical',
|
|
4804
|
+
});
|
|
4805
|
+
}
|
|
4806
|
+
return this.formConfig();
|
|
4807
|
+
});
|
|
4808
|
+
this.formUpdate = new EventEmitter();
|
|
4809
|
+
}
|
|
4810
|
+
get sanitizedFields() {
|
|
4811
|
+
return (this.fields || []).filter((field) => {
|
|
4812
|
+
if (field.hidden) {
|
|
4813
|
+
return false;
|
|
4814
|
+
}
|
|
4815
|
+
const type = field.isDataElement
|
|
4816
|
+
? 'dataElement'
|
|
4817
|
+
: 'trackedEntityAttribute';
|
|
4818
|
+
const elementItem = field[type] || field;
|
|
4819
|
+
if (!elementItem) {
|
|
4820
|
+
return true;
|
|
4821
|
+
}
|
|
4822
|
+
const availableRule = head((this.programRuleActions || []).filter((ruleAction) => {
|
|
4823
|
+
const fieldId = ruleAction.field || ruleAction[type]?.id;
|
|
4824
|
+
return (fieldId === elementItem.id &&
|
|
4825
|
+
(ruleAction.programRuleActionType === 'HIDEFIELD' ||
|
|
4826
|
+
ruleAction.actionType === 'HIDEFIELD'));
|
|
4827
|
+
}));
|
|
4828
|
+
if (!availableRule) {
|
|
4829
|
+
return true;
|
|
4830
|
+
}
|
|
4831
|
+
const actionType = availableRule?.programRuleActionType || availableRule?.actionType;
|
|
4832
|
+
return actionType !== 'HIDEFIELD';
|
|
4833
|
+
});
|
|
4834
|
+
}
|
|
4835
|
+
get layoutCssClass() {
|
|
4836
|
+
if (!this.isFormHorizontal) {
|
|
4837
|
+
return 'col-12';
|
|
4838
|
+
}
|
|
4839
|
+
const numberOfFields = this.sanitizedFields.length;
|
|
4840
|
+
if (numberOfFields === 2) {
|
|
4841
|
+
return 'col-sm-6';
|
|
4842
|
+
}
|
|
4843
|
+
if (numberOfFields === 1) {
|
|
4844
|
+
return 'col-12';
|
|
4845
|
+
}
|
|
4846
|
+
return 'col-sm-4';
|
|
4847
|
+
}
|
|
4848
|
+
onUpdateFields(programRuleActions) {
|
|
4849
|
+
this.fields = (this.fields || []).filter((field) => {
|
|
4850
|
+
const type = field.isDataElement
|
|
4851
|
+
? 'dataElement'
|
|
4852
|
+
: 'trackedEntityAttribute';
|
|
4853
|
+
const elementItem = field[type] || field;
|
|
4854
|
+
if (!elementItem) {
|
|
4855
|
+
return true;
|
|
4856
|
+
}
|
|
4857
|
+
const availableRule = head((programRuleActions || []).filter((rule) => {
|
|
4858
|
+
return (rule[type] &&
|
|
4859
|
+
rule[type].id === elementItem.id &&
|
|
4860
|
+
rule.programRuleActionType === 'HIDEFIELD');
|
|
4861
|
+
}));
|
|
4862
|
+
if (!availableRule) {
|
|
4863
|
+
return true;
|
|
4864
|
+
}
|
|
4865
|
+
return (availableRule && availableRule.programRuleActionType !== 'HIDEFIELD');
|
|
4866
|
+
});
|
|
4867
|
+
}
|
|
4868
|
+
ngOnChanges() {
|
|
4869
|
+
this.values = this.form.getRawValue();
|
|
4870
|
+
}
|
|
4871
|
+
onSubmit() {
|
|
4872
|
+
this.formUpdate.emit(this.form.getRawValue());
|
|
4873
|
+
}
|
|
4874
|
+
onFieldUpdate(form, field) {
|
|
4875
|
+
if (!this.showSaveButton && form) {
|
|
4876
|
+
this.formUpdate.emit(new FormValue(this.form, this.fields, field));
|
|
4877
|
+
this.values = form.getRawValue();
|
|
4878
|
+
}
|
|
4879
|
+
}
|
|
4880
|
+
onClear() {
|
|
4881
|
+
this.form.reset();
|
|
4882
|
+
}
|
|
4883
|
+
isFormInValid() {
|
|
4884
|
+
return this.form.invalid;
|
|
4885
|
+
}
|
|
4886
|
+
onRunTimeOptionUpdate(result) {
|
|
4887
|
+
if (this.fieldComponents) {
|
|
4888
|
+
const fieldToUpdate = this.fieldComponents.find((fieldComponent) => fieldComponent?.field()?.dependentField?.id === result?.field?.id);
|
|
4889
|
+
const parentOption = result?.options.find((option) => option.code === this.form?.value[result?.field?.id]);
|
|
4890
|
+
fieldToUpdate?.onUpdateRuntimeOptions(parentOption?.options || []);
|
|
4891
|
+
}
|
|
4892
|
+
}
|
|
4893
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4894
|
+
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"] }] }); }
|
|
4895
|
+
}
|
|
4896
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: FormComponent, decorators: [{
|
|
4897
|
+
type: Component,
|
|
4898
|
+
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"] }]
|
|
4899
|
+
}], propDecorators: { fields: [{
|
|
4900
|
+
type: Input
|
|
4901
|
+
}], form: [{
|
|
4902
|
+
type: Input
|
|
4903
|
+
}], isFormHorizontal: [{
|
|
4904
|
+
type: Input
|
|
4905
|
+
}], showSaveButton: [{
|
|
4906
|
+
type: Input
|
|
4907
|
+
}], fieldsData: [{
|
|
4908
|
+
type: Input
|
|
4909
|
+
}], fieldClass: [{
|
|
4910
|
+
type: Input
|
|
4911
|
+
}], shouldRenderAsCheckBoxesButton: [{
|
|
4912
|
+
type: Input
|
|
4913
|
+
}], programRuleActions: [{
|
|
4914
|
+
type: Input
|
|
4915
|
+
}], dataEntities: [{
|
|
4916
|
+
type: Input
|
|
4917
|
+
}], formUpdate: [{
|
|
4918
|
+
type: Output
|
|
4919
|
+
}], fieldComponents: [{
|
|
4920
|
+
type: ViewChildren,
|
|
4921
|
+
args: [FormFieldComponent]
|
|
4922
|
+
}] } });
|
|
4923
|
+
|
|
4924
|
+
class RepeatableFormComponent {
|
|
4925
|
+
#eventFormValue$;
|
|
4926
|
+
#showForm$;
|
|
4927
|
+
#events$;
|
|
4928
|
+
constructor() {
|
|
4929
|
+
this.ngZone = inject(NgZone);
|
|
4930
|
+
this.fieldGroup = input.required();
|
|
4931
|
+
this.events = model();
|
|
4932
|
+
this.dataEntities = input.required();
|
|
4933
|
+
this.repeatableEvents = [];
|
|
4934
|
+
this.repeatableData = {};
|
|
4935
|
+
this.repeatableStageUpdate = new EventEmitter();
|
|
4936
|
+
this.eventFormValue = signal(null);
|
|
4937
|
+
this.showForm = signal(false);
|
|
4938
|
+
this.eventIndex = signal(0);
|
|
4939
|
+
this.#eventFormValue$ = toObservable(this.eventFormValue);
|
|
4940
|
+
this.#showForm$ = toObservable(this.showForm);
|
|
4941
|
+
this.#events$ = toObservable(this.events);
|
|
4942
|
+
}
|
|
4943
|
+
get isValid() {
|
|
4944
|
+
return !Object.keys(this.repeatableData).some((index) => {
|
|
4945
|
+
const formValue = this.repeatableData[index];
|
|
4946
|
+
return !formValue?.isValid;
|
|
4947
|
+
});
|
|
4948
|
+
}
|
|
4949
|
+
ngOnInit() {
|
|
4950
|
+
this.eventForm = FormUtil.getFormGroup(this.fieldGroup().fields, {});
|
|
4951
|
+
this.eventFormValue.set(new FormValue(this.eventForm, this.fieldGroup().fields));
|
|
4952
|
+
this.repeatableEvents = (this.events() || []).map((event, index) => {
|
|
4953
|
+
const fieldControls = (this.fieldGroup().fields || []).reduce((fieldObject, field) => {
|
|
4954
|
+
const value = (event.dataValueEntities || {})[field.key] || '';
|
|
4955
|
+
return {
|
|
4956
|
+
...fieldObject,
|
|
4957
|
+
[field.key]: new FormControl(value, field.required ? [Validators.required] : []),
|
|
4958
|
+
};
|
|
4959
|
+
}, {});
|
|
4960
|
+
const form = new FormGroup(fieldControls);
|
|
4961
|
+
this.repeatableData[index] = new FormValue(form, this.fieldGroup().fields || []);
|
|
4962
|
+
return { ...event, form };
|
|
4963
|
+
});
|
|
4964
|
+
this.repeatableStageUpdate.emit(this.repeatableData);
|
|
4965
|
+
}
|
|
4966
|
+
onFormUpdate(formValue) {
|
|
4967
|
+
this.eventFormValue.set(formValue);
|
|
4968
|
+
this.repeatableData = {
|
|
4969
|
+
...this.repeatableData,
|
|
4970
|
+
[this.eventIndex()]: formValue,
|
|
4971
|
+
};
|
|
4972
|
+
}
|
|
4973
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: RepeatableFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4974
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.8", type: RepeatableFormComponent, isStandalone: false, selector: "ng-dhis2-ui-repeatable-form", inputs: { formObject: { classPropertyName: "formObject", publicName: "formObject", isSignal: false, isRequired: false, transformFunction: null }, formData: { classPropertyName: "formData", publicName: "formData", isSignal: false, isRequired: false, transformFunction: null }, fieldGroup: { classPropertyName: "fieldGroup", publicName: "fieldGroup", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: false, isRequired: false, transformFunction: null }, numberOfRows: { classPropertyName: "numberOfRows", publicName: "numberOfRows", isSignal: false, isRequired: false, transformFunction: null }, programRuleActions: { classPropertyName: "programRuleActions", publicName: "programRuleActions", isSignal: false, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, program: { classPropertyName: "program", publicName: "program", isSignal: false, isRequired: false, transformFunction: null }, programStage: { classPropertyName: "programStage", publicName: "programStage", isSignal: false, isRequired: false, transformFunction: null }, repeatDependentField: { classPropertyName: "repeatDependentField", publicName: "repeatDependentField", isSignal: false, isRequired: false, transformFunction: null }, dataEntities: { classPropertyName: "dataEntities", publicName: "dataEntities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { events: "eventsChange", repeatableStageUpdate: "repeatableStageUpdate" }, ngImport: i0, template: "<div class=\"form__repeatable-stage-container\">\n <!-- <ng-dhis2-ui-wrapper [component]=\"EventTable()\"></ng-dhis2-ui-wrapper> -->\n @if(showForm()) {\n <div class=\"form__repeatable-stage-form\">\n <ng-dhis2-ui-form\n [fields]=\"fieldGroup().fields || []\"\n [form]=\"eventForm\"\n [programRuleActions]=\"programRuleActions\"\n [dataEntities]=\"{}\"\n [isFormHorizontal]=\"false\"\n (formUpdate)=\"onFormUpdate($event)\"\n >\n </ng-dhis2-ui-form>\n\n <!-- <ng-dhis2-ui-wrapper [component]=\"FormActionButtons\"></ng-dhis2-ui-wrapper> -->\n </div>\n }\n</div>\n", styles: [".form__repeatable-stage-container{margin-top:16px}.form__repeatable-stage-form{border:solid 1px rgb(232,237,242);border-top-style:none;background-color:#fff;padding:16px}\n"], dependencies: [{ kind: "component", type: FormComponent, selector: "ng-dhis2-ui-form", inputs: ["formConfig", "fields", "form", "isFormHorizontal", "showSaveButton", "fieldsData", "fieldClass", "shouldRenderAsCheckBoxesButton", "programRuleActions", "dataEntities"], outputs: ["formUpdate"] }] }); }
|
|
4975
|
+
}
|
|
4976
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: RepeatableFormComponent, decorators: [{
|
|
4977
|
+
type: Component,
|
|
4978
|
+
args: [{ selector: 'ng-dhis2-ui-repeatable-form', standalone: false, template: "<div class=\"form__repeatable-stage-container\">\n <!-- <ng-dhis2-ui-wrapper [component]=\"EventTable()\"></ng-dhis2-ui-wrapper> -->\n @if(showForm()) {\n <div class=\"form__repeatable-stage-form\">\n <ng-dhis2-ui-form\n [fields]=\"fieldGroup().fields || []\"\n [form]=\"eventForm\"\n [programRuleActions]=\"programRuleActions\"\n [dataEntities]=\"{}\"\n [isFormHorizontal]=\"false\"\n (formUpdate)=\"onFormUpdate($event)\"\n >\n </ng-dhis2-ui-form>\n\n <!-- <ng-dhis2-ui-wrapper [component]=\"FormActionButtons\"></ng-dhis2-ui-wrapper> -->\n </div>\n }\n</div>\n", styles: [".form__repeatable-stage-container{margin-top:16px}.form__repeatable-stage-form{border:solid 1px rgb(232,237,242);border-top-style:none;background-color:#fff;padding:16px}\n"] }]
|
|
4979
|
+
}], ctorParameters: () => [], propDecorators: { formObject: [{
|
|
4980
|
+
type: Input
|
|
4981
|
+
}], formData: [{
|
|
4982
|
+
type: Input
|
|
4983
|
+
}], form: [{
|
|
4984
|
+
type: Input
|
|
4985
|
+
}], numberOfRows: [{
|
|
4986
|
+
type: Input
|
|
4987
|
+
}], programRuleActions: [{
|
|
4988
|
+
type: Input
|
|
4989
|
+
}], program: [{
|
|
4990
|
+
type: Input
|
|
4991
|
+
}], programStage: [{
|
|
4992
|
+
type: Input
|
|
4993
|
+
}], repeatDependentField: [{
|
|
4994
|
+
type: Input
|
|
4995
|
+
}], repeatableStageUpdate: [{
|
|
4996
|
+
type: Output
|
|
4997
|
+
}] } });
|
|
4998
|
+
|
|
4999
|
+
class SectionFormComponent {
|
|
5000
|
+
constructor() {
|
|
5001
|
+
this.ngZone = inject(NgZone);
|
|
5002
|
+
this.loading = input();
|
|
5003
|
+
this.formMetaData = input.required();
|
|
5004
|
+
this.dataValueEntities = input.required();
|
|
5005
|
+
this.formGroups = {};
|
|
5006
|
+
this.formValueEntity = {};
|
|
5007
|
+
this.repeatableFormValueEntity = {};
|
|
5008
|
+
this.ruleActions = [];
|
|
5009
|
+
this.save = new EventEmitter();
|
|
5010
|
+
this.formUpdate = new EventEmitter();
|
|
5011
|
+
this.cancel = new EventEmitter();
|
|
5012
|
+
this.inValid = signal(true);
|
|
5013
|
+
this.inValid$ = toObservable(this.inValid);
|
|
5014
|
+
}
|
|
5015
|
+
ngOnInit() {
|
|
5016
|
+
if (this.formMetaData().sections) {
|
|
5017
|
+
(this.formMetaData().sections || []).forEach((formSection) => {
|
|
5018
|
+
(formSection.fieldGroups || []).forEach((fieldGroup) => {
|
|
5019
|
+
const formGroup = FormUtil.getFormGroup(fieldGroup.fields, this.dataValueEntities());
|
|
5020
|
+
const formValue = new FormValue(formGroup, fieldGroup.fields);
|
|
5021
|
+
this.formGroups[fieldGroup.id] = formGroup;
|
|
5022
|
+
if (!fieldGroup.repeatableStage) {
|
|
5023
|
+
this.formValueEntity[fieldGroup.id] = formValue;
|
|
5024
|
+
}
|
|
5025
|
+
else {
|
|
5026
|
+
this.repeatableFormValueEntity[fieldGroup.dataKey || fieldGroup.id] = {
|
|
5027
|
+
0: formValue,
|
|
5028
|
+
};
|
|
5029
|
+
}
|
|
5030
|
+
});
|
|
5031
|
+
});
|
|
5032
|
+
this.inValid.set(this.checkIfInValid());
|
|
5033
|
+
this.ruleActions = new ProgramRuleEngine()
|
|
5034
|
+
.setRules(this.formMetaData().rules)
|
|
5035
|
+
.setDataValues(this.#getDataValue())
|
|
5036
|
+
.execute();
|
|
5037
|
+
}
|
|
5038
|
+
}
|
|
5039
|
+
onUpdateRepeatableStage(repeatableData, fieldGroup) {
|
|
5040
|
+
if (!isEmpty(repeatableData)) {
|
|
5041
|
+
this.repeatableFormValueEntity[fieldGroup.dataKey || fieldGroup.id] =
|
|
5042
|
+
repeatableData;
|
|
5043
|
+
this.inValid.set(this.checkIfInValid());
|
|
5044
|
+
const dataValues = this.#getDataValue();
|
|
5045
|
+
this.formUpdate.emit(dataValues);
|
|
5046
|
+
}
|
|
5047
|
+
}
|
|
5048
|
+
onFormUpdate(formValue, fieldGroupId) {
|
|
5049
|
+
this.formValueEntity[fieldGroupId] = formValue;
|
|
5050
|
+
this.inValid.set(this.checkIfInValid());
|
|
5051
|
+
const dataValues = this.#getDataValue();
|
|
5052
|
+
this.ruleActions = new ProgramRuleEngine()
|
|
5053
|
+
.setRules(this.formMetaData().rules)
|
|
5054
|
+
.setDataValues(dataValues)
|
|
5055
|
+
.execute();
|
|
5056
|
+
this.formUpdate.emit(dataValues);
|
|
5057
|
+
}
|
|
5058
|
+
onSubmit() {
|
|
5059
|
+
const dataValues = this.#getDataValue();
|
|
5060
|
+
this.save.emit(dataValues);
|
|
5061
|
+
}
|
|
5062
|
+
onCancel(event) {
|
|
5063
|
+
event?.stopPropagation();
|
|
5064
|
+
this.cancel.emit();
|
|
5065
|
+
}
|
|
5066
|
+
#getDataValue() {
|
|
5067
|
+
const dataValues = Object.keys(this.formValueEntity).reduce((valueObject, key) => {
|
|
5068
|
+
const values = this.formValueEntity[key]?.form?.getRawValue();
|
|
5069
|
+
return { ...valueObject, ...(values || {}) };
|
|
5070
|
+
}, {});
|
|
5071
|
+
const repeatableValues = Object.keys(this.repeatableFormValueEntity).reduce((repeatableObject, key) => {
|
|
5072
|
+
const formValueEntity = this.repeatableFormValueEntity[key];
|
|
5073
|
+
const values = Object.keys(formValueEntity)
|
|
5074
|
+
.map((valueIndex) => {
|
|
5075
|
+
return (formValueEntity[+valueIndex] || {}).form?.getRawValue();
|
|
5076
|
+
})
|
|
5077
|
+
.filter((value) => value);
|
|
5078
|
+
return { ...repeatableObject, [key]: values };
|
|
5079
|
+
}, {});
|
|
5080
|
+
return { ...dataValues, ...repeatableValues };
|
|
5081
|
+
}
|
|
5082
|
+
checkIfInValid() {
|
|
5083
|
+
const valueValidity = Object.keys(this.formValueEntity)
|
|
5084
|
+
.map((key) => {
|
|
5085
|
+
return (this.formValueEntity[key] || {}).isValid;
|
|
5086
|
+
})
|
|
5087
|
+
.some((validity) => !validity);
|
|
5088
|
+
const repeatableDataValidity = Object.keys(this.repeatableFormValueEntity)
|
|
5089
|
+
.map((key) => {
|
|
5090
|
+
return Object.keys(this.repeatableFormValueEntity[key]).some((valueIndex) => {
|
|
5091
|
+
return ((this.repeatableFormValueEntity[key] || {})[+valueIndex] || {}).isValid;
|
|
5092
|
+
});
|
|
5093
|
+
})
|
|
5094
|
+
.some((validity) => !validity);
|
|
5095
|
+
return valueValidity || repeatableDataValidity;
|
|
5096
|
+
}
|
|
5097
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SectionFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5098
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.8", type: SectionFormComponent, isStandalone: false, selector: "ng-dhis2-ui-section-form", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, formMetaData: { classPropertyName: "formMetaData", publicName: "formMetaData", isSignal: true, isRequired: true, transformFunction: null }, dataValueEntities: { classPropertyName: "dataValueEntities", publicName: "dataValueEntities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { save: "save", formUpdate: "formUpdate", cancel: "cancel" }, ngImport: i0, template: "<ng-container *ngIf=\"formMetaData()\">\n <ng-container *ngFor=\"let formSection of formMetaData().sections\">\n @if(formSection?.name; as sectionName) {\n <div class=\"form__section-name\">\n {{ sectionName }}\n </div>\n }\n <div class=\"form__section-content\">\n <ng-container *ngIf=\"formSection\">\n <div *ngFor=\"let fieldGroup of formSection?.fieldGroups\">\n <ng-container *ngIf=\"formGroups[fieldGroup.id] as formGroup\">\n <div\n *ngIf=\"fieldGroup.name && !fieldGroup.repeatableStage\"\n class=\"form__field-group-name\"\n >\n {{ fieldGroup?.name }}\n </div>\n <div *ngIf=\"fieldGroup.fields\">\n <!-- Single stage form section -->\n <ng-container *ngIf=\"!fieldGroup.repeatableStage\">\n <ng-dhis2-ui-form\n *ngIf=\"fieldGroup.fields.length > 0\"\n [fields]=\"fieldGroup.fields\"\n [form]=\"formGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [programRuleActions]=\"ruleActions\"\n [isFormHorizontal]=\"fieldGroup.isFormHorizontal || false\"\n (formUpdate)=\"onFormUpdate($event, fieldGroup.id)\"\n ></ng-dhis2-ui-form>\n </ng-container>\n\n <!-- Repeatable stage form section -->\n <ng-container *ngIf=\"fieldGroup.repeatableStage\">\n @if(fieldGroup.repeatDependentField) {\n\n <ng-container *ngIf=\"fieldGroup.repeatDependentField\">\n <ng-container\n *ngIf=\"{\n numberOfRows:\n dataValueEntities()[fieldGroup.repeatDependentField]\n } as dataParams\"\n >\n <ng-dhis2-ui-repeatable-form\n *ngIf=\"\n dataParams.numberOfRows &&\n dataParams.numberOfRows !== '0'\n \"\n [fieldGroup]=\"fieldGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [form]=\"formGroup\"\n [program]=\"formSection.program || ''\"\n [programStage]=\"fieldGroup.repeatableStage\"\n [programRuleActions]=\"ruleActions\"\n [numberOfRows]=\"+dataParams.numberOfRows\"\n [repeatDependentField]=\"\n fieldGroup.repeatDependentField || ''\n \"\n [events]=\"dataValueEntities()[fieldGroup.dataKey!]\"\n (repeatableStageUpdate)=\"\n onUpdateRepeatableStage($event, fieldGroup)\n \"\n ></ng-dhis2-ui-repeatable-form\n ></ng-container>\n </ng-container>\n } @else {\n <ng-dhis2-ui-repeatable-form\n [fieldGroup]=\"fieldGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [form]=\"formGroup\"\n [program]=\"formSection.program || ''\"\n [programStage]=\"fieldGroup.repeatableStage\"\n [programRuleActions]=\"ruleActions\"\n [numberOfRows]=\"1\"\n [repeatDependentField]=\"fieldGroup.repeatDependentField || ''\"\n [events]=\"dataValueEntities()[fieldGroup.dataKey!]\"\n (repeatableStageUpdate)=\"\n onUpdateRepeatableStage($event, fieldGroup)\n \"\n ></ng-dhis2-ui-repeatable-form>\n }\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</ng-container>\n", styles: [".form__section-name{font-size:16px;font-weight:600;margin-bottom:16px}.form__section-content{margin-bottom:24px}.form__field-group-name{font-size:14px;font-weight:500;padding-bottom:8px;border-bottom:solid 1px rgb(232,237,242);margin-bottom:16px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormComponent, selector: "ng-dhis2-ui-form", inputs: ["formConfig", "fields", "form", "isFormHorizontal", "showSaveButton", "fieldsData", "fieldClass", "shouldRenderAsCheckBoxesButton", "programRuleActions", "dataEntities"], outputs: ["formUpdate"] }, { kind: "component", type: RepeatableFormComponent, selector: "ng-dhis2-ui-repeatable-form", inputs: ["formObject", "formData", "fieldGroup", "form", "numberOfRows", "programRuleActions", "events", "program", "programStage", "repeatDependentField", "dataEntities"], outputs: ["eventsChange", "repeatableStageUpdate"] }] }); }
|
|
5099
|
+
}
|
|
5100
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SectionFormComponent, decorators: [{
|
|
5101
|
+
type: Component,
|
|
5102
|
+
args: [{ selector: 'ng-dhis2-ui-section-form', standalone: false, template: "<ng-container *ngIf=\"formMetaData()\">\n <ng-container *ngFor=\"let formSection of formMetaData().sections\">\n @if(formSection?.name; as sectionName) {\n <div class=\"form__section-name\">\n {{ sectionName }}\n </div>\n }\n <div class=\"form__section-content\">\n <ng-container *ngIf=\"formSection\">\n <div *ngFor=\"let fieldGroup of formSection?.fieldGroups\">\n <ng-container *ngIf=\"formGroups[fieldGroup.id] as formGroup\">\n <div\n *ngIf=\"fieldGroup.name && !fieldGroup.repeatableStage\"\n class=\"form__field-group-name\"\n >\n {{ fieldGroup?.name }}\n </div>\n <div *ngIf=\"fieldGroup.fields\">\n <!-- Single stage form section -->\n <ng-container *ngIf=\"!fieldGroup.repeatableStage\">\n <ng-dhis2-ui-form\n *ngIf=\"fieldGroup.fields.length > 0\"\n [fields]=\"fieldGroup.fields\"\n [form]=\"formGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [programRuleActions]=\"ruleActions\"\n [isFormHorizontal]=\"fieldGroup.isFormHorizontal || false\"\n (formUpdate)=\"onFormUpdate($event, fieldGroup.id)\"\n ></ng-dhis2-ui-form>\n </ng-container>\n\n <!-- Repeatable stage form section -->\n <ng-container *ngIf=\"fieldGroup.repeatableStage\">\n @if(fieldGroup.repeatDependentField) {\n\n <ng-container *ngIf=\"fieldGroup.repeatDependentField\">\n <ng-container\n *ngIf=\"{\n numberOfRows:\n dataValueEntities()[fieldGroup.repeatDependentField]\n } as dataParams\"\n >\n <ng-dhis2-ui-repeatable-form\n *ngIf=\"\n dataParams.numberOfRows &&\n dataParams.numberOfRows !== '0'\n \"\n [fieldGroup]=\"fieldGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [form]=\"formGroup\"\n [program]=\"formSection.program || ''\"\n [programStage]=\"fieldGroup.repeatableStage\"\n [programRuleActions]=\"ruleActions\"\n [numberOfRows]=\"+dataParams.numberOfRows\"\n [repeatDependentField]=\"\n fieldGroup.repeatDependentField || ''\n \"\n [events]=\"dataValueEntities()[fieldGroup.dataKey!]\"\n (repeatableStageUpdate)=\"\n onUpdateRepeatableStage($event, fieldGroup)\n \"\n ></ng-dhis2-ui-repeatable-form\n ></ng-container>\n </ng-container>\n } @else {\n <ng-dhis2-ui-repeatable-form\n [fieldGroup]=\"fieldGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [form]=\"formGroup\"\n [program]=\"formSection.program || ''\"\n [programStage]=\"fieldGroup.repeatableStage\"\n [programRuleActions]=\"ruleActions\"\n [numberOfRows]=\"1\"\n [repeatDependentField]=\"fieldGroup.repeatDependentField || ''\"\n [events]=\"dataValueEntities()[fieldGroup.dataKey!]\"\n (repeatableStageUpdate)=\"\n onUpdateRepeatableStage($event, fieldGroup)\n \"\n ></ng-dhis2-ui-repeatable-form>\n }\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</ng-container>\n", styles: [".form__section-name{font-size:16px;font-weight:600;margin-bottom:16px}.form__section-content{margin-bottom:24px}.form__field-group-name{font-size:14px;font-weight:500;padding-bottom:8px;border-bottom:solid 1px rgb(232,237,242);margin-bottom:16px}\n"] }]
|
|
5103
|
+
}], ctorParameters: () => [], propDecorators: { save: [{
|
|
5104
|
+
type: Output
|
|
5105
|
+
}], formUpdate: [{
|
|
5106
|
+
type: Output
|
|
5107
|
+
}], cancel: [{
|
|
5108
|
+
type: Output
|
|
5109
|
+
}] } });
|
|
5110
|
+
|
|
5111
|
+
class D2FormModule {
|
|
5112
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
5113
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, declarations: [FormFieldComponent,
|
|
5114
|
+
FormComponent,
|
|
5115
|
+
RepeatableFormComponent,
|
|
5116
|
+
SectionFormComponent,
|
|
5117
|
+
FormFieldItemComponent], imports: [CommonModule,
|
|
5118
|
+
ReactiveFormsModule,
|
|
5119
|
+
ReactWrapperModule,
|
|
5120
|
+
OrganisationUnitSelectorModule], exports: [FormFieldComponent,
|
|
5121
|
+
FormComponent,
|
|
5122
|
+
RepeatableFormComponent,
|
|
5123
|
+
SectionFormComponent] }); }
|
|
5124
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, imports: [CommonModule,
|
|
5125
|
+
ReactiveFormsModule,
|
|
5126
|
+
OrganisationUnitSelectorModule] }); }
|
|
5127
|
+
}
|
|
5128
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, decorators: [{
|
|
5129
|
+
type: NgModule,
|
|
5130
|
+
args: [{
|
|
5131
|
+
declarations: [
|
|
5132
|
+
FormFieldComponent,
|
|
5133
|
+
FormComponent,
|
|
5134
|
+
RepeatableFormComponent,
|
|
5135
|
+
SectionFormComponent,
|
|
5136
|
+
FormFieldItemComponent,
|
|
5137
|
+
],
|
|
5138
|
+
imports: [
|
|
5139
|
+
CommonModule,
|
|
5140
|
+
ReactiveFormsModule,
|
|
5141
|
+
ReactWrapperModule,
|
|
5142
|
+
OrganisationUnitSelectorModule,
|
|
5143
|
+
],
|
|
5144
|
+
exports: [
|
|
5145
|
+
FormFieldComponent,
|
|
5146
|
+
FormComponent,
|
|
5147
|
+
RepeatableFormComponent,
|
|
5148
|
+
SectionFormComponent,
|
|
5149
|
+
],
|
|
5150
|
+
}]
|
|
5151
|
+
}] });
|
|
5152
|
+
|
|
5153
|
+
// Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
|
|
5154
|
+
// Use of this source code is governed by a BSD-style
|
|
5155
|
+
// license that can be found in the LICENSE file.
|
|
5156
|
+
|
|
5157
|
+
class TrackerFormComponent {
|
|
5158
|
+
constructor() {
|
|
5159
|
+
this.program = input.required();
|
|
5160
|
+
this.d2 = window.d2Web;
|
|
5161
|
+
}
|
|
5162
|
+
async ngOnInit() {
|
|
5163
|
+
this.trackerQuery = this.d2.trackerModule.trackedEntity.setProgram(this.program());
|
|
5164
|
+
const program = await this.trackerQuery.getMetaData();
|
|
5165
|
+
if (program) {
|
|
5166
|
+
this.formMetaData = new FormMetaData({
|
|
5167
|
+
programs: [program],
|
|
5168
|
+
}).toJson();
|
|
5169
|
+
}
|
|
5170
|
+
}
|
|
5171
|
+
onSave(event) { }
|
|
5172
|
+
onCancel() { }
|
|
5173
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5174
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.8", type: TrackerFormComponent, isStandalone: false, selector: "ng-dhis2-ui-tracker-form", inputs: { program: { classPropertyName: "program", publicName: "program", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@if(formMetaData) {\n<ng-dhis2-ui-section-form\n [formMetaData]=\"formMetaData\"\n [dataValueEntities]=\"{}\"\n (save)=\"onSave($event)\"\n (cancel)=\"onCancel()\"\n/>\n}\n", dependencies: [{ kind: "component", type: SectionFormComponent, selector: "ng-dhis2-ui-section-form", inputs: ["loading", "formMetaData", "dataValueEntities"], outputs: ["save", "formUpdate", "cancel"] }] }); }
|
|
5175
|
+
}
|
|
5176
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormComponent, decorators: [{
|
|
5177
|
+
type: Component,
|
|
5178
|
+
args: [{ selector: 'ng-dhis2-ui-tracker-form', standalone: false, template: "@if(formMetaData) {\n<ng-dhis2-ui-section-form\n [formMetaData]=\"formMetaData\"\n [dataValueEntities]=\"{}\"\n (save)=\"onSave($event)\"\n (cancel)=\"onCancel()\"\n/>\n}\n" }]
|
|
5179
|
+
}] });
|
|
5180
|
+
|
|
5181
|
+
class TrackerFormModule {
|
|
5182
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
5183
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, declarations: [TrackerFormComponent], imports: [CommonModule, D2FormModule], exports: [TrackerFormComponent] }); }
|
|
5184
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, imports: [CommonModule, D2FormModule] }); }
|
|
5185
|
+
}
|
|
5186
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, decorators: [{
|
|
5187
|
+
type: NgModule,
|
|
5188
|
+
args: [{
|
|
5189
|
+
imports: [CommonModule, D2FormModule],
|
|
5190
|
+
declarations: [TrackerFormComponent],
|
|
5191
|
+
exports: [TrackerFormComponent],
|
|
5192
|
+
}]
|
|
5193
|
+
}] });
|
|
5194
|
+
|
|
5195
|
+
// Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
|
|
5196
|
+
// Use of this source code is governed by a BSD-style
|
|
5197
|
+
// license that can be found in the LICENSE file.
|
|
5198
|
+
|
|
3470
5199
|
/**
|
|
3471
5200
|
* Generated bundle index. Do not edit.
|
|
3472
5201
|
*/
|
|
3473
5202
|
|
|
3474
|
-
export { ButtonComponent, ButtonModule, HeaderBarComponent, HeaderBarModule, LineListModule, LineListTableComponent, OrganisationUnitSelectionConfig, OrganisationUnitSelectorComponent, OrganisationUnitSelectorModalComponent, OrganisationUnitSelectorModule, PeriodSelectorComponent, PeriodSelectorModalComponent, PeriodSelectorModule,
|
|
5203
|
+
export { Boolean$1 as Boolean, ButtonComponent, ButtonModule, CheckBox, D2FormModule, DateField, DateRangeValue, Dropdown, FieldConfig, FieldControlTypeUtil, FieldDropdown, FieldType, FieldUtil, FormComponent, FormConfig, FormField, FormFieldComponent, FormFieldGroup, FormFieldTypeUtil, FormMetaData, FormMetadataSection, FormUtil, FormValue, FormValueUtil, HeaderBarComponent, HeaderBarModule, LineListModule, LineListTableComponent, MetadataRule, MetadataRuleAction, OrganisationUnitSelectionConfig, OrganisationUnitSelectorComponent, OrganisationUnitSelectorModalComponent, OrganisationUnitSelectorModule, PeriodSelectorComponent, PeriodSelectorModalComponent, PeriodSelectorModule, ReactWrapperModule, RepeatableFormComponent, SectionFormComponent, TrackerFormComponent, TrackerFormModule, TranslationUtil };
|
|
3475
5204
|
//# sourceMappingURL=iapps-ng-dhis2-ui.mjs.map
|