@iapps/ng-dhis2-ui 1.1.1 → 1.1.3
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 +786 -232
- package/fesm2022/iapps-ng-dhis2-ui.mjs.map +1 -1
- package/index.d.ts +4 -1
- package/lib/modules/button/button.component.d.ts +2 -2
- package/lib/modules/data-table-ui/components/dropdown-menu/dropdown-menu.d.ts +19 -0
- package/lib/modules/data-table-ui/components/dropdown-menu/dropdown-menu.styles.d.ts +5 -0
- package/lib/modules/data-table-ui/components/dropdown-menu/index.d.ts +1 -0
- package/lib/modules/data-table-ui/containers/data-table-ui/data-table-ui.component.d.ts +19 -0
- package/lib/modules/data-table-ui/data-table-ui.module.d.ts +10 -0
- package/lib/modules/data-table-ui/hooks/index.d.ts +1 -0
- package/lib/modules/data-table-ui/hooks/use-dynamic-styles.hook.d.ts +1 -0
- package/lib/modules/data-table-ui/index.d.ts +3 -0
- package/lib/modules/data-table-ui/models/data-table.models.d.ts +10 -0
- package/lib/modules/form/components/base-form-field.component.d.ts +2 -2
- package/lib/modules/form/containers/repeatable-form/repeatable-form.component.d.ts +11 -4
- package/lib/modules/form/containers/section-form/section-form.component.d.ts +10 -9
- package/lib/modules/form/form.module.d.ts +3 -2
- package/lib/modules/form/interfaces/form-field-group.interface.d.ts +2 -1
- package/lib/modules/form/models/form-field-group.model.d.ts +1 -1
- package/lib/modules/form/models/form-metadata.model.d.ts +2 -1
- package/lib/modules/form/models/form-value.model.d.ts +3 -1
- package/lib/modules/form/utils/field-type.util.d.ts +1 -1
- package/lib/modules/form/utils/field.util.d.ts +1 -1
- package/lib/modules/form/utils/index.d.ts +1 -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/selection-filters-ui/containers/selection-filters-ui/selection-filters-ui.component.d.ts +20 -0
- package/lib/modules/selection-filters-ui/index.d.ts +2 -0
- package/lib/modules/selection-filters-ui/models/selection-filters-ui.model.d.ts +36 -0
- package/lib/modules/selection-filters-ui/selection-filters-ui.module.d.ts +10 -0
- 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/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
|
@@ -27,7 +27,7 @@ import { MenuItem, MenuDivider } from '@dhis2-ui/menu';
|
|
|
27
27
|
import parse from 'html-react-parser';
|
|
28
28
|
import { Button as Button$1, IconDimensionData16, IconClock16, IconDimensionOrgUnit16, spacers as spacers$1, colors as colors$1, IconEdit16, theme as theme$1, Tooltip, SingleSelectField, SingleSelectOption, InputField as InputField$1, TabBar, Tab, Transfer, Modal as Modal$1, ModalTitle as ModalTitle$1, ModalContent as ModalContent$1, ModalActions as ModalActions$1, ButtonStrip as ButtonStrip$1, Checkbox, OrganisationUnitTree, MultiSelect, MultiSelectOption, IconWarningFilled16, Layer as Layer$1, Popper, FlyoutMenu, MenuItem as MenuItem$1, IconMore24, CircularLoader as CircularLoader$1, DataTable, TableHead, DataTableRow, DataTableColumnHeader, TableBody, DataTableCell, TableFoot, Pagination, FileInputField, FileListItem, TextAreaField } from '@dhis2/ui';
|
|
29
29
|
import { getNowInCalendar, generateFixedPeriods } from '@dhis2/multi-calendar-dates';
|
|
30
|
-
import { isObject, isString, sortBy, isArray, find, camelCase, flatten, head,
|
|
30
|
+
import { isObject, isString, sortBy, isArray, find, camelCase, flatten, head, isEmpty } from 'lodash';
|
|
31
31
|
import cx from 'classnames';
|
|
32
32
|
import { map as map$1, switchMap } from 'rxjs/operators';
|
|
33
33
|
import * as i2 from '@angular/forms';
|
|
@@ -1018,7 +1018,7 @@ HeaderBar.propTypes = {
|
|
|
1018
1018
|
};
|
|
1019
1019
|
|
|
1020
1020
|
window.React = React;
|
|
1021
|
-
class
|
|
1021
|
+
class ReactWrapperModule {
|
|
1022
1022
|
constructor(elementRef) {
|
|
1023
1023
|
this.elementRef = elementRef;
|
|
1024
1024
|
}
|
|
@@ -1047,14 +1047,13 @@ class ReactWrapperComponent {
|
|
|
1047
1047
|
" "));
|
|
1048
1048
|
}
|
|
1049
1049
|
}
|
|
1050
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type:
|
|
1051
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.8", type:
|
|
1050
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1051
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.8", type: ReactWrapperModule, isStandalone: true, selector: "ng-dhis2-ui-wrapper", inputs: { props: "props", component: "component" }, queries: [{ propertyName: "content", first: true, predicate: ["ngDhis2UiContent"], descendants: true }], ngImport: i0 }); }
|
|
1052
1052
|
}
|
|
1053
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type:
|
|
1053
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, decorators: [{
|
|
1054
1054
|
type: Directive,
|
|
1055
1055
|
args: [{
|
|
1056
1056
|
selector: 'ng-dhis2-ui-wrapper',
|
|
1057
|
-
standalone: false,
|
|
1058
1057
|
}]
|
|
1059
1058
|
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { props: [{
|
|
1060
1059
|
type: Input
|
|
@@ -1065,25 +1064,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
1065
1064
|
args: ['ngDhis2UiContent']
|
|
1066
1065
|
}] } });
|
|
1067
1066
|
|
|
1068
|
-
class ReactWrapperModule {
|
|
1069
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1070
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, declarations: [ReactWrapperComponent], imports: [CommonModule], exports: [ReactWrapperComponent] }); }
|
|
1071
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, imports: [CommonModule] }); }
|
|
1072
|
-
}
|
|
1073
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: ReactWrapperModule, decorators: [{
|
|
1074
|
-
type: NgModule,
|
|
1075
|
-
args: [{
|
|
1076
|
-
imports: [CommonModule],
|
|
1077
|
-
declarations: [ReactWrapperComponent],
|
|
1078
|
-
exports: [ReactWrapperComponent],
|
|
1079
|
-
}]
|
|
1080
|
-
}] });
|
|
1081
|
-
|
|
1082
|
-
// Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
|
|
1083
|
-
// Use of this source code is governed by a BSD-style
|
|
1084
|
-
// license that can be found in the LICENSE file.
|
|
1085
|
-
|
|
1086
|
-
class HeaderBarComponent extends ReactWrapperComponent {
|
|
1067
|
+
class HeaderBarComponent extends ReactWrapperModule {
|
|
1087
1068
|
constructor(elementRef, httpClient) {
|
|
1088
1069
|
super(elementRef);
|
|
1089
1070
|
this.httpClient = httpClient;
|
|
@@ -1107,7 +1088,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
1107
1088
|
args: [{
|
|
1108
1089
|
selector: 'ng-dhis2-ui-header-bar',
|
|
1109
1090
|
template: `<ng-container></ng-container>`,
|
|
1110
|
-
standalone: false
|
|
1091
|
+
standalone: false,
|
|
1111
1092
|
}]
|
|
1112
1093
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NgxDhis2HttpClientService }] });
|
|
1113
1094
|
|
|
@@ -1129,7 +1110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
1129
1110
|
// Use of this source code is governed by a BSD-style
|
|
1130
1111
|
// license that can be found in the LICENSE file.
|
|
1131
1112
|
|
|
1132
|
-
class ButtonComponent extends
|
|
1113
|
+
class ButtonComponent extends ReactWrapperModule {
|
|
1133
1114
|
constructor() {
|
|
1134
1115
|
super(...arguments);
|
|
1135
1116
|
this.buttonClick = new EventEmitter();
|
|
@@ -1164,7 +1145,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
1164
1145
|
args: [{
|
|
1165
1146
|
selector: 'ng-dhis2-ui-button',
|
|
1166
1147
|
template: '<ng-content></ng-content>',
|
|
1167
|
-
standalone: false
|
|
1148
|
+
standalone: false,
|
|
1168
1149
|
}]
|
|
1169
1150
|
}], propDecorators: { label: [{
|
|
1170
1151
|
type: Input
|
|
@@ -2251,7 +2232,7 @@ PeriodDimension.defaultProps = {
|
|
|
2251
2232
|
selectedPeriods: [],
|
|
2252
2233
|
};
|
|
2253
2234
|
|
|
2254
|
-
class PeriodSelectorModalComponent extends
|
|
2235
|
+
class PeriodSelectorModalComponent extends ReactWrapperModule {
|
|
2255
2236
|
constructor(elementRef, httpClient) {
|
|
2256
2237
|
super(elementRef);
|
|
2257
2238
|
this.httpClient = httpClient;
|
|
@@ -2321,7 +2302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
2321
2302
|
type: Output
|
|
2322
2303
|
}] } });
|
|
2323
2304
|
|
|
2324
|
-
class PeriodSelectorComponent extends
|
|
2305
|
+
class PeriodSelectorComponent extends ReactWrapperModule {
|
|
2325
2306
|
constructor(elementRef, httpClient, ngZone) {
|
|
2326
2307
|
super(elementRef);
|
|
2327
2308
|
this.httpClient = httpClient;
|
|
@@ -2758,7 +2739,7 @@ class OrganisationUnitSelectionConfig {
|
|
|
2758
2739
|
// Use of this source code is governed by a BSD-style
|
|
2759
2740
|
// license that can be found in the LICENSE file.
|
|
2760
2741
|
|
|
2761
|
-
class OrganisationUnitSelectorComponent extends
|
|
2742
|
+
class OrganisationUnitSelectorComponent extends ReactWrapperModule {
|
|
2762
2743
|
constructor(elementRef, httpClient, ngZone) {
|
|
2763
2744
|
super(elementRef);
|
|
2764
2745
|
this.httpClient = httpClient;
|
|
@@ -2839,7 +2820,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
2839
2820
|
type: Output
|
|
2840
2821
|
}] } });
|
|
2841
2822
|
|
|
2842
|
-
class OrganisationUnitSelectorModalComponent extends
|
|
2823
|
+
class OrganisationUnitSelectorModalComponent extends ReactWrapperModule {
|
|
2843
2824
|
constructor(elementRef, httpClient) {
|
|
2844
2825
|
super(elementRef);
|
|
2845
2826
|
this.httpClient = httpClient;
|
|
@@ -2967,6 +2948,102 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
2967
2948
|
// Use of this source code is governed by a BSD-style
|
|
2968
2949
|
// license that can be found in the LICENSE file.
|
|
2969
2950
|
|
|
2951
|
+
const dropdownStyles$1 = {
|
|
2952
|
+
layer: {
|
|
2953
|
+
zIndex: '1 !important',
|
|
2954
|
+
},
|
|
2955
|
+
};
|
|
2956
|
+
|
|
2957
|
+
// Helper function to generate a unique class name
|
|
2958
|
+
const generateClassName$1 = (base) => `${base}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2959
|
+
// Helper function to convert camelCased properties to hyphenated CSS properties
|
|
2960
|
+
const convertStylesToCSS$1 = (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$1(className, styles[key]);
|
|
2965
|
+
cssString += `${key} { ${mediaStyles} }`;
|
|
2966
|
+
}
|
|
2967
|
+
else if (key.startsWith("&:")) {
|
|
2968
|
+
const pseudoClass = key.replace("&", "");
|
|
2969
|
+
cssString += `${pseudoClass} { ${convertStylesToCSS$1("", 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$1 = (stylesObj) => {
|
|
2981
|
+
const [classNames, setClassNames] = useState({});
|
|
2982
|
+
useEffect(() => {
|
|
2983
|
+
const convertedStyles = Object.keys(stylesObj).map((key) => {
|
|
2984
|
+
const className = generateClassName$1(key);
|
|
2985
|
+
const styleElement = document.createElement("style");
|
|
2986
|
+
styleElement.innerHTML = convertStylesToCSS$1(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$1 = () => {
|
|
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$1 = (params) => {
|
|
3021
|
+
const { onClose, onMenuClick, anchorRef, dropDownOptions } = params;
|
|
3022
|
+
const [CurrentModal, setCurrentModal] = useCurrentModal$1();
|
|
3023
|
+
const styles = useDynamicStyles$1(dropdownStyles$1);
|
|
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$1 = (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$1, { dropDownOptions: dropdownOptions, anchorRef: ref, onClose: () => setVisible(false), onMenuClick: (dropDownOption) => {
|
|
3043
|
+
onClick(dropDownOption);
|
|
3044
|
+
} }))));
|
|
3045
|
+
};
|
|
3046
|
+
|
|
2970
3047
|
// export function buildFilters(filters: AttributeFilter[]): string {
|
|
2971
3048
|
// return filters
|
|
2972
3049
|
// .map(({ attribute, operator, value }) => `filter=${attribute}:${operator}:${value}`)
|
|
@@ -3031,12 +3108,13 @@ class LineListService {
|
|
|
3031
3108
|
this.httpClient = httpClient;
|
|
3032
3109
|
}
|
|
3033
3110
|
getProgramMetadata(programId) {
|
|
3034
|
-
return this.httpClient.get(`programs/${programId}.json?fields=programType,programStages[id,name,programStageDataElements[dataElement[id,name]]],organisationUnits[id,name]
|
|
3111
|
+
return this.httpClient.get(`programs/${programId}.json?fields=programType,programStages[id,name,programStageDataElements[dataElement[id,name]]],organisationUnits[id,name],*`);
|
|
3035
3112
|
}
|
|
3036
|
-
getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
|
|
3113
|
+
getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters = [], startDate, endDate, ouMode) {
|
|
3037
3114
|
const filterParams = buildFilters(filters);
|
|
3038
3115
|
const dateFilter = startDate && endDate ? `&programStartDate=${startDate}&programEndDate=${endDate}` : '';
|
|
3039
|
-
|
|
3116
|
+
const ouModeIdentifier = ouMode ? `&ouMode=${ouMode}` : ``;
|
|
3117
|
+
return this.httpClient.get(`trackedEntityInstances.json?program=${programId}&ou=${orgUnit}${ouModeIdentifier}&page=${page}&pageSize=${pageSize}&fields=trackedEntityInstance,attributes[*,displayInList],enrollments[*]&totalPages=true&${filterParams}${dateFilter}`).pipe(map$1((response) => {
|
|
3040
3118
|
response.trackedEntityInstances.forEach((tei) => {
|
|
3041
3119
|
// Filter attributes to only include those with displayInList=true
|
|
3042
3120
|
tei.attributes = tei.attributes.filter((attr) => attr.displayInList);
|
|
@@ -3044,32 +3122,34 @@ class LineListService {
|
|
|
3044
3122
|
return response;
|
|
3045
3123
|
}));
|
|
3046
3124
|
}
|
|
3047
|
-
getEvents(programId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
|
|
3125
|
+
getEvents(programId, orgUnit, page, pageSize, filters = [], startDate, endDate, ouMode) {
|
|
3048
3126
|
const filterParams = buildFilters(filters);
|
|
3049
3127
|
const dateFilter = startDate && endDate ? `&startDate=${startDate}&endDate=${endDate}` : '';
|
|
3050
|
-
|
|
3128
|
+
const ouModeIdentifier = ouMode ? `&ouMode=${ouMode}` : ``;
|
|
3129
|
+
return this.httpClient.get(`events.json?program=${programId}&orgUnit=${orgUnit}${ouModeIdentifier}&page=${page}&pageSize=${pageSize}&fields=*&totalPages=true&${filterParams}${dateFilter}`);
|
|
3051
3130
|
}
|
|
3052
|
-
getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters = [], startDate, endDate) {
|
|
3131
|
+
getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters = [], startDate, endDate, ouMode) {
|
|
3053
3132
|
const filterParams = buildFilters(filters);
|
|
3054
3133
|
const dateFilter = startDate && endDate ? `&startDate=${startDate}&endDate=${endDate}` : '';
|
|
3055
|
-
|
|
3134
|
+
const ouModeIdentifier = ouMode ? `&ouMode=${ouMode}` : ``;
|
|
3135
|
+
return this.httpClient.get(`events.json?programStage=${programStageId}&orgUnit=${orgUnit}${ouModeIdentifier}&page=${page}&pageSize=${pageSize}&fields=*&totalPages=true&${filterParams}${dateFilter}`);
|
|
3056
3136
|
}
|
|
3057
|
-
getLineListData(programId, orgUnit = '', programStageId, page = 1, pageSize = 10, filters = [], startDate, endDate) {
|
|
3137
|
+
getLineListData(programId, orgUnit = '', programStageId, page = 1, pageSize = 10, filters = [], startDate, endDate, ouMode) {
|
|
3058
3138
|
return this.getProgramMetadata(programId).pipe(switchMap((programMetadata) => {
|
|
3059
3139
|
if (programStageId) {
|
|
3060
|
-
return this.getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((events) => ({
|
|
3140
|
+
return this.getEventsByProgramStage(programStageId, orgUnit, page, pageSize, filters, startDate, endDate, ouMode).pipe(map$1((events) => ({
|
|
3061
3141
|
metadata: programMetadata,
|
|
3062
3142
|
data: events,
|
|
3063
3143
|
})));
|
|
3064
3144
|
}
|
|
3065
3145
|
if (programMetadata.programType === 'WITH_REGISTRATION') {
|
|
3066
|
-
return this.getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((teis) => ({
|
|
3146
|
+
return this.getTrackedEntityInstances(programId, orgUnit, page, pageSize, filters, startDate, endDate, ouMode).pipe(map$1((teis) => ({
|
|
3067
3147
|
metadata: programMetadata,
|
|
3068
3148
|
data: teis,
|
|
3069
3149
|
})));
|
|
3070
3150
|
}
|
|
3071
3151
|
else {
|
|
3072
|
-
return this.getEvents(programId, orgUnit, page, pageSize, filters, startDate, endDate).pipe(map$1((events) => ({
|
|
3152
|
+
return this.getEvents(programId, orgUnit, page, pageSize, filters, startDate, endDate, ouMode).pipe(map$1((events) => ({
|
|
3073
3153
|
metadata: programMetadata,
|
|
3074
3154
|
data: events,
|
|
3075
3155
|
})));
|
|
@@ -3083,102 +3163,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
3083
3163
|
type: Injectable
|
|
3084
3164
|
}], ctorParameters: () => [{ type: i1.NgxDhis2HttpClientService }] });
|
|
3085
3165
|
|
|
3086
|
-
const dropdownStyles = {
|
|
3087
|
-
layer: {
|
|
3088
|
-
zIndex: '1 !important',
|
|
3089
|
-
},
|
|
3090
|
-
};
|
|
3091
|
-
|
|
3092
|
-
// Helper function to generate a unique class name
|
|
3093
|
-
const generateClassName = (base) => `${base}-${Math.random().toString(36).substr(2, 9)}`;
|
|
3094
|
-
// Helper function to convert camelCased properties to hyphenated CSS properties
|
|
3095
|
-
const convertStylesToCSS = (className, styles) => {
|
|
3096
|
-
let cssString = `.${className} {`;
|
|
3097
|
-
for (const key in styles) {
|
|
3098
|
-
if (typeof styles[key] === "object" && key.startsWith("@media")) {
|
|
3099
|
-
const mediaStyles = convertStylesToCSS(className, styles[key]);
|
|
3100
|
-
cssString += `${key} { ${mediaStyles} }`;
|
|
3101
|
-
}
|
|
3102
|
-
else if (key.startsWith("&:")) {
|
|
3103
|
-
const pseudoClass = key.replace("&", "");
|
|
3104
|
-
cssString += `${pseudoClass} { ${convertStylesToCSS("", styles[key])} }`;
|
|
3105
|
-
}
|
|
3106
|
-
else {
|
|
3107
|
-
const cssKey = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
3108
|
-
cssString += `${cssKey}: ${styles[key]}; `;
|
|
3109
|
-
}
|
|
3110
|
-
}
|
|
3111
|
-
cssString += "}";
|
|
3112
|
-
return cssString;
|
|
3113
|
-
};
|
|
3114
|
-
// Custom hook for dynamic styles with generics
|
|
3115
|
-
const useDynamicStyles = (stylesObj) => {
|
|
3116
|
-
const [classNames, setClassNames] = useState({});
|
|
3117
|
-
useEffect(() => {
|
|
3118
|
-
const convertedStyles = Object.keys(stylesObj).map((key) => {
|
|
3119
|
-
const className = generateClassName(key);
|
|
3120
|
-
const styleElement = document.createElement("style");
|
|
3121
|
-
styleElement.innerHTML = convertStylesToCSS(className, stylesObj[key]);
|
|
3122
|
-
document.head.appendChild(styleElement);
|
|
3123
|
-
return {
|
|
3124
|
-
key,
|
|
3125
|
-
className,
|
|
3126
|
-
styleElement,
|
|
3127
|
-
};
|
|
3128
|
-
});
|
|
3129
|
-
setClassNames(convertedStyles.reduce((classNameEntity, convertedStyle) => {
|
|
3130
|
-
return {
|
|
3131
|
-
...classNameEntity,
|
|
3132
|
-
[convertedStyle.key]: convertedStyle.className,
|
|
3133
|
-
};
|
|
3134
|
-
}, {}));
|
|
3135
|
-
return () => {
|
|
3136
|
-
convertedStyles.forEach((convertedStyle) => {
|
|
3137
|
-
document.head.removeChild(convertedStyle.styleElement);
|
|
3138
|
-
});
|
|
3139
|
-
};
|
|
3140
|
-
}, []);
|
|
3141
|
-
return classNames;
|
|
3142
|
-
};
|
|
3143
|
-
|
|
3144
|
-
const useCurrentModal = () => {
|
|
3145
|
-
const [CurrentModal, setCurrentModal] = useState();
|
|
3146
|
-
return [
|
|
3147
|
-
CurrentModal,
|
|
3148
|
-
(Modal) => {
|
|
3149
|
-
// As setState supports functional updates, we can't pass functional
|
|
3150
|
-
// components directly
|
|
3151
|
-
setCurrentModal(() => Modal);
|
|
3152
|
-
},
|
|
3153
|
-
];
|
|
3154
|
-
};
|
|
3155
|
-
const ContextMenu = (params) => {
|
|
3156
|
-
const { onClose, onMenuClick, anchorRef, dropDownOptions } = params;
|
|
3157
|
-
const [CurrentModal, setCurrentModal] = useCurrentModal();
|
|
3158
|
-
const styles = useDynamicStyles(dropdownStyles);
|
|
3159
|
-
return (React__default.createElement(React__default.Fragment, null,
|
|
3160
|
-
React__default.createElement(Layer$1, { onBackdropClick: (event, data) => onClose(event, data), className: styles.layer },
|
|
3161
|
-
React__default.createElement(Popper, { reference: anchorRef, placement: "bottom-start" },
|
|
3162
|
-
React__default.createElement(FlyoutMenu, null, dropDownOptions.map((dropDownOption, index) => (React__default.createElement(MenuItem$1, { key: index, destructive: dropDownOption.destructive, label: dropDownOption.label, icon: dropDownOption.icon, onClick: () => {
|
|
3163
|
-
onMenuClick(dropDownOption);
|
|
3164
|
-
onClose();
|
|
3165
|
-
}, dense: true })))))),
|
|
3166
|
-
CurrentModal && (React__default.createElement(CurrentModal, { onClose: () => {
|
|
3167
|
-
onClose();
|
|
3168
|
-
setCurrentModal(null);
|
|
3169
|
-
} }))));
|
|
3170
|
-
};
|
|
3171
|
-
const DropdownMenu = (props) => {
|
|
3172
|
-
const ref = useRef();
|
|
3173
|
-
const [visible, setVisible] = useState(false);
|
|
3174
|
-
const { dropdownOptions, onClick } = props;
|
|
3175
|
-
return (React__default.createElement("div", { ref: ref, style: { display: "inline-block" } },
|
|
3176
|
-
React__default.createElement(Button$1, { small: true, secondary: true, icon: React__default.createElement(IconMore24, { color: colors$1.grey600 }), onClick: () => setVisible(true) }),
|
|
3177
|
-
visible && (React__default.createElement(ContextMenu, { dropDownOptions: dropdownOptions, anchorRef: ref, onClose: () => setVisible(false), onMenuClick: (dropDownOption) => {
|
|
3178
|
-
onClick(dropDownOption);
|
|
3179
|
-
} }))));
|
|
3180
|
-
};
|
|
3181
|
-
|
|
3182
3166
|
const getProgramStageData = (response, programStageId, pager) => {
|
|
3183
3167
|
const events = response.data.events;
|
|
3184
3168
|
const allDataElements = new Set();
|
|
@@ -3207,6 +3191,14 @@ const getProgramStageData = (response, programStageId, pager) => {
|
|
|
3207
3191
|
const getTrackedEntityData = (response, programId, pager, filters) => {
|
|
3208
3192
|
let teis = response.data
|
|
3209
3193
|
.trackedEntityInstances;
|
|
3194
|
+
let programMetaData = response.metadata.programTrackedEntityAttributes;
|
|
3195
|
+
const programAttributesMap = programMetaData.reduce((acc, attribute) => {
|
|
3196
|
+
if (attribute.displayInList) {
|
|
3197
|
+
acc[attribute.id] = attribute.displayName;
|
|
3198
|
+
}
|
|
3199
|
+
return acc;
|
|
3200
|
+
}, {});
|
|
3201
|
+
console.log('metadata', programAttributesMap);
|
|
3210
3202
|
if (filters) {
|
|
3211
3203
|
teis = getFilteredTrackedEntityInstances(teis, filters);
|
|
3212
3204
|
}
|
|
@@ -3218,7 +3210,12 @@ const getTrackedEntityData = (response, programId, pager, filters) => {
|
|
|
3218
3210
|
: tei.attributes;
|
|
3219
3211
|
attributes.forEach((attr) => allAttributes.add(attr.attribute));
|
|
3220
3212
|
});
|
|
3221
|
-
|
|
3213
|
+
console.log('all of the attributes', allAttributes);
|
|
3214
|
+
// const filteredAttributes = new Set(
|
|
3215
|
+
// [...allAttributes].filter((attributeId) => programAttributesMap[attributeId])
|
|
3216
|
+
// );
|
|
3217
|
+
// console.log('Filtered All Attributes:', filteredAttributes);
|
|
3218
|
+
let entityColumns = Array.from(allAttributes).map((attrId) => {
|
|
3222
3219
|
const foundAttribute = teis
|
|
3223
3220
|
.flatMap((tei) => {
|
|
3224
3221
|
const matchingEnrollment = tei.enrollments.find((enrollment) => enrollment.program === programId);
|
|
@@ -3232,6 +3229,10 @@ const getTrackedEntityData = (response, programId, pager, filters) => {
|
|
|
3232
3229
|
key: attrId,
|
|
3233
3230
|
};
|
|
3234
3231
|
});
|
|
3232
|
+
entityColumns = entityColumns.filter((column) => {
|
|
3233
|
+
// Check if the column label is part of any value in programAttributesMap
|
|
3234
|
+
return Object.values(programAttributesMap).some((value) => value.includes(column.label));
|
|
3235
|
+
});
|
|
3235
3236
|
const attributesData = teis.map((tei, idx) => {
|
|
3236
3237
|
let row = {
|
|
3237
3238
|
trackedEntityInstance: tei.trackedEntityInstance,
|
|
@@ -3278,7 +3279,7 @@ const addActionsColumn = (columns, actionOptions) => {
|
|
|
3278
3279
|
};
|
|
3279
3280
|
|
|
3280
3281
|
// src/app/line-list-table.component.ts
|
|
3281
|
-
class LineListTableComponent extends
|
|
3282
|
+
class LineListTableComponent extends ReactWrapperModule {
|
|
3282
3283
|
constructor() {
|
|
3283
3284
|
super(...arguments);
|
|
3284
3285
|
this.actionSelected = new EventEmitter();
|
|
@@ -3332,7 +3333,7 @@ class LineListTableComponent extends ReactWrapperComponent {
|
|
|
3332
3333
|
useEffect(() => {
|
|
3333
3334
|
setLoading(true);
|
|
3334
3335
|
this.lineListService
|
|
3335
|
-
.getLineListData(this.programId, this.orgUnit, this.programStageId, pager.page, pager.pageSize, this.attributeFilters, this.startDate, this.endDate)
|
|
3336
|
+
.getLineListData(this.programId, this.orgUnit, this.programStageId, pager.page, pager.pageSize, this.attributeFilters, this.startDate, this.endDate, this.ouMode)
|
|
3336
3337
|
.subscribe((response) => {
|
|
3337
3338
|
let entityColumns = [];
|
|
3338
3339
|
let responsePager;
|
|
@@ -3384,23 +3385,31 @@ class LineListTableComponent extends ReactWrapperComponent {
|
|
|
3384
3385
|
},
|
|
3385
3386
|
}));
|
|
3386
3387
|
};
|
|
3387
|
-
return (React__default.createElement("div", null, loading ? (React__default.createElement(
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
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$1, { dropdownOptions: getDropdownOptions(row), onClick: (option) => option.onClick?.() })) : (row[col.key])))))))),
|
|
3401
|
+
React__default.createElement(TableFoot, null,
|
|
3402
|
+
React__default.createElement(DataTableRow, null,
|
|
3403
|
+
React__default.createElement(DataTableCell, { colSpan: columns.length.toString() },
|
|
3404
|
+
React__default.createElement("div", null,
|
|
3405
|
+
React__default.createElement(Pagination, { page: pager.page, pageCount: pager.pageCount, pageSize: pager.pageSize, total: pager.total, onPageChange: (page) => setPager((prev) => ({ ...prev, page })), onPageSizeChange: (pageSize) => {
|
|
3406
|
+
const newPageSize = Number(pageSize);
|
|
3407
|
+
setPager((prev) => ({
|
|
3408
|
+
...prev,
|
|
3409
|
+
page: 1,
|
|
3410
|
+
pageSize: newPageSize,
|
|
3411
|
+
}));
|
|
3412
|
+
}, pageSizes: ['5', '10', '20', '50'] })))))))));
|
|
3404
3413
|
};
|
|
3405
3414
|
}
|
|
3406
3415
|
ngOnChanges(changes) {
|
|
@@ -3433,7 +3442,7 @@ class LineListTableComponent extends ReactWrapperComponent {
|
|
|
3433
3442
|
this.render();
|
|
3434
3443
|
}
|
|
3435
3444
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListTableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
3436
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: LineListTableComponent, isStandalone: false, selector: "app-line-list", inputs: { programId: "programId", orgUnit: "orgUnit", programStageId: "programStageId", actionOptions: "actionOptions", attributeFilters: "attributeFilters", startDate: "startDate", endDate: "endDate", filters: "filters" }, outputs: { actionSelected: "actionSelected" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: ["[data-test=dhis2-uiwidgets-pagination]{display:flex!important;flex-direction:row!important;justify-content:space-between!important;align-items:center!important}\n"] }); }
|
|
3445
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: LineListTableComponent, isStandalone: false, selector: "app-line-list", inputs: { programId: "programId", orgUnit: "orgUnit", programStageId: "programStageId", actionOptions: "actionOptions", attributeFilters: "attributeFilters", startDate: "startDate", endDate: "endDate", filters: "filters", ouMode: "ouMode" }, outputs: { actionSelected: "actionSelected" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: ["[data-test=dhis2-uiwidgets-pagination]{display:flex!important;flex-direction:row!important;justify-content:space-between!important;align-items:center!important}\n"] }); }
|
|
3437
3446
|
}
|
|
3438
3447
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListTableComponent, decorators: [{
|
|
3439
3448
|
type: Component,
|
|
@@ -3454,6 +3463,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
3454
3463
|
type: Input
|
|
3455
3464
|
}], filters: [{
|
|
3456
3465
|
type: Input
|
|
3466
|
+
}], ouMode: [{
|
|
3467
|
+
type: Input
|
|
3457
3468
|
}], actionSelected: [{
|
|
3458
3469
|
type: Output
|
|
3459
3470
|
}] } });
|
|
@@ -3473,6 +3484,186 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
3473
3484
|
}]
|
|
3474
3485
|
}] });
|
|
3475
3486
|
|
|
3487
|
+
const dropdownStyles = {
|
|
3488
|
+
layer: {
|
|
3489
|
+
zIndex: '1 !important',
|
|
3490
|
+
},
|
|
3491
|
+
};
|
|
3492
|
+
|
|
3493
|
+
// Helper function to generate a unique class name
|
|
3494
|
+
const generateClassName = (base) => `${base}-${Math.random().toString(36).substr(2, 9)}`;
|
|
3495
|
+
// Helper function to convert camelCased properties to hyphenated CSS properties
|
|
3496
|
+
const convertStylesToCSS = (className, styles) => {
|
|
3497
|
+
let cssString = `.${className} {`;
|
|
3498
|
+
for (const key in styles) {
|
|
3499
|
+
if (typeof styles[key] === "object" && key.startsWith("@media")) {
|
|
3500
|
+
const mediaStyles = convertStylesToCSS(className, styles[key]);
|
|
3501
|
+
cssString += `${key} { ${mediaStyles} }`;
|
|
3502
|
+
}
|
|
3503
|
+
else if (key.startsWith("&:")) {
|
|
3504
|
+
const pseudoClass = key.replace("&", "");
|
|
3505
|
+
cssString += `${pseudoClass} { ${convertStylesToCSS("", styles[key])} }`;
|
|
3506
|
+
}
|
|
3507
|
+
else {
|
|
3508
|
+
const cssKey = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
3509
|
+
cssString += `${cssKey}: ${styles[key]}; `;
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3512
|
+
cssString += "}";
|
|
3513
|
+
return cssString;
|
|
3514
|
+
};
|
|
3515
|
+
// Custom hook for dynamic styles with generics
|
|
3516
|
+
const useDynamicStyles = (stylesObj) => {
|
|
3517
|
+
const [classNames, setClassNames] = useState({});
|
|
3518
|
+
useEffect(() => {
|
|
3519
|
+
const convertedStyles = Object.keys(stylesObj).map((key) => {
|
|
3520
|
+
const className = generateClassName(key);
|
|
3521
|
+
const styleElement = document.createElement("style");
|
|
3522
|
+
styleElement.innerHTML = convertStylesToCSS(className, stylesObj[key]);
|
|
3523
|
+
document.head.appendChild(styleElement);
|
|
3524
|
+
return {
|
|
3525
|
+
key,
|
|
3526
|
+
className,
|
|
3527
|
+
styleElement,
|
|
3528
|
+
};
|
|
3529
|
+
});
|
|
3530
|
+
setClassNames(convertedStyles.reduce((classNameEntity, convertedStyle) => {
|
|
3531
|
+
return {
|
|
3532
|
+
...classNameEntity,
|
|
3533
|
+
[convertedStyle.key]: convertedStyle.className,
|
|
3534
|
+
};
|
|
3535
|
+
}, {}));
|
|
3536
|
+
return () => {
|
|
3537
|
+
convertedStyles.forEach((convertedStyle) => {
|
|
3538
|
+
document.head.removeChild(convertedStyle.styleElement);
|
|
3539
|
+
});
|
|
3540
|
+
};
|
|
3541
|
+
}, []);
|
|
3542
|
+
return classNames;
|
|
3543
|
+
};
|
|
3544
|
+
|
|
3545
|
+
const useCurrentModal = () => {
|
|
3546
|
+
const [CurrentModal, setCurrentModal] = useState();
|
|
3547
|
+
return [
|
|
3548
|
+
CurrentModal,
|
|
3549
|
+
(Modal) => {
|
|
3550
|
+
// As setState supports functional updates, we can't pass functional
|
|
3551
|
+
// components directly
|
|
3552
|
+
setCurrentModal(() => Modal);
|
|
3553
|
+
},
|
|
3554
|
+
];
|
|
3555
|
+
};
|
|
3556
|
+
const ContextMenu = (params) => {
|
|
3557
|
+
const { onClose, onMenuClick, anchorRef, dropDownOptions } = params;
|
|
3558
|
+
const [CurrentModal, setCurrentModal] = useCurrentModal();
|
|
3559
|
+
const styles = useDynamicStyles(dropdownStyles);
|
|
3560
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
3561
|
+
React__default.createElement(Layer$1, { onBackdropClick: (event, data) => onClose(event, data), className: styles.layer },
|
|
3562
|
+
React__default.createElement(Popper, { reference: anchorRef, placement: "bottom-start" },
|
|
3563
|
+
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: () => {
|
|
3564
|
+
onMenuClick(dropDownOption);
|
|
3565
|
+
onClose();
|
|
3566
|
+
}, dense: true })))))),
|
|
3567
|
+
CurrentModal && (React__default.createElement(CurrentModal, { onClose: () => {
|
|
3568
|
+
onClose();
|
|
3569
|
+
setCurrentModal(null);
|
|
3570
|
+
} }))));
|
|
3571
|
+
};
|
|
3572
|
+
const DropdownMenu = (props) => {
|
|
3573
|
+
const ref = useRef();
|
|
3574
|
+
const [visible, setVisible] = useState(false);
|
|
3575
|
+
const { dropdownOptions, onClick } = props;
|
|
3576
|
+
return (React__default.createElement("div", { ref: ref, style: { display: "inline-block" } },
|
|
3577
|
+
React__default.createElement(Button$1, { small: true, secondary: true, icon: React__default.createElement(IconMore24, { color: colors$1.grey600 }), onClick: () => setVisible(true) }),
|
|
3578
|
+
visible && (React__default.createElement(ContextMenu, { dropDownOptions: dropdownOptions, anchorRef: ref, onClose: () => setVisible(false), onMenuClick: (dropDownOption) => {
|
|
3579
|
+
onClick(dropDownOption);
|
|
3580
|
+
} }))));
|
|
3581
|
+
};
|
|
3582
|
+
|
|
3583
|
+
class DataTableUIComponent extends ReactWrapperModule {
|
|
3584
|
+
constructor() {
|
|
3585
|
+
super(...arguments);
|
|
3586
|
+
this.actionSelected = new EventEmitter();
|
|
3587
|
+
this.DataTableUI = () => {
|
|
3588
|
+
const [columns, setColumns] = useState([]);
|
|
3589
|
+
const [tableData, setTableData] = useState([]);
|
|
3590
|
+
useEffect(() => {
|
|
3591
|
+
if (!this.data || !this.columnDefinitions)
|
|
3592
|
+
return;
|
|
3593
|
+
const filteredColumns = this.columnDefinitions.filter((col) => col.visible !== false);
|
|
3594
|
+
const sortedColumns = filteredColumns.sort((a, b) => {
|
|
3595
|
+
const indexA = Number(a.index) || 0;
|
|
3596
|
+
const indexB = Number(b.index) || 0;
|
|
3597
|
+
return indexA - indexB;
|
|
3598
|
+
});
|
|
3599
|
+
setColumns(sortedColumns);
|
|
3600
|
+
setTableData(this.data);
|
|
3601
|
+
}, [this.data, this.columnDefinitions]);
|
|
3602
|
+
const getDropdownOptions = (row) => {
|
|
3603
|
+
return (this.actionOptions || []).map((option) => ({
|
|
3604
|
+
...option,
|
|
3605
|
+
onClick: () => {
|
|
3606
|
+
// Ensure the onClick is called with the correct context
|
|
3607
|
+
if (option.onClick) {
|
|
3608
|
+
option.onClick(row); // Passing row to the handler
|
|
3609
|
+
}
|
|
3610
|
+
this.actionSelected.emit({ action: option.label, row }); // Emit action and row details
|
|
3611
|
+
},
|
|
3612
|
+
}));
|
|
3613
|
+
};
|
|
3614
|
+
return (React__default.createElement("div", null,
|
|
3615
|
+
React__default.createElement(DataTable, null,
|
|
3616
|
+
React__default.createElement(TableHead, null,
|
|
3617
|
+
React__default.createElement(DataTableRow, null,
|
|
3618
|
+
columns.map((col) => (React__default.createElement(DataTableColumnHeader, { key: col.column }, col.display))),
|
|
3619
|
+
this.actionOptions && this.actionOptions.length > 0 && (React__default.createElement(DataTableColumnHeader, null, "Actions")))),
|
|
3620
|
+
React__default.createElement(TableBody, null, tableData.map((row, rowIndex) => (React__default.createElement(DataTableRow, { key: rowIndex },
|
|
3621
|
+
columns.map((col) => (React__default.createElement(DataTableCell, { key: col.column }, row[col.column] || '-'))),
|
|
3622
|
+
this.actionOptions && this.actionOptions.length > 0 && (React__default.createElement(DataTableCell, null,
|
|
3623
|
+
React__default.createElement(DropdownMenu, { dropdownOptions: getDropdownOptions(row), onClick: (option) => option.onClick?.(row) }))))))),
|
|
3624
|
+
React__default.createElement(TableFoot, null,
|
|
3625
|
+
React__default.createElement(DataTableRow, null,
|
|
3626
|
+
React__default.createElement(DataTableCell, { colSpan: columns.length + 1 }))))));
|
|
3627
|
+
};
|
|
3628
|
+
}
|
|
3629
|
+
async ngAfterViewInit() {
|
|
3630
|
+
if (!this.elementRef)
|
|
3631
|
+
throw new Error('No element ref');
|
|
3632
|
+
this.reactDomRoot = ReactDOM.createRoot(this.elementRef.nativeElement);
|
|
3633
|
+
this.component = this.DataTableUI;
|
|
3634
|
+
this.render();
|
|
3635
|
+
}
|
|
3636
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: DataTableUIComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
3637
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: DataTableUIComponent, isStandalone: false, selector: "app-data-table-ui", inputs: { data: "data", columnDefinitions: "columnDefinitions", actionOptions: "actionOptions" }, outputs: { actionSelected: "actionSelected" }, usesInheritance: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [""] }); }
|
|
3638
|
+
}
|
|
3639
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: DataTableUIComponent, decorators: [{
|
|
3640
|
+
type: Component,
|
|
3641
|
+
args: [{ selector: 'app-data-table-ui', standalone: false, template: '<ng-content></ng-content>' }]
|
|
3642
|
+
}], propDecorators: { data: [{
|
|
3643
|
+
type: Input
|
|
3644
|
+
}], columnDefinitions: [{
|
|
3645
|
+
type: Input
|
|
3646
|
+
}], actionOptions: [{
|
|
3647
|
+
type: Input
|
|
3648
|
+
}], actionSelected: [{
|
|
3649
|
+
type: Output
|
|
3650
|
+
}] } });
|
|
3651
|
+
|
|
3652
|
+
class DataTableUIModule {
|
|
3653
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: DataTableUIModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
3654
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: DataTableUIModule, declarations: [DataTableUIComponent], imports: [CommonModule, SharedDhis2UiModule, ReactWrapperModule], exports: [DataTableUIComponent] }); }
|
|
3655
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: DataTableUIModule, imports: [CommonModule, SharedDhis2UiModule] }); }
|
|
3656
|
+
}
|
|
3657
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: DataTableUIModule, decorators: [{
|
|
3658
|
+
type: NgModule,
|
|
3659
|
+
args: [{
|
|
3660
|
+
declarations: [DataTableUIComponent],
|
|
3661
|
+
exports: [DataTableUIComponent],
|
|
3662
|
+
imports: [CommonModule, SharedDhis2UiModule, ReactWrapperModule],
|
|
3663
|
+
providers: [],
|
|
3664
|
+
}]
|
|
3665
|
+
}] });
|
|
3666
|
+
|
|
3476
3667
|
class FormField {
|
|
3477
3668
|
constructor(options = {}) {
|
|
3478
3669
|
this.value = options.value || '';
|
|
@@ -3911,6 +4102,13 @@ class FormValueUtil {
|
|
|
3911
4102
|
}
|
|
3912
4103
|
}
|
|
3913
4104
|
|
|
4105
|
+
class TranslationUtil {
|
|
4106
|
+
static getTranslatedFormName(field, locale = 'sw') {
|
|
4107
|
+
const translation = (field['translations'] || []).find((translation) => translation['locale'] == locale && translation['property'] == 'NAME');
|
|
4108
|
+
return (translation ? translation['value'] : field['formName'] || field['name']);
|
|
4109
|
+
}
|
|
4110
|
+
}
|
|
4111
|
+
|
|
3914
4112
|
// Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
|
|
3915
4113
|
// Use of this source code is governed by a BSD-style
|
|
3916
4114
|
// license that can be found in the LICENSE file.
|
|
@@ -3922,6 +4120,9 @@ class FormFieldGroup {
|
|
|
3922
4120
|
const fields = this.params.formFieldGroup?.fields || [];
|
|
3923
4121
|
return fields
|
|
3924
4122
|
.map((field) => {
|
|
4123
|
+
if (field instanceof FormField) {
|
|
4124
|
+
return field;
|
|
4125
|
+
}
|
|
3925
4126
|
const fieldMetaData = this.params.fieldMetaData.find((attribute) => attribute['id'] === field.id);
|
|
3926
4127
|
if (!fieldMetaData) {
|
|
3927
4128
|
return null;
|
|
@@ -3964,7 +4165,7 @@ class FormFieldGroup {
|
|
|
3964
4165
|
toJson() {
|
|
3965
4166
|
return {
|
|
3966
4167
|
id: this.params.formFieldGroup?.id,
|
|
3967
|
-
name: this.params.formFieldGroup
|
|
4168
|
+
name: TranslationUtil.getTranslatedFormName(this.params.formFieldGroup, this.params.locale),
|
|
3968
4169
|
isFormHorizontal: this.params.formFieldGroup?.isFormHorizontal,
|
|
3969
4170
|
repeatDependentField: this.params.formFieldGroup?.repeatDependentField,
|
|
3970
4171
|
dataKey: this.params.formFieldGroup?.dataKey,
|
|
@@ -4071,7 +4272,11 @@ class FormMetaData {
|
|
|
4071
4272
|
this.params = params;
|
|
4072
4273
|
}
|
|
4073
4274
|
get sections() {
|
|
4074
|
-
|
|
4275
|
+
const customSections = this.params.customFormMetaData?.sections;
|
|
4276
|
+
if (!customSections) {
|
|
4277
|
+
return this.#getSectionFromPrograms(this.params.programs);
|
|
4278
|
+
}
|
|
4279
|
+
return (this.params.customFormMetaData?.sections || [])
|
|
4075
4280
|
.map((section) => {
|
|
4076
4281
|
const program = this.params.programs.find((program) => section.program === program['id']);
|
|
4077
4282
|
if (!program) {
|
|
@@ -4091,7 +4296,7 @@ class FormMetaData {
|
|
|
4091
4296
|
get rules() {
|
|
4092
4297
|
let ruleVariables = [];
|
|
4093
4298
|
return [
|
|
4094
|
-
...(this.params.
|
|
4299
|
+
...(this.params.customFormMetaData?.rules || []),
|
|
4095
4300
|
...(flatten(this.params.programs.map((program) => {
|
|
4096
4301
|
ruleVariables = [
|
|
4097
4302
|
...ruleVariables,
|
|
@@ -4101,10 +4306,131 @@ class FormMetaData {
|
|
|
4101
4306
|
})) || []).map((rule) => new MetadataRule(rule, ruleVariables).toJson()),
|
|
4102
4307
|
];
|
|
4103
4308
|
}
|
|
4309
|
+
#getSectionFromPrograms(programs) {
|
|
4310
|
+
const sections = flatten(programs.map((program) => {
|
|
4311
|
+
return [
|
|
4312
|
+
this.#getReportingDetailsSection(program),
|
|
4313
|
+
new FormMetadataSection({
|
|
4314
|
+
section: {
|
|
4315
|
+
id: 'registration',
|
|
4316
|
+
name: 'Registration',
|
|
4317
|
+
fieldGroups: (program.programSections || []).length > 0
|
|
4318
|
+
? program.programSections.map((programSection) => {
|
|
4319
|
+
return {
|
|
4320
|
+
id: programSection.id,
|
|
4321
|
+
name: programSection.name,
|
|
4322
|
+
sortOrder: programSection.sortOrder,
|
|
4323
|
+
fields: programSection.trackedEntityAttributes,
|
|
4324
|
+
};
|
|
4325
|
+
})
|
|
4326
|
+
: [
|
|
4327
|
+
{
|
|
4328
|
+
id: 'registration',
|
|
4329
|
+
name: '',
|
|
4330
|
+
sortOrder: 1,
|
|
4331
|
+
fields: (program.programTrackedEntityAttributes || []).map((programTrackedEntityAttribute) => {
|
|
4332
|
+
return {
|
|
4333
|
+
id: programTrackedEntityAttribute
|
|
4334
|
+
.trackedEntityAttribute?.id,
|
|
4335
|
+
};
|
|
4336
|
+
}),
|
|
4337
|
+
},
|
|
4338
|
+
],
|
|
4339
|
+
},
|
|
4340
|
+
program,
|
|
4341
|
+
locale: this.params.locale,
|
|
4342
|
+
}).toJson(),
|
|
4343
|
+
...(program.programStages || []).map((programStage) => {
|
|
4344
|
+
return new FormMetadataSection({
|
|
4345
|
+
section: {
|
|
4346
|
+
id: programStage.id,
|
|
4347
|
+
name: programStage.name,
|
|
4348
|
+
fieldGroups: (programStage.programStageSections || []).length > 0
|
|
4349
|
+
? programStage.programStageSections.map((programStageSection) => {
|
|
4350
|
+
return {
|
|
4351
|
+
id: programStageSection.id,
|
|
4352
|
+
name: programStageSection.name,
|
|
4353
|
+
dataKey: camelCase(programStage.code),
|
|
4354
|
+
repeatableStage: programStage.repeatable
|
|
4355
|
+
? programStage.id
|
|
4356
|
+
: undefined,
|
|
4357
|
+
sortOrder: programStageSection.sortOrder,
|
|
4358
|
+
fields: programStageSection.dataElements,
|
|
4359
|
+
};
|
|
4360
|
+
})
|
|
4361
|
+
: [
|
|
4362
|
+
{
|
|
4363
|
+
id: programStage.id,
|
|
4364
|
+
dataKey: camelCase(programStage.code),
|
|
4365
|
+
repeatableStage: programStage.repeatable
|
|
4366
|
+
? programStage.id
|
|
4367
|
+
: undefined,
|
|
4368
|
+
fields: (programStage.programStageDataElements || []).map((programStageDataElement) => {
|
|
4369
|
+
return {
|
|
4370
|
+
id: programStageDataElement.dataElement?.id,
|
|
4371
|
+
};
|
|
4372
|
+
}),
|
|
4373
|
+
},
|
|
4374
|
+
],
|
|
4375
|
+
},
|
|
4376
|
+
program,
|
|
4377
|
+
locale: this.params.locale,
|
|
4378
|
+
}).toJson();
|
|
4379
|
+
}),
|
|
4380
|
+
];
|
|
4381
|
+
}));
|
|
4382
|
+
if (sections.length === 0) {
|
|
4383
|
+
return [];
|
|
4384
|
+
}
|
|
4385
|
+
return sections;
|
|
4386
|
+
}
|
|
4387
|
+
#getReportingDetailsSection(program) {
|
|
4388
|
+
return new FormMetadataSection({
|
|
4389
|
+
section: {
|
|
4390
|
+
id: 'reporting_details',
|
|
4391
|
+
name: 'Reporting details',
|
|
4392
|
+
fieldGroups: [
|
|
4393
|
+
{
|
|
4394
|
+
id: 'reporting_details',
|
|
4395
|
+
sortOrder: 1,
|
|
4396
|
+
isFormHorizontal: true,
|
|
4397
|
+
fields: [
|
|
4398
|
+
new FormField({
|
|
4399
|
+
id: 'orgUnit',
|
|
4400
|
+
key: 'orgUnit',
|
|
4401
|
+
label: 'Organisation unit',
|
|
4402
|
+
code: 'orgUnit',
|
|
4403
|
+
required: true,
|
|
4404
|
+
controlType: 'org-unit',
|
|
4405
|
+
}),
|
|
4406
|
+
new DateField({
|
|
4407
|
+
id: 'enrollmentDate',
|
|
4408
|
+
label: program.enrollmentDateLabel || 'Enrollment date',
|
|
4409
|
+
code: 'enrollmentDate',
|
|
4410
|
+
key: 'enrollmentDate',
|
|
4411
|
+
required: true,
|
|
4412
|
+
}),
|
|
4413
|
+
program.displayIncidentDate
|
|
4414
|
+
? new DateField({
|
|
4415
|
+
id: 'incidentDate',
|
|
4416
|
+
label: program.incidentDateLabel || 'Incident date',
|
|
4417
|
+
code: 'incidentDate',
|
|
4418
|
+
key: 'incidentDate',
|
|
4419
|
+
required: true,
|
|
4420
|
+
})
|
|
4421
|
+
: null,
|
|
4422
|
+
].filter((field) => field),
|
|
4423
|
+
},
|
|
4424
|
+
],
|
|
4425
|
+
},
|
|
4426
|
+
program,
|
|
4427
|
+
locale: this.params.locale,
|
|
4428
|
+
}).toJson();
|
|
4429
|
+
}
|
|
4104
4430
|
toJson() {
|
|
4105
4431
|
return {
|
|
4106
|
-
id: this.params.
|
|
4107
|
-
name: this.params.
|
|
4432
|
+
id: this.params.customFormMetaData?.id,
|
|
4433
|
+
name: TranslationUtil.getTranslatedFormName(this.params.customFormMetaData || {}, this.params.locale),
|
|
4108
4434
|
fields: this.fields,
|
|
4109
4435
|
sections: this.sections,
|
|
4110
4436
|
rules: this.rules,
|
|
@@ -4124,16 +4450,18 @@ class FormValue {
|
|
|
4124
4450
|
clear() {
|
|
4125
4451
|
this.form.reset();
|
|
4126
4452
|
}
|
|
4127
|
-
getValues() {
|
|
4453
|
+
getValues(options) {
|
|
4128
4454
|
const newValues = {};
|
|
4129
4455
|
const formValues = this.form?.getRawValue();
|
|
4456
|
+
if (options?.valueOnly) {
|
|
4457
|
+
return formValues;
|
|
4458
|
+
}
|
|
4130
4459
|
Object.keys(formValues).forEach((key) => {
|
|
4131
4460
|
const field = find(this.fields, ['key', key]);
|
|
4132
4461
|
if (field) {
|
|
4133
4462
|
newValues[key] = {
|
|
4134
|
-
|
|
4463
|
+
...field,
|
|
4135
4464
|
value: formValues[key],
|
|
4136
|
-
options: field.options,
|
|
4137
4465
|
};
|
|
4138
4466
|
}
|
|
4139
4467
|
});
|
|
@@ -4148,7 +4476,7 @@ class FormValue {
|
|
|
4148
4476
|
// Copyright 2024 UDSM DHIS2 Lab. All rights reserved.
|
|
4149
4477
|
// Use of this source code is governed by a BSD-style
|
|
4150
4478
|
// license that can be found in the LICENSE file.
|
|
4151
|
-
class BaseFormFieldComponent extends
|
|
4479
|
+
class BaseFormFieldComponent extends ReactWrapperModule {
|
|
4152
4480
|
constructor() {
|
|
4153
4481
|
super(...arguments);
|
|
4154
4482
|
this.ngZone = inject(NgZone);
|
|
@@ -4774,12 +5102,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
4774
5102
|
}] } });
|
|
4775
5103
|
|
|
4776
5104
|
class RepeatableFormComponent {
|
|
5105
|
+
#eventFormValue$;
|
|
5106
|
+
#showForm$;
|
|
5107
|
+
#events$;
|
|
4777
5108
|
constructor() {
|
|
5109
|
+
this.ngZone = inject(NgZone);
|
|
4778
5110
|
this.fieldGroup = input.required();
|
|
5111
|
+
this.events = model();
|
|
4779
5112
|
this.dataEntities = input.required();
|
|
4780
5113
|
this.repeatableEvents = [];
|
|
4781
5114
|
this.repeatableData = {};
|
|
4782
5115
|
this.repeatableStageUpdate = new EventEmitter();
|
|
5116
|
+
this.eventFormValue = signal(null);
|
|
5117
|
+
this.showForm = signal(false);
|
|
5118
|
+
this.eventIndex = signal(0);
|
|
5119
|
+
this.#eventFormValue$ = toObservable(this.eventFormValue);
|
|
5120
|
+
this.#showForm$ = toObservable(this.showForm);
|
|
5121
|
+
this.#events$ = toObservable(this.events);
|
|
4783
5122
|
}
|
|
4784
5123
|
get isValid() {
|
|
4785
5124
|
return !Object.keys(this.repeatableData).some((index) => {
|
|
@@ -4788,9 +5127,9 @@ class RepeatableFormComponent {
|
|
|
4788
5127
|
});
|
|
4789
5128
|
}
|
|
4790
5129
|
ngOnInit() {
|
|
4791
|
-
this.
|
|
4792
|
-
|
|
4793
|
-
|
|
5130
|
+
this.eventForm = FormUtil.getFormGroup(this.fieldGroup().fields, {});
|
|
5131
|
+
this.eventFormValue.set(new FormValue(this.eventForm, this.fieldGroup().fields));
|
|
5132
|
+
this.repeatableEvents = (this.events() || []).map((event, index) => {
|
|
4794
5133
|
const fieldControls = (this.fieldGroup().fields || []).reduce((fieldObject, field) => {
|
|
4795
5134
|
const value = (event.dataValueEntities || {})[field.key] || '';
|
|
4796
5135
|
return {
|
|
@@ -4804,19 +5143,20 @@ class RepeatableFormComponent {
|
|
|
4804
5143
|
});
|
|
4805
5144
|
this.repeatableStageUpdate.emit(this.repeatableData);
|
|
4806
5145
|
}
|
|
4807
|
-
onFormUpdate(formValue
|
|
4808
|
-
this.
|
|
4809
|
-
|
|
4810
|
-
this.
|
|
4811
|
-
|
|
5146
|
+
onFormUpdate(formValue) {
|
|
5147
|
+
this.eventFormValue.set(formValue);
|
|
5148
|
+
this.repeatableData = {
|
|
5149
|
+
...this.repeatableData,
|
|
5150
|
+
[this.eventIndex()]: formValue,
|
|
5151
|
+
};
|
|
4812
5152
|
}
|
|
4813
5153
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: RepeatableFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4814
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
5154
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.8", type: RepeatableFormComponent, isStandalone: false, selector: "ng-dhis2-ui-repeatable-form", inputs: { formObject: { classPropertyName: "formObject", publicName: "formObject", isSignal: false, isRequired: false, transformFunction: null }, formData: { classPropertyName: "formData", publicName: "formData", isSignal: false, isRequired: false, transformFunction: null }, fieldGroup: { classPropertyName: "fieldGroup", publicName: "fieldGroup", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: false, isRequired: false, transformFunction: null }, numberOfRows: { classPropertyName: "numberOfRows", publicName: "numberOfRows", isSignal: false, isRequired: false, transformFunction: null }, programRuleActions: { classPropertyName: "programRuleActions", publicName: "programRuleActions", isSignal: false, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, program: { classPropertyName: "program", publicName: "program", isSignal: false, isRequired: false, transformFunction: null }, programStage: { classPropertyName: "programStage", publicName: "programStage", isSignal: false, isRequired: false, transformFunction: null }, repeatDependentField: { classPropertyName: "repeatDependentField", publicName: "repeatDependentField", isSignal: false, isRequired: false, transformFunction: null }, dataEntities: { classPropertyName: "dataEntities", publicName: "dataEntities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { events: "eventsChange", repeatableStageUpdate: "repeatableStageUpdate" }, ngImport: i0, template: "<div class=\"form__repeatable-stage-container\">\n <!-- <ng-dhis2-ui-wrapper [component]=\"EventTable()\"></ng-dhis2-ui-wrapper> -->\n @if(showForm()) {\n <div class=\"form__repeatable-stage-form\">\n <ng-dhis2-ui-form\n [fields]=\"fieldGroup().fields || []\"\n [form]=\"eventForm\"\n [programRuleActions]=\"programRuleActions\"\n [dataEntities]=\"{}\"\n [isFormHorizontal]=\"false\"\n (formUpdate)=\"onFormUpdate($event)\"\n >\n </ng-dhis2-ui-form>\n\n <!-- <ng-dhis2-ui-wrapper [component]=\"FormActionButtons\"></ng-dhis2-ui-wrapper> -->\n </div>\n }\n</div>\n", styles: [".form__repeatable-stage-container{margin-top:16px}.form__repeatable-stage-form{border:solid 1px rgb(232,237,242);border-top-style:none;background-color:#fff;padding:16px}\n"], dependencies: [{ kind: "component", type: FormComponent, selector: "ng-dhis2-ui-form", inputs: ["formConfig", "fields", "form", "isFormHorizontal", "showSaveButton", "fieldsData", "fieldClass", "shouldRenderAsCheckBoxesButton", "programRuleActions", "dataEntities"], outputs: ["formUpdate"] }] }); }
|
|
4815
5155
|
}
|
|
4816
5156
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: RepeatableFormComponent, decorators: [{
|
|
4817
5157
|
type: Component,
|
|
4818
|
-
args: [{ selector: 'ng-dhis2-ui-repeatable-form', standalone: false, template: "<div>\n <
|
|
4819
|
-
}], propDecorators: { formObject: [{
|
|
5158
|
+
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"] }]
|
|
5159
|
+
}], ctorParameters: () => [], propDecorators: { formObject: [{
|
|
4820
5160
|
type: Input
|
|
4821
5161
|
}], formData: [{
|
|
4822
5162
|
type: Input
|
|
@@ -4826,8 +5166,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
4826
5166
|
type: Input
|
|
4827
5167
|
}], programRuleActions: [{
|
|
4828
5168
|
type: Input
|
|
4829
|
-
}], events: [{
|
|
4830
|
-
type: Input
|
|
4831
5169
|
}], program: [{
|
|
4832
5170
|
type: Input
|
|
4833
5171
|
}], programStage: [{
|
|
@@ -4840,8 +5178,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
4840
5178
|
|
|
4841
5179
|
class SectionFormComponent {
|
|
4842
5180
|
constructor() {
|
|
5181
|
+
this.ngZone = inject(NgZone);
|
|
4843
5182
|
this.loading = input();
|
|
4844
|
-
this.isLabResulst = false;
|
|
4845
5183
|
this.formMetaData = input.required();
|
|
4846
5184
|
this.dataValueEntities = input.required();
|
|
4847
5185
|
this.formGroups = {};
|
|
@@ -4851,43 +5189,27 @@ class SectionFormComponent {
|
|
|
4851
5189
|
this.save = new EventEmitter();
|
|
4852
5190
|
this.formUpdate = new EventEmitter();
|
|
4853
5191
|
this.cancel = new EventEmitter();
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
const valueValidity = Object.keys(this.formValueEntity)
|
|
4857
|
-
.map((key) => {
|
|
4858
|
-
return (this.formValueEntity[key] || {}).isValid;
|
|
4859
|
-
})
|
|
4860
|
-
.some((validity) => !validity);
|
|
4861
|
-
const repeatableDataValidity = Object.keys(this.repeatableFormValueEntity)
|
|
4862
|
-
.map((key) => {
|
|
4863
|
-
return Object.keys(this.repeatableFormValueEntity[key]).some((valueIndex) => {
|
|
4864
|
-
return ((this.repeatableFormValueEntity[key] || {})[+valueIndex] || {}).isValid;
|
|
4865
|
-
});
|
|
4866
|
-
})
|
|
4867
|
-
.some((validity) => !validity);
|
|
4868
|
-
return valueValidity && repeatableDataValidity;
|
|
5192
|
+
this.inValid = signal(true);
|
|
5193
|
+
this.inValid$ = toObservable(this.inValid);
|
|
4869
5194
|
}
|
|
4870
5195
|
ngOnInit() {
|
|
4871
5196
|
if (this.formMetaData().sections) {
|
|
4872
5197
|
(this.formMetaData().sections || []).forEach((formSection) => {
|
|
4873
5198
|
(formSection.fieldGroups || []).forEach((fieldGroup) => {
|
|
4874
5199
|
const formGroup = FormUtil.getFormGroup(fieldGroup.fields, this.dataValueEntities());
|
|
4875
|
-
// Set bookingId as default value for `travelerReferenceId` after search refLabNum
|
|
4876
|
-
const refLabNum = formGroup.get('refLabNum');
|
|
4877
|
-
const travelerReferenceIdControl = formGroup.get('travelerReferenceId');
|
|
4878
|
-
if (travelerReferenceIdControl) {
|
|
4879
|
-
const defaultValue = this.clientId ? this.clientId : '';
|
|
4880
|
-
travelerReferenceIdControl.setValue(defaultValue);
|
|
4881
|
-
}
|
|
4882
|
-
else if (refLabNum) {
|
|
4883
|
-
const defaultValue = this.labNumber ? this.labNumber : '';
|
|
4884
|
-
refLabNum.setValue(defaultValue);
|
|
4885
|
-
}
|
|
4886
5200
|
const formValue = new FormValue(formGroup, fieldGroup.fields);
|
|
4887
|
-
this.formValueEntity[fieldGroup.id] = formValue;
|
|
4888
5201
|
this.formGroups[fieldGroup.id] = formGroup;
|
|
5202
|
+
if (!fieldGroup.repeatableStage) {
|
|
5203
|
+
this.formValueEntity[fieldGroup.id] = formValue;
|
|
5204
|
+
}
|
|
5205
|
+
else {
|
|
5206
|
+
this.repeatableFormValueEntity[fieldGroup.dataKey || fieldGroup.id] = {
|
|
5207
|
+
0: formValue,
|
|
5208
|
+
};
|
|
5209
|
+
}
|
|
4889
5210
|
});
|
|
4890
5211
|
});
|
|
5212
|
+
this.inValid.set(this.checkIfInValid());
|
|
4891
5213
|
this.ruleActions = new ProgramRuleEngine()
|
|
4892
5214
|
.setRules(this.formMetaData().rules)
|
|
4893
5215
|
.setDataValues(this.#getDataValue())
|
|
@@ -4895,13 +5217,17 @@ class SectionFormComponent {
|
|
|
4895
5217
|
}
|
|
4896
5218
|
}
|
|
4897
5219
|
onUpdateRepeatableStage(repeatableData, fieldGroup) {
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
5220
|
+
if (!isEmpty(repeatableData)) {
|
|
5221
|
+
this.repeatableFormValueEntity[fieldGroup.dataKey || fieldGroup.id] =
|
|
5222
|
+
repeatableData;
|
|
5223
|
+
this.inValid.set(this.checkIfInValid());
|
|
5224
|
+
const dataValues = this.#getDataValue();
|
|
5225
|
+
this.formUpdate.emit(dataValues);
|
|
5226
|
+
}
|
|
4902
5227
|
}
|
|
4903
5228
|
onFormUpdate(formValue, fieldGroupId) {
|
|
4904
5229
|
this.formValueEntity[fieldGroupId] = formValue;
|
|
5230
|
+
this.inValid.set(this.checkIfInValid());
|
|
4905
5231
|
const dataValues = this.#getDataValue();
|
|
4906
5232
|
this.ruleActions = new ProgramRuleEngine()
|
|
4907
5233
|
.setRules(this.formMetaData().rules)
|
|
@@ -4909,13 +5235,12 @@ class SectionFormComponent {
|
|
|
4909
5235
|
.execute();
|
|
4910
5236
|
this.formUpdate.emit(dataValues);
|
|
4911
5237
|
}
|
|
4912
|
-
onSubmit(
|
|
4913
|
-
event.stopPropagation();
|
|
5238
|
+
onSubmit() {
|
|
4914
5239
|
const dataValues = this.#getDataValue();
|
|
4915
5240
|
this.save.emit(dataValues);
|
|
4916
5241
|
}
|
|
4917
5242
|
onCancel(event) {
|
|
4918
|
-
event
|
|
5243
|
+
event?.stopPropagation();
|
|
4919
5244
|
this.cancel.emit();
|
|
4920
5245
|
}
|
|
4921
5246
|
#getDataValue() {
|
|
@@ -4934,21 +5259,28 @@ class SectionFormComponent {
|
|
|
4934
5259
|
}, {});
|
|
4935
5260
|
return { ...dataValues, ...repeatableValues };
|
|
4936
5261
|
}
|
|
5262
|
+
checkIfInValid() {
|
|
5263
|
+
const valueValidity = Object.keys(this.formValueEntity)
|
|
5264
|
+
.map((key) => {
|
|
5265
|
+
return (this.formValueEntity[key] || {}).isValid;
|
|
5266
|
+
})
|
|
5267
|
+
.some((validity) => !validity);
|
|
5268
|
+
const repeatableDataValidity = Object.keys(this.repeatableFormValueEntity)
|
|
5269
|
+
.map((key) => {
|
|
5270
|
+
return Object.keys(this.repeatableFormValueEntity[key]).some((valueIndex) => {
|
|
5271
|
+
return ((this.repeatableFormValueEntity[key] || {})[+valueIndex] || {}).isValid;
|
|
5272
|
+
});
|
|
5273
|
+
})
|
|
5274
|
+
.some((validity) => !validity);
|
|
5275
|
+
return valueValidity || repeatableDataValidity;
|
|
5276
|
+
}
|
|
4937
5277
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SectionFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4938
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.8", type: SectionFormComponent, isStandalone: false, selector: "ng-dhis2-ui-section-form", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null },
|
|
5278
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.8", type: SectionFormComponent, isStandalone: false, selector: "ng-dhis2-ui-section-form", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, formMetaData: { classPropertyName: "formMetaData", publicName: "formMetaData", isSignal: true, isRequired: true, transformFunction: null }, dataValueEntities: { classPropertyName: "dataValueEntities", publicName: "dataValueEntities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { save: "save", formUpdate: "formUpdate", cancel: "cancel" }, ngImport: i0, template: "<ng-container *ngIf=\"formMetaData()\">\n <ng-container *ngFor=\"let formSection of formMetaData().sections\">\n @if(formSection?.name; as sectionName) {\n <div class=\"form__section-name\">\n {{ sectionName }}\n </div>\n }\n <div class=\"form__section-content\">\n <ng-container *ngIf=\"formSection\">\n <div *ngFor=\"let fieldGroup of formSection?.fieldGroups\">\n <ng-container *ngIf=\"formGroups[fieldGroup.id] as formGroup\">\n <div\n *ngIf=\"fieldGroup.name && !fieldGroup.repeatableStage\"\n class=\"form__field-group-name\"\n >\n {{ fieldGroup?.name }}\n </div>\n <div *ngIf=\"fieldGroup.fields\">\n <!-- Single stage form section -->\n <ng-container *ngIf=\"!fieldGroup.repeatableStage\">\n <ng-dhis2-ui-form\n *ngIf=\"fieldGroup.fields.length > 0\"\n [fields]=\"fieldGroup.fields\"\n [form]=\"formGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [programRuleActions]=\"ruleActions\"\n [isFormHorizontal]=\"fieldGroup.isFormHorizontal || false\"\n (formUpdate)=\"onFormUpdate($event, fieldGroup.id)\"\n ></ng-dhis2-ui-form>\n </ng-container>\n\n <!-- Repeatable stage form section -->\n <ng-container *ngIf=\"fieldGroup.repeatableStage\">\n @if(fieldGroup.repeatDependentField) {\n\n <ng-container *ngIf=\"fieldGroup.repeatDependentField\">\n <ng-container\n *ngIf=\"{\n numberOfRows:\n dataValueEntities()[fieldGroup.repeatDependentField]\n } as dataParams\"\n >\n <ng-dhis2-ui-repeatable-form\n *ngIf=\"\n dataParams.numberOfRows &&\n dataParams.numberOfRows !== '0'\n \"\n [fieldGroup]=\"fieldGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [form]=\"formGroup\"\n [program]=\"formSection.program || ''\"\n [programStage]=\"fieldGroup.repeatableStage\"\n [programRuleActions]=\"ruleActions\"\n [numberOfRows]=\"+dataParams.numberOfRows\"\n [repeatDependentField]=\"\n fieldGroup.repeatDependentField || ''\n \"\n [events]=\"dataValueEntities()[fieldGroup.dataKey!]\"\n (repeatableStageUpdate)=\"\n onUpdateRepeatableStage($event, fieldGroup)\n \"\n ></ng-dhis2-ui-repeatable-form\n ></ng-container>\n </ng-container>\n } @else {\n <ng-dhis2-ui-repeatable-form\n [fieldGroup]=\"fieldGroup\"\n [dataEntities]=\"dataValueEntities()\"\n [form]=\"formGroup\"\n [program]=\"formSection.program || ''\"\n [programStage]=\"fieldGroup.repeatableStage\"\n [programRuleActions]=\"ruleActions\"\n [numberOfRows]=\"1\"\n [repeatDependentField]=\"fieldGroup.repeatDependentField || ''\"\n [events]=\"dataValueEntities()[fieldGroup.dataKey!]\"\n (repeatableStageUpdate)=\"\n onUpdateRepeatableStage($event, fieldGroup)\n \"\n ></ng-dhis2-ui-repeatable-form>\n }\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</ng-container>\n", styles: [".form__section-name{font-size:16px;font-weight:600;margin-bottom:16px}.form__section-content{margin-bottom:24px}.form__field-group-name{font-size:14px;font-weight:500;padding-bottom:8px;border-bottom:solid 1px rgb(232,237,242);margin-bottom:16px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormComponent, selector: "ng-dhis2-ui-form", inputs: ["formConfig", "fields", "form", "isFormHorizontal", "showSaveButton", "fieldsData", "fieldClass", "shouldRenderAsCheckBoxesButton", "programRuleActions", "dataEntities"], outputs: ["formUpdate"] }, { kind: "component", type: RepeatableFormComponent, selector: "ng-dhis2-ui-repeatable-form", inputs: ["formObject", "formData", "fieldGroup", "form", "numberOfRows", "programRuleActions", "events", "program", "programStage", "repeatDependentField", "dataEntities"], outputs: ["eventsChange", "repeatableStageUpdate"] }] }); }
|
|
4939
5279
|
}
|
|
4940
5280
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SectionFormComponent, decorators: [{
|
|
4941
5281
|
type: Component,
|
|
4942
|
-
args: [{ selector: 'ng-dhis2-ui-section-form', standalone: false, template: "<ng-container *ngIf=\"formMetaData()\">\n <ng-container *ngFor=\"let formSection of formMetaData().sections\">\n @if(formSection?.name; as sectionName) {\n <div class=\"
|
|
4943
|
-
}], propDecorators: {
|
|
4944
|
-
type: Input
|
|
4945
|
-
}], isLabResulst: [{
|
|
4946
|
-
type: Input
|
|
4947
|
-
}], clientId: [{
|
|
4948
|
-
type: Input
|
|
4949
|
-
}], labNumber: [{
|
|
4950
|
-
type: Input
|
|
4951
|
-
}], save: [{
|
|
5282
|
+
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"] }]
|
|
5283
|
+
}], ctorParameters: () => [], propDecorators: { save: [{
|
|
4952
5284
|
type: Output
|
|
4953
5285
|
}], formUpdate: [{
|
|
4954
5286
|
type: Output
|
|
@@ -4962,11 +5294,16 @@ class D2FormModule {
|
|
|
4962
5294
|
FormComponent,
|
|
4963
5295
|
RepeatableFormComponent,
|
|
4964
5296
|
SectionFormComponent,
|
|
4965
|
-
FormFieldItemComponent], imports: [CommonModule,
|
|
5297
|
+
FormFieldItemComponent], imports: [CommonModule,
|
|
5298
|
+
ReactiveFormsModule,
|
|
5299
|
+
ReactWrapperModule,
|
|
5300
|
+
OrganisationUnitSelectorModule], exports: [FormFieldComponent,
|
|
4966
5301
|
FormComponent,
|
|
4967
5302
|
RepeatableFormComponent,
|
|
4968
5303
|
SectionFormComponent] }); }
|
|
4969
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, imports: [CommonModule,
|
|
5304
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, imports: [CommonModule,
|
|
5305
|
+
ReactiveFormsModule,
|
|
5306
|
+
OrganisationUnitSelectorModule] }); }
|
|
4970
5307
|
}
|
|
4971
5308
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: D2FormModule, decorators: [{
|
|
4972
5309
|
type: NgModule,
|
|
@@ -4978,7 +5315,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
4978
5315
|
SectionFormComponent,
|
|
4979
5316
|
FormFieldItemComponent,
|
|
4980
5317
|
],
|
|
4981
|
-
imports: [
|
|
5318
|
+
imports: [
|
|
5319
|
+
CommonModule,
|
|
5320
|
+
ReactiveFormsModule,
|
|
5321
|
+
ReactWrapperModule,
|
|
5322
|
+
OrganisationUnitSelectorModule,
|
|
5323
|
+
],
|
|
4982
5324
|
exports: [
|
|
4983
5325
|
FormFieldComponent,
|
|
4984
5326
|
FormComponent,
|
|
@@ -4992,9 +5334,221 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
4992
5334
|
// Use of this source code is governed by a BSD-style
|
|
4993
5335
|
// license that can be found in the LICENSE file.
|
|
4994
5336
|
|
|
5337
|
+
class SelectionFiltersComponent extends ReactWrapperModule {
|
|
5338
|
+
constructor() {
|
|
5339
|
+
super(...arguments);
|
|
5340
|
+
this.actionOptions = [];
|
|
5341
|
+
this.attributeFilters = [];
|
|
5342
|
+
this.dataElementFilters = [];
|
|
5343
|
+
this.actionSelected = new EventEmitter();
|
|
5344
|
+
this.SelectionFiltersUI = () => {
|
|
5345
|
+
const [filters, setFilters] = useState({
|
|
5346
|
+
attributeFilters: this.attributeFilters || [],
|
|
5347
|
+
dataElementFilters: this.dataElementFilters || [],
|
|
5348
|
+
});
|
|
5349
|
+
useEffect(() => {
|
|
5350
|
+
setFilters({
|
|
5351
|
+
attributeFilters: this.attributeFilters,
|
|
5352
|
+
dataElementFilters: this.dataElementFilters,
|
|
5353
|
+
});
|
|
5354
|
+
}, [this.attributeFilters, this.dataElementFilters]);
|
|
5355
|
+
const handleAttributeChange = (index, selectedValue) => {
|
|
5356
|
+
setFilters((prevFilters) => {
|
|
5357
|
+
const updatedFilters = [...prevFilters.attributeFilters];
|
|
5358
|
+
updatedFilters[index] = { ...updatedFilters[index], value: selectedValue };
|
|
5359
|
+
return { ...prevFilters, attributeFilters: updatedFilters };
|
|
5360
|
+
});
|
|
5361
|
+
};
|
|
5362
|
+
const handleDataElementChange = (index, selectedValue) => {
|
|
5363
|
+
setFilters((prevFilters) => {
|
|
5364
|
+
const updatedFilters = [...prevFilters.dataElementFilters];
|
|
5365
|
+
updatedFilters[index] = { ...updatedFilters[index], value: selectedValue };
|
|
5366
|
+
return { ...prevFilters, dataElementFilters: updatedFilters };
|
|
5367
|
+
});
|
|
5368
|
+
};
|
|
5369
|
+
const handleSearch = () => {
|
|
5370
|
+
this.actionSelected.emit(filters);
|
|
5371
|
+
};
|
|
5372
|
+
// Grid Column Span Logic for Attribute Filters
|
|
5373
|
+
const getAttributeColumnSpan = (index) => {
|
|
5374
|
+
const totalItems = filters.attributeFilters.length;
|
|
5375
|
+
if (totalItems <= 4) {
|
|
5376
|
+
// If 1 to 4 items, place them in a single row (span all columns if there's only one item)
|
|
5377
|
+
if (totalItems === 1) {
|
|
5378
|
+
return 'span 4'; // One item spans all four columns
|
|
5379
|
+
}
|
|
5380
|
+
if (totalItems === 2) {
|
|
5381
|
+
return 'span 2'; // Two items, each spans 2 columns
|
|
5382
|
+
}
|
|
5383
|
+
if (totalItems === 3) {
|
|
5384
|
+
return 'span 1'; // Three items, each spans one column
|
|
5385
|
+
}
|
|
5386
|
+
if (totalItems === 4) {
|
|
5387
|
+
return 'span 1'; // Four items, each spans one column
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5390
|
+
else {
|
|
5391
|
+
// More than 4 items, recursively adjust the placement
|
|
5392
|
+
const rowIndex = Math.floor(index / 2); // Calculate row by pairs
|
|
5393
|
+
if (index % 2 === 0) {
|
|
5394
|
+
// For first item in each row, span 2 columns
|
|
5395
|
+
return 'span 2';
|
|
5396
|
+
}
|
|
5397
|
+
else if (index === totalItems - 1) {
|
|
5398
|
+
// Last item, spans the full row (4 columns)
|
|
5399
|
+
return 'span 4';
|
|
5400
|
+
}
|
|
5401
|
+
else {
|
|
5402
|
+
// For other items, span 2 columns
|
|
5403
|
+
return 'span 2';
|
|
5404
|
+
}
|
|
5405
|
+
}
|
|
5406
|
+
return 'span 1'; // Default behavior
|
|
5407
|
+
};
|
|
5408
|
+
// Grid Column Span Logic for Data Element Filters
|
|
5409
|
+
const getDataElementColumnSpan = (index) => {
|
|
5410
|
+
const totalItems = filters.dataElementFilters.length;
|
|
5411
|
+
if (totalItems <= 4) {
|
|
5412
|
+
// If 1 to 4 items, place them in a single row (span all columns if there's only one item)
|
|
5413
|
+
if (totalItems === 1) {
|
|
5414
|
+
return 'span 4'; // One item spans all four columns
|
|
5415
|
+
}
|
|
5416
|
+
if (totalItems === 2) {
|
|
5417
|
+
return 'span 2'; // Two items, each spans 2 columns
|
|
5418
|
+
}
|
|
5419
|
+
if (totalItems === 3) {
|
|
5420
|
+
return 'span 1'; // Three items, each spans one column
|
|
5421
|
+
}
|
|
5422
|
+
if (totalItems === 4) {
|
|
5423
|
+
return 'span 1'; // Four items, each spans one column
|
|
5424
|
+
}
|
|
5425
|
+
}
|
|
5426
|
+
else {
|
|
5427
|
+
// More than 4 items, recursively adjust the placement
|
|
5428
|
+
const rowIndex = Math.floor(index / 2); // Calculate row by pairs
|
|
5429
|
+
if (index % 2 === 0) {
|
|
5430
|
+
// For first item in each row, span 2 columns
|
|
5431
|
+
return 'span 2';
|
|
5432
|
+
}
|
|
5433
|
+
else if (index === totalItems - 1) {
|
|
5434
|
+
// Last item, spans the full row (4 columns)
|
|
5435
|
+
return 'span 4';
|
|
5436
|
+
}
|
|
5437
|
+
else {
|
|
5438
|
+
// For other items, span 2 columns
|
|
5439
|
+
return 'span 2';
|
|
5440
|
+
}
|
|
5441
|
+
}
|
|
5442
|
+
return 'span 1'; // Default behavior
|
|
5443
|
+
};
|
|
5444
|
+
return (React__default.createElement("div", { style: {
|
|
5445
|
+
fontFamily: 'Arial, sans-serif',
|
|
5446
|
+
padding: '20px',
|
|
5447
|
+
backgroundColor: '#f9f9f9',
|
|
5448
|
+
borderRadius: '8px',
|
|
5449
|
+
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)',
|
|
5450
|
+
} },
|
|
5451
|
+
React__default.createElement("div", { style: {
|
|
5452
|
+
display: 'grid',
|
|
5453
|
+
gridTemplateColumns: 'repeat(4, 1fr)',
|
|
5454
|
+
gap: '16px',
|
|
5455
|
+
} }, filters.attributeFilters.map((filter, index) => (React__default.createElement("div", { key: index, style: { gridColumn: getAttributeColumnSpan(index) } }, filter.hasOptions && filter.options.length > 0 ? (React__default.createElement(SingleSelectField, { className: "single-select", label: filter.name || 'Select Option', selected: filter.value, onChange: (event) => handleAttributeChange(index, event.selected) }, filter.options.map((option, i) => (React__default.createElement(SingleSelectOption, { key: i, label: option.name, value: option.id }))))) : (React__default.createElement(InputField$1, { className: "input-field", label: filter.name || 'Program name', value: filter.value, onChange: (event) => handleAttributeChange(index, event.value) })))))),
|
|
5456
|
+
React__default.createElement("div", { style: {
|
|
5457
|
+
display: 'grid',
|
|
5458
|
+
gridTemplateColumns: 'repeat(4, 1fr)',
|
|
5459
|
+
gap: '16px',
|
|
5460
|
+
} }, filters.dataElementFilters.map((filter, index) => (React__default.createElement("div", { key: index, style: { gridColumn: getDataElementColumnSpan(index) } }, filter.hasOptions && filter.options.length > 0 ? (React__default.createElement(SingleSelectField, { className: "single-select", label: filter.name || 'Aggregation type', selected: filter.value, onChange: (event) => handleDataElementChange(index, event.selected) }, filter.options.map((option, i) => (React__default.createElement(SingleSelectOption, { key: i, label: option.name, value: option.id }))))) : (React__default.createElement(InputField$1, { className: "input-field", label: filter.name || 'Program name', value: filter.value, onChange: (event) => handleDataElementChange(index, event.value) })))))),
|
|
5461
|
+
React__default.createElement("div", { style: { textAlign: 'right', marginTop: '16px' } },
|
|
5462
|
+
React__default.createElement(Button$1, { onClick: handleSearch }, "Search"))));
|
|
5463
|
+
};
|
|
5464
|
+
}
|
|
5465
|
+
async ngAfterViewInit() {
|
|
5466
|
+
if (!this.elementRef)
|
|
5467
|
+
throw new Error('No element ref');
|
|
5468
|
+
this.reactDomRoot = ReactDOM.createRoot(this.elementRef.nativeElement);
|
|
5469
|
+
this.component = this.SelectionFiltersUI;
|
|
5470
|
+
this.render();
|
|
5471
|
+
}
|
|
5472
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SelectionFiltersComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
5473
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.8", type: SelectionFiltersComponent, isStandalone: false, selector: "app-selection-filters-ui", inputs: { actionOptions: "actionOptions", attributeFilters: "attributeFilters", dataElementFilters: "dataElementFilters", startDate: "startDate", endDate: "endDate" }, outputs: { actionSelected: "actionSelected" }, usesInheritance: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [".react-filters-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-bottom:20px}.input-field,.single-select{width:100%}\n"] }); }
|
|
5474
|
+
}
|
|
5475
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SelectionFiltersComponent, decorators: [{
|
|
5476
|
+
type: Component,
|
|
5477
|
+
args: [{ selector: 'app-selection-filters-ui', template: '<ng-content></ng-content>', standalone: false, styles: [".react-filters-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-bottom:20px}.input-field,.single-select{width:100%}\n"] }]
|
|
5478
|
+
}], propDecorators: { actionOptions: [{
|
|
5479
|
+
type: Input
|
|
5480
|
+
}], attributeFilters: [{
|
|
5481
|
+
type: Input
|
|
5482
|
+
}], dataElementFilters: [{
|
|
5483
|
+
type: Input
|
|
5484
|
+
}], startDate: [{
|
|
5485
|
+
type: Input
|
|
5486
|
+
}], endDate: [{
|
|
5487
|
+
type: Input
|
|
5488
|
+
}], actionSelected: [{
|
|
5489
|
+
type: Output
|
|
5490
|
+
}] } });
|
|
5491
|
+
|
|
5492
|
+
class SelectionFiltersUiModule {
|
|
5493
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SelectionFiltersUiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
5494
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: SelectionFiltersUiModule, declarations: [SelectionFiltersComponent], imports: [CommonModule, SharedDhis2UiModule, ReactWrapperModule], exports: [SelectionFiltersComponent] }); }
|
|
5495
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SelectionFiltersUiModule, imports: [CommonModule, SharedDhis2UiModule] }); }
|
|
5496
|
+
}
|
|
5497
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: SelectionFiltersUiModule, decorators: [{
|
|
5498
|
+
type: NgModule,
|
|
5499
|
+
args: [{
|
|
5500
|
+
declarations: [SelectionFiltersComponent],
|
|
5501
|
+
imports: [CommonModule, SharedDhis2UiModule, ReactWrapperModule],
|
|
5502
|
+
exports: [SelectionFiltersComponent],
|
|
5503
|
+
}]
|
|
5504
|
+
}] });
|
|
5505
|
+
|
|
5506
|
+
class TrackerFormComponent {
|
|
5507
|
+
constructor() {
|
|
5508
|
+
this.program = input.required();
|
|
5509
|
+
this.d2 = window.d2Web;
|
|
5510
|
+
}
|
|
5511
|
+
async ngOnInit() {
|
|
5512
|
+
this.trackerQuery = this.d2.trackerModule.trackedEntity.setProgram(this.program());
|
|
5513
|
+
const program = await this.trackerQuery.getMetaData();
|
|
5514
|
+
const instance = await this.trackerQuery.create();
|
|
5515
|
+
if (program) {
|
|
5516
|
+
this.formMetaData = new FormMetaData({
|
|
5517
|
+
programs: [program],
|
|
5518
|
+
}).toJson();
|
|
5519
|
+
}
|
|
5520
|
+
}
|
|
5521
|
+
onSave(event) { }
|
|
5522
|
+
onCancel() { }
|
|
5523
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5524
|
+
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"] }] }); }
|
|
5525
|
+
}
|
|
5526
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormComponent, decorators: [{
|
|
5527
|
+
type: Component,
|
|
5528
|
+
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" }]
|
|
5529
|
+
}] });
|
|
5530
|
+
|
|
5531
|
+
class TrackerFormModule {
|
|
5532
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
5533
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, declarations: [TrackerFormComponent], imports: [CommonModule, D2FormModule], exports: [TrackerFormComponent] }); }
|
|
5534
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, imports: [CommonModule, D2FormModule] }); }
|
|
5535
|
+
}
|
|
5536
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: TrackerFormModule, decorators: [{
|
|
5537
|
+
type: NgModule,
|
|
5538
|
+
args: [{
|
|
5539
|
+
imports: [CommonModule, D2FormModule],
|
|
5540
|
+
declarations: [TrackerFormComponent],
|
|
5541
|
+
exports: [TrackerFormComponent],
|
|
5542
|
+
}]
|
|
5543
|
+
}] });
|
|
5544
|
+
|
|
5545
|
+
// Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
|
|
5546
|
+
// Use of this source code is governed by a BSD-style
|
|
5547
|
+
// license that can be found in the LICENSE file.
|
|
5548
|
+
|
|
4995
5549
|
/**
|
|
4996
5550
|
* Generated bundle index. Do not edit.
|
|
4997
5551
|
*/
|
|
4998
5552
|
|
|
4999
|
-
export { Boolean$1 as Boolean, ButtonComponent, ButtonModule, CheckBox, D2FormModule, DateField, DateRangeValue, Dropdown, FieldConfig, FieldControlTypeUtil, FieldDropdown, FieldType, FieldUtil, FormComponent, FormConfig, FormField, FormFieldComponent, FormFieldGroup, FormFieldTypeUtil, FormMetaData, FormMetadataSection, FormUtil, FormValue, FormValueUtil, HeaderBarComponent, HeaderBarModule, LineListModule, LineListTableComponent, MetadataRule, MetadataRuleAction, OrganisationUnitSelectionConfig, OrganisationUnitSelectorComponent, OrganisationUnitSelectorModalComponent, OrganisationUnitSelectorModule, PeriodSelectorComponent, PeriodSelectorModalComponent, PeriodSelectorModule,
|
|
5553
|
+
export { Boolean$1 as Boolean, ButtonComponent, ButtonModule, CheckBox, D2FormModule, DataTableUIComponent, DataTableUIModule, 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, SelectionFiltersComponent, SelectionFiltersUiModule, TrackerFormComponent, TrackerFormModule, TranslationUtil };
|
|
5000
5554
|
//# sourceMappingURL=iapps-ng-dhis2-ui.mjs.map
|