@openg2p/registry-widgets 1.1.3 → 1.1.4-dev.1
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/utils/executeSectionSave.d.ts.map +1 -1
- package/dist/components/SectionRenderer.d.ts +61 -0
- package/dist/components/SectionRenderer.d.ts.map +1 -0
- package/dist/hooks/useGeoHierarchy.d.ts +1 -0
- package/dist/hooks/useGeoHierarchy.d.ts.map +1 -1
- package/dist/hooks/useGeoWidgetCascade.d.ts +12 -0
- package/dist/hooks/useGeoWidgetCascade.d.ts.map +1 -0
- package/dist/hooks/useWidgetTranslation.d.ts +16 -0
- package/dist/hooks/useWidgetTranslation.d.ts.map +1 -0
- package/dist/i18n/config.d.ts +21 -0
- package/dist/i18n/config.d.ts.map +1 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.esm.js +141 -25
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +141 -25
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +9 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/buildSectionChanges.d.ts +11 -0
- package/dist/utils/buildSectionChanges.d.ts.map +1 -0
- package/dist/utils/geoHierarchy.d.ts +13 -0
- package/dist/utils/geoHierarchy.d.ts.map +1 -1
- package/dist/utils/schemaNamespace.d.ts +12 -0
- package/dist/utils/schemaNamespace.d.ts.map +1 -0
- package/dist/widgets/ArrayWidget.d.ts +29 -0
- package/dist/widgets/ArrayWidget.d.ts.map +1 -0
- package/dist/widgets/CurrencyInputWidget.d.ts +24 -0
- package/dist/widgets/CurrencyInputWidget.d.ts.map +1 -0
- package/dist/widgets/DocsWidget.d.ts.map +1 -1
- package/dist/widgets/GeoHierarchyWidget.d.ts.map +1 -1
- package/dist/widgets/HeaderSectionWidget.d.ts.map +1 -1
- package/dist/widgets/IterableAccordionWidget.d.ts +30 -0
- package/dist/widgets/IterableAccordionWidget.d.ts.map +1 -0
- package/dist/widgets/SimpleTableWidget.d.ts +32 -0
- package/dist/widgets/SimpleTableWidget.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executeSectionSave.d.ts","sourceRoot":"","sources":["../../../../src/components/SectionRenderer/utils/executeSectionSave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"executeSectionSave.d.ts","sourceRoot":"","sources":["../../../../src/components/SectionRenderer/utils/executeSectionSave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAO/C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;KAAE,CAAC;IACnC,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,sBAAsB,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAwGD,eAAO,MAAM,kBAAkB,GAAU,qIAUtC,wBAAwB,KAAG,OAAO,CAAC,wBAAwB,CAwD7D,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { SectionConfig } from '../types';
|
|
2
|
+
import { UseBaseWidgetOptions } from '../hooks/useBaseWidget';
|
|
3
|
+
import { SectionMode } from './SectionsContainer';
|
|
4
|
+
export interface SectionChanges {
|
|
5
|
+
section_id?: string;
|
|
6
|
+
section_register_id?: string;
|
|
7
|
+
records: unknown[];
|
|
8
|
+
files?: unknown[];
|
|
9
|
+
image?: File | null;
|
|
10
|
+
}
|
|
11
|
+
export interface SectionRendererProps {
|
|
12
|
+
section: SectionConfig;
|
|
13
|
+
dataSourceRequestHandler?: UseBaseWidgetOptions['dataSourceRequestHandler'];
|
|
14
|
+
schemaData?: UseBaseWidgetOptions['schemaData'];
|
|
15
|
+
onValueChange?: UseBaseWidgetOptions['onValueChange'];
|
|
16
|
+
gridColumnSpan?: number;
|
|
17
|
+
onSectionSave?: (changes: SectionChanges) => Promise<void> | void;
|
|
18
|
+
hideEditButton?: boolean;
|
|
19
|
+
mode?: SectionMode;
|
|
20
|
+
namespace?: string;
|
|
21
|
+
changeRequestType?: 'new' | 'old';
|
|
22
|
+
showChangeRequestLabel?: boolean;
|
|
23
|
+
dbSectionId?: string;
|
|
24
|
+
sectionRegisterId?: string;
|
|
25
|
+
/** Called when the section's dirty (has unsaved changes) status changes. Only fires while in edit mode. */
|
|
26
|
+
onSectionDirtyChange?: (sectionId: string, isDirty: boolean) => void;
|
|
27
|
+
/** IntakeForm mode: 0-based index of this section within the form */
|
|
28
|
+
sectionIndex?: number;
|
|
29
|
+
/** IntakeForm mode: total number of sections in the form */
|
|
30
|
+
sectionCount?: number;
|
|
31
|
+
/** IntakeForm mode: index of the currently expanded section (null = all collapsed) */
|
|
32
|
+
expandedSectionIndex?: number | null;
|
|
33
|
+
/** IntakeForm mode: called when user requests to expand a section (e.g. clicks accordion header) */
|
|
34
|
+
onExpandSection?: (index: number) => void;
|
|
35
|
+
/** IntakeForm mode: called when section save completes successfully (collapse current, expand next) */
|
|
36
|
+
onSectionSaveSuccess?: (index: number) => void;
|
|
37
|
+
/** IntakeForm mode: called when user clicks Previous (collapse current, expand previous) */
|
|
38
|
+
onPreviousSection?: (index: number) => void;
|
|
39
|
+
/** IntakeForm mode: when true or undefined, sections are editable; when false, sections are readonly */
|
|
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;
|
|
47
|
+
/** RegistryView: called when this section enters or exits edit mode. Used by SectionsContainer to enforce single-edit. */
|
|
48
|
+
onEditModeChange?: (sectionId: string, editing: boolean) => void;
|
|
49
|
+
/** RegistryView: when true, forces this section out of edit mode (another section took over). */
|
|
50
|
+
forceExitEdit?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Renders a section with its panels
|
|
54
|
+
*
|
|
55
|
+
* Layout behavior:
|
|
56
|
+
* - Section width is based on max 3 panels (or more on high resolution)
|
|
57
|
+
* - Panels wrap when they exceed available width
|
|
58
|
+
* - Sections can sit side-by-side if there's space
|
|
59
|
+
*/
|
|
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;
|
|
61
|
+
//# sourceMappingURL=SectionRenderer.d.ts.map
|
|
@@ -0,0 +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;AAuDlD,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,4CAqlDtB,CAAC"}
|
|
@@ -9,6 +9,7 @@ export declare function useGeoHierarchy({ config }: UseGeoHierarchyOptions): {
|
|
|
9
9
|
options: Record<string, GeoSelectOption[]>;
|
|
10
10
|
resolvedLabels: Record<string, string>;
|
|
11
11
|
columnCounts: number[];
|
|
12
|
+
columnSpan: number;
|
|
12
13
|
visibleColumns: {
|
|
13
14
|
index: number;
|
|
14
15
|
levels: GeoLevel[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGeoHierarchy.d.ts","sourceRoot":"","sources":["../../src/hooks/useGeoHierarchy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAA4B,MAAM,UAAU,CAAC;AAKtE,OAAO,EACL,QAAQ,EAER,eAAe,
|
|
1
|
+
{"version":3,"file":"useGeoHierarchy.d.ts","sourceRoot":"","sources":["../../src/hooks/useGeoHierarchy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAA4B,MAAM,UAAU,CAAC;AAKtE,OAAO,EACL,QAAQ,EAER,eAAe,EAQf,gBAAgB,EASjB,MAAM,uBAAuB,CAAC;AAE/B,UAAU,sBAAsB;IAC9B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AA+BD,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,EAAE,sBAAsB;;;;;;;;;;;;;;;oCA0V3C,MAAM,aAAa,MAAM,GAAG,SAAS;iCAuF3B,MAAM;;;;;;;;;;;;;;;;;;;;;;;EAGtC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseWidgetConfig, DataSourceRequestHandler } from '../types';
|
|
2
|
+
export interface UseGeoWidgetCascadeOptions {
|
|
3
|
+
config: BaseWidgetConfig;
|
|
4
|
+
dataSourceRequestHandler?: DataSourceRequestHandler;
|
|
5
|
+
values: Record<string, any>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Hook for geo widget cascade functionality
|
|
9
|
+
* Handles geo hierarchy building and cascade behavior
|
|
10
|
+
*/
|
|
11
|
+
export declare const useGeoWidgetCascade: (options: UseGeoWidgetCascadeOptions) => void;
|
|
12
|
+
//# sourceMappingURL=useGeoWidgetCascade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGeoWidgetCascade.d.ts","sourceRoot":"","sources":["../../src/hooks/useGeoWidgetCascade.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAmBtE,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,gBAAgB,CAAC;IACzB,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC7B;AAGD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,0BAA0B,SAwMtE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom hook for widget translations
|
|
3
|
+
* Provides translation function with widget-specific namespace and fallback support
|
|
4
|
+
*/
|
|
5
|
+
export declare const useWidgetTranslation: () => {
|
|
6
|
+
t: (keyOrString: string | undefined | null, options?: {
|
|
7
|
+
defaultValue?: string;
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
}) => string;
|
|
10
|
+
translate: (keyOrString: string | undefined | null, options?: {
|
|
11
|
+
defaultValue?: string;
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
}) => string;
|
|
14
|
+
translateConfig: (value: string | undefined | null, fallback?: string) => string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=useWidgetTranslation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWidgetTranslation.d.ts","sourceRoot":"","sources":["../../src/hooks/useWidgetTranslation.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,oBAAoB;qBAoBhB,MAAM,GAAG,SAAS,GAAG,IAAI,YAC5B;QACR,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,KACA,MAAM;6BALM,MAAM,GAAG,SAAS,GAAG,IAAI,YAC5B;QACR,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,KACA,MAAM;6BA0BA,MAAM,GAAG,SAAS,GAAG,IAAI,aACrB,MAAM,KAChB,MAAM;CAqDV,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import i18n from 'i18next';
|
|
2
|
+
/**
|
|
3
|
+
* Initialize i18n for the widget library
|
|
4
|
+
* Can be customized by passing custom resources or configuration
|
|
5
|
+
*
|
|
6
|
+
* If no resources are provided, it will attempt to automatically load translations
|
|
7
|
+
* from the consuming project's locale directory.
|
|
8
|
+
*
|
|
9
|
+
* If options are provided and the default instance is already initialized,
|
|
10
|
+
* creates a new i18n instance to avoid reinitialization issues.
|
|
11
|
+
*/
|
|
12
|
+
export declare const initI18n: (options?: {
|
|
13
|
+
resources?: Record<string, any>;
|
|
14
|
+
lng?: string;
|
|
15
|
+
fallbackLng?: string;
|
|
16
|
+
debug?: boolean;
|
|
17
|
+
loadPath?: string | string[];
|
|
18
|
+
autoLoad?: boolean;
|
|
19
|
+
}) => Promise<import("i18next").i18n>;
|
|
20
|
+
export default i18n;
|
|
21
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/i18n/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,SAAS,CAAC;AA6C3B;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,GAAU,UAAU;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,oCAuEA,CAAC;AAwBF,eAAe,IAAI,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -57,7 +57,14 @@ interface DocsWidgetDocumentConfig {
|
|
|
57
57
|
}
|
|
58
58
|
interface GeoHierarchyLayout {
|
|
59
59
|
distribution?: 'fixed';
|
|
60
|
+
/** Explicit levels-per-column counts, e.g. [3, 3] for a 6-level hierarchy in 2 columns. */
|
|
60
61
|
columns?: number[];
|
|
62
|
+
/**
|
|
63
|
+
* How many section columns this hierarchy occupies (1–3), matching panel-column-span.
|
|
64
|
+
* Levels are distributed evenly across these columns.
|
|
65
|
+
* When omitted, derived from level count: ≤3 → 1, 4–5 → 2, ≥6 → 3.
|
|
66
|
+
*/
|
|
67
|
+
columnSpan?: number;
|
|
61
68
|
columnIndex?: number;
|
|
62
69
|
}
|
|
63
70
|
/** Optional read path for edit-mode hydration (defaults from widget-data-path). */
|
|
@@ -180,7 +187,8 @@ interface BaseWidgetConfig {
|
|
|
180
187
|
/** Column layout for geo-hierarchy widget (e.g. 3 levels per column). */
|
|
181
188
|
'widget-geo-layout'?: GeoHierarchyLayout;
|
|
182
189
|
/**
|
|
183
|
-
* Read path for geo_code_hierarchy_json (
|
|
190
|
+
* Read path for geo_code_hierarchy_json (hydrate/display).
|
|
191
|
+
* To also persist draft hierarchy on edit/save, use object widget-data-path with a hierarchy key.
|
|
184
192
|
*/
|
|
185
193
|
'widget-geo-hierarchy-path'?: string;
|
|
186
194
|
widgets?: BaseWidgetConfig[];
|
package/dist/index.esm.js
CHANGED
|
@@ -2988,6 +2988,15 @@ const extractProfileImage = (records) => {
|
|
|
2988
2988
|
profileImage = value;
|
|
2989
2989
|
copy[key] = '';
|
|
2990
2990
|
}
|
|
2991
|
+
else if (isSerializedFile(value)) {
|
|
2992
|
+
try {
|
|
2993
|
+
profileImage = deserializeFile(value);
|
|
2994
|
+
copy[key] = '';
|
|
2995
|
+
}
|
|
2996
|
+
catch (err) {
|
|
2997
|
+
console.error('Failed to deserialize profile image:', err);
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
2991
3000
|
}
|
|
2992
3001
|
return copy;
|
|
2993
3002
|
});
|
|
@@ -8695,10 +8704,6 @@ const DEFAULT_LABELS = {
|
|
|
8695
8704
|
lastApprovedBy: 'Last Approved by',
|
|
8696
8705
|
lastApprovedAt: 'Last Approved at',
|
|
8697
8706
|
};
|
|
8698
|
-
// Options are loaded in both view and edit modes because view mode
|
|
8699
|
-
// needs them to resolve display labels (e.g. "active" → "Active").
|
|
8700
|
-
// For API data sources, loading is deferred to edit mode to avoid
|
|
8701
|
-
// unnecessary network calls when only labels are needed.
|
|
8702
8707
|
function useFieldDataSource(fieldKey, fieldConfig, isReadonly) {
|
|
8703
8708
|
const [options, setOptions] = useState([]);
|
|
8704
8709
|
const { dataSourceRequestHandler, schemaData } = useWidgetContext();
|
|
@@ -8802,11 +8807,15 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
8802
8807
|
const imageUrlVal = findValue('imageUrl');
|
|
8803
8808
|
const [previewUrl, setPreviewUrl] = useState(null);
|
|
8804
8809
|
useEffect(() => {
|
|
8805
|
-
if (imageUrlVal
|
|
8810
|
+
if (isFile(imageUrlVal)) {
|
|
8806
8811
|
const url = URL.createObjectURL(imageUrlVal);
|
|
8807
8812
|
setPreviewUrl(url);
|
|
8808
8813
|
return () => URL.revokeObjectURL(url);
|
|
8809
8814
|
}
|
|
8815
|
+
if (isSerializedFile(imageUrlVal) && imageUrlVal.data) {
|
|
8816
|
+
setPreviewUrl(`data:${imageUrlVal.type};base64,${imageUrlVal.data}`);
|
|
8817
|
+
return;
|
|
8818
|
+
}
|
|
8810
8819
|
setPreviewUrl(null);
|
|
8811
8820
|
}, [imageUrlVal]);
|
|
8812
8821
|
const displayImageUrl = previewUrl || (typeof imageUrlVal === 'string' && imageUrlVal ? imageUrlVal : null);
|
|
@@ -8910,16 +8919,25 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
8910
8919
|
}, [statusValue, statusOptions]);
|
|
8911
8920
|
const statusColor = statusColors[String(statusValue).toLowerCase()] || 'var(--owt-color-text-muted, #6B7280)';
|
|
8912
8921
|
const fileInputRef = useRef(null);
|
|
8913
|
-
const handleImageUpload = useCallback((e) => {
|
|
8922
|
+
const handleImageUpload = useCallback(async (e) => {
|
|
8914
8923
|
const file = e.target.files?.[0];
|
|
8915
8924
|
if (!file || !paths.imageUrl)
|
|
8916
8925
|
return;
|
|
8917
|
-
|
|
8918
|
-
|
|
8926
|
+
try {
|
|
8927
|
+
const serialized = await serializeFile(file);
|
|
8928
|
+
dispatch(setValues(setValueByPath({ ...values }, paths.imageUrl, serialized)));
|
|
8929
|
+
}
|
|
8930
|
+
catch (err) {
|
|
8931
|
+
console.error('[HeaderSectionWidget] Error serializing image:', err);
|
|
8932
|
+
}
|
|
8933
|
+
finally {
|
|
8934
|
+
e.target.value = '';
|
|
8935
|
+
}
|
|
8919
8936
|
}, [paths.imageUrl, values, dispatch]);
|
|
8920
8937
|
const handleImageDelete = useCallback(() => {
|
|
8921
8938
|
if (!paths.imageUrl)
|
|
8922
8939
|
return;
|
|
8940
|
+
setPreviewUrl(null);
|
|
8923
8941
|
dispatch(setValues(setValueByPath({ ...values }, paths.imageUrl, null)));
|
|
8924
8942
|
}, [paths.imageUrl, values, dispatch]);
|
|
8925
8943
|
const cls = `header-section-widget-${widgetConfig['widget-id']}`;
|
|
@@ -10596,6 +10614,33 @@ function buildOrderedLevels(flat) {
|
|
|
10596
10614
|
return ordered;
|
|
10597
10615
|
}
|
|
10598
10616
|
const GEO_SECTION_COLUMN_SLOTS = 3;
|
|
10617
|
+
/**
|
|
10618
|
+
* Suggested panel/widget column span from hierarchy depth:
|
|
10619
|
+
* ≤3 levels → 1, 4–5 → 2, ≥6 → 3.
|
|
10620
|
+
*/
|
|
10621
|
+
function suggestedGeoColumnSpan(levelCount) {
|
|
10622
|
+
if (levelCount <= 0) {
|
|
10623
|
+
return 1;
|
|
10624
|
+
}
|
|
10625
|
+
if (levelCount <= 3) {
|
|
10626
|
+
return 1;
|
|
10627
|
+
}
|
|
10628
|
+
if (levelCount < 6) {
|
|
10629
|
+
return 2;
|
|
10630
|
+
}
|
|
10631
|
+
return GEO_SECTION_COLUMN_SLOTS;
|
|
10632
|
+
}
|
|
10633
|
+
/** Clamp span to 1…GEO_SECTION_COLUMN_SLOTS and at most the level count. */
|
|
10634
|
+
function resolveGeoColumnSpan(levelCount, explicitSpan) {
|
|
10635
|
+
const preferred = explicitSpan !== undefined && explicitSpan !== null
|
|
10636
|
+
? explicitSpan
|
|
10637
|
+
: suggestedGeoColumnSpan(levelCount);
|
|
10638
|
+
const clamped = Math.min(GEO_SECTION_COLUMN_SLOTS, Math.max(1, Math.floor(preferred)));
|
|
10639
|
+
if (levelCount <= 0) {
|
|
10640
|
+
return clamped;
|
|
10641
|
+
}
|
|
10642
|
+
return Math.min(clamped, levelCount);
|
|
10643
|
+
}
|
|
10599
10644
|
/** Slice ordered levels into section columns per counts, e.g. [3, 2, 0]. */
|
|
10600
10645
|
function distributeLevelsToColumns(levels, columnCounts) {
|
|
10601
10646
|
const columns = columnCounts.map(() => []);
|
|
@@ -10626,19 +10671,22 @@ function resolveGeoLevelColumns(levels, layout) {
|
|
|
10626
10671
|
const columnCounts = layout.distribution === 'fixed'
|
|
10627
10672
|
? padColumnCounts(layout.columns, GEO_SECTION_COLUMN_SLOTS)
|
|
10628
10673
|
: layout.columns;
|
|
10674
|
+
const columns = distributeLevelsToColumns(levels, columnCounts);
|
|
10675
|
+
const occupied = columns.filter((column) => column.length > 0).length;
|
|
10629
10676
|
return {
|
|
10630
10677
|
columnCounts,
|
|
10631
|
-
columns
|
|
10678
|
+
columns,
|
|
10679
|
+
columnSpan: resolveGeoColumnSpan(levels.length, layout.columnSpan ?? occupied),
|
|
10632
10680
|
};
|
|
10633
10681
|
}
|
|
10634
|
-
//
|
|
10635
|
-
//
|
|
10636
|
-
|
|
10637
|
-
const
|
|
10638
|
-
const columns = distributeLevelsContiguous(levels, columnCount);
|
|
10682
|
+
// Distribute top-to-bottom across the allotted column span so order stays
|
|
10683
|
+
// correct when columns stack on small screens.
|
|
10684
|
+
const columnSpan = resolveGeoColumnSpan(levels.length, layout?.columnSpan);
|
|
10685
|
+
const columns = distributeLevelsContiguous(levels, columnSpan);
|
|
10639
10686
|
return {
|
|
10640
10687
|
columnCounts: columns.map((column) => column.length),
|
|
10641
10688
|
columns,
|
|
10689
|
+
columnSpan,
|
|
10642
10690
|
};
|
|
10643
10691
|
}
|
|
10644
10692
|
function padColumnCounts(counts, slotCount) {
|
|
@@ -10781,6 +10829,42 @@ function getDeepestSelectedValue(orderedLevels, selectedValues) {
|
|
|
10781
10829
|
}
|
|
10782
10830
|
return deepest;
|
|
10783
10831
|
}
|
|
10832
|
+
/** Build geo_code_hierarchy_json document from current selections (for save payload). */
|
|
10833
|
+
function buildHierarchyJson(orderedLevels, selectedValues, options, resolvedLabels = {}) {
|
|
10834
|
+
const hierarchy = [];
|
|
10835
|
+
for (const level of orderedLevels) {
|
|
10836
|
+
const levelValueId = selectedValues[level.level_id];
|
|
10837
|
+
if (!levelValueId) {
|
|
10838
|
+
break;
|
|
10839
|
+
}
|
|
10840
|
+
const optionLabel = options[level.level_id]?.find((item) => item.value === levelValueId)?.label;
|
|
10841
|
+
const mnemonic = optionLabel || resolvedLabels[levelValueId] || levelValueId;
|
|
10842
|
+
hierarchy.push({
|
|
10843
|
+
level_id: level.level_id,
|
|
10844
|
+
level: level.level_mnemonic,
|
|
10845
|
+
level_mnemonic: level.level_mnemonic,
|
|
10846
|
+
level_value_id: levelValueId,
|
|
10847
|
+
level_value_mnemonic: mnemonic,
|
|
10848
|
+
});
|
|
10849
|
+
}
|
|
10850
|
+
if (hierarchy.length === 0) {
|
|
10851
|
+
return null;
|
|
10852
|
+
}
|
|
10853
|
+
return {
|
|
10854
|
+
hierarchy,
|
|
10855
|
+
lowest_level_value_id: hierarchy[hierarchy.length - 1].level_value_id,
|
|
10856
|
+
};
|
|
10857
|
+
}
|
|
10858
|
+
/** Preserve string vs object storage shape used by the existing hierarchy field. */
|
|
10859
|
+
function formatHierarchyForPersist(document, previous) {
|
|
10860
|
+
if (document === null) {
|
|
10861
|
+
return typeof previous === 'string' ? '' : null;
|
|
10862
|
+
}
|
|
10863
|
+
if (typeof previous === 'string') {
|
|
10864
|
+
return JSON.stringify(document);
|
|
10865
|
+
}
|
|
10866
|
+
return document;
|
|
10867
|
+
}
|
|
10784
10868
|
function clearDescendants(orderedLevels, fromIndex, selectedValues, options) {
|
|
10785
10869
|
const nextSelected = { ...selectedValues };
|
|
10786
10870
|
const nextOptions = { ...options };
|
|
@@ -10856,7 +10940,10 @@ function useGeoHierarchy({ config }) {
|
|
|
10856
10940
|
const geoLayout = config['widget-geo-layout'];
|
|
10857
10941
|
const hierarchyJsonPath = useMemo(() => resolveHierarchyPath(config), [config]);
|
|
10858
10942
|
const dataPath = useMemo(() => resolveDataPath(config), [config]);
|
|
10859
|
-
/**
|
|
10943
|
+
/**
|
|
10944
|
+
* Approved hierarchy for hydrate/display: schema first, then store.
|
|
10945
|
+
* Edits persist draft hierarchy into store values for save; schema keeps approved.
|
|
10946
|
+
*/
|
|
10860
10947
|
const baseHierarchyJson = useMemo(() => {
|
|
10861
10948
|
if (!hierarchyJsonPath) {
|
|
10862
10949
|
return null;
|
|
@@ -10956,17 +11043,23 @@ function useGeoHierarchy({ config }) {
|
|
|
10956
11043
|
});
|
|
10957
11044
|
return transformGeoValueOptions(payload);
|
|
10958
11045
|
}, [fetchRawValues]);
|
|
10959
|
-
/**
|
|
10960
|
-
const persistDeepestValue = useCallback((nextSelectedValues, orderedLevels) => {
|
|
11046
|
+
/** Persist leaf id + current hierarchy structure for save (schema approved value stays preferred for read). */
|
|
11047
|
+
const persistDeepestValue = useCallback((nextSelectedValues, orderedLevels, nextOptions, nextResolvedLabels) => {
|
|
10961
11048
|
if (initializingRef.current || hydratingRef.current || isReadonly) {
|
|
10962
11049
|
return;
|
|
10963
11050
|
}
|
|
10964
11051
|
const deepest = getDeepestSelectedValue(orderedLevels, nextSelectedValues);
|
|
10965
11052
|
selfPersistedValueRef.current = deepest ? String(deepest) : '';
|
|
11053
|
+
const hierarchyDocument = buildHierarchyJson(orderedLevels, nextSelectedValues, nextOptions, nextResolvedLabels);
|
|
11054
|
+
const hierarchyPayload = formatHierarchyForPersist(hierarchyDocument, baseHierarchyRef.current);
|
|
10966
11055
|
const rawDataPath = config['widget-data-path'];
|
|
10967
11056
|
const nextValue = deepest ?? null;
|
|
10968
11057
|
if (rawDataPath && typeof rawDataPath === 'object') {
|
|
10969
|
-
|
|
11058
|
+
const payload = { value: nextValue };
|
|
11059
|
+
if ('hierarchy' in rawDataPath) {
|
|
11060
|
+
payload.hierarchy = hierarchyPayload;
|
|
11061
|
+
}
|
|
11062
|
+
base.onChange(payload);
|
|
10970
11063
|
}
|
|
10971
11064
|
else {
|
|
10972
11065
|
base.onChange(nextValue);
|
|
@@ -11108,9 +11201,7 @@ function useGeoHierarchy({ config }) {
|
|
|
11108
11201
|
nextSelectedValues = cleared.selectedValues;
|
|
11109
11202
|
setSelectedValues(nextSelectedValues);
|
|
11110
11203
|
setOptions(cleared.options);
|
|
11111
|
-
|
|
11112
|
-
persistDeepestValue(nextSelectedValues, levels);
|
|
11113
|
-
}
|
|
11204
|
+
persistDeepestValue(nextSelectedValues, levels, cleared.options, resolvedLabels);
|
|
11114
11205
|
if (!nextValue || levelIndex >= levels.length - 1) {
|
|
11115
11206
|
return;
|
|
11116
11207
|
}
|
|
@@ -11122,9 +11213,17 @@ function useGeoHierarchy({ config }) {
|
|
|
11122
11213
|
const message = error instanceof Error ? error.message : 'Failed to load child geo level values';
|
|
11123
11214
|
setGeoError(message);
|
|
11124
11215
|
}
|
|
11125
|
-
}, [
|
|
11216
|
+
}, [
|
|
11217
|
+
isReadonly,
|
|
11218
|
+
levels,
|
|
11219
|
+
selectedValues,
|
|
11220
|
+
options,
|
|
11221
|
+
resolvedLabels,
|
|
11222
|
+
persistDeepestValue,
|
|
11223
|
+
loadOptionsForLevel,
|
|
11224
|
+
]);
|
|
11126
11225
|
const readonlyPath = useMemo(() => buildReadonlyPath(levels, selectedValues, options, resolvedLabels), [levels, selectedValues, options, resolvedLabels]);
|
|
11127
|
-
const { columnCounts, columns: levelColumns } = useMemo(() => resolveGeoLevelColumns(levels, geoLayout), [levels, geoLayout]);
|
|
11226
|
+
const { columnCounts, columns: levelColumns, columnSpan } = useMemo(() => resolveGeoLevelColumns(levels, geoLayout), [levels, geoLayout]);
|
|
11128
11227
|
const visibleColumns = useMemo(() => {
|
|
11129
11228
|
const columnIndex = geoLayout?.columnIndex;
|
|
11130
11229
|
if (columnIndex === undefined || columnIndex === null) {
|
|
@@ -11142,6 +11241,7 @@ function useGeoHierarchy({ config }) {
|
|
|
11142
11241
|
options,
|
|
11143
11242
|
resolvedLabels,
|
|
11144
11243
|
columnCounts,
|
|
11244
|
+
columnSpan,
|
|
11145
11245
|
visibleColumns,
|
|
11146
11246
|
loadingLevels,
|
|
11147
11247
|
loadingLevelId,
|
|
@@ -11211,11 +11311,12 @@ const GeoHierarchyWidget = ({ config }) => {
|
|
|
11211
11311
|
isLevelEnabled,
|
|
11212
11312
|
formatLevelLabel,
|
|
11213
11313
|
};
|
|
11314
|
+
const layoutColumnCount = Math.max(visibleColumns.length, 1);
|
|
11214
11315
|
const content = visibleColumns.length <= 1 ? (renderLevelRows({
|
|
11215
11316
|
...rowProps,
|
|
11216
11317
|
columnLevels: visibleColumns[0]?.levels ?? levels,
|
|
11217
11318
|
})) : (jsxRuntimeExports.jsx("div", { className: "flex flex-col lg:grid w-full", style: {
|
|
11218
|
-
gridTemplateColumns: `repeat(${
|
|
11319
|
+
gridTemplateColumns: `repeat(${layoutColumnCount}, minmax(200px, 1fr))`,
|
|
11219
11320
|
}, children: visibleColumns.map((column, position) => {
|
|
11220
11321
|
const isLast = position === visibleColumns.length - 1;
|
|
11221
11322
|
const columnClassName = [
|
|
@@ -11343,7 +11444,22 @@ const DocsWidget = ({ config }) => {
|
|
|
11343
11444
|
fileInputRefs.current[docKey] = el;
|
|
11344
11445
|
} })] })), hasFile && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { type: "button", onClick: (e) => handlePreview(file, e), className: "inline-flex items-center px-3 py-1 rounded-md border border-gray-300 text-sm font-medium text-gray-900 bg-gray-50 focus:outline-none", title: fileName, children: t?.('common.view') ?? 'View' }), jsxRuntimeExports.jsx("button", { type: "button", onClick: () => handleRemove(docKey), className: "inline-flex items-center px-3 py-1 rounded-md border border-gray-300 text-sm font-medium text-gray-900 bg-gray-50 focus:outline-none", title: "Remove", children: t?.('common.remove') ?? 'Remove' })] }))] }) })] }) }, docKey));
|
|
11345
11446
|
};
|
|
11346
|
-
return (jsxRuntimeExports.jsxs("div", { className: isReadonly ? 'DocsDisplayWidget mb-[10px]' : 'DocsWidget mb-[10px]', children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col lg:grid
|
|
11447
|
+
return (jsxRuntimeExports.jsxs("div", { className: isReadonly ? 'DocsDisplayWidget mb-[10px]' : 'DocsWidget mb-[10px]', children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col lg:grid w-full", style: { gridTemplateColumns: `repeat(${docColumns.length || 1}, minmax(0, 1fr))` }, children: docColumns.map((column, columnIndex) => {
|
|
11448
|
+
const isLast = columnIndex === docColumns.length - 1;
|
|
11449
|
+
const columnClassName = [
|
|
11450
|
+
'flex flex-col min-w-0 relative',
|
|
11451
|
+
columnIndex > 0 ? 'lg:pl-10' : '',
|
|
11452
|
+
isLast ? '' : 'lg:pr-10',
|
|
11453
|
+
]
|
|
11454
|
+
.filter(Boolean)
|
|
11455
|
+
.join(' ');
|
|
11456
|
+
return (jsxRuntimeExports.jsxs("div", { className: columnClassName, children: [!isLast && (jsxRuntimeExports.jsx("div", { className: "hidden lg:block absolute right-0 top-0 w-px", style: {
|
|
11457
|
+
bottom: '5px',
|
|
11458
|
+
backgroundColor: isReadonly
|
|
11459
|
+
? 'var(--owt-panel-divider-color, #C4C4C4)'
|
|
11460
|
+
: 'var(--owt-color-primary, #F5BB1A)',
|
|
11461
|
+
} })), column.map((doc) => renderSlot(doc))] }, `docs-column-${columnIndex}`));
|
|
11462
|
+
}) }), jsxRuntimeExports.jsx(FilePreviewModal, { file: previewFile, isOpen: isPreviewOpen && !!previewFile, onClose: () => {
|
|
11347
11463
|
setIsPreviewOpen(false);
|
|
11348
11464
|
setPreviewFile(null);
|
|
11349
11465
|
} })] }));
|