Add matrix-group display for monthly/quarterly time-series fields in Stage 5
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { useId, useState } from "react";
|
||||
import { useId, useMemo, useState } from "react";
|
||||
import type { StageSectionConfig, SelectOption } from "@/types/form";
|
||||
import type { UseFormRegister, FieldValues, FieldErrors } from "react-hook-form";
|
||||
import { FieldRenderer } from "./fields/FieldRenderer";
|
||||
import { MatrixGroup } from "./MatrixGroup";
|
||||
import { evaluate } from "@/lib/conditional";
|
||||
|
||||
interface StageSectionProps {
|
||||
@@ -38,7 +39,19 @@ export function StageSection({
|
||||
const headingId = useId();
|
||||
const panelId = useId();
|
||||
|
||||
const visibleFields = section.fields.filter((f) => evaluate(f.visibleWhen, formValues));
|
||||
// Names of fields that appear inside any matrix group; excluded from the
|
||||
// standalone per-field grid so they don't render twice.
|
||||
const matrixFieldNames = useMemo(() => {
|
||||
const names = new Set<string>();
|
||||
for (const m of section.matrixGroups ?? []) {
|
||||
for (const row of m.rows) for (const f of row.fields) names.add(f);
|
||||
}
|
||||
return names;
|
||||
}, [section.matrixGroups]);
|
||||
|
||||
const visibleFields = section.fields.filter(
|
||||
(f) => evaluate(f.visibleWhen, formValues) && !matrixFieldNames.has(f.name),
|
||||
);
|
||||
|
||||
return (
|
||||
<section
|
||||
@@ -88,9 +101,16 @@ export function StageSection({
|
||||
{section.intro && (
|
||||
<p className="mb-5 text-sm text-stone-600 leading-relaxed">{section.intro}</p>
|
||||
)}
|
||||
{visibleFields.length === 0 ? (
|
||||
{(section.matrixGroups ?? []).length > 0 && (
|
||||
<div className="mb-6 space-y-5">
|
||||
{section.matrixGroups!.map((g) => (
|
||||
<MatrixGroup key={g.id} group={g} register={register} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{visibleFields.length === 0 && (section.matrixGroups ?? []).length === 0 ? (
|
||||
<p className="text-sm italic text-stone-500">No fields are visible at this stage.</p>
|
||||
) : (
|
||||
) : visibleFields.length === 0 ? null : (
|
||||
<div className="grid grid-cols-1 gap-x-6 gap-y-5 md:grid-cols-2">
|
||||
{visibleFields.map((f) => {
|
||||
const resolvedOptions = f.optionGroupId ? options[f.optionGroupId] : undefined;
|
||||
|
||||
Reference in New Issue
Block a user