@iapps/ng-dhis2-ui 1.2.133 → 1.2.135
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 +426 -37
- package/fesm2022/iapps-ng-dhis2-ui.mjs.map +1 -1
- package/index.d.ts +9 -4
- package/package.json +1 -1
|
@@ -6536,6 +6536,157 @@ const CoordinatePickerField = ({ label, name, value, required, disabled, error,
|
|
|
6536
6536
|
React__default.createElement(Button$1, { primary: true, onClick: handleConfirmFromMap, disabled: !pendingCoordinate }, "Use Selected Location")))))));
|
|
6537
6537
|
};
|
|
6538
6538
|
|
|
6539
|
+
const ALL_COUNTRIES = [
|
|
6540
|
+
// East Africa first (for convenience)
|
|
6541
|
+
{ isoCode: 'TZ', dialCode: '+255', name: 'Tanzania', flag: '🇹🇿' },
|
|
6542
|
+
{ isoCode: 'KE', dialCode: '+254', name: 'Kenya', flag: '🇰🇪' },
|
|
6543
|
+
{ isoCode: 'UG', dialCode: '+256', name: 'Uganda', flag: '🇺🇬' },
|
|
6544
|
+
{ isoCode: 'RW', dialCode: '+250', name: 'Rwanda', flag: '🇷🇼' },
|
|
6545
|
+
{ isoCode: 'BI', dialCode: '+257', name: 'Burundi', flag: '🇧🇮' },
|
|
6546
|
+
{ isoCode: 'SS', dialCode: '+211', name: 'South Sudan', flag: '🇸🇸' },
|
|
6547
|
+
{ isoCode: 'ET', dialCode: '+251', name: 'Ethiopia', flag: '🇪🇹' },
|
|
6548
|
+
// A few examples from other regions:
|
|
6549
|
+
{ isoCode: 'GB', dialCode: '+44', name: 'United Kingdom', flag: '🇬🇧' },
|
|
6550
|
+
{ isoCode: 'US', dialCode: '+1', name: 'United States', flag: '🇺🇸' },
|
|
6551
|
+
{ isoCode: 'CA', dialCode: '+1', name: 'Canada', flag: '🇨🇦' },
|
|
6552
|
+
{ isoCode: 'DE', dialCode: '+49', name: 'Germany', flag: '🇩🇪' },
|
|
6553
|
+
{ isoCode: 'IN', dialCode: '+91', name: 'India', flag: '🇮🇳' },
|
|
6554
|
+
{ isoCode: 'CN', dialCode: '+86', name: 'China', flag: '🇨🇳' },
|
|
6555
|
+
{ isoCode: 'BR', dialCode: '+55', name: 'Brazil', flag: '🇧🇷' },
|
|
6556
|
+
// 👉 Here you add the rest of the world.
|
|
6557
|
+
// You can load a standard JSON of all countries (isoCode, dialCode, name, flag)
|
|
6558
|
+
// and generate this array at build time if you prefer.
|
|
6559
|
+
];
|
|
6560
|
+
|
|
6561
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
6562
|
+
const DEFAULT_COUNTRY_ISO = 'TZ';
|
|
6563
|
+
const FilterableSingleSelectField = SingleSelectField;
|
|
6564
|
+
function normalizeTanzaniaLocal(raw) {
|
|
6565
|
+
const digits = (raw || '').replace(/\D/g, '');
|
|
6566
|
+
if (!digits)
|
|
6567
|
+
return '';
|
|
6568
|
+
if (digits.startsWith('255')) {
|
|
6569
|
+
let sub = digits.slice(3);
|
|
6570
|
+
if (sub.startsWith('0'))
|
|
6571
|
+
sub = sub.slice(1);
|
|
6572
|
+
return ('0' + sub).slice(0, 10);
|
|
6573
|
+
}
|
|
6574
|
+
if (digits.startsWith('0')) {
|
|
6575
|
+
return digits.slice(0, 10);
|
|
6576
|
+
}
|
|
6577
|
+
if (/^[67]\d{7,9}$/.test(digits)) {
|
|
6578
|
+
return ('0' + digits).slice(0, 10);
|
|
6579
|
+
}
|
|
6580
|
+
if (digits.length >= 9 && !digits.startsWith('0')) {
|
|
6581
|
+
return ('0' + digits.slice(0, 9)).slice(0, 10);
|
|
6582
|
+
}
|
|
6583
|
+
return digits.slice(0, 10);
|
|
6584
|
+
}
|
|
6585
|
+
const InternationalPhoneField = ({ name, label, placeholder, value, required, disabled, error, validationText, inputWidth, defaultCountryIsoCode = DEFAULT_COUNTRY_ISO, onChange, onBlur, }) => {
|
|
6586
|
+
const [selectedIsoCode, setSelectedIsoCode] = React__default.useState(defaultCountryIsoCode);
|
|
6587
|
+
const [filterText, setFilterText] = React__default.useState('');
|
|
6588
|
+
const [leadingZeroWarning, setLeadingZeroWarning] = React__default.useState(null);
|
|
6589
|
+
const selectedCountry = ALL_COUNTRIES.find((c) => c.isoCode === selectedIsoCode) ??
|
|
6590
|
+
ALL_COUNTRIES.find((c) => c.isoCode === DEFAULT_COUNTRY_ISO);
|
|
6591
|
+
const [localNumber, setLocalNumber] = React__default.useState('');
|
|
6592
|
+
React__default.useEffect(() => {
|
|
6593
|
+
const raw = value ?? '';
|
|
6594
|
+
if (selectedCountry.isoCode === 'TZ') {
|
|
6595
|
+
const normalizedStored = normalizeTanzaniaLocal(raw);
|
|
6596
|
+
if (!normalizedStored) {
|
|
6597
|
+
setLocalNumber('');
|
|
6598
|
+
return;
|
|
6599
|
+
}
|
|
6600
|
+
const digits = normalizedStored.replace(/\D/g, '');
|
|
6601
|
+
const ui = digits.startsWith('0') ? digits.slice(1) : digits;
|
|
6602
|
+
setLocalNumber(ui);
|
|
6603
|
+
}
|
|
6604
|
+
else {
|
|
6605
|
+
const digits = raw.replace(/\D/g, '').slice(0, 15);
|
|
6606
|
+
setLocalNumber(digits);
|
|
6607
|
+
}
|
|
6608
|
+
setLeadingZeroWarning(null);
|
|
6609
|
+
}, [value, selectedCountry.isoCode]);
|
|
6610
|
+
const filteredCountries = React__default.useMemo(() => {
|
|
6611
|
+
const term = filterText.trim().toLowerCase();
|
|
6612
|
+
if (!term)
|
|
6613
|
+
return ALL_COUNTRIES;
|
|
6614
|
+
return ALL_COUNTRIES.filter((c) => {
|
|
6615
|
+
const haystack = `${c.name} ${c.dialCode} ${c.isoCode}`.toLowerCase();
|
|
6616
|
+
return haystack.includes(term);
|
|
6617
|
+
});
|
|
6618
|
+
}, [filterText]);
|
|
6619
|
+
const handleCountryChange = ({ selected }) => {
|
|
6620
|
+
setSelectedIsoCode(selected);
|
|
6621
|
+
};
|
|
6622
|
+
const handleLocalChange = ({ value }) => {
|
|
6623
|
+
const digitsOnly = (value || '').replace(/\D/g, '');
|
|
6624
|
+
if (selectedCountry.isoCode === 'TZ') {
|
|
6625
|
+
let ui = digitsOnly;
|
|
6626
|
+
if (ui.startsWith('0')) {
|
|
6627
|
+
setLeadingZeroWarning('For Tanzania, do not start the number with 0. Enter it without the leading 0 (e.g. 767000000).');
|
|
6628
|
+
ui = ui.slice(1);
|
|
6629
|
+
}
|
|
6630
|
+
else {
|
|
6631
|
+
setLeadingZeroWarning(null);
|
|
6632
|
+
}
|
|
6633
|
+
ui = ui.slice(0, 9);
|
|
6634
|
+
const stored = ui ? '0' + ui : '';
|
|
6635
|
+
setLocalNumber(ui);
|
|
6636
|
+
onChange(stored);
|
|
6637
|
+
}
|
|
6638
|
+
else {
|
|
6639
|
+
const ui = digitsOnly.slice(0, 15);
|
|
6640
|
+
setLocalNumber(ui);
|
|
6641
|
+
onChange(ui);
|
|
6642
|
+
setLeadingZeroWarning(null);
|
|
6643
|
+
}
|
|
6644
|
+
};
|
|
6645
|
+
const effectiveValidationText = leadingZeroWarning ??
|
|
6646
|
+
validationText ??
|
|
6647
|
+
'Enter the phone number without the leading 0 (e.g. 767000000). The country code is already applied, and the system will store it as 0767000000 for Tanzania.';
|
|
6648
|
+
const hasError = Boolean(error || leadingZeroWarning);
|
|
6649
|
+
const wrapperStyle = {
|
|
6650
|
+
maxWidth: typeof inputWidth === 'number' ? inputWidth : inputWidth || 480,
|
|
6651
|
+
display: 'flex',
|
|
6652
|
+
flexDirection: 'column',
|
|
6653
|
+
gap: '0.5rem',
|
|
6654
|
+
};
|
|
6655
|
+
return (React__default.createElement("div", { style: wrapperStyle },
|
|
6656
|
+
label && (React__default.createElement("label", { htmlFor: name, style: {
|
|
6657
|
+
fontSize: '0.875rem',
|
|
6658
|
+
fontWeight: 500,
|
|
6659
|
+
color: '#1f2933',
|
|
6660
|
+
} },
|
|
6661
|
+
label,
|
|
6662
|
+
required ? (React__default.createElement("span", { style: { color: '#e53935', marginLeft: 4 } }, "*")) : null)),
|
|
6663
|
+
React__default.createElement("div", { style: {
|
|
6664
|
+
display: 'flex',
|
|
6665
|
+
width: '100%',
|
|
6666
|
+
gap: '0.75rem',
|
|
6667
|
+
alignItems: 'stretch',
|
|
6668
|
+
} },
|
|
6669
|
+
React__default.createElement("div", { style: {
|
|
6670
|
+
flex: '0 0 auto',
|
|
6671
|
+
width: 260,
|
|
6672
|
+
} },
|
|
6673
|
+
React__default.createElement(FilterableSingleSelectField, { selected: selectedIsoCode, onChange: handleCountryChange, disabled: disabled, dense: true, filterable: true, onFilterChange: ({ value }) => setFilterText(value), noMatchText: "No matching country" }, filteredCountries.map((country) => (React__default.createElement(SingleSelectOption, { disabled: disabled, key: country.isoCode, value: country.isoCode, label: `${country.flag} ${country.name} (${country.dialCode})` }))))),
|
|
6674
|
+
React__default.createElement("div", { style: { flex: '1 1 0', minWidth: 0 } },
|
|
6675
|
+
React__default.createElement(InputField$1, { type: "tel", name: name, placeholder: placeholder ?? '767000000', value: localNumber, required: required, disabled: disabled, error: hasError, validationText: effectiveValidationText, autoComplete: "tel", max: selectedCountry.isoCode === 'TZ' ? '9' : '15', onChange: handleLocalChange, onBlur: () => {
|
|
6676
|
+
if (selectedCountry.isoCode === 'TZ') {
|
|
6677
|
+
const digits = (localNumber || '')
|
|
6678
|
+
.replace(/\D/g, '')
|
|
6679
|
+
.slice(0, 9);
|
|
6680
|
+
const stored = digits ? '0' + digits : '';
|
|
6681
|
+
if (digits !== localNumber) {
|
|
6682
|
+
setLocalNumber(digits);
|
|
6683
|
+
onChange(stored);
|
|
6684
|
+
}
|
|
6685
|
+
}
|
|
6686
|
+
onBlur?.();
|
|
6687
|
+
} })))));
|
|
6688
|
+
};
|
|
6689
|
+
|
|
6539
6690
|
// Copyright 2024 UDSM DHIS2 Lab. All rights reserved.
|
|
6540
6691
|
// Use of this source code is governed by a BSD-style
|
|
6541
6692
|
// license that can be found in the LICENSE file.
|
|
@@ -6661,7 +6812,6 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
6661
6812
|
value &&
|
|
6662
6813
|
value.length > 0 &&
|
|
6663
6814
|
touched)) {
|
|
6664
|
-
// if (this.field().unique && value && value.length > 0 && touched) {
|
|
6665
6815
|
setCheckingUniqueness(true);
|
|
6666
6816
|
setRecordExistError(undefined);
|
|
6667
6817
|
try {
|
|
@@ -6684,6 +6834,18 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
6684
6834
|
};
|
|
6685
6835
|
const formFieldContent = () => {
|
|
6686
6836
|
switch (this.field().controlType) {
|
|
6837
|
+
case 'number':
|
|
6838
|
+
return (React__default.createElement(InputField$1, { error: hasError, validationText: validationError, type: this.field().type, inputWidth: inputWidth, required: this.field().required, name: this.field().id, label: this.label(), min: this.field().min?.toString(), max: this.field().max?.toString(), placeholder: this.placeholder(), value: value, readOnly: disabled, onChange: (event) => {
|
|
6839
|
+
onValueChange(event.value);
|
|
6840
|
+
}, onBlur: () => {
|
|
6841
|
+
checkValueUniqueness();
|
|
6842
|
+
} }));
|
|
6843
|
+
case 'tel':
|
|
6844
|
+
return (React__default.createElement(InternationalPhoneField, { name: this.field().id, label: this.label(), placeholder: this.placeholder(), value: value ?? '', required: this.field().required, disabled: disabled, error: hasError, validationText: validationError, inputWidth: this.fieldConfig()?.inputWidth, defaultCountryIsoCode: "TZ", onChange: (localNumber) => {
|
|
6845
|
+
onValueChange(localNumber);
|
|
6846
|
+
}, onBlur: () => {
|
|
6847
|
+
checkValueUniqueness();
|
|
6848
|
+
} }));
|
|
6687
6849
|
case 'coordinate':
|
|
6688
6850
|
return (React__default.createElement("div", { style: { display: 'flex', flexDirection: 'column', gap: 12 } },
|
|
6689
6851
|
React__default.createElement(NoticeBox, { title: "Location capture required" },
|
|
@@ -6772,9 +6934,7 @@ class BaseFormFieldComponent extends ReactWrapperModule {
|
|
|
6772
6934
|
case 'date-time': {
|
|
6773
6935
|
const field = this.field();
|
|
6774
6936
|
const isDateTimeField = field.type === 'date-time';
|
|
6775
|
-
const inputType = isDateTimeField
|
|
6776
|
-
? 'datetime-local'
|
|
6777
|
-
: 'date';
|
|
6937
|
+
const inputType = isDateTimeField ? 'datetime-local' : 'date';
|
|
6778
6938
|
// Value coming from DHIS2 store
|
|
6779
6939
|
const htmlValue = this.formatValueForHtmlInputFromDhis(value, isDateTimeField);
|
|
6780
6940
|
const htmlMin = field.min
|
|
@@ -7780,9 +7940,9 @@ class FieldUtil {
|
|
|
7780
7940
|
case FieldType.TRUE_ONLY:
|
|
7781
7941
|
return 'checkbox';
|
|
7782
7942
|
case FieldType.NUMBER:
|
|
7783
|
-
return '
|
|
7943
|
+
return 'number';
|
|
7784
7944
|
case FieldType.PHONE_NUMBER:
|
|
7785
|
-
return '
|
|
7945
|
+
return 'tel';
|
|
7786
7946
|
case FieldType.ORG_UNIT:
|
|
7787
7947
|
return 'org-unit';
|
|
7788
7948
|
case FieldType.DATE:
|
|
@@ -7826,7 +7986,9 @@ class FieldControlTypeUtil {
|
|
|
7826
7986
|
case FieldType.TRUE_ONLY:
|
|
7827
7987
|
return 'checkbox';
|
|
7828
7988
|
case FieldType.NUMBER:
|
|
7829
|
-
return '
|
|
7989
|
+
return 'number';
|
|
7990
|
+
case FieldType.PHONE_NUMBER:
|
|
7991
|
+
return 'tel';
|
|
7830
7992
|
case FieldType.INTEGER_ZERO_OR_POSITIVE:
|
|
7831
7993
|
return 'textbox';
|
|
7832
7994
|
case FieldType.ORG_UNIT:
|
|
@@ -7864,6 +8026,8 @@ class FormFieldTypeUtil {
|
|
|
7864
8026
|
return 'coordinate';
|
|
7865
8027
|
case FieldType.DATE_TIME:
|
|
7866
8028
|
return 'date-time';
|
|
8029
|
+
case FieldType.PHONE_NUMBER:
|
|
8030
|
+
return 'tel';
|
|
7867
8031
|
default:
|
|
7868
8032
|
return 'text';
|
|
7869
8033
|
}
|
|
@@ -10104,6 +10268,47 @@ class ProgramEntryFormMetaData {
|
|
|
10104
10268
|
this.config = config;
|
|
10105
10269
|
return this;
|
|
10106
10270
|
}
|
|
10271
|
+
getFieldIdentifiers(field) {
|
|
10272
|
+
const f = field;
|
|
10273
|
+
const candidateIds = [
|
|
10274
|
+
f.key,
|
|
10275
|
+
field.id,
|
|
10276
|
+
f.code,
|
|
10277
|
+
f.attribute,
|
|
10278
|
+
f.trackedEntityAttribute,
|
|
10279
|
+
f.dataElement,
|
|
10280
|
+
];
|
|
10281
|
+
return candidateIds.filter((value) => typeof value === 'string' && value.length > 0);
|
|
10282
|
+
}
|
|
10283
|
+
getAutoAssignedFieldIdSet() {
|
|
10284
|
+
const autoAssigned = this.config?.autoAssignedValues;
|
|
10285
|
+
if (!autoAssigned?.length) {
|
|
10286
|
+
return null;
|
|
10287
|
+
}
|
|
10288
|
+
if (!this.autoAssignedFieldIdSet) {
|
|
10289
|
+
this.autoAssignedFieldIdSet = new Set(autoAssigned
|
|
10290
|
+
.map(({ field }) => field)
|
|
10291
|
+
.filter((value) => typeof value === 'string' && value.length > 0));
|
|
10292
|
+
}
|
|
10293
|
+
return this.autoAssignedFieldIdSet;
|
|
10294
|
+
}
|
|
10295
|
+
shouldDisableField(field) {
|
|
10296
|
+
const fieldIdentifiers = this.getFieldIdentifiers(field);
|
|
10297
|
+
if (!fieldIdentifiers.length) {
|
|
10298
|
+
return false;
|
|
10299
|
+
}
|
|
10300
|
+
const autoAssignedIdSet = this.getAutoAssignedFieldIdSet();
|
|
10301
|
+
if (!autoAssignedIdSet) {
|
|
10302
|
+
return false;
|
|
10303
|
+
}
|
|
10304
|
+
return fieldIdentifiers.some((id) => autoAssignedIdSet.has(id));
|
|
10305
|
+
}
|
|
10306
|
+
withDisabledFlags(field) {
|
|
10307
|
+
return {
|
|
10308
|
+
...field,
|
|
10309
|
+
disabled: true,
|
|
10310
|
+
};
|
|
10311
|
+
}
|
|
10107
10312
|
getProgramPromise() {
|
|
10108
10313
|
const program = this.config.program;
|
|
10109
10314
|
const programQuery = this.d2.programModule.program
|
|
@@ -10206,37 +10411,115 @@ class ProgramEntryFormMetaData {
|
|
|
10206
10411
|
if (!this.program) {
|
|
10207
10412
|
return [];
|
|
10208
10413
|
}
|
|
10209
|
-
|
|
10414
|
+
const fields = new ProgramEntryFormFieldUtil(this.program, this.config)
|
|
10415
|
+
.fields;
|
|
10416
|
+
const autoAssigned = this.config?.autoAssignedValues;
|
|
10417
|
+
if (!autoAssigned?.length) {
|
|
10418
|
+
return fields;
|
|
10419
|
+
}
|
|
10420
|
+
return fields.map((field) => this.shouldDisableField(field) ? this.withDisabledFlags(field) : field);
|
|
10210
10421
|
}
|
|
10422
|
+
// get sections(): IProgramEntryFormSection[] {
|
|
10423
|
+
// if (!this.program) {
|
|
10424
|
+
// return [];
|
|
10425
|
+
// }
|
|
10426
|
+
// const { displayType, formType } = this.config;
|
|
10427
|
+
// if (!this.program || this.config.displayType !== 'FLAT') {
|
|
10428
|
+
// return [];
|
|
10429
|
+
// }
|
|
10430
|
+
// if (displayType === 'FLAT' && formType === 'TRACKER') {
|
|
10431
|
+
// return new ProgramEntryFormSectionUtil(this.program, this.config)
|
|
10432
|
+
// .programEntryFormSections;
|
|
10433
|
+
// }
|
|
10434
|
+
// return new ProgramEntryFormSectionUtil(this.program, this.config)
|
|
10435
|
+
// .programEntryFormSections;
|
|
10436
|
+
// }
|
|
10437
|
+
// get programStageSections(): IProgramEntryFormSection[] {
|
|
10438
|
+
// if (!this.program) {
|
|
10439
|
+
// return [];
|
|
10440
|
+
// }
|
|
10441
|
+
// const { displayType, formType } = this.config;
|
|
10442
|
+
// if (displayType === 'FLAT' && formType === 'EVENT') {
|
|
10443
|
+
// return new ProgramStageEntryFormSectionUtil(this.program, this.config)
|
|
10444
|
+
// .programStageEntryFormSections;
|
|
10445
|
+
// }
|
|
10446
|
+
// if (displayType === 'SECTION') {
|
|
10447
|
+
// return new ProgramStageEntryFormSectionUtil(this.program, this.config)
|
|
10448
|
+
// .programStageEntryFormSections;
|
|
10449
|
+
// }
|
|
10450
|
+
// return [];
|
|
10451
|
+
// }
|
|
10211
10452
|
get sections() {
|
|
10212
10453
|
if (!this.program) {
|
|
10213
10454
|
return [];
|
|
10214
10455
|
}
|
|
10215
|
-
const { displayType
|
|
10216
|
-
if (
|
|
10456
|
+
const { displayType } = this.config;
|
|
10457
|
+
if (displayType !== 'FLAT') {
|
|
10217
10458
|
return [];
|
|
10218
10459
|
}
|
|
10219
|
-
|
|
10220
|
-
|
|
10221
|
-
|
|
10460
|
+
const baseSections = new ProgramEntryFormSectionUtil(this.program, this.config).programEntryFormSections;
|
|
10461
|
+
const autoAssigned = this.config?.autoAssignedValues;
|
|
10462
|
+
if (!autoAssigned?.length) {
|
|
10463
|
+
return baseSections;
|
|
10222
10464
|
}
|
|
10223
|
-
return
|
|
10224
|
-
.
|
|
10465
|
+
return baseSections.map((section) => {
|
|
10466
|
+
const formFields = section.formFields ?? [];
|
|
10467
|
+
if (!formFields.length) {
|
|
10468
|
+
return section;
|
|
10469
|
+
}
|
|
10470
|
+
let hasDisabledField = false;
|
|
10471
|
+
const updatedFields = formFields.map((field) => {
|
|
10472
|
+
if (this.shouldDisableField(field)) {
|
|
10473
|
+
hasDisabledField = true;
|
|
10474
|
+
return this.withDisabledFlags(field);
|
|
10475
|
+
}
|
|
10476
|
+
return field;
|
|
10477
|
+
});
|
|
10478
|
+
if (!hasDisabledField) {
|
|
10479
|
+
return section;
|
|
10480
|
+
}
|
|
10481
|
+
return {
|
|
10482
|
+
...section,
|
|
10483
|
+
formFields: updatedFields,
|
|
10484
|
+
};
|
|
10485
|
+
});
|
|
10225
10486
|
}
|
|
10226
10487
|
get programStageSections() {
|
|
10227
10488
|
if (!this.program) {
|
|
10228
10489
|
return [];
|
|
10229
10490
|
}
|
|
10230
10491
|
const { displayType, formType } = this.config;
|
|
10231
|
-
|
|
10232
|
-
|
|
10233
|
-
|
|
10492
|
+
const isFlatEvent = displayType === 'FLAT' && formType === 'EVENT';
|
|
10493
|
+
const isSectionDisplay = displayType === 'SECTION';
|
|
10494
|
+
if (!isFlatEvent && !isSectionDisplay) {
|
|
10495
|
+
return [];
|
|
10234
10496
|
}
|
|
10235
|
-
|
|
10236
|
-
|
|
10237
|
-
|
|
10497
|
+
const baseSections = new ProgramStageEntryFormSectionUtil(this.program, this.config).programStageEntryFormSections;
|
|
10498
|
+
const autoAssigned = this.config?.autoAssignedValues;
|
|
10499
|
+
if (!autoAssigned?.length) {
|
|
10500
|
+
return baseSections;
|
|
10238
10501
|
}
|
|
10239
|
-
return
|
|
10502
|
+
return baseSections.map((section) => {
|
|
10503
|
+
const formFields = section.formFields ?? [];
|
|
10504
|
+
if (!formFields.length) {
|
|
10505
|
+
return section;
|
|
10506
|
+
}
|
|
10507
|
+
let hasDisabledField = false;
|
|
10508
|
+
const updatedFields = formFields.map((field) => {
|
|
10509
|
+
if (this.shouldDisableField(field)) {
|
|
10510
|
+
hasDisabledField = true;
|
|
10511
|
+
return this.withDisabledFlags(field);
|
|
10512
|
+
}
|
|
10513
|
+
return field;
|
|
10514
|
+
});
|
|
10515
|
+
if (!hasDisabledField) {
|
|
10516
|
+
return section;
|
|
10517
|
+
}
|
|
10518
|
+
return {
|
|
10519
|
+
...section,
|
|
10520
|
+
formFields: updatedFields,
|
|
10521
|
+
};
|
|
10522
|
+
});
|
|
10240
10523
|
}
|
|
10241
10524
|
get rules() {
|
|
10242
10525
|
if (!this.program || !this.program.programRules) {
|
|
@@ -10355,23 +10638,54 @@ class ProgramEntryFormModule {
|
|
|
10355
10638
|
};
|
|
10356
10639
|
}, ...(ngDevMode ? [{ debugName: "FormActionButtons" }] : []));
|
|
10357
10640
|
}
|
|
10641
|
+
// async ngOnInit() {
|
|
10642
|
+
// this.loading.set(true);
|
|
10643
|
+
// try {
|
|
10644
|
+
// // Loading metadata
|
|
10645
|
+
// const metaData = await new ProgramEntryFormMetaData()
|
|
10646
|
+
// .setConfig(this.config())
|
|
10647
|
+
// .get();
|
|
10648
|
+
// this.metaData.set(metaData);
|
|
10649
|
+
// // Load initial instance information
|
|
10650
|
+
// const instance = await this.#getInstance();
|
|
10651
|
+
// this.instance.set(instance);
|
|
10652
|
+
// if (this.config().autoAssignedValues) {
|
|
10653
|
+
// this.#updateInstanceWithAutoAssignedValues(
|
|
10654
|
+
// this.config().autoAssignedValues || []
|
|
10655
|
+
// );
|
|
10656
|
+
// }
|
|
10657
|
+
// this.loading.set(false);
|
|
10658
|
+
// } catch (err) {
|
|
10659
|
+
// this.loading.set(false);
|
|
10660
|
+
// }
|
|
10661
|
+
// }
|
|
10358
10662
|
async ngOnInit() {
|
|
10359
10663
|
this.loading.set(true);
|
|
10360
10664
|
try {
|
|
10361
|
-
|
|
10665
|
+
const config = this.config();
|
|
10362
10666
|
const metaData = await new ProgramEntryFormMetaData()
|
|
10363
|
-
.setConfig(
|
|
10667
|
+
.setConfig(config)
|
|
10364
10668
|
.get();
|
|
10669
|
+
if (!metaData) {
|
|
10670
|
+
console.error('ProgramEntryFormMetaData.get() returned null');
|
|
10671
|
+
return;
|
|
10672
|
+
}
|
|
10365
10673
|
this.metaData.set(metaData);
|
|
10366
|
-
// Load initial instance information
|
|
10367
10674
|
const instance = await this.#getInstance();
|
|
10675
|
+
if (!instance) {
|
|
10676
|
+
console.error('Failed to create or load instance for program entry form');
|
|
10677
|
+
return;
|
|
10678
|
+
}
|
|
10368
10679
|
this.instance.set(instance);
|
|
10369
|
-
|
|
10370
|
-
|
|
10680
|
+
const autoAssigned = config.autoAssignedValues;
|
|
10681
|
+
if (autoAssigned?.length) {
|
|
10682
|
+
this.#updateInstanceWithAutoAssignedValues(autoAssigned);
|
|
10371
10683
|
}
|
|
10372
|
-
this.loading.set(false);
|
|
10373
10684
|
}
|
|
10374
|
-
catch (
|
|
10685
|
+
catch (error) {
|
|
10686
|
+
console.error('Error during ProgramEntryForm initialization', error);
|
|
10687
|
+
}
|
|
10688
|
+
finally {
|
|
10375
10689
|
this.loading.set(false);
|
|
10376
10690
|
}
|
|
10377
10691
|
}
|
|
@@ -10388,18 +10702,93 @@ class ProgramEntryFormModule {
|
|
|
10388
10702
|
onCancel() {
|
|
10389
10703
|
this.formCancel.emit();
|
|
10390
10704
|
}
|
|
10705
|
+
#resolveFieldRuntimeId(configuredKey, metaData) {
|
|
10706
|
+
const formFields = metaData?.formFields;
|
|
10707
|
+
if (!formFields || formFields.length === 0) {
|
|
10708
|
+
return configuredKey;
|
|
10709
|
+
}
|
|
10710
|
+
for (let index = 0; index < formFields.length; index++) {
|
|
10711
|
+
const currentField = formFields[index];
|
|
10712
|
+
if (currentField.id === configuredKey) {
|
|
10713
|
+
return currentField.id;
|
|
10714
|
+
}
|
|
10715
|
+
if (currentField.attribute === configuredKey ||
|
|
10716
|
+
currentField.trackedEntityAttribute === configuredKey) {
|
|
10717
|
+
return currentField.id;
|
|
10718
|
+
}
|
|
10719
|
+
if (currentField.dataElement === configuredKey) {
|
|
10720
|
+
return currentField.id;
|
|
10721
|
+
}
|
|
10722
|
+
}
|
|
10723
|
+
return configuredKey;
|
|
10724
|
+
}
|
|
10725
|
+
// #updateInstanceWithAutoAssignedValues(
|
|
10726
|
+
// autoAssignedValues: AutoAssignedValues[]
|
|
10727
|
+
// ) {
|
|
10728
|
+
// const assignedDataValues = autoAssignedValues.reduce(
|
|
10729
|
+
// (entities, assignedValue) => {
|
|
10730
|
+
// return {
|
|
10731
|
+
// ...entities,
|
|
10732
|
+
// [assignedValue.field]: assignedValue.value,
|
|
10733
|
+
// };
|
|
10734
|
+
// },
|
|
10735
|
+
// {}
|
|
10736
|
+
// );
|
|
10737
|
+
// this.#updateInstance(assignedDataValues);
|
|
10738
|
+
// }
|
|
10391
10739
|
#updateInstanceWithAutoAssignedValues(autoAssignedValues) {
|
|
10392
|
-
const
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10398
|
-
|
|
10740
|
+
const valueCount = autoAssignedValues?.length ?? 0;
|
|
10741
|
+
if (valueCount === 0) {
|
|
10742
|
+
return;
|
|
10743
|
+
}
|
|
10744
|
+
const metaData = this.metaData();
|
|
10745
|
+
const aggregatedValues = {};
|
|
10746
|
+
for (let index = 0; index < valueCount; index++) {
|
|
10747
|
+
const { field: configuredKey, value } = autoAssignedValues[index];
|
|
10748
|
+
const semanticKey = metaData
|
|
10749
|
+
? this.#resolveFieldRuntimeId(configuredKey, metaData)
|
|
10750
|
+
: configuredKey;
|
|
10751
|
+
aggregatedValues[semanticKey] = value;
|
|
10752
|
+
if (configuredKey !== semanticKey) {
|
|
10753
|
+
aggregatedValues[configuredKey] = value;
|
|
10754
|
+
}
|
|
10755
|
+
}
|
|
10756
|
+
if (Object.keys(aggregatedValues).length === 0) {
|
|
10757
|
+
return;
|
|
10758
|
+
}
|
|
10759
|
+
this.#updateInstance(aggregatedValues);
|
|
10399
10760
|
}
|
|
10761
|
+
// #updateInstance(dataValues: Record<string, unknown>) {
|
|
10762
|
+
// this.instance.update((instance) => {
|
|
10763
|
+
// instance?.updateDataValues(dataValues, this.config().updateTeiOrgUnit);
|
|
10764
|
+
// return instance;
|
|
10765
|
+
// });
|
|
10766
|
+
// }
|
|
10767
|
+
// #updateInstance(dataValues: Record<string, unknown>) {
|
|
10768
|
+
// this.instance.update((instance) => {
|
|
10769
|
+
// if (!instance) {
|
|
10770
|
+
// return instance;
|
|
10771
|
+
// }
|
|
10772
|
+
// instance.updateDataValues(dataValues, this.config().updateTeiOrgUnit);
|
|
10773
|
+
// return instance;
|
|
10774
|
+
// });
|
|
10775
|
+
// }
|
|
10400
10776
|
#updateInstance(dataValues) {
|
|
10777
|
+
if (!dataValues || Object.keys(dataValues).length === 0) {
|
|
10778
|
+
return;
|
|
10779
|
+
}
|
|
10780
|
+
const shouldUpdateOrgUnit = this.config().updateTeiOrgUnit;
|
|
10401
10781
|
this.instance.update((instance) => {
|
|
10402
|
-
|
|
10782
|
+
if (!instance) {
|
|
10783
|
+
return instance;
|
|
10784
|
+
}
|
|
10785
|
+
for (const key in dataValues) {
|
|
10786
|
+
if (Object.prototype.hasOwnProperty.call(dataValues, key)) {
|
|
10787
|
+
instance[key] =
|
|
10788
|
+
dataValues[key];
|
|
10789
|
+
}
|
|
10790
|
+
}
|
|
10791
|
+
instance.updateDataValues(dataValues, shouldUpdateOrgUnit);
|
|
10403
10792
|
return instance;
|
|
10404
10793
|
});
|
|
10405
10794
|
}
|