@openg2p/registry-widgets 0.1.4 → 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/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 -1
- package/dist/index.esm.js +110 -22
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +110 -22
- package/dist/index.js.map +1 -1
- package/dist/widgets/DisplayWidget.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -951,32 +951,63 @@ const useBaseWidget = (options) => {
|
|
|
951
951
|
if (isLayoutWidget) {
|
|
952
952
|
return undefined; // Layout widgets don't have values
|
|
953
953
|
}
|
|
954
|
+
// Helper to extract displayable value from object (especially geo hierarchy objects)
|
|
955
|
+
const extractValueFromObject = (obj) => {
|
|
956
|
+
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
|
|
957
|
+
return obj;
|
|
958
|
+
}
|
|
959
|
+
// Check for geo hierarchy structure first
|
|
960
|
+
if ('geo_code_hierarchy_json' in obj || 'geo_lowest_level_value_id' in obj) {
|
|
961
|
+
if ('geo_lowest_level_value_id' in obj) {
|
|
962
|
+
return obj.geo_lowest_level_value_id;
|
|
963
|
+
}
|
|
964
|
+
// If it's a geo hierarchy object but no extractable ID, return undefined to avoid rendering object
|
|
965
|
+
return undefined;
|
|
966
|
+
}
|
|
967
|
+
// Try common value fields
|
|
968
|
+
if ('value' in obj) {
|
|
969
|
+
return obj.value;
|
|
970
|
+
}
|
|
971
|
+
if ('id' in obj) {
|
|
972
|
+
return obj.id;
|
|
973
|
+
}
|
|
974
|
+
if ('label' in obj) {
|
|
975
|
+
return obj.label;
|
|
976
|
+
}
|
|
977
|
+
if ('name' in obj) {
|
|
978
|
+
return obj.name;
|
|
979
|
+
}
|
|
980
|
+
// If no extractable value found, return undefined to avoid rendering object as React child
|
|
981
|
+
// This prevents "Objects are not valid as a React child" errors
|
|
982
|
+
return undefined;
|
|
983
|
+
};
|
|
954
984
|
// Try to get value from widgetId first (this should have the actual selected value)
|
|
955
985
|
// For geo widgets with dataPath, widgetId stores the actual ID, while dataPath stores the hierarchy object
|
|
956
986
|
let value = values[widgetId];
|
|
987
|
+
// Extract value if it's an object (handles geo hierarchy objects stored in widgetId)
|
|
988
|
+
if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {
|
|
989
|
+
value = extractValueFromObject(value);
|
|
990
|
+
}
|
|
957
991
|
// If widgetId doesn't have a value, try dataPath
|
|
958
992
|
if (value === undefined && config['widget-data-path']) {
|
|
959
993
|
value = getWidgetValue(values, config['widget-data-path'], widgetId);
|
|
960
|
-
//
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
if (geoConfig?.isLastLevel && value && typeof value === 'object' && !Array.isArray(value)) {
|
|
964
|
-
// If it's a geo hierarchy object, extract the actual value
|
|
965
|
-
if ('geo_lowest_level_value_id' in value) {
|
|
966
|
-
value = value.geo_lowest_level_value_id;
|
|
967
|
-
}
|
|
968
|
-
else if ('value' in value) {
|
|
969
|
-
value = value.value;
|
|
970
|
-
}
|
|
971
|
-
else if ('id' in value) {
|
|
972
|
-
value = value.id;
|
|
973
|
-
}
|
|
994
|
+
// Extract value if it's an object (handles geo hierarchy objects from dataPath)
|
|
995
|
+
if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {
|
|
996
|
+
value = extractValueFromObject(value);
|
|
974
997
|
}
|
|
975
998
|
}
|
|
976
999
|
// If value is still undefined and user has set a value, try reading from widgetId as backup
|
|
977
1000
|
// This handles cases where dataPath lookup might fail temporarily
|
|
978
1001
|
if (value === undefined && userHasSetValueRef.current && values[widgetId] !== undefined) {
|
|
979
1002
|
value = values[widgetId];
|
|
1003
|
+
// Extract value if it's an object (handles geo hierarchy objects)
|
|
1004
|
+
if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {
|
|
1005
|
+
value = extractValueFromObject(value);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
// Final safety check: if value is still an object, extract displayable value
|
|
1009
|
+
if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {
|
|
1010
|
+
value = extractValueFromObject(value);
|
|
980
1011
|
}
|
|
981
1012
|
// If user has explicitly set a value, always return it (even if undefined/null)
|
|
982
1013
|
// This prevents the default from overwriting user selections
|
|
@@ -2246,7 +2277,7 @@ const WidgetProvider = ({ store, dataSourceRequestHandler, schemaData, translate
|
|
|
2246
2277
|
widgetStore.dispatch(setValues(schemaData));
|
|
2247
2278
|
}
|
|
2248
2279
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2249
|
-
}, []); // Only run on mount
|
|
2280
|
+
}, [schemaData, widgetStore]); // Only run on mount
|
|
2250
2281
|
const content = (jsxRuntimeExports.jsx(reactRedux.Provider, { store: widgetStore, children: jsxRuntimeExports.jsx(WidgetContext.Provider, { value: contextValue, children: jsxRuntimeExports.jsx(WidgetEventBusContext.Provider, { value: eventBus, children: children }) }) }));
|
|
2251
2282
|
return content;
|
|
2252
2283
|
};
|
|
@@ -2256,8 +2287,11 @@ const WidgetRenderer = ({ config, dataSourceRequestHandler: propDataSourceReques
|
|
|
2256
2287
|
const context = useWidgetContext();
|
|
2257
2288
|
const dataSourceRequestHandler = propDataSourceRequestHandler || context.dataSourceRequestHandler;
|
|
2258
2289
|
const schemaData = propSchemaData || context.schemaData;
|
|
2290
|
+
// Warn if dataSourceRequestHandler is missing for API data sources, but don't break rendering
|
|
2291
|
+
// This allows widgets to render in read-only or static modes (e.g., CRView)
|
|
2259
2292
|
if (!dataSourceRequestHandler && config['widget-data-source']?.type === 'api') {
|
|
2260
|
-
console.
|
|
2293
|
+
console.warn(`[WidgetRenderer] dataSourceRequestHandler is not provided for widget ${config['widget-id']} with API data source. ` +
|
|
2294
|
+
`The widget will render but API data source functionality will be disabled.`);
|
|
2261
2295
|
}
|
|
2262
2296
|
// Get values from Redux for cascade hooks
|
|
2263
2297
|
const values = reactRedux.useSelector((state) => state.widget.values);
|
|
@@ -3193,7 +3227,7 @@ const namespaceSectionConfig = (section, namespace) => {
|
|
|
3193
3227
|
* - Panels wrap when they exceed available width
|
|
3194
3228
|
* - Sections can sit side-by-side if there's space
|
|
3195
3229
|
*/
|
|
3196
|
-
const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton = false, mode = 'RegistryView', namespace, }) => {
|
|
3230
|
+
const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton = false, mode = 'RegistryView', namespace, changeRequestType, showChangeRequestLabel = true, }) => {
|
|
3197
3231
|
const { translateConfig, translate } = useWidgetTranslation();
|
|
3198
3232
|
const { schemaData: contextSchemaData, dataSourceRequestHandler: contextDataSourceRequestHandler } = useWidgetContext();
|
|
3199
3233
|
const store = reactRedux.useStore();
|
|
@@ -3811,11 +3845,12 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3811
3845
|
align-items: center;
|
|
3812
3846
|
gap: 0.5rem;
|
|
3813
3847
|
}
|
|
3814
|
-
` }), 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, style: {
|
|
3848
|
+
` }), 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: {
|
|
3815
3849
|
gridColumn: `span ${columnSpan}`,
|
|
3816
3850
|
width: '100%',
|
|
3817
3851
|
borderRadius: '10px',
|
|
3818
|
-
backgroundColor: '#FFFFFF',
|
|
3852
|
+
backgroundColor: changeRequestType === 'old' ? '#F9F9F9' : '#FFFFFF', // Faded background for old change requests
|
|
3853
|
+
opacity: changeRequestType === 'old' ? 0.95 : 1, // Slight opacity reduction for old sections
|
|
3819
3854
|
...(isEditMode && sectionHeight ? {
|
|
3820
3855
|
height: `${sectionHeight}px`,
|
|
3821
3856
|
minHeight: `${sectionHeight}px`
|
|
@@ -3824,7 +3859,27 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
|
|
|
3824
3859
|
minHeight: 'auto',
|
|
3825
3860
|
height: 'auto'
|
|
3826
3861
|
}),
|
|
3827
|
-
}, children: [sectionToRender['section-title'] && (jsxRuntimeExports.
|
|
3862
|
+
}, children: [sectionToRender['section-title'] && (jsxRuntimeExports.jsxs("div", { style: {
|
|
3863
|
+
marginTop: '35px',
|
|
3864
|
+
marginBottom: '16px',
|
|
3865
|
+
display: 'flex',
|
|
3866
|
+
alignItems: 'center',
|
|
3867
|
+
gap: '12px',
|
|
3868
|
+
flexWrap: 'wrap',
|
|
3869
|
+
}, 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: {
|
|
3870
|
+
display: 'inline-flex',
|
|
3871
|
+
alignItems: 'center',
|
|
3872
|
+
padding: '4px 12px',
|
|
3873
|
+
borderRadius: '4px',
|
|
3874
|
+
fontSize: '12px',
|
|
3875
|
+
fontWeight: 600,
|
|
3876
|
+
textTransform: 'uppercase',
|
|
3877
|
+
letterSpacing: '0.5px',
|
|
3878
|
+
backgroundColor: changeRequestType === 'new' ? '#28a745' : '#ffcccc', // Green for new, faded red for old
|
|
3879
|
+
color: changeRequestType === 'new' ? '#FFFFFF' : '#cc0000',
|
|
3880
|
+
whiteSpace: 'nowrap',
|
|
3881
|
+
boxShadow: changeRequestType === 'new' ? '0 2px 4px rgba(40, 167, 69, 0.3)' : 'none',
|
|
3882
|
+
}, 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: {
|
|
3828
3883
|
marginTop: '20px',
|
|
3829
3884
|
paddingBottom: '30px',
|
|
3830
3885
|
display: 'flex',
|
|
@@ -7397,8 +7452,41 @@ const CurrencyInputWidget = ({ config }) => {
|
|
|
7397
7452
|
const DisplayWidget = ({ config }) => {
|
|
7398
7453
|
const { value, formattedValue, config: widgetConfig, } = useBaseWidget({ config });
|
|
7399
7454
|
const { translateConfig } = useWidgetTranslation();
|
|
7400
|
-
//
|
|
7401
|
-
const
|
|
7455
|
+
// Helper to safely convert value to display string
|
|
7456
|
+
const getDisplayValue = (val) => {
|
|
7457
|
+
if (val === null || val === undefined) {
|
|
7458
|
+
return '';
|
|
7459
|
+
}
|
|
7460
|
+
// If it's already a string or number, return as string
|
|
7461
|
+
if (typeof val === 'string' || typeof val === 'number') {
|
|
7462
|
+
return String(val);
|
|
7463
|
+
}
|
|
7464
|
+
// If it's an object (like geo hierarchy), try to extract a meaningful value
|
|
7465
|
+
if (typeof val === 'object' && !Array.isArray(val)) {
|
|
7466
|
+
// For geo hierarchy objects, try to extract the actual value
|
|
7467
|
+
if ('geo_lowest_level_value_id' in val) {
|
|
7468
|
+
return String(val.geo_lowest_level_value_id || '');
|
|
7469
|
+
}
|
|
7470
|
+
if ('value' in val) {
|
|
7471
|
+
return String(val.value || '');
|
|
7472
|
+
}
|
|
7473
|
+
if ('id' in val) {
|
|
7474
|
+
return String(val.id || '');
|
|
7475
|
+
}
|
|
7476
|
+
// If no extractable value, return empty string to avoid rendering object
|
|
7477
|
+
return '';
|
|
7478
|
+
}
|
|
7479
|
+
// For arrays, join them or return empty
|
|
7480
|
+
if (Array.isArray(val)) {
|
|
7481
|
+
return val.length > 0 ? val.map(String).join(', ') : '';
|
|
7482
|
+
}
|
|
7483
|
+
// Fallback: convert to string
|
|
7484
|
+
return String(val);
|
|
7485
|
+
};
|
|
7486
|
+
// Use formatted value if available, otherwise safely convert raw value
|
|
7487
|
+
const displayValue = formattedValue !== undefined
|
|
7488
|
+
? (typeof formattedValue === 'object' ? getDisplayValue(formattedValue) : String(formattedValue))
|
|
7489
|
+
: getDisplayValue(value);
|
|
7402
7490
|
const label = translateConfig(widgetConfig['widget-label']);
|
|
7403
7491
|
// If no label, render as paragraph text
|
|
7404
7492
|
if (!label || label.trim() === '') {
|