@openg2p/registry-widgets 1.1.0-dev.10 → 1.1.0-dev.12
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/dist/components/SectionRenderer.d.ts +7 -1
- package/dist/components/SectionRenderer.d.ts.map +1 -1
- package/dist/components/SectionsContainer.d.ts.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.esm.js +49 -18
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +49 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -38,6 +38,12 @@ export interface SectionRendererProps {
|
|
|
38
38
|
onPreviousSection?: (index: number) => void;
|
|
39
39
|
/** IntakeForm mode: when true or undefined, sections are editable; when false, sections are readonly */
|
|
40
40
|
isDraft?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* IntakeForm mode: when true the accordion header is clickable so the user can open/close this
|
|
43
|
+
* section freely. False (default) locks the header — navigation is only via Next/Previous.
|
|
44
|
+
* SectionsContainer sets this to true for every visited section plus the one immediately after.
|
|
45
|
+
*/
|
|
46
|
+
isAccessible?: boolean;
|
|
41
47
|
/** RegistryView: called when this section enters or exits edit mode. Used by SectionsContainer to enforce single-edit. */
|
|
42
48
|
onEditModeChange?: (sectionId: string, editing: boolean) => void;
|
|
43
49
|
/** RegistryView: when true, forces this section out of edit mode (another section took over). */
|
|
@@ -51,5 +57,5 @@ export interface SectionRendererProps {
|
|
|
51
57
|
* - Panels wrap when they exceed available width
|
|
52
58
|
* - Sections can sit side-by-side if there's space
|
|
53
59
|
*/
|
|
54
|
-
export declare const SectionRenderer: ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton, mode, namespace, changeRequestType, showChangeRequestLabel, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, onEditModeChange, forceExitEdit, }: SectionRendererProps) => import("react/jsx-runtime").JSX.Element;
|
|
60
|
+
export declare const SectionRenderer: ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton, mode, namespace, changeRequestType, showChangeRequestLabel, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, isAccessible, onEditModeChange, forceExitEdit, }: SectionRendererProps) => import("react/jsx-runtime").JSX.Element;
|
|
55
61
|
//# sourceMappingURL=SectionRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionRenderer.d.ts","sourceRoot":"","sources":["../../src/components/SectionRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAyC,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAQ9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA2ClD,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,aAAa,CAAC;IACvB,wBAAwB,CAAC,EAAE,oBAAoB,CAAC,0BAA0B,CAAC,CAAC;IAC5E,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAClC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAGjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,2GAA2G;IAC3G,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAErE,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oGAAoG;IACpG,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,uGAAuG;IACvG,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,4FAA4F;IAC5F,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"SectionRenderer.d.ts","sourceRoot":"","sources":["../../src/components/SectionRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAyC,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAQ9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA2ClD,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,aAAa,CAAC;IACvB,wBAAwB,CAAC,EAAE,oBAAoB,CAAC,0BAA0B,CAAC,CAAC;IAC5E,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAClC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAGjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,2GAA2G;IAC3G,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAErE,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oGAAoG;IACpG,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,uGAAuG;IACvG,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,4FAA4F;IAC5F,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,0HAA0H;IAC1H,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjE,iGAAiG;IACjG,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAGD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,saAyB7B,oBAAoB,4CAo+CtB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionsContainer.d.ts","sourceRoot":"","sources":["../../src/components/SectionsContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAmB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOpE,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEnE,uHAAuH;AACvH,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,qEAAqE;IACrE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,qFAAqF;IACrF,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAClD;;;OAGG;IACD,iBAAiB,IAAI,cAAc,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAEpE,wHAAwH;IACxH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrE,0JAA0J;IAC1J,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACpD;AAoFD;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,yMAa/B,sBAAsB,
|
|
1
|
+
{"version":3,"file":"SectionsContainer.d.ts","sourceRoot":"","sources":["../../src/components/SectionsContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAmB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOpE,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEnE,uHAAuH;AACvH,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,qEAAqE;IACrE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,qFAAqF;IACrF,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAClD;;;OAGG;IACD,iBAAiB,IAAI,cAAc,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAEpE,wHAAwH;IACxH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrE,0JAA0J;IAC1J,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACpD;AAoFD;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,yMAa/B,sBAAsB,4CAkVxB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -707,6 +707,12 @@ interface SectionRendererProps {
|
|
|
707
707
|
onPreviousSection?: (index: number) => void;
|
|
708
708
|
/** IntakeForm mode: when true or undefined, sections are editable; when false, sections are readonly */
|
|
709
709
|
isDraft?: boolean;
|
|
710
|
+
/**
|
|
711
|
+
* IntakeForm mode: when true the accordion header is clickable so the user can open/close this
|
|
712
|
+
* section freely. False (default) locks the header — navigation is only via Next/Previous.
|
|
713
|
+
* SectionsContainer sets this to true for every visited section plus the one immediately after.
|
|
714
|
+
*/
|
|
715
|
+
isAccessible?: boolean;
|
|
710
716
|
/** RegistryView: called when this section enters or exits edit mode. Used by SectionsContainer to enforce single-edit. */
|
|
711
717
|
onEditModeChange?: (sectionId: string, editing: boolean) => void;
|
|
712
718
|
/** RegistryView: when true, forces this section out of edit mode (another section took over). */
|
|
@@ -720,7 +726,7 @@ interface SectionRendererProps {
|
|
|
720
726
|
* - Panels wrap when they exceed available width
|
|
721
727
|
* - Sections can sit side-by-side if there's space
|
|
722
728
|
*/
|
|
723
|
-
declare const SectionRenderer: ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton, mode, namespace, changeRequestType, showChangeRequestLabel, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, onEditModeChange, forceExitEdit, }: SectionRendererProps) => react_jsx_runtime.JSX.Element;
|
|
729
|
+
declare const SectionRenderer: ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton, mode, namespace, changeRequestType, showChangeRequestLabel, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, isAccessible, onEditModeChange, forceExitEdit, }: SectionRendererProps) => react_jsx_runtime.JSX.Element;
|
|
724
730
|
|
|
725
731
|
interface SectionBuilderProps {
|
|
726
732
|
initialSection?: SectionConfig;
|
package/dist/index.esm.js
CHANGED
|
@@ -3946,7 +3946,7 @@ function scopedClassSelectors(sectionClassId, classNames) {
|
|
|
3946
3946
|
* - Panels wrap when they exceed available width
|
|
3947
3947
|
* - Sections can sit side-by-side if there's space
|
|
3948
3948
|
*/
|
|
3949
|
-
const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton = false, mode = 'RegistryView', namespace, changeRequestType, showChangeRequestLabel = true, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, onEditModeChange, forceExitEdit, }) => {
|
|
3949
|
+
const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton = false, mode = 'RegistryView', namespace, changeRequestType, showChangeRequestLabel = true, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, isAccessible = false, onEditModeChange, forceExitEdit, }) => {
|
|
3950
3950
|
const { translateConfig, translate } = useWidgetTranslation();
|
|
3951
3951
|
const resolvedTheme = useWidgetTheme();
|
|
3952
3952
|
const portalCSSVariables = useMemo(() => themeToCSSVariables(resolvedTheme), [resolvedTheme]);
|
|
@@ -4012,17 +4012,25 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4012
4012
|
const isExpandedFromContainer = typeof sectionIndex === 'number' && expandedSectionIndex === sectionIndex;
|
|
4013
4013
|
const isExpandedStandalone = sectionIndex === undefined && standaloneExpanded;
|
|
4014
4014
|
const isExpanded = mode === 'IntakeForm' && (isExpandedFromContainer || isExpandedStandalone);
|
|
4015
|
-
//
|
|
4016
|
-
//
|
|
4017
|
-
|
|
4015
|
+
// IntakeForm only: tracks whether the user has clicked Next on this section at least once.
|
|
4016
|
+
// Used to unlock the accordion header so the user can navigate back to a visited section.
|
|
4017
|
+
const [hasBeenSavedByUser, setHasBeenSavedByUser] = useState(false);
|
|
4018
|
+
// Accordion header click behaviour in IntakeForm mode:
|
|
4019
|
+
// - Standalone (no sectionIndex): always toggleable.
|
|
4020
|
+
// - Managed by SectionsContainer: toggleable only when isAccessible is true
|
|
4021
|
+
// (i.e. the section has been visited OR is the immediate next one).
|
|
4022
|
+
// Sections beyond that remain locked.
|
|
4018
4023
|
const handleAccordionToggle = useCallback(() => {
|
|
4019
4024
|
if (mode !== 'IntakeForm')
|
|
4020
4025
|
return;
|
|
4021
4026
|
if (sectionIndex === undefined) {
|
|
4022
4027
|
setStandaloneExpanded(prev => !prev);
|
|
4023
4028
|
}
|
|
4024
|
-
|
|
4025
|
-
|
|
4029
|
+
else if (isAccessible && onExpandSection) {
|
|
4030
|
+
onExpandSection(sectionIndex);
|
|
4031
|
+
}
|
|
4032
|
+
// Intentionally no-op for locked sections (isAccessible === false)
|
|
4033
|
+
}, [mode, sectionIndex, isAccessible, onExpandSection]);
|
|
4026
4034
|
// Recursively count all vertical panels, especially those nested inside horizontal panels
|
|
4027
4035
|
// Typically: horizontal panels at first level contain vertical panels at second level
|
|
4028
4036
|
// Accounts for panel-column-span: a panel with column-span 3 counts as 3 columns
|
|
@@ -4357,8 +4365,6 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4357
4365
|
const baselineSnapshotRef = useRef(null);
|
|
4358
4366
|
// IntakeForm only: increment when baseline is updated after save - forces badge to update (refs don't trigger re-renders)
|
|
4359
4367
|
const [intakeFormBaselineTrigger, setIntakeFormBaselineTrigger] = useState(0);
|
|
4360
|
-
// IntakeForm only: tracks whether the user has actually saved this section (prevents "Saved" badge on initial load)
|
|
4361
|
-
const [hasBeenSavedByUser, setHasBeenSavedByUser] = useState(false);
|
|
4362
4368
|
// IntakeForm: treat as edit mode for dirty tracking when isDraft. RegistryView: use isEditMode.
|
|
4363
4369
|
const effectiveEditModeForDirty = mode === 'IntakeForm' ? (isDraft !== false) : isEditMode;
|
|
4364
4370
|
// Compute isDirty: compare current store state to baseline (only when in edit mode)
|
|
@@ -4591,6 +4597,11 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4591
4597
|
}
|
|
4592
4598
|
onSectionDirtyChange?.(sectionId, false);
|
|
4593
4599
|
}
|
|
4600
|
+
else if (mode === 'IntakeForm') {
|
|
4601
|
+
// No onSectionSave provided, but still mark section as visited so the
|
|
4602
|
+
// user can navigate back to it by clicking the accordion header.
|
|
4603
|
+
setHasBeenSavedByUser(true);
|
|
4604
|
+
}
|
|
4594
4605
|
// Always navigate to the next section
|
|
4595
4606
|
onSectionSaveSuccess?.(sectionIndex);
|
|
4596
4607
|
}, [store, onSectionSave, onSectionSaveSuccess, sectionIndex, originalSection, schemaData, contextSchemaData, namespace, hasSupportingDocuments, dbSectionId, sectionRegisterId, dispatch, buildSectionSnapshot, sectionId, onSectionDirtyChange, mode, isDraft]);
|
|
@@ -4862,7 +4873,7 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4862
4873
|
}),
|
|
4863
4874
|
}, children: mode === 'IntakeForm' ? (
|
|
4864
4875
|
/* IntakeForm: accordion layout - header always visible, content only when expanded */
|
|
4865
|
-
jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("button", { type: "button", id: `intake-form-accordion-header-${sectionId}`, className: "intake-form-accordion-header", onClick: handleAccordionToggle, "aria-expanded": isExpanded, "aria-controls": isExpanded ? `intake-form-accordion-content-${sectionId}` : undefined, "data-interactive": sectionIndex === undefined ? 'true' : 'false', style: {
|
|
4876
|
+
jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("button", { type: "button", id: `intake-form-accordion-header-${sectionId}`, className: "intake-form-accordion-header", onClick: handleAccordionToggle, "aria-expanded": isExpanded, "aria-controls": isExpanded ? `intake-form-accordion-content-${sectionId}` : undefined, "data-interactive": sectionIndex === undefined || isAccessible ? 'true' : 'false', style: {
|
|
4866
4877
|
width: '100%',
|
|
4867
4878
|
display: 'flex',
|
|
4868
4879
|
alignItems: 'flex-start',
|
|
@@ -4872,7 +4883,7 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
4872
4883
|
marginBottom: 0,
|
|
4873
4884
|
background: 'none',
|
|
4874
4885
|
border: 'none',
|
|
4875
|
-
cursor: sectionIndex === undefined ? 'pointer' : 'default',
|
|
4886
|
+
cursor: sectionIndex === undefined || isAccessible ? 'pointer' : 'default',
|
|
4876
4887
|
textAlign: 'left',
|
|
4877
4888
|
fontFamily: 'Roboto, sans-serif',
|
|
4878
4889
|
}, children: [jsxRuntimeExports.jsxs("div", { style: { flex: 1, display: 'flex', alignItems: 'center', gap: '12px', minWidth: 0 }, children: [jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold", style: { margin: 0 }, children: sectionToRender['section-title']
|
|
@@ -5170,6 +5181,11 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
5170
5181
|
const dataSourceRequestHandler = propDataSourceRequestHandler || contextDataSourceRequestHandler;
|
|
5171
5182
|
// IntakeForm mode: accordion state - which section is expanded (null = none; first expanded by default)
|
|
5172
5183
|
const [expandedSectionIndex, setExpandedSectionIndex] = useState(0);
|
|
5184
|
+
// IntakeForm mode: high-water mark of the furthest section the user has clicked Next on.
|
|
5185
|
+
// A section at index i is accessible when i <= maxVisitedIndex + 1
|
|
5186
|
+
// (i.e. every visited section plus the one immediately after it).
|
|
5187
|
+
// Starts at -1 so only section 0 is accessible before any Next is clicked.
|
|
5188
|
+
const [maxVisitedIndex, setMaxVisitedIndex] = useState(-1);
|
|
5173
5189
|
// RegistryView: track which section is currently in edit mode (by section-id); null = none
|
|
5174
5190
|
const [editingSectionId, setEditingSectionId] = useState(null);
|
|
5175
5191
|
const handleEditModeChange = useCallback((sectionId, editing) => {
|
|
@@ -5180,6 +5196,11 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
5180
5196
|
// Stable ref for namespace so formHandle useMemo doesn't depend on the (possibly inline) function identity
|
|
5181
5197
|
const namespaceRef = useRef(namespace);
|
|
5182
5198
|
namespaceRef.current = namespace;
|
|
5199
|
+
// Stable ref for sections so formHandle useMemo doesn't depend on the (possibly unstable) array reference.
|
|
5200
|
+
// Without this, an inline sections={[...]} prop would recreate formHandle every render, causing
|
|
5201
|
+
// onFormReady to fire every render → host setState → infinite re-render loop.
|
|
5202
|
+
const safeSectionsRef = useRef(safeSections);
|
|
5203
|
+
safeSectionsRef.current = safeSections;
|
|
5183
5204
|
// Stable refs so formHandle closure can access current mode and accordion setter without stale captures
|
|
5184
5205
|
const modeRef = useRef(mode);
|
|
5185
5206
|
modeRef.current = mode;
|
|
@@ -5194,8 +5215,9 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
5194
5215
|
const handleExpandSection = useCallback((index) => {
|
|
5195
5216
|
setExpandedSectionIndex(prev => (prev === index ? null : index));
|
|
5196
5217
|
}, []);
|
|
5197
|
-
// IntakeForm mode: called after section save - collapse current, expand next
|
|
5218
|
+
// IntakeForm mode: called after section save - advance high-water mark, collapse current, expand next
|
|
5198
5219
|
const handleSectionSaveSuccess = useCallback((index) => {
|
|
5220
|
+
setMaxVisitedIndex(prev => Math.max(prev, index));
|
|
5199
5221
|
if (index + 1 < safeSections.length) {
|
|
5200
5222
|
setExpandedSectionIndex(index + 1);
|
|
5201
5223
|
}
|
|
@@ -5227,6 +5249,9 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
5227
5249
|
}, [mode, safeSections.length, expandedSectionIndex]);
|
|
5228
5250
|
const UNSAVED_CHANGES_ERROR = 'Unsaved changes detected. Please save all sections before submitting.';
|
|
5229
5251
|
// Form handle for onFormReady - allows host to validate and get all section data from its own Submit button
|
|
5252
|
+
// IMPORTANT: safeSections is intentionally accessed via safeSectionsRef.current (not closed over directly)
|
|
5253
|
+
// so that this memo never depends on the sections array reference. This prevents an infinite re-render
|
|
5254
|
+
// loop when the host passes an unstable sections prop (e.g. inline array or derived state).
|
|
5230
5255
|
const formHandle = useMemo(() => {
|
|
5231
5256
|
const getValues = () => store.getState().widget?.values || {};
|
|
5232
5257
|
const getNamespace = (section, index) => {
|
|
@@ -5248,10 +5273,11 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
5248
5273
|
if (modeRef.current !== 'IntakeForm')
|
|
5249
5274
|
checkNoUnsavedChanges();
|
|
5250
5275
|
const values = getValues();
|
|
5276
|
+
const sections = safeSectionsRef.current;
|
|
5251
5277
|
let allValid = true;
|
|
5252
5278
|
let firstInvalidIndex = null;
|
|
5253
|
-
for (let i = 0; i <
|
|
5254
|
-
const section =
|
|
5279
|
+
for (let i = 0; i < sections.length; i++) {
|
|
5280
|
+
const section = sections[i];
|
|
5255
5281
|
const ns = getNamespace(section, i);
|
|
5256
5282
|
const sectionToValidate = ns ? namespaceSectionConfig(section, ns) : section;
|
|
5257
5283
|
const valid = sectionValidate(sectionToValidate, values, dispatch);
|
|
@@ -5271,10 +5297,11 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
5271
5297
|
if (modeRef.current !== 'IntakeForm')
|
|
5272
5298
|
checkNoUnsavedChanges();
|
|
5273
5299
|
const values = getValues();
|
|
5300
|
+
const sections = safeSectionsRef.current;
|
|
5274
5301
|
const results = [];
|
|
5275
5302
|
let firstInvalidIndex = null;
|
|
5276
|
-
for (let i = 0; i <
|
|
5277
|
-
const section =
|
|
5303
|
+
for (let i = 0; i < sections.length; i++) {
|
|
5304
|
+
const section = sections[i];
|
|
5278
5305
|
const ns = getNamespace(section, i);
|
|
5279
5306
|
const sectionToValidate = ns ? namespaceSectionConfig(section, ns) : section;
|
|
5280
5307
|
const valid = sectionValidate(sectionToValidate, values, dispatch);
|
|
@@ -5296,16 +5323,18 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
5296
5323
|
},
|
|
5297
5324
|
getStructuredData: () => {
|
|
5298
5325
|
const values = getValues();
|
|
5326
|
+
const sections = safeSectionsRef.current;
|
|
5299
5327
|
const results = [];
|
|
5300
|
-
for (let i = 0; i <
|
|
5301
|
-
const section =
|
|
5328
|
+
for (let i = 0; i < sections.length; i++) {
|
|
5329
|
+
const section = sections[i];
|
|
5302
5330
|
const ns = getNamespace(section, i);
|
|
5303
5331
|
results.push(buildSectionChanges(section, values, ns));
|
|
5304
5332
|
}
|
|
5305
5333
|
return results;
|
|
5306
5334
|
},
|
|
5307
5335
|
};
|
|
5308
|
-
|
|
5336
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5337
|
+
}, [store, dispatch]); // safeSections intentionally omitted — accessed via safeSectionsRef
|
|
5309
5338
|
// Call onFormReady when form is ready (sections loaded)
|
|
5310
5339
|
useEffect(() => {
|
|
5311
5340
|
if (onFormReady && safeSections.length > 0) {
|
|
@@ -5389,6 +5418,8 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
|
|
|
5389
5418
|
onSectionSaveSuccess: handleSectionSaveSuccess,
|
|
5390
5419
|
onPreviousSection: handlePreviousSection,
|
|
5391
5420
|
isDraft,
|
|
5421
|
+
// Accessible = every visited section + the one immediately after
|
|
5422
|
+
isAccessible: index <= maxVisitedIndex + 1,
|
|
5392
5423
|
}
|
|
5393
5424
|
: {};
|
|
5394
5425
|
// RegistryView: single-edit coordination props
|