diff --git a/server.js b/server.js
index 5f57269..3416b9e 100644
--- a/server.js
+++ b/server.js
@@ -631,6 +631,7 @@ function renderOrderDetail(order) {
function renderOrderForm(step, stepKey = "demografi", fppTests = [], mouId = "") {
const fppGroups = groupFppTestsForSelection(fppTests);
+ const packedGroups = packFppGroupsIntoColumns(fppGroups, 5);
const steps = [
["demografi", "Demografi", "Patient identity and contact details."],
["diagnosa", "Diagnosa", "Clinical indication and diagnosis."],
@@ -689,50 +690,58 @@ function renderOrderForm(step, stepKey = "demografi", fppTests = [], mouId = "")
0 selected
${
- fppGroups.length
- ? `${fppGroups
+ packedGroups.length
+ ? `
${packedGroups
.map(
- (group) => `
-
-
-
${escapeHtml(group.heading)}
-
${group.sections.reduce((sum, section) => sum + section.tests.length, 0)} tests
-
-
- ${group.sections
- .map(
- (section) => `
-
- ${section.title ? `${escapeHtml(section.title)}
` : ""}
-
-
- `,
- )
- .join("")}
-
-
+ (column) => `
+
+ ${column
+ .map(
+ (group) => `
+
+
+
${escapeHtml(group.heading)}
+
${group.sections.reduce((sum, section) => sum + section.tests.length, 0)} tests
+
+
+ ${group.sections
+ .map(
+ (section) => `
+
+ ${section.title ? `${escapeHtml(section.title)}
` : ""}
+
+
+ `,
+ )
+ .join("")}
+
+
+ `,
+ )
+ .join("")}
+
`,
)
.join("")}
`
@@ -954,9 +963,30 @@ function groupFppTestsForSelection(tests = []) {
}));
}
+function packFppGroupsIntoColumns(groups = [], maxColumns = 5) {
+ const columnCount = Math.min(Math.max(groups.length, 1), maxColumns);
+ const columns = Array.from({ length: columnCount }, () => ({ items: [], score: 0 }));
+ const estimateScore = (group) =>
+ 1 +
+ group.sections.length +
+ group.sections.reduce((sum, section) => sum + section.tests.length * 0.12, 0);
+
+ for (const group of groups) {
+ let target = columns[0];
+ for (const column of columns) {
+ if (column.score < target.score) target = column;
+ }
+ target.items.push(group);
+ target.score += estimateScore(group);
+ }
+
+ return columns.map((column) => column.items);
+}
+
function renderFpp(groups, activeGroup = "All") {
const availableGroups = groups.map((item) => item.heading);
const visibleGroups = activeGroup === "All" ? groups : groups.filter((item) => item.heading === activeGroup);
+ const packedGroups = packFppGroupsIntoColumns(visibleGroups, 5);
return `
- ${visibleGroups
+ ${packedGroups
.map(
- (group) => `
-
-
-
${escapeHtml(group.heading)}
-
${group.sections.reduce((sum, section) => sum + section.tests.length, 0)} tests
-
-
- ${group.sections
- .map(
- (section) => `
-
- ${section.title ? `${escapeHtml(section.title)}
` : ""}
-
- ${section.tests
- .map(
- (test) => `
- -
-
- ${escapeHtml(test.name)}
-
- `,
- )
- .join("")}
-
-
- `,
- )
- .join("")}
-
-
+ (column) => `
+
+ ${column
+ .map(
+ (group) => `
+
+
+
${escapeHtml(group.heading)}
+
${group.sections.reduce((sum, section) => sum + section.tests.length, 0)} tests
+
+
+ ${group.sections
+ .map(
+ (section) => `
+
+ ${section.title ? `${escapeHtml(section.title)}
` : ""}
+
+ ${section.tests
+ .map(
+ (test) => `
+ -
+
+ ${escapeHtml(test.name)}
+
+ `,
+ )
+ .join("")}
+
+
+ `,
+ )
+ .join("")}
+
+
+ `,
+ )
+ .join("")}
+
`,
)
.join("")}
diff --git a/styles.css b/styles.css
index 934c40a..ec18250 100644
--- a/styles.css
+++ b/styles.css
@@ -745,6 +745,13 @@ tr:last-child td {
align-items: start;
}
+.fpp-select-stack {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ min-width: 0;
+}
+
.fpp-select-column {
overflow: hidden;
border-radius: 8px;