@iapps/ng-dhis2-ui 1.2.153 → 1.2.154

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.
@@ -8818,6 +8818,84 @@ class BaseFormFieldComponent extends ReactWrapperModule {
8818
8818
  // Stable React key, avoids generateUUID re-mounting.
8819
8819
  return String(option?.value ?? option?.id ?? option?.code ?? option?.label ?? '');
8820
8820
  }
8821
+ formatValueForHtmlInputFromDhis(rawValue, isDateTimeField) {
8822
+ if (rawValue == null)
8823
+ return '';
8824
+ const trimmed = String(rawValue).trim();
8825
+ if (!trimmed)
8826
+ return '';
8827
+ const pad = (n) => String(n).padStart(2, '0');
8828
+ if (!isDateTimeField) {
8829
+ // Already in HTML date format
8830
+ if (/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
8831
+ return trimmed;
8832
+ }
8833
+ // ISO-like datetime -> preserve calendar date portion directly
8834
+ const datePartMatch = trimmed.match(/^(\d{4}-\d{2}-\d{2})[T\s]/);
8835
+ if (datePartMatch) {
8836
+ return datePartMatch[1];
8837
+ }
8838
+ // Fallback parse only if needed
8839
+ const date = new Date(trimmed);
8840
+ if (Number.isNaN(date.getTime())) {
8841
+ return '';
8842
+ }
8843
+ return (`${date.getFullYear()}-` +
8844
+ `${pad(date.getMonth() + 1)}-` +
8845
+ `${pad(date.getDate())}`);
8846
+ }
8847
+ // Already in HTML datetime-local format
8848
+ if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(trimmed)) {
8849
+ return trimmed;
8850
+ }
8851
+ // ISO-like datetime with optional seconds/timezone -> keep YYYY-MM-DDTHH:mm only
8852
+ const dateTimeMatch = trimmed.match(/^(\d{4}-\d{2}-\d{2})[T\s](\d{2}):(\d{2})/);
8853
+ if (dateTimeMatch) {
8854
+ return `${dateTimeMatch[1]}T${dateTimeMatch[2]}:${dateTimeMatch[3]}`;
8855
+ }
8856
+ const parsedDate = new Date(trimmed);
8857
+ if (Number.isNaN(parsedDate.getTime())) {
8858
+ return '';
8859
+ }
8860
+ const year = parsedDate.getFullYear();
8861
+ const month = pad(parsedDate.getMonth() + 1);
8862
+ const day = pad(parsedDate.getDate());
8863
+ const hours = pad(parsedDate.getHours());
8864
+ const minutes = pad(parsedDate.getMinutes());
8865
+ return `${year}-${month}-${day}T${hours}:${minutes}`;
8866
+ }
8867
+ pickEarlierDateLimit(metadataMax, systemMax) {
8868
+ if (!metadataMax && !systemMax)
8869
+ return undefined;
8870
+ if (!metadataMax)
8871
+ return systemMax;
8872
+ if (!systemMax)
8873
+ return metadataMax;
8874
+ return metadataMax < systemMax ? metadataMax : systemMax;
8875
+ }
8876
+ getNowForHtmlDateInput(isDateTimeField) {
8877
+ const now = new Date();
8878
+ const pad = (n) => String(n).padStart(2, '0');
8879
+ const datePart = `${now.getFullYear()}-` +
8880
+ `${pad(now.getMonth() + 1)}-` +
8881
+ `${pad(now.getDate())}`;
8882
+ if (!isDateTimeField) {
8883
+ return datePart;
8884
+ }
8885
+ const timePart = `${pad(now.getHours())}:${pad(now.getMinutes())}`;
8886
+ return `${datePart}T${timePart}`;
8887
+ }
8888
+ resolveHtmlMax(field, isDateTimeField) {
8889
+ // When future dates are allowed, do not limit picker selection at all
8890
+ if (field.allowFutureDate === true) {
8891
+ return undefined;
8892
+ }
8893
+ const metadataMax = field.max
8894
+ ? this.formatValueForHtmlInputFromDhis(String(field.max), isDateTimeField)
8895
+ : undefined;
8896
+ const systemMax = this.getNowForHtmlDateInput(isDateTimeField);
8897
+ return this.pickEarlierDateLimit(metadataMax, systemMax);
8898
+ }
8821
8899
  #getInputField() {
8822
8900
  return () => {
8823
8901
  const fg = this.form();
@@ -9025,18 +9103,23 @@ class BaseFormFieldComponent extends ReactWrapperModule {
9025
9103
  case 'date':
9026
9104
  case 'date-time': {
9027
9105
  const isDateTimeField = f.type === 'date-time';
9028
- const inputType = isDateTimeField ? 'datetime-local' : 'date';
9029
- const htmlValue = this.formatValueForHtmlInputFromDhis(value, isDateTimeField);
9030
- const htmlMin = f.min
9106
+ const inputType = isDateTimeField
9107
+ ? 'datetime-local'
9108
+ : 'date';
9109
+ const allowFutureDate = f.allowFutureDate === true;
9110
+ const htmlValue = value != null && String(value).trim() !== ''
9111
+ ? this.formatValueForHtmlInputFromDhis(String(value), isDateTimeField)
9112
+ : '';
9113
+ const htmlMin = f.min != null && String(f.min).trim() !== ''
9031
9114
  ? this.formatValueForHtmlInputFromDhis(String(f.min), isDateTimeField)
9032
9115
  : undefined;
9033
- const metadataMax = f.max
9034
- ? this.formatValueForHtmlInputFromDhis(String(f.max), isDateTimeField)
9035
- : undefined;
9036
- const systemMax = this.getNowForHtmlDateInput(isDateTimeField);
9037
- const htmlMax = this.pickEarlierDateLimit(metadataMax, systemMax);
9116
+ const htmlMax = allowFutureDate
9117
+ ? undefined
9118
+ : f.max
9119
+ ? this.pickEarlierDateLimit(this.formatValueForHtmlInputFromDhis(String(f.max), isDateTimeField), this.getNowForHtmlDateInput(isDateTimeField))
9120
+ : this.getNowForHtmlDateInput(isDateTimeField);
9038
9121
  return (React__default.createElement(InputField$1, { error: hasError, validationText: validationError, type: inputType, inputWidth: inputWidth, required: f.required, name: f.id, label: this.label(), min: htmlMin, max: htmlMax, placeholder: this.placeholder(), value: htmlValue, readOnly: disabled, onChange: ({ value: newValue }) => {
9039
- const normalized = this.normalizeDateValueFromHtmlInput(newValue, isDateTimeField, true);
9122
+ const normalized = this.normalizeDateValueFromHtmlInput(newValue, isDateTimeField, allowFutureDate);
9040
9123
  onValueChange(normalized);
9041
9124
  }, onBlur: () => checkValueUniqueness() }));
9042
9125
  }
@@ -9085,71 +9168,20 @@ class BaseFormFieldComponent extends ReactWrapperModule {
9085
9168
  `${pad(date.getHours())}:` +
9086
9169
  `${pad(date.getMinutes())}`);
9087
9170
  }
9088
- formatValueForHtmlInputFromDhis(rawValue, isDateTimeField) {
9089
- if (!rawValue)
9090
- return '';
9091
- const trimmed = rawValue.trim();
9092
- if (!trimmed)
9093
- return '';
9094
- const pad = (n) => String(n).padStart(2, '0');
9095
- if (!isDateTimeField) {
9096
- if (/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
9097
- return trimmed;
9098
- }
9099
- const date = new Date(trimmed);
9100
- if (Number.isNaN(date.getTime())) {
9101
- return '';
9102
- }
9103
- return (`${date.getFullYear()}-` +
9104
- `${pad(date.getMonth() + 1)}-` +
9105
- `${pad(date.getDate())}`);
9106
- }
9107
- const parsedDate = new Date(trimmed);
9108
- if (Number.isNaN(parsedDate.getTime())) {
9109
- return '';
9110
- }
9111
- const year = parsedDate.getFullYear();
9112
- const month = pad(parsedDate.getMonth() + 1);
9113
- const day = pad(parsedDate.getDate());
9114
- const hours = pad(parsedDate.getHours());
9115
- const minutes = pad(parsedDate.getMinutes());
9116
- return `${year}-${month}-${day}T${hours}:${minutes}`;
9117
- }
9118
- getNowForHtmlDateInput(isDateTimeField) {
9119
- const now = new Date();
9120
- const pad = (n) => String(n).padStart(2, '0');
9121
- const datePart = `${now.getFullYear()}-` +
9122
- `${pad(now.getMonth() + 1)}-` +
9123
- `${pad(now.getDate())}`;
9124
- if (!isDateTimeField) {
9125
- return datePart;
9126
- }
9127
- const timePart = `${pad(now.getHours())}:` + `${pad(now.getMinutes())}`;
9128
- return `${datePart}T${timePart}`;
9129
- }
9130
- pickEarlierDateLimit(metadataMax, systemMax) {
9131
- if (!metadataMax && !systemMax)
9132
- return undefined;
9133
- if (!metadataMax)
9134
- return systemMax;
9135
- if (!systemMax)
9136
- return metadataMax;
9137
- return metadataMax < systemMax ? metadataMax : systemMax;
9138
- }
9139
9171
  /**
9140
- * Normalizes value from the HTML input into DHIS storage format.
9141
- *
9142
- * For date:
9143
- * - Input: "YYYY-MM-DD"
9144
- * - Output: "YYYY-MM-DD"
9145
- *
9146
- * For datetime:
9147
- * - Input: "YYYY-MM-DDTHH:mm" (local)
9148
- * - Output: ISO string in UTC: "YYYY-MM-DDTHH:mm:ss.sssZ"
9149
- *
9150
- * If disallowFuture = true, any value beyond "now" is clamped to now.
9151
- */
9152
- normalizeDateValueFromHtmlInput(inputValue, isDateTimeField, disallowFuture) {
9172
+ * Normalizes value from the HTML input into DHIS storage format.
9173
+ *
9174
+ * For date:
9175
+ * - Input: "YYYY-MM-DD"
9176
+ * - Output: "YYYY-MM-DD"
9177
+ *
9178
+ * For datetime:
9179
+ * - Input: "YYYY-MM-DDTHH:mm" (local)
9180
+ * - Output: ISO string in UTC: "YYYY-MM-DDTHH:mm:ss.sssZ"
9181
+ *
9182
+ * If allowFutureDate = false, any value beyond "now" is clamped to now.
9183
+ */
9184
+ normalizeDateValueFromHtmlInput(inputValue, isDateTimeField, allowFutureDate) {
9153
9185
  const trimmed = (inputValue ?? '').trim();
9154
9186
  if (!trimmed)
9155
9187
  return null;
@@ -9157,7 +9189,7 @@ class BaseFormFieldComponent extends ReactWrapperModule {
9157
9189
  if (!/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
9158
9190
  return null;
9159
9191
  }
9160
- if (disallowFuture) {
9192
+ if (!allowFutureDate) {
9161
9193
  const todayStr = this.getNowForHtmlDateInput(false);
9162
9194
  if (trimmed > todayStr) {
9163
9195
  return todayStr;
@@ -9175,13 +9207,10 @@ class BaseFormFieldComponent extends ReactWrapperModule {
9175
9207
  if (Number.isNaN(localDate.getTime())) {
9176
9208
  return null;
9177
9209
  }
9178
- if (disallowFuture) {
9210
+ if (!allowFutureDate) {
9179
9211
  const now = new Date();
9180
9212
  if (localDate.getTime() > now.getTime()) {
9181
- // Option A: clamp to now
9182
9213
  return now.toISOString();
9183
- // Option B: reject:
9184
- // return null;
9185
9214
  }
9186
9215
  }
9187
9216
  // Store as UTC ISO string with millis, e.g. "2025-11-26T21:01:00.000Z"
@@ -10219,6 +10248,7 @@ class FormFieldGroup {
10219
10248
  controlType: FieldUtil.getFieldControlType(fieldMetaData['valueType'], hasOptions),
10220
10249
  metaType: fieldMetaData['metaType'],
10221
10250
  stepId: fieldMetaData['stepId'],
10251
+ allowFutureDate: fieldMetaData['allowFutureDate'],
10222
10252
  extension,
10223
10253
  });
10224
10254
  })
@@ -10804,6 +10834,7 @@ class FormUtil {
10804
10834
  min: field.min,
10805
10835
  max: field.max,
10806
10836
  maxLength: field.maxLength,
10837
+ allowFutureDate: field.allowFutureDate,
10807
10838
  });
10808
10839
  });
10809
10840
  }
@@ -11921,6 +11952,8 @@ class ProgramEntryFormFieldUtil {
11921
11952
  controlType: FieldUtil.getFieldControlType(field.valueType, hasOptions),
11922
11953
  metaType: field.metaType,
11923
11954
  stepId: field.stepId,
11955
+ allowFutureDate: field
11956
+ .allowFutureDate,
11924
11957
  extension,
11925
11958
  });
11926
11959
  })
@@ -11957,334 +11990,6 @@ class ProgramStageEntryFormSection {
11957
11990
  }
11958
11991
  }
11959
11992
 
11960
- /* eslint-disable @typescript-eslint/no-explicit-any */
11961
- // // // Copyright 2025 UDSM DHIS2 Lab. All rights reserved.
11962
- // // // Use of this source code is governed by a BSD-style
11963
- // // // license that can be found in the LICENSE file.
11964
- // import { camelCase, isUndefined } from 'lodash';
11965
- // import { Program, ProgramStage, ProgramStageSection } from '@iapps/d2-web-sdk';
11966
- // import {
11967
- // IProgramStageEntryFormSection,
11968
- // ProgramStageEntryFormSection,
11969
- // } from '../models/program-stage-entry-form-section.model';
11970
- // import { ProgramEntryFormConfig } from '../models/program-entry-form.config';
11971
- // import { IFormField } from '../../form/interfaces/form-field.interface';
11972
- // import { FieldDropdown } from '../../form/models/field-dropdown.model';
11973
- // import { FormField } from '../../form/models/form-field.model';
11974
- // import { FieldUtil } from '../../form/utils';
11975
- // import { ProgramEntryFormFieldUtil } from './program-entry-form-field.util';
11976
- // // import {
11977
- // // IProgramStageEntryFormSection,
11978
- // // ProgramEntryFormConfig,
11979
- // // ProgramStageEntryFormSection,
11980
- // // } from '../models';
11981
- // // TODO: START - DEPRECATED APPROACH
11982
- // // import { Program, ProgramStage, ProgramStageSection } from '@iapps/d2-web-sdk';
11983
- // // import {
11984
- // // IProgramStageEntryFormSection,
11985
- // // ProgramEntryFormConfig,
11986
- // // ProgramStageEntryFormSection,
11987
- // // } from '../models';
11988
- // // export class ProgramStageEntryFormSectionUtil {
11989
- // // constructor(
11990
- // // private program: Program,
11991
- // // private config: ProgramEntryFormConfig
11992
- // // ) {}
11993
- // // // get getProgramStageSections(): IProgramStageEntryFormSection[] {
11994
- // // // return (this.program.programStages || []).flatMap((stage) =>
11995
- // // // (stage.programStageSections || []).map(
11996
- // // // (programStageSection: ProgramStageSection) =>
11997
- // // // new ProgramStageSection(programStageSection)
11998
- // // // )
11999
- // // // );
12000
- // // // }
12001
- // // get programStageEntryFormSections(): IProgramStageEntryFormSection[] {
12002
- // // return (this.program.programStages || []).flatMap((stage: ProgramStage) =>
12003
- // // (stage.programStageSections || []).map(
12004
- // // (section: ProgramStageSection) =>
12005
- // // new ProgramStageEntryFormSection({
12006
- // // id: section.id,
12007
- // // name: section.displayName,
12008
- // // description: '',
12009
- // // formFields: fieldsForSection(stage, section),
12010
- // // orientation: 'HORIZONTAL',
12011
- // // })
12012
- // // )
12013
- // // );
12014
- // // }
12015
- // // }
12016
- // // TODO: END - DEPRECATED APPROACH
12017
- // // export class ProgramStageEntryFormSectionUtil {
12018
- // // constructor(
12019
- // // private program: Program,
12020
- // // private config: ProgramEntryFormConfig
12021
- // // ) {}
12022
- // // get programStageEntryFormSections(): IProgramStageEntryFormSection[] {
12023
- // // const stageId = this.#getStageIdFromConfig();
12024
- // // if (!stageId) return [];
12025
- // // const programStage = this.#findStageById(stageId);
12026
- // // if (!programStage) return [];
12027
- // // return (programStage.programStageSections || []).map(
12028
- // // (section: ProgramStageSection) =>
12029
- // // new ProgramStageEntryFormSection({
12030
- // // id: section.id,
12031
- // // name: section.displayName,
12032
- // // description: section?.description,
12033
- // // formFields: this.#mapSectionToFormFields(programStage, section),
12034
- // // orientation: 'HORIZONTAL',
12035
- // // })
12036
- // // );
12037
- // // }
12038
- // // #getStageIdFromConfig(): string | null {
12039
- // // const programStageRef: any = (this.config as any)?.programStage;
12040
- // // if (!programStageRef) return null;
12041
- // // if (typeof programStageRef === 'string' && programStageRef.trim()) {
12042
- // // return programStageRef.trim();
12043
- // // }
12044
- // // const candidateId =
12045
- // // programStageRef.id ??
12046
- // // programStageRef.stageId ??
12047
- // // programStageRef.programStageId ??
12048
- // // programStageRef.value?.id ??
12049
- // // null;
12050
- // // return typeof candidateId === 'string' && candidateId.trim()
12051
- // // ? candidateId.trim()
12052
- // // : null;
12053
- // // }
12054
- // // #findStageById(stageId: string): ProgramStage | null {
12055
- // // return (
12056
- // // (this.program.programStages || []).find(
12057
- // // (stage: ProgramStage) => (stage as any)?.id === stageId
12058
- // // ) ?? null
12059
- // // );
12060
- // // }
12061
- // // #mapSectionToFormFields(
12062
- // // stage: ProgramStage,
12063
- // // section: ProgramStageSection
12064
- // // ): IFormField<string>[] {
12065
- // // const stageDataElements: any[] =
12066
- // // (stage as any).programStageDataElements || [];
12067
- // // const sectionElementIds: string[] =
12068
- // // (section as any).dataElements?.map((d: { id: string }) => d.id) ??
12069
- // // (section as any).dataElementsIds ??
12070
- // // [];
12071
- // // const relevantStageElements = sectionElementIds.length
12072
- // // ? stageDataElements.filter((pde) =>
12073
- // // sectionElementIds.includes(pde?.dataElement?.id)
12074
- // // )
12075
- // // : stageDataElements;
12076
- // // const mappedFields = relevantStageElements
12077
- // // .map((pde) => this.#mapDataElementToFormField(pde, stage.id))
12078
- // // .filter((field): field is IFormField<string> => field != null)
12079
- // // .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
12080
- // // const extraReportFields = (this as any)?.reportFields ?? [];
12081
- // // return [...extraReportFields, ...mappedFields];
12082
- // // }
12083
- // // #mapDataElementToFormField(
12084
- // // pde: any,
12085
- // // stageId: string
12086
- // // ): IFormField<string> | null {
12087
- // // const dataElement = pde?.dataElement;
12088
- // // if (!dataElement?.id) return null;
12089
- // // const baseField = {
12090
- // // id: dataElement.id,
12091
- // // code: dataElement.code,
12092
- // // formName: dataElement.formName,
12093
- // // name: dataElement.displayName,
12094
- // // mandatory: !!pde.compulsory,
12095
- // // valueType: dataElement.valueType,
12096
- // // sortOrder: pde.sortOrder,
12097
- // // stepId: stageId,
12098
- // // optionSet: dataElement.optionSet,
12099
- // // };
12100
- // // const options = FieldDropdown.getDropdownOptions(baseField);
12101
- // // const hasOptions = options?.length > 0;
12102
- // // const fieldExtension = this.config.formFieldExtensions?.find(
12103
- // // (fx: any) => fx?.id === baseField.id
12104
- // // );
12105
- // // const autoAssignedValue = this.#getAutoAssignedValue(baseField);
12106
- // // if (
12107
- // // !isUndefined(autoAssignedValue) &&
12108
- // // this.config.hideCustomAssignedFields
12109
- // // ) {
12110
- // // return null;
12111
- // // }
12112
- // // return new FormField<string>({
12113
- // // ...baseField,
12114
- // // label: baseField.formName || baseField.name,
12115
- // // key: baseField.code ? camelCase(baseField.code) : baseField.id,
12116
- // // required: baseField.mandatory,
12117
- // // type: FieldUtil.getFieldType(baseField.valueType),
12118
- // // options,
12119
- // // disabled: this.#getDisabledStatus(baseField),
12120
- // // order: baseField.sortOrder,
12121
- // // hasOptions,
12122
- // // controlType: FieldUtil.getFieldControlType(
12123
- // // baseField.valueType,
12124
- // // hasOptions
12125
- // // ),
12126
- // // extension: fieldExtension,
12127
- // // });
12128
- // // }
12129
- // // #getAutoAssignedValue(field: any): unknown {
12130
- // // const impl = (this as any)?.['#getAutoAssignedValue'];
12131
- // // return typeof impl === 'function' ? impl.call(this, field) : undefined;
12132
- // // }
12133
- // // #getDisabledStatus(field: any): boolean {
12134
- // // const impl = (this as any)?.['#getDisabledStatus'];
12135
- // // return typeof impl === 'function' ? impl.call(this, field) : false;
12136
- // // }
12137
- // // }
12138
- // export class ProgramStageEntryFormSectionUtil {
12139
- // private readonly fieldUtil: ProgramEntryFormFieldUtil;
12140
- // constructor(
12141
- // private readonly program: Program,
12142
- // private readonly config: ProgramEntryFormConfig
12143
- // ) {
12144
- // this.fieldUtil = new ProgramEntryFormFieldUtil(program, config);
12145
- // }
12146
- // get programStageEntryFormSections(): IProgramStageEntryFormSection[] {
12147
- // const stageId = this.#getStageIdFromConfig();
12148
- // if (!stageId || !this.program) {
12149
- // return [];
12150
- // }
12151
- // const programStage = this.#findStageById(stageId);
12152
- // if (!programStage) {
12153
- // return [];
12154
- // }
12155
- // const sections: IProgramStageEntryFormSection[] = [];
12156
- // const basicDetailsFields = this.fieldUtil.eventReportFields;
12157
- // if (basicDetailsFields?.length) {
12158
- // sections.push(
12159
- // new ProgramStageEntryFormSection({
12160
- // id: `${programStage.id}_basic_information`,
12161
- // name: 'Basic Information',
12162
- // description: '',
12163
- // formFields: basicDetailsFields,
12164
- // orientation: 'VERTICAL',
12165
- // })
12166
- // );
12167
- // }
12168
- // const stageSections = programStage.programStageSections ?? [];
12169
- // for (const section of stageSections) {
12170
- // const sectionFormFields = this.#mapSectionToFormFields(
12171
- // programStage,
12172
- // section
12173
- // );
12174
- // if (!sectionFormFields.length) {
12175
- // continue;
12176
- // }
12177
- // sections.push(
12178
- // new ProgramStageEntryFormSection({
12179
- // id: section.id,
12180
- // name: section.displayName,
12181
- // description: section?.description,
12182
- // formFields: sectionFormFields,
12183
- // orientation: 'HORIZONTAL',
12184
- // })
12185
- // );
12186
- // }
12187
- // return sections;
12188
- // }
12189
- // #getStageIdFromConfig(): string | null {
12190
- // const programStageRef: any = (this.config as any)?.programStage;
12191
- // if (!programStageRef) return null;
12192
- // if (typeof programStageRef === 'string' && programStageRef.trim()) {
12193
- // return programStageRef.trim();
12194
- // }
12195
- // const candidateId =
12196
- // programStageRef.id ??
12197
- // programStageRef.stageId ??
12198
- // programStageRef.programStageId ??
12199
- // programStageRef.value?.id ??
12200
- // null;
12201
- // return typeof candidateId === 'string' && candidateId.trim()
12202
- // ? candidateId.trim()
12203
- // : null;
12204
- // }
12205
- // #findStageById(stageId: string): ProgramStage | null {
12206
- // return (
12207
- // (this.program.programStages || []).find(
12208
- // (stage: ProgramStage) => (stage as any)?.id === stageId
12209
- // ) ?? null
12210
- // );
12211
- // }
12212
- // #mapSectionToFormFields(
12213
- // stage: ProgramStage,
12214
- // section: ProgramStageSection
12215
- // ): IFormField<string>[] {
12216
- // const stageDataElements: any[] =
12217
- // (stage as any).programStageDataElements || [];
12218
- // const sectionElementIds: string[] =
12219
- // (section as any).dataElements?.map((d: { id: string }) => d.id) ??
12220
- // (section as any).dataElementsIds ??
12221
- // [];
12222
- // const relevantStageElements = sectionElementIds.length
12223
- // ? stageDataElements.filter((pde) =>
12224
- // sectionElementIds.includes(pde?.dataElement?.id)
12225
- // )
12226
- // : stageDataElements;
12227
- // const mappedFields = relevantStageElements
12228
- // .map((pde) => this.#mapDataElementToFormField(pde, stage.id))
12229
- // .filter((field): field is IFormField<string> => field != null)
12230
- // .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
12231
- // return mappedFields;
12232
- // }
12233
- // #mapDataElementToFormField(
12234
- // pde: any,
12235
- // stageId: string
12236
- // ): IFormField<string> | null {
12237
- // const dataElement = pde?.dataElement;
12238
- // if (!dataElement?.id) return null;
12239
- // const baseField = {
12240
- // id: dataElement.id,
12241
- // code: dataElement.code,
12242
- // formName: dataElement.formName,
12243
- // name: dataElement.displayName,
12244
- // mandatory: !!pde.compulsory,
12245
- // valueType: dataElement.valueType,
12246
- // sortOrder: pde.sortOrder,
12247
- // stepId: stageId,
12248
- // optionSet: dataElement.optionSet,
12249
- // };
12250
- // const options = FieldDropdown.getDropdownOptions(baseField);
12251
- // const hasOptions = options?.length > 0;
12252
- // const fieldExtension = this.config.formFieldExtensions?.find(
12253
- // (fx: any) => fx?.id === baseField.id
12254
- // );
12255
- // const autoAssignedValue = this.#getAutoAssignedValue(baseField);
12256
- // if (
12257
- // !isUndefined(autoAssignedValue) &&
12258
- // this.config.hideCustomAssignedFields
12259
- // ) {
12260
- // return null;
12261
- // }
12262
- // return new FormField<string>({
12263
- // ...baseField,
12264
- // label: baseField.formName || baseField.name,
12265
- // key: baseField.code ? camelCase(baseField.code) : baseField.id,
12266
- // required: baseField.mandatory,
12267
- // type: FieldUtil.getFieldType(baseField.valueType),
12268
- // options,
12269
- // disabled: this.#getDisabledStatus(baseField),
12270
- // order: baseField.sortOrder,
12271
- // hasOptions,
12272
- // controlType: FieldUtil.getFieldControlType(
12273
- // baseField.valueType,
12274
- // hasOptions
12275
- // ),
12276
- // extension: fieldExtension,
12277
- // });
12278
- // }
12279
- // #getAutoAssignedValue(field: any): unknown {
12280
- // const impl = (this as any)?.['#getAutoAssignedValue'];
12281
- // return typeof impl === 'function' ? impl.call(this, field) : undefined;
12282
- // }
12283
- // #getDisabledStatus(field: any): boolean {
12284
- // const impl = (this as any)?.['#getDisabledStatus'];
12285
- // return typeof impl === 'function' ? impl.call(this, field) : false;
12286
- // }
12287
- // }
12288
11993
  class ProgramStageEntryFormSectionUtil {
12289
11994
  #sortedCanonicalStageFieldsCache = null;
12290
11995
  constructor(program, config) {
@@ -12397,6 +12102,7 @@ class ProgramStageEntryFormSectionUtil {
12397
12102
  valueType: dataElementDefinition.valueType,
12398
12103
  sortOrder: programStageDataElement.sortOrder,
12399
12104
  stepId: programStageId,
12105
+ allowFutureDate: programStageDataElement.allowFutureDate,
12400
12106
  optionSet: dataElementDefinition.optionSet,
12401
12107
  };
12402
12108
  const dropdownOptions = FieldDropdown.getDropdownOptions(fieldBaseConfig);