@openg2p/registry-widgets 0.1.3 → 0.1.5
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/SectionBuilder/JSONEditorPanel.d.ts +0 -1
- package/dist/components/SectionBuilder/JSONEditorPanel.d.ts.map +1 -1
- package/dist/components/SectionBuilder/PropertyEditor.d.ts.map +1 -1
- package/dist/components/SectionBuilder/SectionBuilder.d.ts.map +1 -1
- package/dist/components/SectionBuilder/VisualBuilderPanel.d.ts.map +1 -1
- package/dist/components/SectionRenderer.d.ts +3 -1
- package/dist/components/SectionRenderer.d.ts.map +1 -1
- package/dist/components/WidgetRenderer.d.ts.map +1 -1
- package/dist/hooks/useBaseWidget.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.esm.js +169 -199
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +169 -199
- package/dist/index.js.map +1 -1
- package/dist/widgets/DisplayWidget.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -950,32 +950,63 @@ const useBaseWidget = (options) => {
|
|
|
950
950
|
if (isLayoutWidget) {
|
|
951
951
|
return undefined; // Layout widgets don't have values
|
|
952
952
|
}
|
|
953
|
+
// Helper to extract displayable value from object (especially geo hierarchy objects)
|
|
954
|
+
const extractValueFromObject = (obj) => {
|
|
955
|
+
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
|
|
956
|
+
return obj;
|
|
957
|
+
}
|
|
958
|
+
// Check for geo hierarchy structure first
|
|
959
|
+
if ('geo_code_hierarchy_json' in obj || 'geo_lowest_level_value_id' in obj) {
|
|
960
|
+
if ('geo_lowest_level_value_id' in obj) {
|
|
961
|
+
return obj.geo_lowest_level_value_id;
|
|
962
|
+
}
|
|
963
|
+
// If it's a geo hierarchy object but no extractable ID, return undefined to avoid rendering object
|
|
964
|
+
return undefined;
|
|
965
|
+
}
|
|
966
|
+
// Try common value fields
|
|
967
|
+
if ('value' in obj) {
|
|
968
|
+
return obj.value;
|
|
969
|
+
}
|
|
970
|
+
if ('id' in obj) {
|
|
971
|
+
return obj.id;
|
|
972
|
+
}
|
|
973
|
+
if ('label' in obj) {
|
|
974
|
+
return obj.label;
|
|
975
|
+
}
|
|
976
|
+
if ('name' in obj) {
|
|
977
|
+
return obj.name;
|
|
978
|
+
}
|
|
979
|
+
// If no extractable value found, return undefined to avoid rendering object as React child
|
|
980
|
+
// This prevents "Objects are not valid as a React child" errors
|
|
981
|
+
return undefined;
|
|
982
|
+
};
|
|
953
983
|
// Try to get value from widgetId first (this should have the actual selected value)
|
|
954
984
|
// For geo widgets with dataPath, widgetId stores the actual ID, while dataPath stores the hierarchy object
|
|
955
985
|
let value = values[widgetId];
|
|
986
|
+
// Extract value if it's an object (handles geo hierarchy objects stored in widgetId)
|
|
987
|
+
if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {
|
|
988
|
+
value = extractValueFromObject(value);
|
|
989
|
+
}
|
|
956
990
|
// If widgetId doesn't have a value, try dataPath
|
|
957
991
|
if (value === undefined && config['widget-data-path']) {
|
|
958
992
|
value = getWidgetValue(values, config['widget-data-path'], widgetId);
|
|
959
|
-
//
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
if (geoConfig?.isLastLevel && value && typeof value === 'object' && !Array.isArray(value)) {
|
|
963
|
-
// If it's a geo hierarchy object, extract the actual value
|
|
964
|
-
if ('geo_lowest_level_value_id' in value) {
|
|
965
|
-
value = value.geo_lowest_level_value_id;
|
|
966
|
-
}
|
|
967
|
-
else if ('value' in value) {
|
|
968
|
-
value = value.value;
|
|
969
|
-
}
|
|
970
|
-
else if ('id' in value) {
|
|
971
|
-
value = value.id;
|
|
972
|
-
}
|
|
993
|
+
// Extract value if it's an object (handles geo hierarchy objects from dataPath)
|
|
994
|
+
if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {
|
|
995
|
+
value = extractValueFromObject(value);
|
|
973
996
|
}
|
|
974
997
|
}
|
|
975
998
|
// If value is still undefined and user has set a value, try reading from widgetId as backup
|
|
976
999
|
// This handles cases where dataPath lookup might fail temporarily
|
|
977
1000
|
if (value === undefined && userHasSetValueRef.current && values[widgetId] !== undefined) {
|
|
978
1001
|
value = values[widgetId];
|
|
1002
|
+
// Extract value if it's an object (handles geo hierarchy objects)
|
|
1003
|
+
if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {
|
|
1004
|
+
value = extractValueFromObject(value);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
// Final safety check: if value is still an object, extract displayable value
|
|
1008
|
+
if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {
|
|
1009
|
+
value = extractValueFromObject(value);
|
|
979
1010
|
}
|
|
980
1011
|
// If user has explicitly set a value, always return it (even if undefined/null)
|
|
981
1012
|
// This prevents the default from overwriting user selections
|
|
@@ -2245,7 +2276,7 @@ const WidgetProvider = ({ store, dataSourceRequestHandler, schemaData, translate
|
|
|
2245
2276
|
widgetStore.dispatch(setValues(schemaData));
|
|
2246
2277
|
}
|
|
2247
2278
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2248
|
-
}, []); // Only run on mount
|
|
2279
|
+
}, [schemaData, widgetStore]); // Only run on mount
|
|
2249
2280
|
const content = (jsxRuntimeExports.jsx(Provider, { store: widgetStore, children: jsxRuntimeExports.jsx(WidgetContext.Provider, { value: contextValue, children: jsxRuntimeExports.jsx(WidgetEventBusContext.Provider, { value: eventBus, children: children }) }) }));
|
|
2250
2281
|
return content;
|
|
2251
2282
|
};
|
|
@@ -2255,8 +2286,11 @@ const WidgetRenderer = ({ config, dataSourceRequestHandler: propDataSourceReques
|
|
|
2255
2286
|
const context = useWidgetContext();
|
|
2256
2287
|
const dataSourceRequestHandler = propDataSourceRequestHandler || context.dataSourceRequestHandler;
|
|
2257
2288
|
const schemaData = propSchemaData || context.schemaData;
|
|
2289
|
+
// Warn if dataSourceRequestHandler is missing for API data sources, but don't break rendering
|
|
2290
|
+
// This allows widgets to render in read-only or static modes (e.g., CRView)
|
|
2258
2291
|
if (!dataSourceRequestHandler && config['widget-data-source']?.type === 'api') {
|
|
2259
|
-
console.
|
|
2292
|
+
console.warn(`[WidgetRenderer] dataSourceRequestHandler is not provided for widget ${config['widget-id']} with API data source. ` +
|
|
2293
|
+
`The widget will render but API data source functionality will be disabled.`);
|
|
2260
2294
|
}
|
|
2261
2295
|
// Get values from Redux for cascade hooks
|
|
2262
2296
|
const values = useSelector((state) => state.widget.values);
|
|
@@ -3192,7 +3226,7 @@ const namespaceSectionConfig = (section, namespace) => {
|
|
|
3192
3226
|
* - Panels wrap when they exceed available width
|
|
3193
3227
|
* - Sections can sit side-by-side if there's space
|
|
3194
3228
|
*/
|
|
3195
|
-
const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton = false, mode = 'RegistryView', namespace, }) => {
|
|
3229
|
+
const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton = false, mode = 'RegistryView', namespace, changeRequestType, showChangeRequestLabel = true, }) => {
|
|
3196
3230
|
const { translateConfig, translate } = useWidgetTranslation();
|
|
3197
3231
|
const { schemaData: contextSchemaData, dataSourceRequestHandler: contextDataSourceRequestHandler } = useWidgetContext();
|
|
3198
3232
|
const store = useStore();
|
|
@@ -3810,11 +3844,12 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3810
3844
|
align-items: center;
|
|
3811
3845
|
gap: 0.5rem;
|
|
3812
3846
|
}
|
|
3813
|
-
` }), jsxRuntimeExports.jsxs("div", { ref: sectionRef, className: `section ${sectionClassId} px-4 sm:px-6 lg:px-8 border-2 border-
|
|
3847
|
+
` }), jsxRuntimeExports.jsxs("div", { ref: sectionRef, className: `section ${sectionClassId} px-4 sm:px-6 lg:px-8 border-2 border-white `, "data-section-id": sectionId, "data-has-table": hasTableWidget ? 'true' : 'false', "data-has-explicit-span": hasExplicitTableSpan ? 'true' : 'false', "data-edit-mode": isEditMode ? 'true' : 'false', "data-column-span": columnSpan, "data-change-request-type": changeRequestType, style: {
|
|
3814
3848
|
gridColumn: `span ${columnSpan}`,
|
|
3815
3849
|
width: '100%',
|
|
3816
3850
|
borderRadius: '10px',
|
|
3817
|
-
backgroundColor: '#FFFFFF',
|
|
3851
|
+
backgroundColor: changeRequestType === 'old' ? '#F9F9F9' : '#FFFFFF', // Faded background for old change requests
|
|
3852
|
+
opacity: changeRequestType === 'old' ? 0.95 : 1, // Slight opacity reduction for old sections
|
|
3818
3853
|
...(isEditMode && sectionHeight ? {
|
|
3819
3854
|
height: `${sectionHeight}px`,
|
|
3820
3855
|
minHeight: `${sectionHeight}px`
|
|
@@ -3823,7 +3858,27 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3823
3858
|
minHeight: 'auto',
|
|
3824
3859
|
height: 'auto'
|
|
3825
3860
|
}),
|
|
3826
|
-
}, children: [sectionToRender['section-title'] && (jsxRuntimeExports.
|
|
3861
|
+
}, children: [sectionToRender['section-title'] && (jsxRuntimeExports.jsxs("div", { style: {
|
|
3862
|
+
marginTop: '35px',
|
|
3863
|
+
marginBottom: '16px',
|
|
3864
|
+
display: 'flex',
|
|
3865
|
+
alignItems: 'center',
|
|
3866
|
+
gap: '12px',
|
|
3867
|
+
flexWrap: 'wrap',
|
|
3868
|
+
}, children: [jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold", style: { margin: 0 }, children: translateConfig(sectionToRender['section-title']) }), mode === 'CRView' && changeRequestType && showChangeRequestLabel && (jsxRuntimeExports.jsx("span", { style: {
|
|
3869
|
+
display: 'inline-flex',
|
|
3870
|
+
alignItems: 'center',
|
|
3871
|
+
padding: '4px 12px',
|
|
3872
|
+
borderRadius: '4px',
|
|
3873
|
+
fontSize: '12px',
|
|
3874
|
+
fontWeight: 600,
|
|
3875
|
+
textTransform: 'uppercase',
|
|
3876
|
+
letterSpacing: '0.5px',
|
|
3877
|
+
backgroundColor: changeRequestType === 'new' ? '#28a745' : '#ffcccc', // Green for new, faded red for old
|
|
3878
|
+
color: changeRequestType === 'new' ? '#FFFFFF' : '#cc0000',
|
|
3879
|
+
whiteSpace: 'nowrap',
|
|
3880
|
+
boxShadow: changeRequestType === 'new' ? '0 2px 4px rgba(40, 167, 69, 0.3)' : 'none',
|
|
3881
|
+
}, children: changeRequestType === 'new' ? 'New' : 'Old' }))] })), jsxRuntimeExports.jsxs("div", { id: gridId, className: "section-panels", style: mode === 'RegistryView' && hideEditButton ? { paddingBottom: '40px' } : {}, children: [editableSection.panels.map((panel, index) => (jsxRuntimeExports.jsx("div", { className: "panel-wrapper", children: jsxRuntimeExports.jsx(PanelRenderer, { panel: panel, dataSourceRequestHandler: dataSourceRequestHandler, schemaData: namespacedSchemaData, onValueChange: onValueChange }) }, panel['panel-id'] || `section-panel-${index}`))), mode === 'CRView' && crViewData && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("hr", { className: "border-gray-300 w-full", style: { height: '1px', marginTop: '20px', marginBottom: '0px' } }), jsxRuntimeExports.jsxs("div", { className: "cr-view-container", style: {
|
|
3827
3882
|
marginTop: '20px',
|
|
3828
3883
|
paddingBottom: '30px',
|
|
3829
3884
|
display: 'flex',
|
|
@@ -4116,7 +4171,7 @@ if (typeof document !== 'undefined') {
|
|
|
4116
4171
|
/**
|
|
4117
4172
|
* JSON Editor Panel - Left side of Section Builder
|
|
4118
4173
|
*/
|
|
4119
|
-
const JSONEditorPanel = ({ section, onChange, onReset,
|
|
4174
|
+
const JSONEditorPanel = ({ section, onChange, onReset, context = 'section', }) => {
|
|
4120
4175
|
const [jsonData, setJsonData] = useState(section);
|
|
4121
4176
|
const [validationErrors, setValidationErrors] = useState([]);
|
|
4122
4177
|
const [rawJsonView, setRawJsonView] = useState(false);
|
|
@@ -4188,96 +4243,6 @@ const JSONEditorPanel = ({ section, onChange, onReset, onSelectNode, context = '
|
|
|
4188
4243
|
window.addEventListener('keydown', handleEscape);
|
|
4189
4244
|
return () => window.removeEventListener('keydown', handleEscape);
|
|
4190
4245
|
}, [showPreview]);
|
|
4191
|
-
// Handle clicks in JSON editor to select corresponding node in visual builder
|
|
4192
|
-
useEffect(() => {
|
|
4193
|
-
if (!onSelectNode || rawJsonView)
|
|
4194
|
-
return; // Only work in tree view, not raw JSON view
|
|
4195
|
-
const handleJsonEditorClick = (e) => {
|
|
4196
|
-
const mouseEvent = e;
|
|
4197
|
-
const target = mouseEvent.target;
|
|
4198
|
-
// Find the key text element (json-edit-react uses .jer-key-text class)
|
|
4199
|
-
const keyElement = target.closest('.jer-key-text') ||
|
|
4200
|
-
target.querySelector('.jer-key-text') ||
|
|
4201
|
-
(target.classList.contains('jer-key-text') ? target : null);
|
|
4202
|
-
if (!keyElement)
|
|
4203
|
-
return;
|
|
4204
|
-
const keyText = keyElement.textContent?.trim();
|
|
4205
|
-
if (!keyText)
|
|
4206
|
-
return;
|
|
4207
|
-
// Remove colon if present
|
|
4208
|
-
const keyName = keyText.replace(':', '').trim();
|
|
4209
|
-
// Map key names to node types and find the corresponding node
|
|
4210
|
-
let nodeId = null;
|
|
4211
|
-
let nodeType = null;
|
|
4212
|
-
if (keyName === 'section-id') {
|
|
4213
|
-
// Find the section-id value
|
|
4214
|
-
const keyRow = keyElement.closest('.jer-collection-header-row, .jer-value-row');
|
|
4215
|
-
if (keyRow) {
|
|
4216
|
-
const valueElement = keyRow.querySelector('.jer-value-text, .jer-string-value');
|
|
4217
|
-
if (valueElement) {
|
|
4218
|
-
nodeId = valueElement.textContent?.replace(/^"|"$/g, '').trim() || section['section-id'];
|
|
4219
|
-
nodeType = 'section';
|
|
4220
|
-
}
|
|
4221
|
-
}
|
|
4222
|
-
}
|
|
4223
|
-
else if (keyName === 'panel-id') {
|
|
4224
|
-
// Find the panel-id value in the current panel object
|
|
4225
|
-
const panelContainer = keyElement.closest('.jer-collection-component');
|
|
4226
|
-
if (panelContainer) {
|
|
4227
|
-
const valueElement = panelContainer.querySelector('.jer-value-text, .jer-string-value');
|
|
4228
|
-
if (valueElement) {
|
|
4229
|
-
// Try to find panel-id value in this panel
|
|
4230
|
-
const allKeys = panelContainer.querySelectorAll('.jer-key-text');
|
|
4231
|
-
for (const key of Array.from(allKeys)) {
|
|
4232
|
-
if (key.textContent?.includes('panel-id')) {
|
|
4233
|
-
const keyRow = key.closest('.jer-collection-header-row, .jer-value-row');
|
|
4234
|
-
if (keyRow) {
|
|
4235
|
-
const valElement = keyRow.querySelector('.jer-value-text, .jer-string-value');
|
|
4236
|
-
if (valElement) {
|
|
4237
|
-
nodeId = valElement.textContent?.replace(/^"|"$/g, '').trim() || null;
|
|
4238
|
-
nodeType = 'panel';
|
|
4239
|
-
break;
|
|
4240
|
-
}
|
|
4241
|
-
}
|
|
4242
|
-
}
|
|
4243
|
-
}
|
|
4244
|
-
}
|
|
4245
|
-
}
|
|
4246
|
-
}
|
|
4247
|
-
else if (keyName === 'widget-id') {
|
|
4248
|
-
// Find the widget-id value in the current widget object
|
|
4249
|
-
const widgetContainer = keyElement.closest('.jer-collection-component');
|
|
4250
|
-
if (widgetContainer) {
|
|
4251
|
-
const allKeys = widgetContainer.querySelectorAll('.jer-key-text');
|
|
4252
|
-
for (const key of Array.from(allKeys)) {
|
|
4253
|
-
if (key.textContent?.includes('widget-id')) {
|
|
4254
|
-
const keyRow = key.closest('.jer-collection-header-row, .jer-value-row');
|
|
4255
|
-
if (keyRow) {
|
|
4256
|
-
const valElement = keyRow.querySelector('.jer-value-text, .jer-string-value');
|
|
4257
|
-
if (valElement) {
|
|
4258
|
-
nodeId = valElement.textContent?.replace(/^"|"$/g, '').trim() || null;
|
|
4259
|
-
nodeType = 'widget';
|
|
4260
|
-
break;
|
|
4261
|
-
}
|
|
4262
|
-
}
|
|
4263
|
-
}
|
|
4264
|
-
}
|
|
4265
|
-
}
|
|
4266
|
-
}
|
|
4267
|
-
// If we found a node, select it in the visual builder
|
|
4268
|
-
if (nodeId && nodeType) {
|
|
4269
|
-
onSelectNode(nodeId, nodeType);
|
|
4270
|
-
}
|
|
4271
|
-
};
|
|
4272
|
-
// Add click listener to the JSON editor container
|
|
4273
|
-
const editorContainer = document.querySelector('.json-editor-scroll-container');
|
|
4274
|
-
if (editorContainer) {
|
|
4275
|
-
editorContainer.addEventListener('click', handleJsonEditorClick);
|
|
4276
|
-
return () => {
|
|
4277
|
-
editorContainer.removeEventListener('click', handleJsonEditorClick);
|
|
4278
|
-
};
|
|
4279
|
-
}
|
|
4280
|
-
}, [onSelectNode, rawJsonView, section]);
|
|
4281
4246
|
// Make section editable for preview - remove readonly flags from widgets
|
|
4282
4247
|
const makeSectionEditable = useCallback((section) => {
|
|
4283
4248
|
const processWidget = (widget) => {
|
|
@@ -4522,7 +4487,7 @@ const JSONEditorPanel = ({ section, onChange, onReset, onSelectNode, context = '
|
|
|
4522
4487
|
minHeight: 0,
|
|
4523
4488
|
borderRight: '0px',
|
|
4524
4489
|
}, children: [jsxRuntimeExports.jsxs("div", { style: {
|
|
4525
|
-
padding: '
|
|
4490
|
+
padding: '16px 20px',
|
|
4526
4491
|
background: '#ffffff',
|
|
4527
4492
|
display: 'flex',
|
|
4528
4493
|
justifyContent: 'space-between',
|
|
@@ -4544,8 +4509,8 @@ const JSONEditorPanel = ({ section, onChange, onReset, onSelectNode, context = '
|
|
|
4544
4509
|
}, children: [jsxRuntimeExports.jsxs("button", { onClick: handleReset, style: {
|
|
4545
4510
|
padding: '6px 12px',
|
|
4546
4511
|
border: '1px solid #ddd',
|
|
4547
|
-
borderRadius: '
|
|
4548
|
-
background: '
|
|
4512
|
+
borderRadius: '10px',
|
|
4513
|
+
background: '#f3f3f3',
|
|
4549
4514
|
color: '#666',
|
|
4550
4515
|
cursor: 'pointer',
|
|
4551
4516
|
display: 'flex',
|
|
@@ -4563,8 +4528,8 @@ const JSONEditorPanel = ({ section, onChange, onReset, onSelectNode, context = '
|
|
|
4563
4528
|
}, title: "Reset to original JSON", children: [jsxRuntimeExports.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }), jsxRuntimeExports.jsx("path", { d: "M21 3v5h-5" }), jsxRuntimeExports.jsx("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }), jsxRuntimeExports.jsx("path", { d: "M3 21v-5h5" })] }), "Reset"] }), jsxRuntimeExports.jsxs("button", { onClick: () => setShowPreview(true), style: {
|
|
4564
4529
|
padding: '6px 12px',
|
|
4565
4530
|
border: '1px solid #ddd',
|
|
4566
|
-
borderRadius: '
|
|
4567
|
-
background: '
|
|
4531
|
+
borderRadius: '10px',
|
|
4532
|
+
background: '#f3f3f3',
|
|
4568
4533
|
color: '#666',
|
|
4569
4534
|
cursor: 'pointer',
|
|
4570
4535
|
display: 'flex',
|
|
@@ -4920,18 +4885,24 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
4920
4885
|
border: '1px solid #ccc',
|
|
4921
4886
|
borderRadius: '4px',
|
|
4922
4887
|
fontSize: '12px',
|
|
4888
|
+
background: 'white',
|
|
4889
|
+
color: '#333',
|
|
4923
4890
|
} })] }), jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '12px', fontWeight: 500 }, children: "Section Title" }), jsxRuntimeExports.jsx("input", { type: "text", value: section['section-title'] || '', onChange: (e) => handleChange('section-title', e.target.value), style: {
|
|
4924
4891
|
width: '100%',
|
|
4925
4892
|
padding: '8px 12px',
|
|
4926
4893
|
border: '1px solid #ccc',
|
|
4927
4894
|
borderRadius: '4px',
|
|
4928
4895
|
fontSize: '12px',
|
|
4896
|
+
background: 'white',
|
|
4897
|
+
color: '#333',
|
|
4929
4898
|
} })] }), jsxRuntimeExports.jsx("div", { style: { marginBottom: '20px' }, children: jsxRuntimeExports.jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', fontSize: '12px' }, children: [jsxRuntimeExports.jsx("input", { type: "checkbox", checked: section['section-editable'] || false, onChange: (e) => handleChange('section-editable', e.target.checked) }), jsxRuntimeExports.jsx("span", { children: "Editable" })] }) }), jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '12px', fontWeight: 500 }, children: "Column Span" }), jsxRuntimeExports.jsx("input", { type: "number", value: section['section-column-span'] || 1, onChange: (e) => handleChange('section-column-span', parseInt(e.target.value) || 1), min: "1", style: {
|
|
4930
4899
|
width: '100%',
|
|
4931
4900
|
padding: '8px 12px',
|
|
4932
4901
|
border: '1px solid #ccc',
|
|
4933
4902
|
borderRadius: '4px',
|
|
4934
4903
|
fontSize: '12px',
|
|
4904
|
+
background: 'white',
|
|
4905
|
+
color: '#333',
|
|
4935
4906
|
} })] })] }));
|
|
4936
4907
|
};
|
|
4937
4908
|
const renderPanelProperties = () => {
|
|
@@ -4942,6 +4913,8 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
4942
4913
|
border: '1px solid #ccc',
|
|
4943
4914
|
borderRadius: '4px',
|
|
4944
4915
|
fontSize: '12px',
|
|
4916
|
+
background: 'white',
|
|
4917
|
+
color: '#333',
|
|
4945
4918
|
} })] }), jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '12px', fontWeight: 500 }, children: "Orientation" }), jsxRuntimeExports.jsx("select", { value: panel['panel-orientation'] || 'vertical', onChange: (e) => handleChange('panel-orientation', e.target.value), style: {
|
|
4946
4919
|
width: '100%',
|
|
4947
4920
|
padding: '8px 12px',
|
|
@@ -4955,6 +4928,8 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
4955
4928
|
border: '1px solid #ccc',
|
|
4956
4929
|
borderRadius: '4px',
|
|
4957
4930
|
fontSize: '12px',
|
|
4931
|
+
background: 'white',
|
|
4932
|
+
color: '#333',
|
|
4958
4933
|
} })] })] }));
|
|
4959
4934
|
};
|
|
4960
4935
|
const renderWidgetProperties = () => {
|
|
@@ -4988,24 +4963,32 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
4988
4963
|
border: '1px solid #ccc',
|
|
4989
4964
|
borderRadius: '4px',
|
|
4990
4965
|
fontSize: '12px',
|
|
4966
|
+
background: 'white',
|
|
4967
|
+
color: '#333',
|
|
4991
4968
|
} })] }), jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '12px', fontWeight: 500 }, children: "Widget Label" }), jsxRuntimeExports.jsx("input", { type: "text", value: widget['widget-label'] || '', onChange: (e) => handleChange('widget-label', e.target.value), style: {
|
|
4992
4969
|
width: '100%',
|
|
4993
4970
|
padding: '8px 12px',
|
|
4994
4971
|
border: '1px solid #ccc',
|
|
4995
4972
|
borderRadius: '4px',
|
|
4996
4973
|
fontSize: '12px',
|
|
4974
|
+
background: 'white',
|
|
4975
|
+
color: '#333',
|
|
4997
4976
|
}, placeholder: "Enter label..." })] }), jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '12px', fontWeight: 500 }, children: "Data Path" }), jsxRuntimeExports.jsx("input", { type: "text", value: typeof widget['widget-data-path'] === 'string' ? widget['widget-data-path'] : '', onChange: (e) => handleChange('widget-data-path', e.target.value), style: {
|
|
4998
4977
|
width: '100%',
|
|
4999
4978
|
padding: '8px 12px',
|
|
5000
4979
|
border: '1px solid #ccc',
|
|
5001
4980
|
borderRadius: '4px',
|
|
5002
4981
|
fontSize: '12px',
|
|
4982
|
+
background: 'white',
|
|
4983
|
+
color: '#333',
|
|
5003
4984
|
}, placeholder: "person.name" })] }), jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '12px', fontWeight: 500 }, children: "Placeholder" }), jsxRuntimeExports.jsx("input", { type: "text", value: widget['widget-data-placeholder'] || '', onChange: (e) => handleChange('widget-data-placeholder', e.target.value), style: {
|
|
5004
4985
|
width: '100%',
|
|
5005
4986
|
padding: '8px 12px',
|
|
5006
4987
|
border: '1px solid #ccc',
|
|
5007
4988
|
borderRadius: '4px',
|
|
5008
4989
|
fontSize: '12px',
|
|
4990
|
+
background: 'white',
|
|
4991
|
+
color: '#333',
|
|
5009
4992
|
}, placeholder: "Enter placeholder..." })] }), jsxRuntimeExports.jsx("div", { style: { marginBottom: '20px' }, children: jsxRuntimeExports.jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', fontSize: '12px' }, children: [jsxRuntimeExports.jsx("input", { type: "checkbox", checked: widget['widget-required'] || false, onChange: (e) => handleChange('widget-required', e.target.checked) }), jsxRuntimeExports.jsx("span", { children: "Required" })] }) }), jsxRuntimeExports.jsx("div", { style: { marginBottom: '20px' }, children: jsxRuntimeExports.jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', fontSize: '12px' }, children: [jsxRuntimeExports.jsx("input", { type: "checkbox", checked: widget['widget-readonly'] || false, onChange: (e) => handleChange('widget-readonly', e.target.checked) }), jsxRuntimeExports.jsx("span", { children: "Readonly" })] }) }), ['select', 'radio', 'checkbox'].includes(widget.widget) && (jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px', padding: '10px', background: '#e3f2fd', borderRadius: '4px' }, children: [jsxRuntimeExports.jsxs("label", { style: { display: 'block', marginBottom: '8px', fontSize: '12px', fontWeight: 600 }, children: ["Data Source (Required for ", widget.widget, ")"] }), jsxRuntimeExports.jsxs("div", { style: { marginBottom: '10px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '11px' }, children: "Source Type" }), jsxRuntimeExports.jsxs("select", { value: widget['widget-data-source']?.type || 'static', onChange: (e) => {
|
|
5010
4993
|
ensureNestedObject('widget-data-source');
|
|
5011
4994
|
handleNestedChange('widget-data-source', 'type', e.target.value);
|
|
@@ -5032,6 +5015,8 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
5032
5015
|
fontSize: '11px',
|
|
5033
5016
|
fontFamily: 'monospace',
|
|
5034
5017
|
minHeight: '80px',
|
|
5018
|
+
background: 'white',
|
|
5019
|
+
color: '#333',
|
|
5035
5020
|
}, placeholder: '[{"value": "opt1", "label": "Option 1"}]' })] })), widget['widget-data-source']?.type === 'api' && (() => {
|
|
5036
5021
|
const apiSource = widget['widget-data-source'];
|
|
5037
5022
|
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { style: { marginBottom: '10px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '11px' }, children: "API URL" }), jsxRuntimeExports.jsx("input", { type: "text", value: apiSource.url || '', onChange: (e) => handleNestedChange('widget-data-source', 'url', e.target.value), style: {
|
|
@@ -5040,18 +5025,24 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
5040
5025
|
border: '1px solid #ccc',
|
|
5041
5026
|
borderRadius: '4px',
|
|
5042
5027
|
fontSize: '11px',
|
|
5028
|
+
background: 'white',
|
|
5029
|
+
color: '#333',
|
|
5043
5030
|
}, placeholder: "https://api.example.com/options" })] }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '11px' }, children: "Value/Label Keys (e.g., \"id\"/\"name\")" }), jsxRuntimeExports.jsxs("div", { style: { display: 'flex', gap: '8px' }, children: [jsxRuntimeExports.jsx("input", { type: "text", value: apiSource.valueKey || '', onChange: (e) => handleNestedChange('widget-data-source', 'valueKey', e.target.value), style: {
|
|
5044
5031
|
flex: 1,
|
|
5045
5032
|
padding: '6px 8px',
|
|
5046
5033
|
border: '1px solid #ccc',
|
|
5047
5034
|
borderRadius: '4px',
|
|
5048
5035
|
fontSize: '11px',
|
|
5036
|
+
background: 'white',
|
|
5037
|
+
color: '#333',
|
|
5049
5038
|
}, placeholder: "value key" }), jsxRuntimeExports.jsx("input", { type: "text", value: apiSource.labelKey || '', onChange: (e) => handleNestedChange('widget-data-source', 'labelKey', e.target.value), style: {
|
|
5050
5039
|
flex: 1,
|
|
5051
5040
|
padding: '6px 8px',
|
|
5052
5041
|
border: '1px solid #ccc',
|
|
5053
5042
|
borderRadius: '4px',
|
|
5054
5043
|
fontSize: '11px',
|
|
5044
|
+
background: 'white',
|
|
5045
|
+
color: '#333',
|
|
5055
5046
|
}, placeholder: "label key" })] })] })] }));
|
|
5056
5047
|
})()] })), widget.widget === 'table' && (jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px', padding: '10px', background: '#fff3e0', borderRadius: '4px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '8px', fontSize: '12px', fontWeight: 600 }, children: "Table Columns" }), jsxRuntimeExports.jsx("div", { style: { fontSize: '11px', color: '#666', marginBottom: '10px' }, children: "Configure columns in JSON editor or add via code" }), jsxRuntimeExports.jsx("textarea", { value: JSON.stringify(widget['widget-data-columns'] || [], null, 2), onChange: (e) => {
|
|
5057
5048
|
try {
|
|
@@ -5069,30 +5060,40 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
5069
5060
|
fontSize: '11px',
|
|
5070
5061
|
fontFamily: 'monospace',
|
|
5071
5062
|
minHeight: '100px',
|
|
5063
|
+
background: 'white',
|
|
5064
|
+
color: '#333',
|
|
5072
5065
|
}, placeholder: '[{"column-key": "col1", "widget-label": "Column 1", "widget": "text"}]' })] })), widget.widget === 'number' && (jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px', padding: '10px', background: '#f3e5f5', borderRadius: '4px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '8px', fontSize: '12px', fontWeight: 600 }, children: "Number Validation" }), jsxRuntimeExports.jsxs("div", { style: { display: 'flex', gap: '10px', marginBottom: '10px' }, children: [jsxRuntimeExports.jsxs("div", { style: { flex: 1 }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '11px' }, children: "Min Value" }), jsxRuntimeExports.jsx("input", { type: "number", value: widget['widget-data-validation']?.min ?? '', onChange: (e) => handleNestedChange('widget-data-validation', 'min', e.target.value ? parseFloat(e.target.value) : undefined), style: {
|
|
5073
5066
|
width: '100%',
|
|
5074
5067
|
padding: '6px 8px',
|
|
5075
5068
|
border: '1px solid #ccc',
|
|
5076
5069
|
borderRadius: '4px',
|
|
5077
5070
|
fontSize: '11px',
|
|
5071
|
+
background: 'white',
|
|
5072
|
+
color: '#333',
|
|
5078
5073
|
} })] }), jsxRuntimeExports.jsxs("div", { style: { flex: 1 }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '11px' }, children: "Max Value" }), jsxRuntimeExports.jsx("input", { type: "number", value: widget['widget-data-validation']?.max ?? '', onChange: (e) => handleNestedChange('widget-data-validation', 'max', e.target.value ? parseFloat(e.target.value) : undefined), style: {
|
|
5079
5074
|
width: '100%',
|
|
5080
5075
|
padding: '6px 8px',
|
|
5081
5076
|
border: '1px solid #ccc',
|
|
5082
5077
|
borderRadius: '4px',
|
|
5083
5078
|
fontSize: '11px',
|
|
5079
|
+
background: 'white',
|
|
5080
|
+
color: '#333',
|
|
5084
5081
|
} })] })] })] })), ['date', 'datetime'].includes(widget.widget) && (jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px', padding: '10px', background: '#e8f5e9', borderRadius: '4px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '8px', fontSize: '12px', fontWeight: 600 }, children: "Date Range Options" }), jsxRuntimeExports.jsxs("div", { style: { display: 'flex', gap: '10px', marginBottom: '10px' }, children: [jsxRuntimeExports.jsxs("div", { style: { flex: 1 }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '11px' }, children: "Min Date" }), jsxRuntimeExports.jsx("input", { type: "date", value: widget['widget-data-options']?.minDate || '', onChange: (e) => handleNestedChange('widget-data-options', 'minDate', e.target.value || undefined), style: {
|
|
5085
5082
|
width: '100%',
|
|
5086
5083
|
padding: '6px 8px',
|
|
5087
5084
|
border: '1px solid #ccc',
|
|
5088
5085
|
borderRadius: '4px',
|
|
5089
5086
|
fontSize: '11px',
|
|
5087
|
+
background: 'white',
|
|
5088
|
+
color: '#333',
|
|
5090
5089
|
} })] }), jsxRuntimeExports.jsxs("div", { style: { flex: 1 }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '11px' }, children: "Max Date" }), jsxRuntimeExports.jsx("input", { type: "date", value: widget['widget-data-options']?.maxDate || '', onChange: (e) => handleNestedChange('widget-data-options', 'maxDate', e.target.value || undefined), style: {
|
|
5091
5090
|
width: '100%',
|
|
5092
5091
|
padding: '6px 8px',
|
|
5093
5092
|
border: '1px solid #ccc',
|
|
5094
5093
|
borderRadius: '4px',
|
|
5095
5094
|
fontSize: '11px',
|
|
5095
|
+
background: 'white',
|
|
5096
|
+
color: '#333',
|
|
5096
5097
|
} })] })] }), jsxRuntimeExports.jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', fontSize: '11px' }, children: [jsxRuntimeExports.jsx("input", { type: "checkbox", checked: widget['widget-data-options']?.showCalendar || false, onChange: (e) => handleNestedChange('widget-data-options', 'showCalendar', e.target.checked) }), jsxRuntimeExports.jsx("span", { children: "Show Calendar" })] })] })), jsxRuntimeExports.jsxs("div", { style: { marginBottom: '20px', padding: '10px', background: '#f0f0f0', borderRadius: '4px' }, children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '8px', fontSize: '12px', fontWeight: 600 }, children: "Validation" }), jsxRuntimeExports.jsx("div", { style: { marginBottom: '10px' }, children: jsxRuntimeExports.jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: '8px', fontSize: '12px' }, children: [jsxRuntimeExports.jsx("input", { type: "checkbox", checked: widget['widget-data-validation']?.required || false, onChange: (e) => {
|
|
5097
5098
|
if (!widget['widget-data-validation']) {
|
|
5098
5099
|
handleChange('widget-data-validation', { required: e.target.checked });
|
|
@@ -5112,6 +5113,8 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
5112
5113
|
border: '1px solid #ccc',
|
|
5113
5114
|
borderRadius: '4px',
|
|
5114
5115
|
fontSize: '11px',
|
|
5116
|
+
background: 'white',
|
|
5117
|
+
color: '#333',
|
|
5115
5118
|
} })] }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("label", { style: { display: 'block', marginBottom: '5px', fontSize: '11px' }, children: "Max Length" }), jsxRuntimeExports.jsx("input", { type: "number", value: widget['widget-data-validation']?.maxLength || '', onChange: (e) => {
|
|
5116
5119
|
const validation = widget['widget-data-validation'] || {};
|
|
5117
5120
|
handleChange('widget-data-validation', {
|
|
@@ -5124,6 +5127,8 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
5124
5127
|
border: '1px solid #ccc',
|
|
5125
5128
|
borderRadius: '4px',
|
|
5126
5129
|
fontSize: '11px',
|
|
5130
|
+
background: 'white',
|
|
5131
|
+
color: '#333',
|
|
5127
5132
|
} })] })] }))] })] }));
|
|
5128
5133
|
};
|
|
5129
5134
|
const getHeaderColor = () => {
|
|
@@ -5153,7 +5158,7 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
5153
5158
|
flex: 1,
|
|
5154
5159
|
padding: '10px',
|
|
5155
5160
|
border: 'none',
|
|
5156
|
-
borderRadius: '
|
|
5161
|
+
borderRadius: '10px',
|
|
5157
5162
|
background: '#f44336',
|
|
5158
5163
|
color: 'white',
|
|
5159
5164
|
fontWeight: 600,
|
|
@@ -5163,7 +5168,7 @@ const PropertyEditor = ({ node, onChange, onDelete, onDuplicate, }) => {
|
|
|
5163
5168
|
flex: 1,
|
|
5164
5169
|
padding: '10px',
|
|
5165
5170
|
border: 'none',
|
|
5166
|
-
borderRadius: '
|
|
5171
|
+
borderRadius: '10px',
|
|
5167
5172
|
background: '#ff9800',
|
|
5168
5173
|
color: 'white',
|
|
5169
5174
|
fontWeight: 600,
|
|
@@ -5322,17 +5327,18 @@ const VisualBuilderPanel = ({ section, selectedNode, onSelectNode, onSectionChan
|
|
|
5322
5327
|
height: '100%',
|
|
5323
5328
|
width: '100%',
|
|
5324
5329
|
minHeight: 0,
|
|
5330
|
+
paddingBottom: '10px',
|
|
5331
|
+
borderRight: '0px',
|
|
5325
5332
|
}, children: [jsxRuntimeExports.jsxs("div", { style: {
|
|
5326
|
-
padding: '
|
|
5333
|
+
padding: '20px 20px 20px 20px',
|
|
5327
5334
|
background: '#ffffff',
|
|
5328
|
-
borderBottom: '1px solid #ddd',
|
|
5329
5335
|
display: 'flex',
|
|
5330
5336
|
justifyContent: 'space-between',
|
|
5331
5337
|
alignItems: 'center',
|
|
5332
|
-
}, children: [jsxRuntimeExports.jsx("div", { style: { fontWeight: 600, fontSize: '16px', color: '#2c3e50' }, children: "Visual Builder" }), jsxRuntimeExports.jsxs("div", { style: { display: 'flex', gap: '10px' }, children: [jsxRuntimeExports.jsx("button", { onClick: handleAddPanel, style: {
|
|
5338
|
+
}, children: [jsxRuntimeExports.jsx("div", { style: { fontWeight: 600, fontSize: '16px', color: '#2c3e50', paddingTop: '5px' }, children: "Visual Builder" }), jsxRuntimeExports.jsxs("div", { style: { display: 'flex', gap: '10px' }, children: [jsxRuntimeExports.jsx("button", { onClick: handleAddPanel, style: {
|
|
5333
5339
|
padding: '8px 16px',
|
|
5334
5340
|
border: 'none',
|
|
5335
|
-
borderRadius: '
|
|
5341
|
+
borderRadius: '10px',
|
|
5336
5342
|
background: '#2196f3',
|
|
5337
5343
|
color: 'white',
|
|
5338
5344
|
fontWeight: 600,
|
|
@@ -5342,7 +5348,7 @@ const VisualBuilderPanel = ({ section, selectedNode, onSelectNode, onSectionChan
|
|
|
5342
5348
|
}, children: "+ Add Panel" }), jsxRuntimeExports.jsx("button", { onClick: handleAddWidget, style: {
|
|
5343
5349
|
padding: '8px 16px',
|
|
5344
5350
|
border: 'none',
|
|
5345
|
-
borderRadius: '
|
|
5351
|
+
borderRadius: '10px',
|
|
5346
5352
|
background: '#4caf50',
|
|
5347
5353
|
color: 'white',
|
|
5348
5354
|
fontWeight: 600,
|
|
@@ -5352,8 +5358,8 @@ const VisualBuilderPanel = ({ section, selectedNode, onSelectNode, onSectionChan
|
|
|
5352
5358
|
}, children: "+ Add Widget" }), onSave && (jsxRuntimeExports.jsx("button", { onClick: handleSave, style: {
|
|
5353
5359
|
padding: '8px 16px',
|
|
5354
5360
|
border: 'none',
|
|
5355
|
-
borderRadius: '
|
|
5356
|
-
background: '#
|
|
5361
|
+
borderRadius: '10px',
|
|
5362
|
+
background: '#000000',
|
|
5357
5363
|
color: 'white',
|
|
5358
5364
|
fontWeight: 600,
|
|
5359
5365
|
cursor: 'pointer',
|
|
@@ -5375,6 +5381,8 @@ const VisualBuilderPanel = ({ section, selectedNode, onSelectNode, onSectionChan
|
|
|
5375
5381
|
flex: 1,
|
|
5376
5382
|
display: 'flex',
|
|
5377
5383
|
overflow: 'hidden',
|
|
5384
|
+
border: '1px solid #ddd',
|
|
5385
|
+
borderRadius: '10px',
|
|
5378
5386
|
minHeight: 0, // Important for flex children to respect overflow
|
|
5379
5387
|
}, children: [jsxRuntimeExports.jsx("div", { style: {
|
|
5380
5388
|
width: '45%',
|
|
@@ -5434,77 +5442,6 @@ const SectionBuilder = ({ initialSection, onChange, onSave, }) => {
|
|
|
5434
5442
|
onChange(original);
|
|
5435
5443
|
}
|
|
5436
5444
|
}, [onChange]);
|
|
5437
|
-
// Handle node selection from JSON editor
|
|
5438
|
-
const handleSelectNodeFromJson = useCallback((nodeId, nodeType) => {
|
|
5439
|
-
// Find the corresponding node in the section structure
|
|
5440
|
-
const findNode = () => {
|
|
5441
|
-
if (nodeType === 'section') {
|
|
5442
|
-
return {
|
|
5443
|
-
type: 'section',
|
|
5444
|
-
id: section['section-id'],
|
|
5445
|
-
label: `Section: ${section['section-id']}`,
|
|
5446
|
-
data: section,
|
|
5447
|
-
};
|
|
5448
|
-
}
|
|
5449
|
-
// Recursively search for panel or widget
|
|
5450
|
-
const searchInPanels = (panels, parent) => {
|
|
5451
|
-
for (const panel of panels) {
|
|
5452
|
-
if (nodeType === 'panel' && panel['panel-id'] === nodeId) {
|
|
5453
|
-
return {
|
|
5454
|
-
type: 'panel',
|
|
5455
|
-
id: panel['panel-id'],
|
|
5456
|
-
label: `Panel: ${panel['panel-id']}`,
|
|
5457
|
-
data: panel,
|
|
5458
|
-
parent: parent,
|
|
5459
|
-
};
|
|
5460
|
-
}
|
|
5461
|
-
// Check nested panels
|
|
5462
|
-
if (panel.panels) {
|
|
5463
|
-
const panelNode = {
|
|
5464
|
-
type: 'panel',
|
|
5465
|
-
id: panel['panel-id'],
|
|
5466
|
-
label: `Panel: ${panel['panel-id']}`,
|
|
5467
|
-
data: panel,
|
|
5468
|
-
parent: parent,
|
|
5469
|
-
};
|
|
5470
|
-
const found = searchInPanels(panel.panels, panelNode);
|
|
5471
|
-
if (found)
|
|
5472
|
-
return found;
|
|
5473
|
-
}
|
|
5474
|
-
// Check widgets
|
|
5475
|
-
if (panel.widgets) {
|
|
5476
|
-
const panelNode = {
|
|
5477
|
-
type: 'panel',
|
|
5478
|
-
id: panel['panel-id'],
|
|
5479
|
-
label: `Panel: ${panel['panel-id']}`,
|
|
5480
|
-
data: panel,
|
|
5481
|
-
parent: parent,
|
|
5482
|
-
};
|
|
5483
|
-
for (const widget of panel.widgets) {
|
|
5484
|
-
if (nodeType === 'widget' && widget['widget-id'] === nodeId) {
|
|
5485
|
-
return {
|
|
5486
|
-
type: 'widget',
|
|
5487
|
-
id: widget['widget-id'],
|
|
5488
|
-
label: `Widget: ${widget['widget-id']} (${widget.widget})`,
|
|
5489
|
-
data: widget,
|
|
5490
|
-
parent: panelNode,
|
|
5491
|
-
};
|
|
5492
|
-
}
|
|
5493
|
-
}
|
|
5494
|
-
}
|
|
5495
|
-
}
|
|
5496
|
-
return null;
|
|
5497
|
-
};
|
|
5498
|
-
if (section.panels) {
|
|
5499
|
-
return searchInPanels(section.panels);
|
|
5500
|
-
}
|
|
5501
|
-
return null;
|
|
5502
|
-
};
|
|
5503
|
-
const node = findNode();
|
|
5504
|
-
if (node) {
|
|
5505
|
-
setSelectedNode(node);
|
|
5506
|
-
}
|
|
5507
|
-
}, [section]);
|
|
5508
5445
|
const handleAddPanel = useCallback((parentId, parentType) => {
|
|
5509
5446
|
const updatedSection = JSON.parse(JSON.stringify(section));
|
|
5510
5447
|
const newPanel = {
|
|
@@ -5684,7 +5621,7 @@ const SectionBuilder = ({ initialSection, onChange, onSave, }) => {
|
|
|
5684
5621
|
padding: '10px 10px 10px 10px',
|
|
5685
5622
|
flexDirection: 'column',
|
|
5686
5623
|
borderRight: '0px',
|
|
5687
|
-
}, children: jsxRuntimeExports.jsx(JSONEditorPanel, { section: section, onChange: handleSectionChange, onReset: handleReset
|
|
5624
|
+
}, children: jsxRuntimeExports.jsx(JSONEditorPanel, { section: section, onChange: handleSectionChange, onReset: handleReset }) }), jsxRuntimeExports.jsx("div", { style: {
|
|
5688
5625
|
width: '50%',
|
|
5689
5626
|
height: '100%',
|
|
5690
5627
|
minHeight: 0,
|
|
@@ -7514,8 +7451,41 @@ const CurrencyInputWidget = ({ config }) => {
|
|
|
7514
7451
|
const DisplayWidget = ({ config }) => {
|
|
7515
7452
|
const { value, formattedValue, config: widgetConfig, } = useBaseWidget({ config });
|
|
7516
7453
|
const { translateConfig } = useWidgetTranslation();
|
|
7517
|
-
//
|
|
7518
|
-
const
|
|
7454
|
+
// Helper to safely convert value to display string
|
|
7455
|
+
const getDisplayValue = (val) => {
|
|
7456
|
+
if (val === null || val === undefined) {
|
|
7457
|
+
return '';
|
|
7458
|
+
}
|
|
7459
|
+
// If it's already a string or number, return as string
|
|
7460
|
+
if (typeof val === 'string' || typeof val === 'number') {
|
|
7461
|
+
return String(val);
|
|
7462
|
+
}
|
|
7463
|
+
// If it's an object (like geo hierarchy), try to extract a meaningful value
|
|
7464
|
+
if (typeof val === 'object' && !Array.isArray(val)) {
|
|
7465
|
+
// For geo hierarchy objects, try to extract the actual value
|
|
7466
|
+
if ('geo_lowest_level_value_id' in val) {
|
|
7467
|
+
return String(val.geo_lowest_level_value_id || '');
|
|
7468
|
+
}
|
|
7469
|
+
if ('value' in val) {
|
|
7470
|
+
return String(val.value || '');
|
|
7471
|
+
}
|
|
7472
|
+
if ('id' in val) {
|
|
7473
|
+
return String(val.id || '');
|
|
7474
|
+
}
|
|
7475
|
+
// If no extractable value, return empty string to avoid rendering object
|
|
7476
|
+
return '';
|
|
7477
|
+
}
|
|
7478
|
+
// For arrays, join them or return empty
|
|
7479
|
+
if (Array.isArray(val)) {
|
|
7480
|
+
return val.length > 0 ? val.map(String).join(', ') : '';
|
|
7481
|
+
}
|
|
7482
|
+
// Fallback: convert to string
|
|
7483
|
+
return String(val);
|
|
7484
|
+
};
|
|
7485
|
+
// Use formatted value if available, otherwise safely convert raw value
|
|
7486
|
+
const displayValue = formattedValue !== undefined
|
|
7487
|
+
? (typeof formattedValue === 'object' ? getDisplayValue(formattedValue) : String(formattedValue))
|
|
7488
|
+
: getDisplayValue(value);
|
|
7519
7489
|
const label = translateConfig(widgetConfig['widget-label']);
|
|
7520
7490
|
// If no label, render as paragraph text
|
|
7521
7491
|
if (!label || label.trim() === '') {
|