@iapps/ng-dhis2-ui 1.1.47 → 1.1.49
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 +413 -103
- package/fesm2022/iapps-ng-dhis2-ui.mjs.map +1 -1
- package/lib/modules/form/components/file-upload-field.component.d.ts +13 -0
- package/lib/modules/form/components/org-unit-form-field.component.d.ts +14 -0
- package/lib/modules/form/hooks/field-validation.hook.d.ts +11 -0
- package/lib/modules/form/hooks/index.d.ts +1 -0
- 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/line-list/containers/line-list.component.d.ts +2 -1
- package/lib/shared/hooks/dynamic-styles.hook.d.ts +1 -0
- package/lib/shared/hooks/index.d.ts +1 -0
- package/lib/shared/index.d.ts +1 -0
- package/lib/shared/utils/predefinedDimensions.d.ts +6 -6
- package/package.json +1 -1
|
@@ -25,9 +25,9 @@ import { Layer } from '@dhis2-ui/layer';
|
|
|
25
25
|
import { CircularLoader } from '@dhis2-ui/loader';
|
|
26
26
|
import { MenuItem, MenuDivider } from '@dhis2-ui/menu';
|
|
27
27
|
import parse from 'html-react-parser';
|
|
28
|
-
import { Button as Button$1, IconDimensionData16, IconClock16, IconDimensionOrgUnit16, spacers as spacers$1, colors as colors$1, IconEdit16, theme as theme$1, Tooltip, SingleSelectField, SingleSelectOption, InputField as InputField$1, TabBar, Tab, Transfer, Modal as Modal$1, ModalTitle as ModalTitle$1, ModalContent as ModalContent$1, ModalActions as ModalActions$1, ButtonStrip as ButtonStrip$1, Checkbox, OrganisationUnitTree, MultiSelect, MultiSelectOption, IconWarningFilled16, Layer as Layer$1, Popper, FlyoutMenu, MenuItem as MenuItem$1, IconMore24, CircularLoader as CircularLoader$1, IconFilter16, DataTable, TableHead, DataTableRow, DataTableColumnHeader, TableBody, DataTableCell, TableFoot, Pagination, FileInputField, FileListItem, MultiSelectField, TextAreaField } from '@dhis2/ui';
|
|
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, IconFilter16, DataTable, TableHead, DataTableRow, DataTableColumnHeader, TableBody, DataTableCell, TableFoot, Pagination, Chip, FileInputField, FileListItem, MultiSelectField, TextAreaField } from '@dhis2/ui';
|
|
29
29
|
import { getNowInCalendar, generateFixedPeriods } from '@dhis2/multi-calendar-dates';
|
|
30
|
-
import { isObject, isString, sortBy, isArray, find, camelCase, flatten, head, isEmpty } from 'lodash';
|
|
30
|
+
import { isObject, isString, sortBy, isArray, find, camelCase, flatten, debounce, isUndefined, 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';
|
|
@@ -1564,6 +1564,62 @@ TransferOption.propTypes = {
|
|
|
1564
1564
|
// Use of this source code is governed by a BSD-style
|
|
1565
1565
|
// license that can be found in the LICENSE file.
|
|
1566
1566
|
|
|
1567
|
+
// Helper function to generate a unique class name
|
|
1568
|
+
const generateClassName$2 = (base) => `${base}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1569
|
+
// Helper function to convert camelCased properties to hyphenated CSS properties
|
|
1570
|
+
const convertStylesToCSS$2 = (className, styles) => {
|
|
1571
|
+
let cssString = `.${className} {`;
|
|
1572
|
+
for (const key in styles) {
|
|
1573
|
+
if (typeof styles[key] === 'object' && key.startsWith('@media')) {
|
|
1574
|
+
const mediaStyles = convertStylesToCSS$2(className, styles[key]);
|
|
1575
|
+
cssString += `${key} { ${mediaStyles} }`;
|
|
1576
|
+
}
|
|
1577
|
+
else if (key.startsWith('&:')) {
|
|
1578
|
+
const pseudoClass = key.replace('&', '');
|
|
1579
|
+
cssString += `${pseudoClass} { ${convertStylesToCSS$2('', styles[key])} }`;
|
|
1580
|
+
}
|
|
1581
|
+
else {
|
|
1582
|
+
const cssKey = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
1583
|
+
cssString += `${cssKey}: ${styles[key]}; `;
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
cssString += '}';
|
|
1587
|
+
return cssString;
|
|
1588
|
+
};
|
|
1589
|
+
// Custom hook for dynamic styles with generics
|
|
1590
|
+
const useDynamicStyles$2 = (stylesObj) => {
|
|
1591
|
+
const [classNames, setClassNames] = useState({});
|
|
1592
|
+
useEffect(() => {
|
|
1593
|
+
const convertedStyles = Object.keys(stylesObj).map((key) => {
|
|
1594
|
+
const className = generateClassName$2(key);
|
|
1595
|
+
const styleElement = document.createElement('style');
|
|
1596
|
+
styleElement.innerHTML = convertStylesToCSS$2(className, stylesObj[key]);
|
|
1597
|
+
document.head.appendChild(styleElement);
|
|
1598
|
+
return {
|
|
1599
|
+
key,
|
|
1600
|
+
className,
|
|
1601
|
+
styleElement,
|
|
1602
|
+
};
|
|
1603
|
+
});
|
|
1604
|
+
setClassNames(convertedStyles.reduce((classNameEntity, convertedStyle) => {
|
|
1605
|
+
return {
|
|
1606
|
+
...classNameEntity,
|
|
1607
|
+
[convertedStyle.key]: convertedStyle.className,
|
|
1608
|
+
};
|
|
1609
|
+
}, {}));
|
|
1610
|
+
return () => {
|
|
1611
|
+
convertedStyles.forEach((convertedStyle) => {
|
|
1612
|
+
document.head.removeChild(convertedStyle.styleElement);
|
|
1613
|
+
});
|
|
1614
|
+
};
|
|
1615
|
+
}, []);
|
|
1616
|
+
return classNames;
|
|
1617
|
+
};
|
|
1618
|
+
|
|
1619
|
+
// Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
|
|
1620
|
+
// Use of this source code is governed by a BSD-style
|
|
1621
|
+
// license that can be found in the LICENSE file.
|
|
1622
|
+
|
|
1567
1623
|
// Copyright 2023 UDSM DHIS2 Lab. All rights reserved.
|
|
1568
1624
|
// Use of this source code is governed by a BSD-style
|
|
1569
1625
|
// license that can be found in the LICENSE file.
|
|
@@ -3364,6 +3420,9 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
3364
3420
|
const [filteredColumns, setFilteredColumns] = useState();
|
|
3365
3421
|
const [inputValues, setInputValues] = useState({});
|
|
3366
3422
|
const [filters, setFilters] = useState(false);
|
|
3423
|
+
//TODO: this will be migrated on the parent component
|
|
3424
|
+
const [checkValue, setCheckValue] = useState([]);
|
|
3425
|
+
const [valueMatch, setValuesMatch] = useState(false);
|
|
3367
3426
|
// Store updaters in refs for Angular to access
|
|
3368
3427
|
const updateRefs = useRef({
|
|
3369
3428
|
setProgramIdState,
|
|
@@ -3413,10 +3472,16 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
3413
3472
|
const { columns, data, filteredEntityColumns } = getTrackedEntityData(response, this.programId, pager, this.filters);
|
|
3414
3473
|
entityColumns = columns;
|
|
3415
3474
|
entityData = data;
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3475
|
+
//TODO: Should be done on the parent
|
|
3476
|
+
let checkValues = [
|
|
3477
|
+
...new Set(response.data?.trackedEntityInstances?.[0]?.enrollments?.[0]?.events?.flatMap((event) => event.dataValues
|
|
3478
|
+
.filter((dataValue) => /^[A-Za-z]{3}$/.test(dataValue.value))
|
|
3479
|
+
.map((dataValue) => dataValue.value))),
|
|
3480
|
+
];
|
|
3481
|
+
if (checkValues) {
|
|
3482
|
+
// this.firstValue.emit(firstTei);
|
|
3483
|
+
setCheckValue(checkValues);
|
|
3484
|
+
setValuesMatch(!checkValues.includes(this.buttonFilter));
|
|
3420
3485
|
}
|
|
3421
3486
|
// setFilteredColumns(filteredEntityColumns);
|
|
3422
3487
|
// Ensure filter inputs do not disappear when no data is returned
|
|
@@ -3508,9 +3573,12 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
3508
3573
|
padding: 8,
|
|
3509
3574
|
marginBottom: 16,
|
|
3510
3575
|
} },
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3576
|
+
valueMatch &&
|
|
3577
|
+
this.dispatchTeis &&
|
|
3578
|
+
(isButtonLoading ? (React__default.createElement(CircularLoader$1, { small: true })) : (
|
|
3579
|
+
//TODO: this implementation should be done where the library will be consumed
|
|
3580
|
+
React__default.createElement(Button$1, { style: {
|
|
3581
|
+
backgroundColor: '#3b82f6',
|
|
3514
3582
|
color: 'white',
|
|
3515
3583
|
padding: '8px 16px',
|
|
3516
3584
|
borderRadius: '4px',
|
|
@@ -3559,7 +3627,7 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
3559
3627
|
React__default.createElement(DataTableRow, null, columns.map((col) => (React__default.createElement(DataTableColumnHeader, { key: col.key }, col.label))))),
|
|
3560
3628
|
React__default.createElement(TableBody, null, data.length > 0 ? (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] || '--' // Display '--' if value is undefined or null
|
|
3561
3629
|
)))))))) : (React__default.createElement(DataTableRow, null,
|
|
3562
|
-
React__default.createElement(DataTableCell, { colSpan: columns.length, style: {
|
|
3630
|
+
React__default.createElement(DataTableCell, { colSpan: columns.length?.toString(), style: {
|
|
3563
3631
|
textAlign: 'center',
|
|
3564
3632
|
fontWeight: 'bold',
|
|
3565
3633
|
color: 'grey',
|
|
@@ -3612,7 +3680,7 @@ class LineListTableComponent extends ReactWrapperModule {
|
|
|
3612
3680
|
this.render();
|
|
3613
3681
|
}
|
|
3614
3682
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListTableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
3615
|
-
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", dispatchTeis: "dispatchTeis", showFilterButton: "showFilterButton", isButtonLoading: "isButtonLoading", buttonLabel: "buttonLabel" }, outputs: { actionSelected: "actionSelected", approvalSelected: "approvalSelected", firstValue: "firstValue" }, 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"] }); }
|
|
3683
|
+
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", dispatchTeis: "dispatchTeis", showFilterButton: "showFilterButton", isButtonLoading: "isButtonLoading", buttonLabel: "buttonLabel", buttonFilter: "buttonFilter" }, outputs: { actionSelected: "actionSelected", approvalSelected: "approvalSelected", firstValue: "firstValue" }, 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"] }); }
|
|
3616
3684
|
}
|
|
3617
3685
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImport: i0, type: LineListTableComponent, decorators: [{
|
|
3618
3686
|
type: Component,
|
|
@@ -3649,6 +3717,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.8", ngImpor
|
|
|
3649
3717
|
type: Input
|
|
3650
3718
|
}], firstValue: [{
|
|
3651
3719
|
type: Output
|
|
3720
|
+
}], buttonFilter: [{
|
|
3721
|
+
type: Input
|
|
3652
3722
|
}] } });
|
|
3653
3723
|
|
|
3654
3724
|
class LineListModule {
|
|
@@ -3818,7 +3888,7 @@ class DataTableUIComponent extends ReactWrapperModule {
|
|
|
3818
3888
|
React__default.createElement(DropdownMenu, { dropdownOptions: getDropdownOptions(row), onClick: (option) => option.onClick?.(row) }))))))),
|
|
3819
3889
|
React__default.createElement(TableFoot, null,
|
|
3820
3890
|
React__default.createElement(DataTableRow, null,
|
|
3821
|
-
React__default.createElement(DataTableCell, { colSpan: columns.length + 1 })))))));
|
|
3891
|
+
React__default.createElement(DataTableCell, { colSpan: (columns.length || 0 + 1).toString() })))))));
|
|
3822
3892
|
};
|
|
3823
3893
|
}
|
|
3824
3894
|
async ngAfterViewInit() {
|
|
@@ -4801,6 +4871,289 @@ class FormValue {
|
|
|
4801
4871
|
// Use of this source code is governed by a BSD-style
|
|
4802
4872
|
// license that can be found in the LICENSE file.
|
|
4803
4873
|
|
|
4874
|
+
// Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
|
|
4875
|
+
// Use of this source code is governed by a BSD-style
|
|
4876
|
+
// license that can be found in the LICENSE file.
|
|
4877
|
+
const useFieldValidation = (props) => {
|
|
4878
|
+
const { form, touched, field, value } = props;
|
|
4879
|
+
const hasError = useMemo(() => {
|
|
4880
|
+
return touched && (form.get(field.id) || form.get(field.key))?.invalid;
|
|
4881
|
+
}, [value, touched]);
|
|
4882
|
+
const validationError = useMemo(() => {
|
|
4883
|
+
if (!touched) {
|
|
4884
|
+
return undefined;
|
|
4885
|
+
}
|
|
4886
|
+
const error = (form.get(field.id) || form.get(field.key))?.errors;
|
|
4887
|
+
if (!error) {
|
|
4888
|
+
return undefined;
|
|
4889
|
+
}
|
|
4890
|
+
if (error['min']) {
|
|
4891
|
+
return `${field.label || 'Value'} should not be less than ${error['min'].min}!`;
|
|
4892
|
+
}
|
|
4893
|
+
else if (error['max']) {
|
|
4894
|
+
return `${field.label || 'Value'} should not be greater than ${error['max'].max}!`;
|
|
4895
|
+
}
|
|
4896
|
+
else if (error['pattern']) {
|
|
4897
|
+
if (field.type === 'email') {
|
|
4898
|
+
return `The email address provided is not valid`;
|
|
4899
|
+
}
|
|
4900
|
+
else if (field.type === 'tel') {
|
|
4901
|
+
return 'Phone number provided is not valid';
|
|
4902
|
+
}
|
|
4903
|
+
else {
|
|
4904
|
+
return `${field.label || 'Value'} should have appropriate format`;
|
|
4905
|
+
}
|
|
4906
|
+
}
|
|
4907
|
+
return error['required']
|
|
4908
|
+
? `${field.label || 'Value'} is required`
|
|
4909
|
+
: undefined;
|
|
4910
|
+
}, [hasError]);
|
|
4911
|
+
return { hasError, validationError };
|
|
4912
|
+
};
|
|
4913
|
+
|
|
4914
|
+
// Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
|
|
4915
|
+
// Use of this source code is governed by a BSD-style
|
|
4916
|
+
// license that can be found in the LICENSE file.
|
|
4917
|
+
|
|
4918
|
+
// Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
|
|
4919
|
+
// Use of this source code is governed by a BSD-style
|
|
4920
|
+
// license that can be found in the LICENSE file.
|
|
4921
|
+
// @flow
|
|
4922
|
+
const orgUnitFieldStyles = {
|
|
4923
|
+
container: {
|
|
4924
|
+
border: '1px solid',
|
|
4925
|
+
borderColor: colors$1.grey400,
|
|
4926
|
+
borderRadius: '3px',
|
|
4927
|
+
height: '100%',
|
|
4928
|
+
width: '100%',
|
|
4929
|
+
zIndex: 0,
|
|
4930
|
+
backgroundColor: 'white',
|
|
4931
|
+
},
|
|
4932
|
+
searchField: {
|
|
4933
|
+
height: '40px',
|
|
4934
|
+
overflow: 'hidden',
|
|
4935
|
+
borderBottomLeftRadius: 0,
|
|
4936
|
+
borderBottomRightRadius: 0,
|
|
4937
|
+
boxShadow: 'none',
|
|
4938
|
+
border: 'none',
|
|
4939
|
+
},
|
|
4940
|
+
debounceFieldContainer: {
|
|
4941
|
+
padding: '8px',
|
|
4942
|
+
background: colors$1.grey100,
|
|
4943
|
+
borderTopLeftRadius: '3px',
|
|
4944
|
+
borderTopRightRadius: '3px',
|
|
4945
|
+
},
|
|
4946
|
+
orgUnitTreeContainer: {
|
|
4947
|
+
borderBottomLeftRadius: '3px',
|
|
4948
|
+
borderBottomRightRadius: '3px',
|
|
4949
|
+
overflow: 'auto',
|
|
4950
|
+
},
|
|
4951
|
+
orgUnitTreeLoader: {
|
|
4952
|
+
padding: '8px',
|
|
4953
|
+
},
|
|
4954
|
+
orgUnitFieldLabel: {
|
|
4955
|
+
marginBottom: '8px',
|
|
4956
|
+
display: 'block',
|
|
4957
|
+
boxSizing: 'border-box',
|
|
4958
|
+
fontSize: '14px',
|
|
4959
|
+
lineHeight: '19px',
|
|
4960
|
+
color: 'rgb(33, 41, 52)',
|
|
4961
|
+
padding: '0',
|
|
4962
|
+
},
|
|
4963
|
+
orgUnitFieldRequiredLabel: {
|
|
4964
|
+
paddingInlineStart: '4px',
|
|
4965
|
+
},
|
|
4966
|
+
};
|
|
4967
|
+
const OrgUnitFormField = (props) => {
|
|
4968
|
+
const { onSelectOrgUnit, label, required, selected, disabled, key } = props;
|
|
4969
|
+
const d2 = window?.d2Web;
|
|
4970
|
+
const classes = useDynamicStyles$2(orgUnitFieldStyles);
|
|
4971
|
+
const config = useMemo(() => {
|
|
4972
|
+
return d2.systemInfo?.toInitObject();
|
|
4973
|
+
}, []);
|
|
4974
|
+
const rootOrgUnits = useMemo(() => {
|
|
4975
|
+
return d2.currentUser?.organisationUnits || [];
|
|
4976
|
+
}, []);
|
|
4977
|
+
const getExpandedItems = () => {
|
|
4978
|
+
if (rootOrgUnits && rootOrgUnits.length === 1) {
|
|
4979
|
+
return [`/${rootOrgUnits[0].id}`];
|
|
4980
|
+
}
|
|
4981
|
+
else if (rootOrgUnits?.length > 1) {
|
|
4982
|
+
return rootOrgUnits.map((root) => root.path);
|
|
4983
|
+
}
|
|
4984
|
+
return undefined;
|
|
4985
|
+
};
|
|
4986
|
+
const initiallyExpanded = getExpandedItems();
|
|
4987
|
+
const [searchText, setSearchText] = useState(undefined);
|
|
4988
|
+
const [loading, setLoading] = useState(true);
|
|
4989
|
+
const [searchLoading, setSearchLoading] = useState();
|
|
4990
|
+
const [searchData, setSearchData] = useState();
|
|
4991
|
+
const [selectedOrgUnit, setSelectedOrgUnit] = React__default.useState();
|
|
4992
|
+
const [expanded, setExpanded] = React__default.useState(initiallyExpanded);
|
|
4993
|
+
const [showOrgUnitTree, setShowOrgUnitTree] = useState(!selected);
|
|
4994
|
+
useEffect(() => {
|
|
4995
|
+
setLoading(true);
|
|
4996
|
+
if (selected) {
|
|
4997
|
+
d2.httpInstance
|
|
4998
|
+
.get(`organisationUnits/${selected}.json?fields=id,name,path,code,ancestors[id,name]`)
|
|
4999
|
+
.then((response) => {
|
|
5000
|
+
if (response.data) {
|
|
5001
|
+
setSelectedOrgUnit(response.data);
|
|
5002
|
+
handleExpand({ path: response.data['path'] });
|
|
5003
|
+
setLoading(false);
|
|
5004
|
+
}
|
|
5005
|
+
});
|
|
5006
|
+
}
|
|
5007
|
+
else {
|
|
5008
|
+
setLoading(false);
|
|
5009
|
+
}
|
|
5010
|
+
}, [selected]);
|
|
5011
|
+
const highlighted = useMemo(() => {
|
|
5012
|
+
if (selectedOrgUnit) {
|
|
5013
|
+
return [selectedOrgUnit['path']];
|
|
5014
|
+
}
|
|
5015
|
+
return undefined;
|
|
5016
|
+
}, [selectedOrgUnit]);
|
|
5017
|
+
const selectedOrgUnitLabel = useMemo(() => {
|
|
5018
|
+
if (selectedOrgUnit) {
|
|
5019
|
+
return [
|
|
5020
|
+
...(selectedOrgUnit['ancestors'] || []),
|
|
5021
|
+
selectedOrgUnit,
|
|
5022
|
+
]
|
|
5023
|
+
.map((orgUnit) => orgUnit['name'])
|
|
5024
|
+
.join(' / ');
|
|
5025
|
+
}
|
|
5026
|
+
return '';
|
|
5027
|
+
}, [selectedOrgUnit]);
|
|
5028
|
+
const handleExpand = ({ path }) => {
|
|
5029
|
+
if (expanded && !expanded.includes(path)) {
|
|
5030
|
+
setExpanded([...expanded, path]);
|
|
5031
|
+
}
|
|
5032
|
+
};
|
|
5033
|
+
const handleCollapse = ({ path }) => {
|
|
5034
|
+
const pathIndex = expanded?.indexOf(path);
|
|
5035
|
+
if (pathIndex && pathIndex !== -1 && expanded) {
|
|
5036
|
+
const updatedExpanded = pathIndex === 0
|
|
5037
|
+
? expanded.slice(1)
|
|
5038
|
+
: [...expanded.slice(0, pathIndex), ...expanded.slice(pathIndex + 1)];
|
|
5039
|
+
setExpanded(updatedExpanded);
|
|
5040
|
+
}
|
|
5041
|
+
};
|
|
5042
|
+
const handleOrgUnitSearch = async (query) => {
|
|
5043
|
+
setSearchLoading(true);
|
|
5044
|
+
try {
|
|
5045
|
+
const searchResponse = await d2.httpInstance.get(`organisationUnits.json?fields=id,displayName,path,publicAccess,access,lastUpdated,children[id,displayName,publicAccess,access,path,children::isNotEmpty]&paging=true&query=${query}&withinUserSearchHierarchy=true&pageSize=15`);
|
|
5046
|
+
setSearchData((searchResponse.data || {})['organisationUnits']);
|
|
5047
|
+
setSearchLoading(false);
|
|
5048
|
+
}
|
|
5049
|
+
catch (e) {
|
|
5050
|
+
setSearchLoading(false);
|
|
5051
|
+
}
|
|
5052
|
+
};
|
|
5053
|
+
const debouncedSearch = useCallback(debounce((value) => {
|
|
5054
|
+
handleOrgUnitSearch(value);
|
|
5055
|
+
}, 500), []);
|
|
5056
|
+
const handleFilterChange = (event) => {
|
|
5057
|
+
setSearchText(event.value);
|
|
5058
|
+
debouncedSearch(event.value);
|
|
5059
|
+
};
|
|
5060
|
+
const ready = useMemo(() => {
|
|
5061
|
+
return searchText?.length ? !searchLoading : !loading;
|
|
5062
|
+
}, [searchText, searchLoading, loading]);
|
|
5063
|
+
const renderOrgUnitTree = () => {
|
|
5064
|
+
if (searchText && searchText?.length > 0) {
|
|
5065
|
+
if (searchLoading) {
|
|
5066
|
+
return (React__default.createElement("div", { className: classes.orgUnitTreeLoader },
|
|
5067
|
+
React__default.createElement(CircularLoader$1, { small: true })));
|
|
5068
|
+
}
|
|
5069
|
+
return (ready && (React__default.createElement(OrganisationUnitTree, { key: `${key}-search`, roots: searchData?.map((orgUnit) => orgUnit.id) || [], singleSelection: true, expanded: expanded, handleExpand: handleExpand, handleCollapse: handleCollapse, selected: highlighted, onChange: (event) => {
|
|
5070
|
+
setSelectedOrgUnit(event);
|
|
5071
|
+
onSelectOrgUnit(event.id);
|
|
5072
|
+
} })));
|
|
5073
|
+
}
|
|
5074
|
+
return (React__default.createElement(OrganisationUnitTree, { key: key, roots: rootOrgUnits?.map((orgUnit) => orgUnit.id) || [], singleSelection: true, expanded: expanded, handleExpand: handleExpand, handleCollapse: handleCollapse, selected: highlighted, onChange: (event) => {
|
|
5075
|
+
setSelectedOrgUnit(event);
|
|
5076
|
+
onSelectOrgUnit(event.id);
|
|
5077
|
+
} }));
|
|
5078
|
+
};
|
|
5079
|
+
const handleBlur = () => {
|
|
5080
|
+
// onBlur && onBlur(null);
|
|
5081
|
+
};
|
|
5082
|
+
return (config && (React__default.createElement(Provider, { config: config, plugin: false, parentAlertsAdd: undefined, showAlertsInPlugin: false },
|
|
5083
|
+
React__default.createElement("div", null,
|
|
5084
|
+
label && (React__default.createElement("div", { className: classes.orgUnitFieldLabel },
|
|
5085
|
+
React__default.createElement("span", null, label),
|
|
5086
|
+
required ? (React__default.createElement("span", { className: classes.orgUnitFieldRequiredLabel }, "*")) : (React__default.createElement(React__default.Fragment, null)))),
|
|
5087
|
+
selected && !showOrgUnitTree ? (selectedOrgUnit ? (React__default.createElement(Tooltip, { content: selectedOrgUnitLabel },
|
|
5088
|
+
React__default.createElement(Chip, { onRemove: () => {
|
|
5089
|
+
setShowOrgUnitTree(true);
|
|
5090
|
+
} }, selectedOrgUnit.name))) : (React__default.createElement("div", { className: classes.orgUnitTreeLoader },
|
|
5091
|
+
React__default.createElement(CircularLoader$1, { small: true })))) : (React__default.createElement("div", { className: classes.container },
|
|
5092
|
+
React__default.createElement("div", { className: classes.debounceFieldContainer },
|
|
5093
|
+
React__default.createElement(InputField$1, { placeholder: "Search", value: searchText, disabled: disabled, onChange: handleFilterChange })),
|
|
5094
|
+
loading ? (React__default.createElement("div", { className: classes.orgUnitTreeLoader },
|
|
5095
|
+
React__default.createElement(CircularLoader$1, { small: true }))) : (React__default.createElement("div", { className: classes.orgUnitTreeContainer, style: { maxHeight: '200px', overflowY: 'auto' } }, renderOrgUnitTree()))))))));
|
|
5096
|
+
};
|
|
5097
|
+
|
|
5098
|
+
// Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
|
|
5099
|
+
// Use of this source code is governed by a BSD-style
|
|
5100
|
+
// license that can be found in the LICENSE file.
|
|
5101
|
+
const FileUploadField = (props) => {
|
|
5102
|
+
const { label, id, uploadUrl, performUpload, validationText, required, hasError, onChange, onUploadSuccess, } = props;
|
|
5103
|
+
const d2 = window?.d2Web;
|
|
5104
|
+
const [file, setFile] = useState(null);
|
|
5105
|
+
const [uploading, setUploading] = useState();
|
|
5106
|
+
const valid = useMemo(() => {
|
|
5107
|
+
if (isUndefined(hasError)) {
|
|
5108
|
+
return undefined;
|
|
5109
|
+
}
|
|
5110
|
+
return !hasError;
|
|
5111
|
+
}, [hasError]);
|
|
5112
|
+
const uploadFile = async (fileItem) => {
|
|
5113
|
+
if (fileItem) {
|
|
5114
|
+
setUploading(true);
|
|
5115
|
+
const formData = new FormData();
|
|
5116
|
+
formData.append('file', fileItem);
|
|
5117
|
+
try {
|
|
5118
|
+
const fileUploadResponse = await d2.httpInstance.post(uploadUrl, formData);
|
|
5119
|
+
setUploading(false);
|
|
5120
|
+
const fileId = fileUploadResponse?.data?.response?.fileResource
|
|
5121
|
+
?.id;
|
|
5122
|
+
if (fileId) {
|
|
5123
|
+
onUploadSuccess(fileId);
|
|
5124
|
+
}
|
|
5125
|
+
}
|
|
5126
|
+
catch (error) {
|
|
5127
|
+
setUploading(false);
|
|
5128
|
+
}
|
|
5129
|
+
}
|
|
5130
|
+
};
|
|
5131
|
+
return (React__default.createElement(FileInputField, { accept: "*", buttonLabel: "Upload a file", label: label, name: id, valid: valid, required: required, validationText: validationText, onChange: (event) => {
|
|
5132
|
+
const fileItem = (event?.files || [])[0];
|
|
5133
|
+
setFile(fileItem);
|
|
5134
|
+
if (performUpload) {
|
|
5135
|
+
uploadFile(fileItem);
|
|
5136
|
+
}
|
|
5137
|
+
else {
|
|
5138
|
+
onChange(file);
|
|
5139
|
+
}
|
|
5140
|
+
// this.ngZone.run(() => {
|
|
5141
|
+
// this.form().get(this.field().id) ||
|
|
5142
|
+
// this.form()
|
|
5143
|
+
// .get(this.field().key)
|
|
5144
|
+
// ?.setValue((event?.files || [])[0]);
|
|
5145
|
+
// this.update.emit({
|
|
5146
|
+
// form: this.form(),
|
|
5147
|
+
// value: (event?.files || [])[0],
|
|
5148
|
+
// });
|
|
5149
|
+
// });
|
|
5150
|
+
// setValue((event?.files || [])[0]);
|
|
5151
|
+
// setTouched(true);
|
|
5152
|
+
} }, file && (React__default.createElement(FileListItem, { cancelText: "Cancel", label: file.name, loading: uploading, onRemove: () => {
|
|
5153
|
+
setFile(null);
|
|
5154
|
+
}, removeText: "Remove" }))));
|
|
5155
|
+
};
|
|
5156
|
+
|
|
4804
5157
|
// Copyright 2024 UDSM DHIS2 Lab. All rights reserved.
|
|
4805
5158
|
// Use of this source code is governed by a BSD-style
|
|
4806
5159
|
// license that can be found in the LICENSE file.
|
|
@@ -4890,45 +5243,15 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
4890
5243
|
}
|
|
4891
5244
|
return [];
|
|
4892
5245
|
}, [value]);
|
|
4893
|
-
const hasError =
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
if (!touched) {
|
|
4900
|
-
return undefined;
|
|
4901
|
-
}
|
|
4902
|
-
const field = this.field();
|
|
4903
|
-
const error = (this.form().get(field.id) || this.form().get(field.key))
|
|
4904
|
-
?.errors;
|
|
4905
|
-
if (!error) {
|
|
4906
|
-
return undefined;
|
|
4907
|
-
}
|
|
4908
|
-
if (error['min']) {
|
|
4909
|
-
return `${this.label() || 'Value'} should not be less than ${error['min'].min}!`;
|
|
4910
|
-
}
|
|
4911
|
-
else if (error['max']) {
|
|
4912
|
-
return `${this.label() || 'Value'} should not be greater than ${error['max'].max}!`;
|
|
4913
|
-
}
|
|
4914
|
-
else if (error['pattern']) {
|
|
4915
|
-
if (field.type === 'email') {
|
|
4916
|
-
return `The email address provided is not valid`;
|
|
4917
|
-
}
|
|
4918
|
-
else if (field.type === 'tel') {
|
|
4919
|
-
return 'Phone number provided is not valid';
|
|
4920
|
-
}
|
|
4921
|
-
else {
|
|
4922
|
-
return `${this.label() || 'Value'} should have appropriate format`;
|
|
4923
|
-
}
|
|
4924
|
-
}
|
|
4925
|
-
return error['required']
|
|
4926
|
-
? `${this.label() || 'Value'} is required`
|
|
4927
|
-
: undefined;
|
|
4928
|
-
}, [hasError]);
|
|
5246
|
+
const { hasError, validationError } = useFieldValidation({
|
|
5247
|
+
field: this.field(),
|
|
5248
|
+
form: this.form(),
|
|
5249
|
+
value,
|
|
5250
|
+
touched,
|
|
5251
|
+
});
|
|
4929
5252
|
switch (this.field().controlType) {
|
|
4930
5253
|
case 'textarea':
|
|
4931
|
-
return (React__default.createElement(TextAreaField, { error: hasError, validationText: validationError,
|
|
5254
|
+
return (React__default.createElement(TextAreaField, { error: hasError, validationText: validationError, inputWidth: this.fieldConfig()?.inputWidth, required: this.field().required, name: this.field().id, label: this.label(), rows: 5, placeholder: this.placeholder(), value: value, onChange: (event) => {
|
|
4932
5255
|
this.ngZone.run(() => {
|
|
4933
5256
|
(this.form().get(this.field().id) ||
|
|
4934
5257
|
this.form().get(this.field().key))?.setValue(event.value);
|
|
@@ -4945,34 +5268,14 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
4945
5268
|
});
|
|
4946
5269
|
} }));
|
|
4947
5270
|
case 'org-unit':
|
|
4948
|
-
return (React__default.createElement(
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
});
|
|
4955
|
-
setTouched(true);
|
|
4956
|
-
} }),
|
|
4957
|
-
showOrgUnit && (React__default.createElement(this.FieldOrgUnitSelector, { selectedOrgUnits: [], onSelectOrgUnit: (selectedOrgUnits) => {
|
|
4958
|
-
if ((selectedOrgUnits || [])[0]) {
|
|
4959
|
-
const selectedOrgUnit = selectedOrgUnits[0];
|
|
4960
|
-
setDisplayValue(selectedOrgUnit.name);
|
|
4961
|
-
setValue(selectedOrgUnit.id);
|
|
4962
|
-
setShowOrgUnit(false);
|
|
4963
|
-
setTouched(true);
|
|
4964
|
-
this.ngZone.run(() => {
|
|
4965
|
-
(this.form().get(this.field().id) ||
|
|
4966
|
-
this.form().get(this.field().key))?.setValue(selectedOrgUnit.id);
|
|
4967
|
-
this.immediateUpdate.emit({
|
|
4968
|
-
form: this.form(),
|
|
4969
|
-
value: selectedOrgUnit.id,
|
|
4970
|
-
});
|
|
4971
|
-
});
|
|
4972
|
-
}
|
|
4973
|
-
} }))));
|
|
5271
|
+
return (React__default.createElement(OrgUnitFormField, { label: this.label(), key: this.field().id, required: this.field().required, onSelectOrgUnit: (selectedOrgUnit) => {
|
|
5272
|
+
setValue(selectedOrgUnit);
|
|
5273
|
+
this.ngZone.run(() => {
|
|
5274
|
+
this.update.emit({ form: this.form(), value });
|
|
5275
|
+
});
|
|
5276
|
+
}, selected: value }));
|
|
4974
5277
|
case 'transfer':
|
|
4975
|
-
return (React__default.createElement(Transfer, { filterable: true, filterPlaceholder: "Search", selected: selected,
|
|
5278
|
+
return (React__default.createElement(Transfer, { filterable: true, filterPlaceholder: "Search", selected: selected, leftHeader: React__default.createElement("div", { style: {
|
|
4976
5279
|
fontSize: 14,
|
|
4977
5280
|
padding: '8px 4px',
|
|
4978
5281
|
} }, this.field().availableOptionsLabel), rightHeader: React__default.createElement("div", { style: {
|
|
@@ -4989,7 +5292,10 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
4989
5292
|
this.update.emit({ form: this.form(), value });
|
|
4990
5293
|
} }));
|
|
4991
5294
|
case 'checkbox':
|
|
4992
|
-
return (React__default.createElement(Checkbox, { checked: Boolean(value), error: hasError, label: this.label(), name: this.field().id, disabled: this.field()?.disabled ||
|
|
5295
|
+
return (React__default.createElement(Checkbox, { checked: Boolean(value), error: hasError, label: this.label(), name: this.field().id, disabled: this.field()?.disabled ||
|
|
5296
|
+
this.field()?.generated ||
|
|
5297
|
+
this.field()?.unique ||
|
|
5298
|
+
false, onChange: (event) => {
|
|
4993
5299
|
this.ngZone.run(() => {
|
|
4994
5300
|
(this.form().get(this.field().id) ||
|
|
4995
5301
|
this.form().get(this.field().key))?.setValue(event.checked);
|
|
@@ -5002,7 +5308,10 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
5002
5308
|
});
|
|
5003
5309
|
} }));
|
|
5004
5310
|
case 'dropdown':
|
|
5005
|
-
return (React__default.createElement(SingleSelectField, { filterable: (this.field().options || []).length > 5, clearable: true, error: hasError, validationText: validationError, inputWidth: this.fieldConfig()?.inputWidth, disabled: this.field()?.disabled ||
|
|
5311
|
+
return (React__default.createElement(SingleSelectField, { filterable: (this.field().options || []).length > 5, clearable: true, error: hasError, validationText: validationError, inputWidth: this.fieldConfig()?.inputWidth, disabled: this.field()?.disabled ||
|
|
5312
|
+
this.field()?.generated ||
|
|
5313
|
+
this.field()?.unique ||
|
|
5314
|
+
false, required: this.field().required, className: "select", label: this.label(), selected: value, onChange: (event) => {
|
|
5006
5315
|
this.ngZone.run(() => {
|
|
5007
5316
|
(this.form().get(this.field().id) ||
|
|
5008
5317
|
this.form().get(this.field().key))?.setValue(event.selected);
|
|
@@ -5015,7 +5324,10 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
5015
5324
|
setTouched(true);
|
|
5016
5325
|
} }, (this.field().options || []).map((option) => (React__default.createElement(SingleSelectOption, { key: crypto.randomUUID() || option.key, label: option.label, value: option.value })))));
|
|
5017
5326
|
case 'multi-dropdown':
|
|
5018
|
-
return (React__default.createElement(MultiSelectField, { clearText: "Clear", clearable: true, empty: "No data found", filterable: (this.field().options || []).length > 5, filterPlaceholder: "Type to filter options", error: hasError, validationText: validationError, inputWidth: this.fieldConfig()?.inputWidth, disabled: this.field()?.disabled ||
|
|
5327
|
+
return (React__default.createElement(MultiSelectField, { clearText: "Clear", clearable: true, empty: "No data found", filterable: (this.field().options || []).length > 5, filterPlaceholder: "Type to filter options", error: hasError, validationText: validationError, inputWidth: this.fieldConfig()?.inputWidth, disabled: this.field()?.disabled ||
|
|
5328
|
+
this.field()?.generated ||
|
|
5329
|
+
this.field()?.unique ||
|
|
5330
|
+
false, label: this.label(), required: this.field().required, loadingText: "Loading options", noMatchText: "No options found", onChange: (event) => {
|
|
5019
5331
|
const selectedValue = (event.selected || []).join(',');
|
|
5020
5332
|
this.ngZone.run(() => {
|
|
5021
5333
|
(this.form().get(this.field().id) ||
|
|
@@ -5029,29 +5341,27 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
5029
5341
|
setTouched(true);
|
|
5030
5342
|
}, selected: arrayValue }, (this.field().options || []).map((option) => (React__default.createElement(MultiSelectOption, { key: option.key, label: option.label, value: option.value })))));
|
|
5031
5343
|
case 'file':
|
|
5032
|
-
return (React__default.createElement(
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
value: (event?.files || [])[0],
|
|
5344
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
5345
|
+
React__default.createElement(FileUploadField, { label: this.label(), id: this.field().id, hasError: hasError, required: this.field().required, validationText: validationError, performUpload: true, uploadUrl: 'fileResources', onUploadSuccess: (fileId) => {
|
|
5346
|
+
this.ngZone.run(() => {
|
|
5347
|
+
this.form().get(this.field().id) ||
|
|
5348
|
+
this.form().get(this.field().key)?.setValue(fileId);
|
|
5349
|
+
this.update.emit({
|
|
5350
|
+
form: this.form(),
|
|
5351
|
+
value: fileId,
|
|
5352
|
+
});
|
|
5042
5353
|
});
|
|
5043
|
-
|
|
5044
|
-
setValue((event?.files || [])[0]);
|
|
5045
|
-
setTouched(true);
|
|
5046
|
-
} }, this.uploadedFiles.map((file, index) => (React__default.createElement(FileListItem, { key: index, cancelText: "Cancel", label: file.name, onCancel: () => { }, onRemove: () => {
|
|
5047
|
-
this.ngZone.run(() => {
|
|
5048
|
-
this.uploadedFiles.splice(index, 1);
|
|
5049
|
-
setValue(this.uploadedFiles);
|
|
5354
|
+
setValue(fileId);
|
|
5050
5355
|
setTouched(true);
|
|
5051
|
-
});
|
|
5052
|
-
}, removeText: "Remove" })))));
|
|
5356
|
+
} })));
|
|
5053
5357
|
default:
|
|
5054
|
-
return (React__default.createElement(InputField$1, { error: hasError, validationText: validationError, type: this.field().type, inputWidth: this.fieldConfig()?.inputWidth, required: this.field().required, name: this.field().id, label: this.label(), min: this.field().min?.toString(), max: this.field().max?.toString(), placeholder: this.placeholder(), value: value, disabled: this.field()?.disabled ||
|
|
5358
|
+
return (React__default.createElement(InputField$1, { error: hasError, validationText: validationError, type: this.field().type, inputWidth: this.fieldConfig()?.inputWidth, required: this.field().required, name: this.field().id, label: this.label(), min: this.field().min?.toString(), max: this.field().max?.toString(), placeholder: this.placeholder(), value: value, disabled: this.field()?.disabled ||
|
|
5359
|
+
this.field()?.generated ||
|
|
5360
|
+
this.field()?.unique ||
|
|
5361
|
+
false, readOnly: this.field()?.disabled ||
|
|
5362
|
+
this.field()?.generated ||
|
|
5363
|
+
this.field()?.unique ||
|
|
5364
|
+
false, onChange: (event) => {
|
|
5055
5365
|
this.ngZone.run(() => {
|
|
5056
5366
|
(this.form().get(this.field().id) ||
|
|
5057
5367
|
this.form().get(this.field().key))?.setValue(event.value);
|
|
@@ -5881,8 +6191,8 @@ class SelectionFiltersComponent extends ReactWrapperModule {
|
|
|
5881
6191
|
setTouched(true);
|
|
5882
6192
|
}
|
|
5883
6193
|
} }))),
|
|
5884
|
-
React__default.createElement(InputField$1, { className: "input-field", label: "Start Date", type: "
|
|
5885
|
-
React__default.createElement(InputField$1, { className: "input-field", label: "End Date", type: "
|
|
6194
|
+
React__default.createElement(InputField$1, { className: "input-field", label: "Start Date", type: "date", value: filters.startDate, onChange: (event) => setFilters({ ...filters, startDate: event.value }) }),
|
|
6195
|
+
React__default.createElement(InputField$1, { className: "input-field", label: "End Date", type: "date", value: filters.endDate, onChange: (event) => setFilters({ ...filters, endDate: event.value }) }),
|
|
5886
6196
|
React__default.createElement("div", { style: {
|
|
5887
6197
|
display: 'flex',
|
|
5888
6198
|
flexDirection: 'column',
|
|
@@ -5901,12 +6211,12 @@ class SelectionFiltersComponent extends ReactWrapperModule {
|
|
|
5901
6211
|
display: 'grid',
|
|
5902
6212
|
gridTemplateColumns: 'repeat(4, 1fr)',
|
|
5903
6213
|
gap: '16px',
|
|
5904
|
-
} }, filters.programAttributesFilters.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',
|
|
6214
|
+
} }, filters.programAttributesFilters.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: crypto.randomUUID() || i, label: option.name, value: option.code }))))) : (React__default.createElement(InputField$1, { className: "input-field", label: filter.name || 'Program name', type: filter.valueType, value: filter.value, onChange: (event) => handleAttributeChange(index, event.value) })))))),
|
|
5905
6215
|
React__default.createElement("div", { style: {
|
|
5906
6216
|
display: 'grid',
|
|
5907
6217
|
gridTemplateColumns: 'repeat(4, 1fr)',
|
|
5908
6218
|
gap: '16px',
|
|
5909
|
-
} }, filters.programStageDataElementFilters.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',
|
|
6219
|
+
} }, filters.programStageDataElementFilters.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: crypto.randomUUID() || i, label: option.name, value: option.code }))))) : (React__default.createElement(InputField$1, { className: "input-field", type: filter.valueType, label: filter.name || 'Program name', value: filter.value, onChange: (event) => handleDataElementChange(index, event.value) })))))),
|
|
5910
6220
|
React__default.createElement("div", { style: { textAlign: 'right', marginTop: '16px' } },
|
|
5911
6221
|
React__default.createElement(Button$1, { onClick: handleSearch }, "Search"))))));
|
|
5912
6222
|
};
|