Skip to content

Commit a870974

Browse files
authored
Merge pull request #182 from EyeSeeTea/development
release: v1.5.0
2 parents ddb875e + ae5d8b8 commit a870974

40 files changed

Lines changed: 628 additions & 198 deletions

i18n/en.pot

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ msgstr ""
55
"Content-Type: text/plain; charset=utf-8\n"
66
"Content-Transfer-Encoding: 8bit\n"
77
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
8-
"POT-Creation-Date: 2026-03-13T13:24:24.302Z\n"
9-
"PO-Revision-Date: 2026-03-13T13:24:24.302Z\n"
8+
"POT-Creation-Date: 2026-03-31T17:32:04.356Z\n"
9+
"PO-Revision-Date: 2026-03-31T17:32:04.356Z\n"
1010

1111
msgid "Mark all notifications as read"
1212
msgstr ""
@@ -47,6 +47,9 @@ msgstr ""
4747
msgid "View comment and audit history"
4848
msgstr ""
4949

50+
msgid "D2 Autogen Forms version: {{version}}"
51+
msgstr ""
52+
5053
msgid "Period"
5154
msgstr ""
5255

i18n/es.po

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
msgid ""
22
msgstr ""
33
"Project-Id-Version: i18next-conv\n"
4-
"POT-Creation-Date: 2026-03-13T13:24:24.302Z\n"
4+
"POT-Creation-Date: 2026-03-31T17:32:04.356Z\n"
55
"PO-Revision-Date: 2018-10-25T09:02:35.143Z\n"
66
"MIME-Version: 1.0\n"
77
"Content-Type: text/plain; charset=UTF-8\n"
@@ -47,6 +47,9 @@ msgstr ""
4747
msgid "View comment and audit history"
4848
msgstr ""
4949

50+
msgid "D2 Autogen Forms version: {{version}}"
51+
msgstr ""
52+
5053
msgid "Period"
5154
msgstr ""
5255

i18n/fr.po

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
msgid ""
22
msgstr ""
33
"Project-Id-Version: i18next-conv\n"
4-
"POT-Creation-Date: 2026-03-13T13:24:24.302Z\n"
4+
"POT-Creation-Date: 2026-03-31T17:32:04.356Z\n"
55
"PO-Revision-Date: 2018-10-25T09:02:35.143Z\n"
66
"MIME-Version: 1.0\n"
77
"Content-Type: text/plain; charset=UTF-8\n"
@@ -47,6 +47,9 @@ msgstr ""
4747
msgid "View comment and audit history"
4848
msgstr ""
4949

50+
msgid "D2 Autogen Forms version: {{version}}"
51+
msgstr ""
52+
5053
msgid "Period"
5154
msgstr ""
5255

i18n/ru.po

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
msgid ""
22
msgstr ""
33
"Project-Id-Version: i18next-conv\n"
4-
"POT-Creation-Date: 2026-03-13T13:24:24.302Z\n"
4+
"POT-Creation-Date: 2026-03-31T17:32:04.356Z\n"
55
"PO-Revision-Date: 2018-10-25T09:02:35.143Z\n"
66
"MIME-Version: 1.0\n"
77
"Content-Type: text/plain; charset=UTF-8\n"
@@ -48,6 +48,9 @@ msgstr ""
4848
msgid "View comment and audit history"
4949
msgstr ""
5050

51+
msgid "D2 Autogen Forms version: {{version}}"
52+
msgstr ""
53+
5154
msgid "Period"
5255
msgstr ""
5356

icon.png

313 KB
Loading

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "d2-autogen-forms",
33
"description": "D2 Autogenerated Forms",
4-
"version": "1.4.0",
4+
"version": "1.5.0",
55
"license": "GPL-3.0",
66
"author": "EyeSeeTea team",
77
"homepage": ".",
@@ -80,7 +80,7 @@
8080
"prepare": "husky install"
8181
},
8282
"appVersions": {
83-
"configurator": "0.2.0"
83+
"configurator": "1.5.0"
8484
},
8585
"devDependencies": {
8686
"@babel/core": "7.16.0",

src/data/common/Dhis2DataElement.ts

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,29 @@ type D2DataElementNewType = Omit<D2DataElement, "valueType"> & {
8282
valueType: D2DataElementTypes;
8383
};
8484

85+
function normalizeCategoryCombo(categoryCombo: D2DataElement["categoryCombo"]): D2DataElement["categoryCombo"] {
86+
const trimCategoryOption = (
87+
co: D2DataElement["categoryCombo"]["categories"][number]["categoryOptions"][number]
88+
) => ({
89+
...co,
90+
code: co.code.trim(),
91+
name: co.name.trim(),
92+
});
93+
94+
return {
95+
...categoryCombo,
96+
categories: categoryCombo.categories.map(category => ({
97+
...category,
98+
categoryOptions: category.categoryOptions.map(trimCategoryOption),
99+
})),
100+
categoryOptionCombos: categoryCombo.categoryOptionCombos.map(coc => ({
101+
...coc,
102+
name: coc.name.trim(),
103+
categoryOptions: coc.categoryOptions.map(trimCategoryOption),
104+
})),
105+
};
106+
}
107+
85108
export function makeCocOrderArray(namesArray: string[][]): string[] {
86109
return namesArray.reduce((prev, current) => {
87110
return prev
@@ -96,9 +119,22 @@ export function makeCocOrderArray(namesArray: string[][]): string[] {
96119
});
97120
}
98121

122+
// Builds a lookup `category-option code → sortOrder` from the parent
123+
// `Category.categoryOptions` arrays. DHIS2 returns these arrays in their
124+
// canonical sort order (set in the maintenance app), so the array index is
125+
// the sortOrder. Used to populate `CategoryOption.sortOrder` independently of
126+
// the (translated) display label.
127+
function buildSortOrderByCode(categories: D2DataElement["categoryCombo"]["categories"]): Record<string, number> {
128+
return _(categories)
129+
.flatMap(cat => cat.categoryOptions.map((co, index) => [co.code, index] as const))
130+
.fromPairs()
131+
.value();
132+
}
133+
99134
function getCocOrdered(
100135
categoryCombo: D2DataElement["categoryCombo"],
101-
config: Dhis2DataStoreDataForm
136+
config: Dhis2DataStoreDataForm,
137+
sortOrderByCode: Record<string, number>
102138
): CategoryOptionCombo[] {
103139
const keyName = config.categoryCombinationsConfig[categoryCombo.code]?.viewType || "formName";
104140
const allCategoryOptions = categoryCombo.categories.flatMap(c =>
@@ -165,7 +201,11 @@ function getCocOrdered(
165201
...x,
166202
originalName: x.name,
167203
name: x[keyName] || x.name || "",
168-
categoryOptions: x.categoryOptions.map(co => ({ ...co, originalName: co.name })),
204+
categoryOptions: x.categoryOptions.map(co => ({
205+
...co,
206+
originalName: co.name,
207+
sortOrder: sortOrderByCode[co.code] ?? Number.POSITIVE_INFINITY,
208+
})),
169209
}));
170210
}
171211

@@ -175,7 +215,8 @@ function isCategoryOptionHidden(code: string, config: Dhis2DataStoreDataForm) {
175215

176216
function getVisibleCategoryOptionCombos(
177217
categoryOptionCombos: D2DataElement["categoryCombo"]["categoryOptionCombos"],
178-
config: Dhis2DataStoreDataForm
218+
config: Dhis2DataStoreDataForm,
219+
sortOrderByCode: Record<string, number>
179220
): CategoryOptionCombo[] {
180221
const hiddenCategoryOptions = _(config.categoryOptionsConfig)
181222
.pickBy(value => value.visible === false)
@@ -191,13 +232,15 @@ function getVisibleCategoryOptionCombos(
191232
categoryOptions: item.categoryOptions.map(co => ({
192233
...co,
193234
originalName: co.name,
235+
sortOrder: sortOrderByCode[co.code] ?? Number.POSITIVE_INFINITY,
194236
})),
195237
};
196238
});
197239
}
198240

199241
function getDataElement(dataElement: D2DataElementNewType, config: Dhis2DataStoreDataForm): DataElement | null {
200242
const { valueType } = dataElement;
243+
const categoryCombo = normalizeCategoryCombo(dataElement.categoryCombo);
201244
const deConfig = config.dataElementsConfig[dataElement.code];
202245
const optionSetFromDataElement = dataElement.optionSet
203246
? {
@@ -210,14 +253,15 @@ function getDataElement(dataElement: D2DataElementNewType, config: Dhis2DataStor
210253
: null;
211254
const optionSetFromCustomConfig = deConfig?.selection?.optionSet;
212255
const optionSet = optionSetFromCustomConfig || optionSetFromDataElement;
256+
const sortOrderByCode = buildSortOrderByCode(categoryCombo.categories);
213257
const categoryCombination = {
214-
id: dataElement.categoryCombo?.id,
215-
name: dataElement.categoryCombo?.name,
216-
categories: dataElement.categoryCombo?.categories.map(cat => {
217-
const keyName = config.categoryCombinationsConfig[dataElement.categoryCombo.code]?.viewType || "formName";
258+
id: categoryCombo?.id,
259+
name: categoryCombo?.name,
260+
categories: categoryCombo?.categories.map(cat => {
261+
const keyName = config.categoryCombinationsConfig[categoryCombo.code]?.viewType || "formName";
218262
return {
219263
...cat,
220-
categoryOptions: cat.categoryOptions.map(co => {
264+
categoryOptions: cat.categoryOptions.map((co, index) => {
221265
const record = {
222266
id: co.id,
223267
name: co.displayName,
@@ -231,13 +275,18 @@ function getDataElement(dataElement: D2DataElementNewType, config: Dhis2DataStor
231275
code: co.code,
232276
name: record[keyName] ?? record.name,
233277
displayFormName: record.formName,
278+
sortOrder: index,
234279
};
235280
}),
236281
};
237282
}),
238-
categoryOptionCombos: getCocOrdered(dataElement.categoryCombo, config),
283+
categoryOptionCombos: getCocOrdered(categoryCombo, config, sortOrderByCode),
239284
};
240-
const categoryOptionCombos = getVisibleCategoryOptionCombos(dataElement.categoryCombo.categoryOptionCombos, config);
285+
const categoryOptionCombos = getVisibleCategoryOptionCombos(
286+
categoryCombo.categoryOptionCombos,
287+
config,
288+
sortOrderByCode
289+
);
241290

242291
const base = {
243292
id: dataElement.id,

src/data/common/Dhis2DataFormRepository.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export class Dhis2DataFormRepository implements DataFormRepository {
7777
removePrefix: dataSetConfig.removePrefix,
7878
customCss: dataSetConfig.customCss,
7979
showNavigation: dataSetConfig.showNavigation,
80+
disableAutoValidation: dataSetConfig.disableAutoValidation,
8081
};
8182
}
8283

src/data/common/Dhis2DataStoreDataForm.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ export const DataStoreConfigCodec = Codec.interface({
305305
customCss: optional(string),
306306
showIndex: optional(boolean),
307307
showNavigation: optional(boolean),
308+
disableAutoValidation: optional(boolean),
308309
rules: optional(array(dataSetRuleCodec)),
309310
sections: optional(
310311
optionalRecord({
@@ -1113,6 +1114,7 @@ export class Dhis2DataStoreDataForm {
11131114
rules: this.getDataFormRules(dataSetConfig?.rules),
11141115
customCss: dataSetConfig?.customCss,
11151116
showNavigation: dataSetConfig?.showNavigation ?? false,
1117+
disableAutoValidation: dataSetConfig?.disableAutoValidation ?? false,
11161118
};
11171119
}
11181120

src/data/common/Dhis2DataValueRepository.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export class Dhis2DataValueRepository implements DataValueRepository {
6969
period: dv.period,
7070
categoryOptionComboId: dv.categoryOptionCombo,
7171
isRequired,
72+
comment: dv.comment || "",
7273
};
7374

7475
const { type } = dataElement;
@@ -203,6 +204,7 @@ export class Dhis2DataValueRepository implements DataValueRepository {
203204
period: combo.period,
204205
categoryOptionComboId: combo.categoryOptionComboId,
205206
isRequired: true,
207+
comment: "",
206208
};
207209

208210
const { type } = dataElement;

0 commit comments

Comments
 (0)