@openg2p/registry-widgets 1.1.0-dev.11 → 1.1.0-dev.13
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/hooks/useBaseWidget.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +198 -80
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +197 -79
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/dataSource.d.ts.map +1 -1
- package/dist/utils/sectionValidate.d.ts.map +1 -1
- package/dist/widgets/BooleanWidget.d.ts.map +1 -1
- package/dist/widgets/DialogTableWidget.d.ts.map +1 -1
- package/dist/widgets/HeaderSectionWidget.d.ts.map +1 -1
- package/dist/widgets/TextAreaWidget.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1078,16 +1078,12 @@ const getApiDataSource = async (dataSource, allValues, dataSourceRequestHandler,
|
|
|
1078
1078
|
console.error('[getApiDataSource] API data source missing endpoint. Use "endpoint" field to specify the operation (e.g., "get_g2p_geo_level_values")');
|
|
1079
1079
|
return [];
|
|
1080
1080
|
}
|
|
1081
|
-
let
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
}
|
|
1087
|
-
catch (error) {
|
|
1088
|
-
console.error('[getApiDataSource] Handler error:', error);
|
|
1089
|
-
throw error;
|
|
1090
|
-
}
|
|
1081
|
+
// Call handler — let any throw propagate to the outer catch so it is logged once
|
|
1082
|
+
// by useBaseWidget rather than double-logged here (which can cascade when
|
|
1083
|
+
// intercept-console-error.js converts console.error calls into thrown errors).
|
|
1084
|
+
const response = await dataSourceRequestHandler(service, endpoint, method, requestParams, {
|
|
1085
|
+
headers: dataSource.headers,
|
|
1086
|
+
});
|
|
1091
1087
|
// Handle OpenG2P response format (response_body.response_payload)
|
|
1092
1088
|
if (response && typeof response === 'object') {
|
|
1093
1089
|
if (response.response_body?.response_payload && Array.isArray(response.response_body.response_payload)) {
|
|
@@ -1110,8 +1106,8 @@ const getApiDataSource = async (dataSource, allValues, dataSourceRequestHandler,
|
|
|
1110
1106
|
return [];
|
|
1111
1107
|
}
|
|
1112
1108
|
catch (error) {
|
|
1113
|
-
|
|
1114
|
-
|
|
1109
|
+
// Rethrow so useBaseWidget's catch can log it with full widget context
|
|
1110
|
+
throw error;
|
|
1115
1111
|
}
|
|
1116
1112
|
};
|
|
1117
1113
|
/**
|
|
@@ -2305,7 +2301,7 @@ const useBaseWidget = (options) => {
|
|
|
2305
2301
|
dispatch(setDataSource({ widgetId, data: transformed }));
|
|
2306
2302
|
}
|
|
2307
2303
|
catch (error) {
|
|
2308
|
-
console.error(`[useBaseWidget] ERROR loading data source for ${widgetId}:`, error);
|
|
2304
|
+
console.error(`[useBaseWidget] ERROR loading data source for widget "${widgetId}" (type="${dataSource.type}"):`, error, '\nWidget config:', config, '\ndataSourceRequestHandler provided:', Boolean(dataSourceRequestHandler));
|
|
2309
2305
|
dispatch(setDataSource({ widgetId, data: [] }));
|
|
2310
2306
|
}
|
|
2311
2307
|
finally {
|
|
@@ -3798,6 +3794,116 @@ const namespaceSectionConfig = (section, namespace) => {
|
|
|
3798
3794
|
return namespaced;
|
|
3799
3795
|
};
|
|
3800
3796
|
|
|
3797
|
+
/** Table-style widgets that bind to an array path in the store / schema. */
|
|
3798
|
+
function isTableLikeWidget(widget) {
|
|
3799
|
+
const w = widget.widget;
|
|
3800
|
+
/** widget-type union in types omits legacy values like simple-table still used at runtime */
|
|
3801
|
+
const t = widget['widget-type'];
|
|
3802
|
+
return (w === 'table' ||
|
|
3803
|
+
w === 'dialog-table' ||
|
|
3804
|
+
w === 'simple-table' ||
|
|
3805
|
+
t === 'table' ||
|
|
3806
|
+
t === 'simple-table');
|
|
3807
|
+
}
|
|
3808
|
+
/**
|
|
3809
|
+
* Resolve `records` for section save payloads.
|
|
3810
|
+
* - Back-compat: path ending in `.records` (e.g. `regId.records`)
|
|
3811
|
+
* - Else: first array snapshot at a string `widget-data-path` on a table-like widget
|
|
3812
|
+
* (e.g. `household.members` for dialog-table)
|
|
3813
|
+
*/
|
|
3814
|
+
function extractTableRecordsFromSnapshot(snapshot, sectionWidgets) {
|
|
3815
|
+
const convention = Object.entries(snapshot).find(([key, value]) => key.endsWith('.records') && Array.isArray(value));
|
|
3816
|
+
if (convention) {
|
|
3817
|
+
return convention[1];
|
|
3818
|
+
}
|
|
3819
|
+
const tablePaths = [];
|
|
3820
|
+
sectionWidgets.forEach((widget) => {
|
|
3821
|
+
if (!isTableLikeWidget(widget))
|
|
3822
|
+
return;
|
|
3823
|
+
const p = widget['widget-data-path'];
|
|
3824
|
+
if (typeof p === 'string' && p.length > 0) {
|
|
3825
|
+
tablePaths.push(p);
|
|
3826
|
+
}
|
|
3827
|
+
else if (p && typeof p === 'object') {
|
|
3828
|
+
Object.values(p).forEach((sub) => {
|
|
3829
|
+
if (typeof sub === 'string' && sub.length > 0)
|
|
3830
|
+
tablePaths.push(sub);
|
|
3831
|
+
});
|
|
3832
|
+
}
|
|
3833
|
+
});
|
|
3834
|
+
for (const path of tablePaths) {
|
|
3835
|
+
const val = snapshot[path];
|
|
3836
|
+
if (Array.isArray(val)) {
|
|
3837
|
+
return val;
|
|
3838
|
+
}
|
|
3839
|
+
}
|
|
3840
|
+
return [];
|
|
3841
|
+
}
|
|
3842
|
+
|
|
3843
|
+
const isColumnRequired = (column, skipRequired) => {
|
|
3844
|
+
if (skipRequired)
|
|
3845
|
+
return false;
|
|
3846
|
+
const validation = column['widget-data-validation'];
|
|
3847
|
+
return !!(column['widget-required'] || validation?.required);
|
|
3848
|
+
};
|
|
3849
|
+
const validateTableLikeWidget = (widget, currentSchemaData, dispatch, skipRequired) => {
|
|
3850
|
+
const widgetId = widget['widget-id'];
|
|
3851
|
+
if (!widgetId)
|
|
3852
|
+
return true;
|
|
3853
|
+
const columns = (widget['widget-data-columns'] || []);
|
|
3854
|
+
const value = getWidgetValue(currentSchemaData, widget['widget-data-path'], widgetId);
|
|
3855
|
+
const rows = Array.isArray(value)
|
|
3856
|
+
? value
|
|
3857
|
+
: [];
|
|
3858
|
+
const activeRows = rows.filter((row) => row?.edit_action !== 'DELETE');
|
|
3859
|
+
const rowErrors = [];
|
|
3860
|
+
let isValid = true;
|
|
3861
|
+
if (!skipRequired && widget['widget-required'] && activeRows.length === 0) {
|
|
3862
|
+
dispatch(setTouched({ widgetId, touched: true }));
|
|
3863
|
+
dispatch(setError({ widgetId, errors: ['At least one record is required'] }));
|
|
3864
|
+
return false;
|
|
3865
|
+
}
|
|
3866
|
+
const hasRequiredColumns = columns.some((col) => isColumnRequired(col, skipRequired));
|
|
3867
|
+
if (!skipRequired && hasRequiredColumns && activeRows.length === 0) {
|
|
3868
|
+
dispatch(setTouched({ widgetId, touched: true }));
|
|
3869
|
+
dispatch(setError({
|
|
3870
|
+
widgetId,
|
|
3871
|
+
errors: ['Add at least one record and fill all required fields'],
|
|
3872
|
+
}));
|
|
3873
|
+
return false;
|
|
3874
|
+
}
|
|
3875
|
+
activeRows.forEach((row, rowIndex) => {
|
|
3876
|
+
columns.forEach((col) => {
|
|
3877
|
+
if (col['widget-readonly'])
|
|
3878
|
+
return;
|
|
3879
|
+
const key = col['column-key'];
|
|
3880
|
+
if (!key)
|
|
3881
|
+
return;
|
|
3882
|
+
const required = isColumnRequired(col, skipRequired);
|
|
3883
|
+
const cellValue = row[key];
|
|
3884
|
+
const errors = validateWidget(cellValue, col['widget-data-validation'], required, skipRequired);
|
|
3885
|
+
if (errors.length > 0) {
|
|
3886
|
+
isValid = false;
|
|
3887
|
+
const label = col['widget-label'] || key;
|
|
3888
|
+
rowErrors.push(`Row ${rowIndex + 1}, ${label}: ${errors[0]}`);
|
|
3889
|
+
}
|
|
3890
|
+
});
|
|
3891
|
+
});
|
|
3892
|
+
if (!isValid) {
|
|
3893
|
+
dispatch(setTouched({ widgetId, touched: true }));
|
|
3894
|
+
dispatch(setError({
|
|
3895
|
+
widgetId,
|
|
3896
|
+
errors: rowErrors.length > 0
|
|
3897
|
+
? rowErrors.slice(0, 5)
|
|
3898
|
+
: ['Please fix required fields in the table'],
|
|
3899
|
+
}));
|
|
3900
|
+
}
|
|
3901
|
+
else {
|
|
3902
|
+
dispatch(setTouched({ widgetId, touched: false }));
|
|
3903
|
+
dispatch(setError({ widgetId, errors: [] }));
|
|
3904
|
+
}
|
|
3905
|
+
return isValid;
|
|
3906
|
+
};
|
|
3801
3907
|
const collectWidgets = (panels) => {
|
|
3802
3908
|
let widgets = [];
|
|
3803
3909
|
panels.forEach((panel) => {
|
|
@@ -3826,6 +3932,13 @@ const sectionValidate = (section, currentSchemaData, dispatch, skipRequired = fa
|
|
|
3826
3932
|
if (!isVisible)
|
|
3827
3933
|
continue;
|
|
3828
3934
|
const widgetId = widget['widget-id'];
|
|
3935
|
+
if (isTableLikeWidget(widget)) {
|
|
3936
|
+
const tableValid = validateTableLikeWidget(widget, currentSchemaData, dispatch, skipRequired);
|
|
3937
|
+
if (!tableValid) {
|
|
3938
|
+
isValid = false;
|
|
3939
|
+
}
|
|
3940
|
+
continue;
|
|
3941
|
+
}
|
|
3829
3942
|
const value = getWidgetValue(currentSchemaData, widget['widget-data-path'], widgetId);
|
|
3830
3943
|
const errors = validateWidget(value, widget['widget-data-validation'], widget['widget-required'], skipRequired);
|
|
3831
3944
|
if (errors.length > 0) {
|
|
@@ -3860,52 +3973,6 @@ const sectionValidate = (section, currentSchemaData, dispatch, skipRequired = fa
|
|
|
3860
3973
|
return isValid;
|
|
3861
3974
|
};
|
|
3862
3975
|
|
|
3863
|
-
/** Table-style widgets that bind to an array path in the store / schema. */
|
|
3864
|
-
function isTableLikeWidget(widget) {
|
|
3865
|
-
const w = widget.widget;
|
|
3866
|
-
/** widget-type union in types omits legacy values like simple-table still used at runtime */
|
|
3867
|
-
const t = widget['widget-type'];
|
|
3868
|
-
return (w === 'table' ||
|
|
3869
|
-
w === 'dialog-table' ||
|
|
3870
|
-
w === 'simple-table' ||
|
|
3871
|
-
t === 'table' ||
|
|
3872
|
-
t === 'simple-table');
|
|
3873
|
-
}
|
|
3874
|
-
/**
|
|
3875
|
-
* Resolve `records` for section save payloads.
|
|
3876
|
-
* - Back-compat: path ending in `.records` (e.g. `regId.records`)
|
|
3877
|
-
* - Else: first array snapshot at a string `widget-data-path` on a table-like widget
|
|
3878
|
-
* (e.g. `household.members` for dialog-table)
|
|
3879
|
-
*/
|
|
3880
|
-
function extractTableRecordsFromSnapshot(snapshot, sectionWidgets) {
|
|
3881
|
-
const convention = Object.entries(snapshot).find(([key, value]) => key.endsWith('.records') && Array.isArray(value));
|
|
3882
|
-
if (convention) {
|
|
3883
|
-
return convention[1];
|
|
3884
|
-
}
|
|
3885
|
-
const tablePaths = [];
|
|
3886
|
-
sectionWidgets.forEach((widget) => {
|
|
3887
|
-
if (!isTableLikeWidget(widget))
|
|
3888
|
-
return;
|
|
3889
|
-
const p = widget['widget-data-path'];
|
|
3890
|
-
if (typeof p === 'string' && p.length > 0) {
|
|
3891
|
-
tablePaths.push(p);
|
|
3892
|
-
}
|
|
3893
|
-
else if (p && typeof p === 'object') {
|
|
3894
|
-
Object.values(p).forEach((sub) => {
|
|
3895
|
-
if (typeof sub === 'string' && sub.length > 0)
|
|
3896
|
-
tablePaths.push(sub);
|
|
3897
|
-
});
|
|
3898
|
-
}
|
|
3899
|
-
});
|
|
3900
|
-
for (const path of tablePaths) {
|
|
3901
|
-
const val = snapshot[path];
|
|
3902
|
-
if (Array.isArray(val)) {
|
|
3903
|
-
return val;
|
|
3904
|
-
}
|
|
3905
|
-
}
|
|
3906
|
-
return [];
|
|
3907
|
-
}
|
|
3908
|
-
|
|
3909
3976
|
/** Root class on readonly label/value rows; SectionRenderer scopes overflow/ellipsis rules here. */
|
|
3910
3977
|
const READONLY_VALUE_ROW_ROOT_CLASSES = [
|
|
3911
3978
|
'TextDisplayWidget',
|
|
@@ -7391,7 +7458,7 @@ const NumberInputWidget = ({ config }) => {
|
|
|
7391
7458
|
if (parsed === null) {
|
|
7392
7459
|
// Allow empty input or partial input (e.g., "-", ".")
|
|
7393
7460
|
if (inputValue === '' || inputValue === '-' || inputValue === '.') {
|
|
7394
|
-
onChange(
|
|
7461
|
+
onChange(null);
|
|
7395
7462
|
}
|
|
7396
7463
|
// Don't update if invalid - let user continue typing
|
|
7397
7464
|
return;
|
|
@@ -7515,6 +7582,8 @@ const BooleanWidget = ({ config }) => {
|
|
|
7515
7582
|
return labels[representation];
|
|
7516
7583
|
}, [representation, formatConfig, translateConfig]);
|
|
7517
7584
|
const { trueLabel, falseLabel } = getLabels();
|
|
7585
|
+
const unsetLabel = React.useMemo(() => translateConfig(formatConfig?.booleanUnsetLabel || 'Not set'), [formatConfig?.booleanUnsetLabel, translateConfig]);
|
|
7586
|
+
const radioGroupName = `${widgetConfig['widget-id'] ?? 'boolean'}__${React.useId().replace(/:/g, '')}`;
|
|
7518
7587
|
// Determine current value (handle null/undefined)
|
|
7519
7588
|
const currentValue = React.useMemo(() => {
|
|
7520
7589
|
if (value === null || value === undefined) {
|
|
@@ -7546,7 +7615,7 @@ const BooleanWidget = ({ config }) => {
|
|
|
7546
7615
|
const label = translateConfig(widgetConfig['widget-label']);
|
|
7547
7616
|
let displayValue = '';
|
|
7548
7617
|
if (currentValue === null) {
|
|
7549
|
-
displayValue = '
|
|
7618
|
+
displayValue = '';
|
|
7550
7619
|
}
|
|
7551
7620
|
else if (currentValue === true) {
|
|
7552
7621
|
displayValue = trueLabel;
|
|
@@ -7558,18 +7627,20 @@ const BooleanWidget = ({ config }) => {
|
|
|
7558
7627
|
}
|
|
7559
7628
|
// Render based on control type
|
|
7560
7629
|
if (controlType === 'checkbox') {
|
|
7561
|
-
return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-
|
|
7630
|
+
return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-baseline", children: [jsxRuntimeExports.jsxs("label", { className: "text-base font-medium leading-normal text-gray-700 md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0 sm:pt-0.5", style: { fontFamily: 'Roboto, sans-serif' }, title: translateConfig(widgetConfig['widget-label']), children: [translateConfig(widgetConfig['widget-label']), widgetConfig['widget-required'] && (jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" }))] }), jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntimeExports.jsxs("label", { className: "inline-flex items-baseline cursor-pointer gap-2", children: [jsxRuntimeExports.jsx("input", { type: "checkbox", checked: currentValue === true, onChange: handleCheckboxChange, onBlur: onBlur, disabled: !isEnabled || widgetConfig['widget-readonly'], className: "relative top-[0.2em] h-4 w-4 shrink-0 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" }), (currentValue === true || currentValue === false) && (jsxRuntimeExports.jsx("span", { className: "text-base text-gray-700 leading-normal", children: currentValue === true ? trueLabel : falseLabel }))] }), touched && error.length > 0 && (jsxRuntimeExports.jsx("p", { className: "text-red-500 text-sm mt-1", children: error[0] }))] })] }) }));
|
|
7562
7631
|
}
|
|
7563
7632
|
if (controlType === 'radio') {
|
|
7564
7633
|
const containerClass = orientation === 'horizontal'
|
|
7565
|
-
? 'flex flex-row
|
|
7566
|
-
: 'flex flex-col
|
|
7567
|
-
|
|
7634
|
+
? 'flex flex-row flex-wrap items-baseline gap-x-4 gap-y-2'
|
|
7635
|
+
: 'flex flex-col items-start gap-2';
|
|
7636
|
+
const radioDisabled = !isEnabled || widgetConfig['widget-readonly'];
|
|
7637
|
+
const optionDisabledClass = radioDisabled ? 'opacity-50 cursor-not-allowed' : '';
|
|
7638
|
+
return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-baseline", children: [jsxRuntimeExports.jsxs("label", { className: "text-base font-medium leading-normal text-gray-700 md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0 sm:pt-0.5", style: { fontFamily: 'Roboto, sans-serif' }, title: translateConfig(widgetConfig['widget-label']), children: [translateConfig(widgetConfig['widget-label']), widgetConfig['widget-required'] && (jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" }))] }), jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntimeExports.jsxs("div", { className: containerClass, onBlur: onBlur, children: [allowUnset && (jsxRuntimeExports.jsxs("label", { className: `inline-flex items-baseline gap-2 cursor-pointer ${optionDisabledClass}`, children: [jsxRuntimeExports.jsx("input", { type: "radio", name: radioGroupName, checked: currentValue === null, onChange: () => handleRadioChange(null), disabled: radioDisabled, className: "relative top-[0.2em] h-4 w-4 shrink-0 text-blue-600 focus:ring-blue-500 border-gray-300" }), jsxRuntimeExports.jsx("span", { className: "text-base text-gray-700 leading-normal", children: unsetLabel })] })), jsxRuntimeExports.jsxs("label", { className: `inline-flex items-baseline gap-2 cursor-pointer ${optionDisabledClass}`, children: [jsxRuntimeExports.jsx("input", { type: "radio", name: radioGroupName, checked: currentValue === true, onChange: () => handleRadioChange(true), disabled: radioDisabled, className: "relative top-[0.2em] h-4 w-4 shrink-0 text-blue-600 focus:ring-blue-500 border-gray-300" }), jsxRuntimeExports.jsx("span", { className: "text-base text-gray-700 leading-normal", children: trueLabel })] }), jsxRuntimeExports.jsxs("label", { className: `inline-flex items-baseline gap-2 cursor-pointer ${optionDisabledClass}`, children: [jsxRuntimeExports.jsx("input", { type: "radio", name: radioGroupName, checked: currentValue === false, onChange: () => handleRadioChange(false), disabled: radioDisabled, className: "relative top-[0.2em] h-4 w-4 shrink-0 text-blue-600 focus:ring-blue-500 border-gray-300" }), jsxRuntimeExports.jsx("span", { className: "text-base text-gray-700 leading-normal", children: falseLabel })] })] }), touched && error.length > 0 && (jsxRuntimeExports.jsx("p", { className: "text-red-500 text-sm mt-1", children: error[0] }))] })] }) }));
|
|
7568
7639
|
}
|
|
7569
7640
|
// Toggle/switch control type
|
|
7570
|
-
return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-
|
|
7641
|
+
return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-baseline", children: [jsxRuntimeExports.jsxs("label", { className: "text-base font-medium leading-normal text-gray-700 sm:min-w-[150px] sm:pr-4 mb-1 sm:mb-0 sm:pt-0.5", style: { fontFamily: 'Roboto, sans-serif' }, title: translateConfig(widgetConfig['widget-label']), children: [translateConfig(widgetConfig['widget-label']), widgetConfig['widget-required'] && (jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" }))] }), jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-3", onBlur: onBlur, children: [allowUnset && (jsxRuntimeExports.jsx("button", { type: "button", onClick: () => handleChange(null), disabled: !isEnabled || widgetConfig['widget-readonly'], className: `px-3 py-1 text-sm border ${currentValue === null
|
|
7571
7642
|
? 'bg-blue-600 text-white border-blue-600'
|
|
7572
|
-
: 'bg-white text-gray-700 border-gray-300'} ${!isEnabled || widgetConfig['widget-readonly'] ? 'opacity-50 cursor-not-allowed' : 'hover:bg-gray-50'}`, style: { borderRadius: '15px' }, children:
|
|
7643
|
+
: 'bg-white text-gray-700 border-gray-300'} ${!isEnabled || widgetConfig['widget-readonly'] ? 'opacity-50 cursor-not-allowed' : 'hover:bg-gray-50'}`, style: { borderRadius: '15px' }, children: unsetLabel })), jsxRuntimeExports.jsx("button", { type: "button", onClick: () => handleChange(true), disabled: !isEnabled || widgetConfig['widget-readonly'], className: `px-3 py-1 text-sm border ${currentValue === true
|
|
7573
7644
|
? 'bg-blue-600 text-white border-blue-600'
|
|
7574
7645
|
: 'bg-white text-gray-700 border-gray-300'} ${!isEnabled || widgetConfig['widget-readonly'] ? 'opacity-50 cursor-not-allowed' : 'hover:bg-gray-50'}`, style: { borderRadius: '15px' }, children: trueLabel }), jsxRuntimeExports.jsx("button", { type: "button", onClick: () => handleChange(false), disabled: !isEnabled || widgetConfig['widget-readonly'], className: `px-3 py-1 text-sm border ${currentValue === false
|
|
7575
7646
|
? 'bg-blue-600 text-white border-blue-600'
|
|
@@ -8280,7 +8351,7 @@ const CheckboxWidget = ({ config }) => {
|
|
|
8280
8351
|
const displayValue = isChecked ? 'Yes' : 'No';
|
|
8281
8352
|
return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] CheckboxDisplayWidget flex flex-col sm:flex-row sm:items-start", children: [label && (jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] })), jsxRuntimeExports.jsx("div", { className: "flex-1", children: jsxRuntimeExports.jsx("div", { className: "text-base text-gray-900 font-medium", title: String(displayValue ?? ''), children: displayValue }) })] }));
|
|
8282
8353
|
}
|
|
8283
|
-
return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-
|
|
8354
|
+
return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-baseline", children: [jsxRuntimeExports.jsxs("label", { className: "text-base font-medium leading-normal text-gray-700 md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0 sm:pt-0.5", style: { fontFamily: 'Roboto, sans-serif' }, title: translateConfig(widgetConfig['widget-label']), children: [translateConfig(widgetConfig['widget-label']), widgetConfig['widget-required'] && (jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" }))] }), jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntimeExports.jsxs("label", { className: "inline-flex cursor-pointer items-baseline gap-2", children: [jsxRuntimeExports.jsx("input", { type: "checkbox", checked: isChecked, onChange: (e) => onChange(e.target.checked), onBlur: onBlur, disabled: !isEnabled || widgetConfig['widget-readonly'], className: "relative top-[0.2em] h-4 w-4 shrink-0 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" }), jsxRuntimeExports.jsx("span", { className: "text-base leading-normal text-gray-700", children: isChecked ? 'Yes' : 'No' })] }), touched && error.length > 0 && (jsxRuntimeExports.jsx("p", { className: "text-red-500 text-sm mt-1", children: error[0] }))] })] }) }));
|
|
8284
8355
|
}
|
|
8285
8356
|
// Multiple checkboxes (with data source) - for array values
|
|
8286
8357
|
// Process and sort options if needed
|
|
@@ -8323,7 +8394,7 @@ const CheckboxWidget = ({ config }) => {
|
|
|
8323
8394
|
switch (layout) {
|
|
8324
8395
|
case 'horizontal':
|
|
8325
8396
|
return {
|
|
8326
|
-
className: 'flex flex-row flex-wrap gap-4',
|
|
8397
|
+
className: 'flex flex-row flex-wrap items-baseline gap-4',
|
|
8327
8398
|
style: undefined,
|
|
8328
8399
|
};
|
|
8329
8400
|
case 'grid':
|
|
@@ -8336,7 +8407,7 @@ const CheckboxWidget = ({ config }) => {
|
|
|
8336
8407
|
case 'vertical':
|
|
8337
8408
|
default:
|
|
8338
8409
|
return {
|
|
8339
|
-
className: 'flex flex-col
|
|
8410
|
+
className: 'flex flex-col gap-2',
|
|
8340
8411
|
style: undefined,
|
|
8341
8412
|
};
|
|
8342
8413
|
}
|
|
@@ -8350,7 +8421,7 @@ const CheckboxWidget = ({ config }) => {
|
|
|
8350
8421
|
: '-';
|
|
8351
8422
|
return (jsxRuntimeExports.jsxs("div", { className: "mb-3 CheckboxDisplayWidget flex flex-col sm:flex-row sm:items-start", children: [label && (jsxRuntimeExports.jsxs("div", { className: "text-sm text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", title: label, children: [label, ":"] })), jsxRuntimeExports.jsx("div", { className: "flex-1", children: jsxRuntimeExports.jsx("div", { className: "text-base text-gray-900 font-medium", title: String(displayValue ?? ''), children: displayValue }) })] }));
|
|
8352
8423
|
}
|
|
8353
|
-
return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-
|
|
8424
|
+
return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-baseline", children: [jsxRuntimeExports.jsxs("label", { className: "text-base font-medium leading-normal text-gray-700 md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0 sm:pt-0.5", style: { fontFamily: 'Roboto, sans-serif' }, title: translateConfig(widgetConfig['widget-label']), children: [translateConfig(widgetConfig['widget-label']), widgetConfig['widget-required'] && (jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" }))] }), jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntimeExports.jsx("div", { className: layoutConfig.className, style: layoutConfig.style, onBlur: onBlur, children: loading ? (jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500", children: translate('common.loading') })) : (processedOptions.map((option) => (jsxRuntimeExports.jsxs("label", { className: `inline-flex cursor-pointer items-baseline gap-2 ${!isEnabled || widgetConfig['widget-readonly'] ? 'opacity-50 cursor-not-allowed' : ''}`, children: [jsxRuntimeExports.jsx("input", { type: "checkbox", value: option.value, checked: selectedValues.includes(option.value), onChange: (e) => handleCheckboxChange(option.value, e.target.checked), disabled: !isEnabled || widgetConfig['widget-readonly'], className: "relative top-[0.2em] h-4 w-4 shrink-0 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" }), jsxRuntimeExports.jsx("span", { className: "text-base leading-normal text-gray-700", children: translateConfig(option.label) })] }, option.value)))) }), touched && error.length > 0 && (jsxRuntimeExports.jsx("p", { className: "text-red-500 text-sm mt-1", children: error[0] }))] })] }) }));
|
|
8354
8425
|
};
|
|
8355
8426
|
|
|
8356
8427
|
const SimpleTableWidget = ({ config }) => {
|
|
@@ -9389,6 +9460,27 @@ const DialogTableWidget = ({ config }) => {
|
|
|
9389
9460
|
}, [formData, columns, storeValues, dialogFieldWidgetId]);
|
|
9390
9461
|
const saveDialog = React.useCallback(() => {
|
|
9391
9462
|
const payload = collectMergedRowPayload();
|
|
9463
|
+
let hasErrors = false;
|
|
9464
|
+
columns.forEach((col) => {
|
|
9465
|
+
const key = col['column-key'];
|
|
9466
|
+
const cellWidgetId = dialogFieldWidgetId(key);
|
|
9467
|
+
const isColReadonly = isReadonly || col['widget-readonly'] === true;
|
|
9468
|
+
if (isColReadonly)
|
|
9469
|
+
return;
|
|
9470
|
+
const cellValue = payload[key];
|
|
9471
|
+
const validationErrors = validateWidget(cellValue, col['widget-data-validation'], col['widget-required']);
|
|
9472
|
+
if (validationErrors && validationErrors.length > 0) {
|
|
9473
|
+
hasErrors = true;
|
|
9474
|
+
dispatch(setError({ widgetId: cellWidgetId, errors: validationErrors }));
|
|
9475
|
+
dispatch(setTouched({ widgetId: cellWidgetId, touched: true }));
|
|
9476
|
+
}
|
|
9477
|
+
else {
|
|
9478
|
+
dispatch(setError({ widgetId: cellWidgetId, errors: [] }));
|
|
9479
|
+
}
|
|
9480
|
+
});
|
|
9481
|
+
if (hasErrors) {
|
|
9482
|
+
return;
|
|
9483
|
+
}
|
|
9392
9484
|
if (dialogMode === 'add') {
|
|
9393
9485
|
const savedRow = { ...payload, edit_action: 'ADD' };
|
|
9394
9486
|
onChange([...rows, savedRow]);
|
|
@@ -9404,7 +9496,7 @@ const DialogTableWidget = ({ config }) => {
|
|
|
9404
9496
|
onChange(newRows);
|
|
9405
9497
|
closeDialog();
|
|
9406
9498
|
}
|
|
9407
|
-
}, [collectMergedRowPayload, dialogMode, onChange, rows, closeDialog, activeRowIndex]);
|
|
9499
|
+
}, [collectMergedRowPayload, dialogMode, onChange, rows, closeDialog, activeRowIndex, columns, dialogFieldWidgetId, isReadonly, dispatch]);
|
|
9408
9500
|
const deleteRow = React.useCallback((rowIndex) => {
|
|
9409
9501
|
const newRows = rows.filter((_, i) => i !== rowIndex);
|
|
9410
9502
|
onChange(newRows);
|
|
@@ -9755,10 +9847,13 @@ const TextAreaWidget = ({ config }) => {
|
|
|
9755
9847
|
// For readonly mode, render as preformatted text using <pre> tag
|
|
9756
9848
|
if (isReadonly) {
|
|
9757
9849
|
const displayValue = getStringValue() || '-';
|
|
9758
|
-
return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] TextAreaDisplayWidget flex flex-col sm:flex-row sm:items-start", children: [label && (jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] })), jsxRuntimeExports.jsx("div", { className: "flex-1", children: jsxRuntimeExports.jsx("
|
|
9850
|
+
return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] TextAreaDisplayWidget flex flex-col sm:flex-row sm:items-start", children: [label && (jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] })), jsxRuntimeExports.jsx("div", { className: "flex-1", children: jsxRuntimeExports.jsx("div", { title: String(displayValue), className: "text-base text-gray-900 font-medium overflow-y-auto whitespace-pre-wrap break-words", style: {
|
|
9759
9851
|
fontFamily: 'Roboto, sans-serif',
|
|
9760
|
-
|
|
9761
|
-
|
|
9852
|
+
height: '56px',
|
|
9853
|
+
minHeight: '56px',
|
|
9854
|
+
maxHeight: '56px',
|
|
9855
|
+
lineHeight: '20px',
|
|
9856
|
+
padding: '8px 0',
|
|
9762
9857
|
backgroundColor: 'transparent',
|
|
9763
9858
|
border: 'none',
|
|
9764
9859
|
}, children: displayValue }) })] }));
|
|
@@ -10227,20 +10322,29 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
10227
10322
|
.${cls} .hdr-field-row {
|
|
10228
10323
|
display: flex;
|
|
10229
10324
|
align-items: flex-start;
|
|
10230
|
-
gap: 0.5rem;
|
|
10231
10325
|
font-size: 1rem;
|
|
10232
10326
|
line-height: 1.6;
|
|
10233
10327
|
}
|
|
10234
10328
|
|
|
10235
10329
|
.${cls} .hdr-field-label {
|
|
10330
|
+
width: 50%;
|
|
10331
|
+
flex: 0 0 50%;
|
|
10236
10332
|
color: rgba(0, 0, 0, 0.5);
|
|
10237
10333
|
font-weight: 400;
|
|
10238
10334
|
white-space: nowrap;
|
|
10335
|
+
overflow: hidden;
|
|
10336
|
+
text-overflow: ellipsis;
|
|
10337
|
+
padding-right: 4px;
|
|
10239
10338
|
}
|
|
10240
10339
|
|
|
10241
10340
|
.${cls} .hdr-field-value {
|
|
10341
|
+
width: 50%;
|
|
10342
|
+
flex: 0 0 50%;
|
|
10242
10343
|
color: var(--owt-color-text, #111827);
|
|
10243
10344
|
font-weight: 500;
|
|
10345
|
+
white-space: nowrap;
|
|
10346
|
+
overflow: hidden;
|
|
10347
|
+
text-overflow: ellipsis;
|
|
10244
10348
|
}
|
|
10245
10349
|
|
|
10246
10350
|
.${cls} .hdr-status-badge {
|
|
@@ -10250,24 +10354,38 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
10250
10354
|
font-size: 0.75rem;
|
|
10251
10355
|
font-weight: 600;
|
|
10252
10356
|
color: #fff;
|
|
10357
|
+
max-width: 100%;
|
|
10358
|
+
overflow: hidden;
|
|
10359
|
+
text-overflow: ellipsis;
|
|
10360
|
+
white-space: nowrap;
|
|
10253
10361
|
}
|
|
10254
10362
|
|
|
10255
10363
|
.${cls} .hdr-meta-row {
|
|
10256
10364
|
display: flex;
|
|
10257
10365
|
align-items: baseline;
|
|
10258
|
-
gap: 0.35rem;
|
|
10259
10366
|
font-size: 1rem;
|
|
10260
10367
|
line-height: 1.6;
|
|
10261
10368
|
}
|
|
10262
10369
|
|
|
10263
10370
|
.${cls} .hdr-meta-label {
|
|
10371
|
+
width: 50%;
|
|
10372
|
+
flex: 0 0 50%;
|
|
10264
10373
|
color: rgba(0, 0, 0, 0.5);
|
|
10265
10374
|
font-weight: 400;
|
|
10375
|
+
white-space: nowrap;
|
|
10376
|
+
overflow: hidden;
|
|
10377
|
+
text-overflow: ellipsis;
|
|
10378
|
+
padding-right: 4px;
|
|
10266
10379
|
}
|
|
10267
10380
|
|
|
10268
10381
|
.${cls} .hdr-meta-value {
|
|
10382
|
+
width: 50%;
|
|
10383
|
+
flex: 0 0 50%;
|
|
10269
10384
|
color: var(--owt-color-text, #111827);
|
|
10270
10385
|
font-weight: 500;
|
|
10386
|
+
white-space: nowrap;
|
|
10387
|
+
overflow: hidden;
|
|
10388
|
+
text-overflow: ellipsis;
|
|
10271
10389
|
}
|
|
10272
10390
|
|
|
10273
10391
|
.${cls} .hdr-select {
|
|
@@ -10331,7 +10449,7 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
10331
10449
|
.parentElement?.querySelector('.hdr-avatar-placeholder');
|
|
10332
10450
|
if (placeholder)
|
|
10333
10451
|
placeholder.style.display = 'flex';
|
|
10334
|
-
} })) : null, jsxRuntimeExports.jsx("div", { className: "hdr-avatar-placeholder", style: { display: displayImageUrl ? 'none' : 'flex' }, children: jsxRuntimeExports.jsx("img", { src: img$f, alt: "Profile Placeholder" }) }), !isReadonly && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { className: "hdr-avatar-overlay", children: [jsxRuntimeExports.jsxs("button", { type: "button", className: "hdr-avatar-action", onClick: () => fileInputRef.current?.click(), children: [jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), jsxRuntimeExports.jsx("polyline", { points: "17 8 12 3 7 8" }), jsxRuntimeExports.jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })] }), "Upload"] }), jsxRuntimeExports.jsxs("button", { type: "button", className: "hdr-avatar-action hdr-avatar-action--delete", onClick: handleImageDelete, children: [jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("polyline", { points: "3 6 5 6 21 6" }), jsxRuntimeExports.jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })] }), "Delete"] })] }), jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", style: { display: 'none' }, onChange: handleImageUpload })] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-info", children: [displayName && jsxRuntimeExports.jsx("div", { className: "hdr-name", children: displayName }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", children: [getLabel('functionalId'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: functionalId || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsx("span", { className: "hdr-field-label", children: getLabel('status') }), isReadonly ? (statusLabel ? (jsxRuntimeExports.jsx("span", { className: "hdr-status-badge", style: { backgroundColor: statusColor }, children: statusLabel })) : (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: "-" }))) : (jsxRuntimeExports.jsxs("select", { className: "hdr-select", value: statusValue, onChange: (e) => updateFieldValue('status', e.target.value), children: [jsxRuntimeExports.jsx("option", { value: "", children: getLabel('select') }), statusOptions.map((opt) => (jsxRuntimeExports.jsx("option", { value: opt.value, children: opt.label }, opt.value)))] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", children: [getLabel('statusReason'), " :"] }), isReadonly ? (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", children: statusReason || '-' })) : (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 4 }, children: [jsxRuntimeExports.jsx("input", { type: "text", className: `hdr-input ${(!isReadonly && (showReasonRequired || isReasonMissing) && isReasonMissing) ? 'hdr-input--error' : ''}`, value: statusReason, placeholder: getLabel('enterReason'), required: isStatusChanged, "aria-required": isStatusChanged, "aria-invalid": !isReadonly && (showReasonRequired || isReasonMissing) && isReasonMissing, onBlur: () => {
|
|
10452
|
+
} })) : null, jsxRuntimeExports.jsx("div", { className: "hdr-avatar-placeholder", style: { display: displayImageUrl ? 'none' : 'flex' }, children: jsxRuntimeExports.jsx("img", { src: img$f, alt: "Profile Placeholder" }) }), !isReadonly && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { className: "hdr-avatar-overlay", children: [jsxRuntimeExports.jsxs("button", { type: "button", className: "hdr-avatar-action", onClick: () => fileInputRef.current?.click(), children: [jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), jsxRuntimeExports.jsx("polyline", { points: "17 8 12 3 7 8" }), jsxRuntimeExports.jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })] }), "Upload"] }), jsxRuntimeExports.jsxs("button", { type: "button", className: "hdr-avatar-action hdr-avatar-action--delete", onClick: handleImageDelete, children: [jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("polyline", { points: "3 6 5 6 21 6" }), jsxRuntimeExports.jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })] }), "Delete"] })] }), jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", style: { display: 'none' }, onChange: handleImageUpload })] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-info", children: [displayName && jsxRuntimeExports.jsx("div", { className: "hdr-name", children: displayName }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", title: `${getLabel('functionalId')} :`, children: [getLabel('functionalId'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-field-value", title: functionalId || '-', children: functionalId || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsx("span", { className: "hdr-field-label", title: getLabel('status'), children: getLabel('status') }), isReadonly ? (statusLabel ? (jsxRuntimeExports.jsx("span", { className: "hdr-status-badge", style: { backgroundColor: statusColor }, title: statusLabel, children: statusLabel })) : (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", title: "-", children: "-" }))) : (jsxRuntimeExports.jsxs("select", { className: "hdr-select", value: statusValue, onChange: (e) => updateFieldValue('status', e.target.value), children: [jsxRuntimeExports.jsx("option", { value: "", children: getLabel('select') }), statusOptions.map((opt) => (jsxRuntimeExports.jsx("option", { value: opt.value, children: opt.label }, opt.value)))] }))] }), jsxRuntimeExports.jsxs("div", { className: "hdr-field-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-field-label", title: `${getLabel('statusReason')} :`, children: [getLabel('statusReason'), " :"] }), isReadonly ? (jsxRuntimeExports.jsx("span", { className: "hdr-field-value", title: statusReason || '-', children: statusReason || '-' })) : (jsxRuntimeExports.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 4 }, children: [jsxRuntimeExports.jsx("input", { type: "text", className: `hdr-input ${(!isReadonly && (showReasonRequired || isReasonMissing) && isReasonMissing) ? 'hdr-input--error' : ''}`, value: statusReason, placeholder: getLabel('enterReason'), required: isStatusChanged, "aria-required": isStatusChanged, "aria-invalid": !isReadonly && (showReasonRequired || isReasonMissing) && isReasonMissing, onBlur: () => {
|
|
10335
10453
|
if (isReasonMissing)
|
|
10336
10454
|
setShowReasonRequired(true);
|
|
10337
10455
|
}, onChange: (e) => {
|
|
@@ -10339,7 +10457,7 @@ const HeaderSectionWidget = ({ config }) => {
|
|
|
10339
10457
|
if (showReasonRequired && String(e.target.value || '').trim().length > 0) {
|
|
10340
10458
|
setShowReasonRequired(false);
|
|
10341
10459
|
}
|
|
10342
|
-
} }), !isReadonly && (showReasonRequired || isReasonMissing) && isReasonMissing ? (jsxRuntimeExports.jsx("div", { className: "hdr-error-text", children: getLabel('enterReason') })) : null] }))] })] })] }), jsxRuntimeExports.jsx("div", { className: "hdr-right", children: jsxRuntimeExports.jsxs("div", { className: "hdr-right-top", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-meta-col", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('createdBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: createdBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('createdAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: createdAt || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('lastApprovedBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: lastApprovedBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", children: [getLabel('lastApprovedAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", children: lastApprovedAt || '-' })] })] }), score ? (jsxRuntimeExports.jsx("div", { className: "hdr-score-ring", style: { ['--pct']: score.percent }, "aria-label": `Completion score ${score.completionDisplay} of ${score.idealDisplay} (${score.percent}%)`, title: `${score.completionDisplay} / ${score.idealDisplay} (${score.percent}%)`, children: jsxRuntimeExports.jsx("div", { className: "hdr-score-value", children: String(score.completionDisplay) }) })) : null] }) })] })] }));
|
|
10460
|
+
} }), !isReadonly && (showReasonRequired || isReasonMissing) && isReasonMissing ? (jsxRuntimeExports.jsx("div", { className: "hdr-error-text", children: getLabel('enterReason') })) : null] }))] })] })] }), jsxRuntimeExports.jsx("div", { className: "hdr-right", children: jsxRuntimeExports.jsxs("div", { className: "hdr-right-top", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-meta-col", children: [jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", title: `${getLabel('createdBy')} :`, children: [getLabel('createdBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", title: createdBy || '-', children: createdBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", title: `${getLabel('createdAt')} :`, children: [getLabel('createdAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", title: createdAt || '-', children: createdAt || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", title: `${getLabel('lastApprovedBy')} :`, children: [getLabel('lastApprovedBy'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", title: lastApprovedBy || '-', children: lastApprovedBy || '-' })] }), jsxRuntimeExports.jsxs("div", { className: "hdr-meta-row", children: [jsxRuntimeExports.jsxs("span", { className: "hdr-meta-label", title: `${getLabel('lastApprovedAt')} :`, children: [getLabel('lastApprovedAt'), " :"] }), jsxRuntimeExports.jsx("span", { className: "hdr-meta-value", title: lastApprovedAt || '-', children: lastApprovedAt || '-' })] })] }), score ? (jsxRuntimeExports.jsx("div", { className: "hdr-score-ring", style: { ['--pct']: score.percent }, "aria-label": `Completion score ${score.completionDisplay} of ${score.idealDisplay} (${score.percent}%)`, title: `${score.completionDisplay} / ${score.idealDisplay} (${score.percent}%)`, children: jsxRuntimeExports.jsx("div", { className: "hdr-score-value", children: String(score.completionDisplay) }) })) : null] }) })] })] }));
|
|
10343
10461
|
};
|
|
10344
10462
|
|
|
10345
10463
|
function getValueByPathOrKey(obj, path) {
|