@openg2p/registry-widgets 1.1.2-dev.9 → 1.1.3-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/SectionBuilder/schemas.d.ts +16 -0
- package/dist/components/SectionBuilder/schemas.d.ts.map +1 -1
- package/dist/hooks/useBaseWidget.d.ts.map +1 -1
- package/dist/index.d.ts +0 -13
- package/dist/index.esm.js +214 -112
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +213 -111
- package/dist/index.js.map +1 -1
- package/dist/utils/conditions.d.ts.map +1 -1
- package/dist/widgets/DialogTableWidget.d.ts +0 -13
- package/dist/widgets/DialogTableWidget.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -406,9 +406,8 @@ const createZodSchema = (validation, required = false) => {
|
|
|
406
406
|
const normalizeBooleanLike = (val) => {
|
|
407
407
|
if (val === true || val === 1)
|
|
408
408
|
return true;
|
|
409
|
-
if (val === false || val === 0
|
|
409
|
+
if (val === false || val === 0)
|
|
410
410
|
return false;
|
|
411
|
-
}
|
|
412
411
|
if (typeof val === 'string') {
|
|
413
412
|
const normalized = val.trim().toLowerCase();
|
|
414
413
|
return normalized === 'true' || normalized === 'yes' || normalized === '1';
|
|
@@ -423,8 +422,11 @@ const evaluateCondition = (condition, allValues) => {
|
|
|
423
422
|
const { operator, value } = condition;
|
|
424
423
|
switch (operator) {
|
|
425
424
|
case 'equals':
|
|
426
|
-
if (typeof value === 'boolean'
|
|
427
|
-
return
|
|
425
|
+
if (typeof value === 'boolean') {
|
|
426
|
+
return typeof fieldValue === 'boolean' && fieldValue === value;
|
|
427
|
+
}
|
|
428
|
+
if (typeof fieldValue === 'boolean') {
|
|
429
|
+
return fieldValue === normalizeBooleanLike(value);
|
|
428
430
|
}
|
|
429
431
|
return fieldValue === value;
|
|
430
432
|
case 'notEquals':
|
|
@@ -2814,6 +2816,8 @@ const useBaseWidget = (options) => {
|
|
|
2814
2816
|
const apiService = dataSource?.type === 'api' ? dataSource.service : '';
|
|
2815
2817
|
const apiEndpoint = dataSource?.type === 'api' ? dataSource.endpoint : '';
|
|
2816
2818
|
const configKey = `${widgetId}-${isReadonly}-${dataSource?.type || 'none'}-${apiService}-${apiEndpoint}`;
|
|
2819
|
+
// Stable key so inline schemaData objects (e.g. dialog-table fields) don't retrigger loads every render
|
|
2820
|
+
const schemaDataKey = React.useMemo(() => (schemaData ? JSON.stringify(schemaData) : ''), [schemaData]);
|
|
2817
2821
|
// Extract dependency value using a granular selector to prevent unnecessary re-renders
|
|
2818
2822
|
// and infinite loops when other unrelated values in the state change.
|
|
2819
2823
|
const dependencyValue = reactRedux.useSelector((state) => {
|
|
@@ -2931,7 +2935,7 @@ const useBaseWidget = (options) => {
|
|
|
2931
2935
|
loadDataSource();
|
|
2932
2936
|
// Use configKey and dependencyValue to ensure effect runs only when relevant state changes
|
|
2933
2937
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2934
|
-
}, [configKey, dependencyValue, dataSourceRequestHandler,
|
|
2938
|
+
}, [configKey, dependencyValue, dataSourceRequestHandler, schemaDataKey, widgetId, dispatch]);
|
|
2935
2939
|
const geoDisplayLabel = React.useMemo(() => {
|
|
2936
2940
|
if (!geoConfig) {
|
|
2937
2941
|
return undefined;
|
|
@@ -10087,6 +10091,56 @@ const TableWidget = ({ config }) => {
|
|
|
10087
10091
|
};
|
|
10088
10092
|
|
|
10089
10093
|
const isUnsetRowValue = (value) => value === null || value === undefined || value === '';
|
|
10094
|
+
const buildDialogConditionValues = (row, columns) => {
|
|
10095
|
+
let context = { ...row };
|
|
10096
|
+
columns.forEach((col) => {
|
|
10097
|
+
const columnKey = col['column-key'];
|
|
10098
|
+
if (!columnKey || row[columnKey] === undefined) {
|
|
10099
|
+
return;
|
|
10100
|
+
}
|
|
10101
|
+
const dataPath = col['widget-data-path'];
|
|
10102
|
+
if (typeof dataPath === 'string' && dataPath) {
|
|
10103
|
+
context = setValueByPath(context, dataPath, row[columnKey]);
|
|
10104
|
+
}
|
|
10105
|
+
});
|
|
10106
|
+
return context;
|
|
10107
|
+
};
|
|
10108
|
+
const buildDialogColumnSegments = (columns) => {
|
|
10109
|
+
const segments = [];
|
|
10110
|
+
let index = 0;
|
|
10111
|
+
while (index < columns.length) {
|
|
10112
|
+
const group = columns[index]['column-group'];
|
|
10113
|
+
if (group) {
|
|
10114
|
+
const groupCols = [];
|
|
10115
|
+
while (index < columns.length && columns[index]['column-group'] === group) {
|
|
10116
|
+
groupCols.push(columns[index]);
|
|
10117
|
+
index += 1;
|
|
10118
|
+
}
|
|
10119
|
+
segments.push({ type: 'group', group, cols: groupCols });
|
|
10120
|
+
}
|
|
10121
|
+
else {
|
|
10122
|
+
segments.push({ type: 'single', col: columns[index] });
|
|
10123
|
+
index += 1;
|
|
10124
|
+
}
|
|
10125
|
+
}
|
|
10126
|
+
return segments;
|
|
10127
|
+
};
|
|
10128
|
+
/** Match TableWidget cell styling for add / update / delete rows */
|
|
10129
|
+
const getRowCellStyle = (editAction) => {
|
|
10130
|
+
if (editAction === 'ADD') {
|
|
10131
|
+
return { color: 'var(--owt-color-success, #16A34A)' };
|
|
10132
|
+
}
|
|
10133
|
+
if (editAction === 'DELETE') {
|
|
10134
|
+
return {
|
|
10135
|
+
color: 'var(--owt-color-error, #B91C1C)',
|
|
10136
|
+
textDecoration: 'line-through',
|
|
10137
|
+
};
|
|
10138
|
+
}
|
|
10139
|
+
if (editAction === 'UPDATE') {
|
|
10140
|
+
return { color: 'var(--owt-color-warning, #F59E0B)' };
|
|
10141
|
+
}
|
|
10142
|
+
return {};
|
|
10143
|
+
};
|
|
10090
10144
|
// Display select value label in view mode
|
|
10091
10145
|
const SelectDisplayValue = ({ config, value }) => {
|
|
10092
10146
|
const { dataSourceOptions, loading } = useBaseWidget({ config });
|
|
@@ -10097,23 +10151,29 @@ const SelectDisplayValue = ({ config, value }) => {
|
|
|
10097
10151
|
const selectedOption = dataSourceOptions.find((option) => option.value === value || String(option.value) === String(value));
|
|
10098
10152
|
return jsxRuntimeExports.jsx("span", { children: selectedOption ? selectedOption.label : String(value) });
|
|
10099
10153
|
};
|
|
10154
|
+
/** Isolated dialog field — avoids re-running data-source effects when sibling fields update. */
|
|
10155
|
+
const DialogTableField = React.memo(function DialogTableField({ col, cellWidgetId, dialogConditionValues, isReadonly, }) {
|
|
10156
|
+
const widgetType = col.widget || 'text';
|
|
10157
|
+
const fieldConfig = React.useMemo(() => {
|
|
10158
|
+
return {
|
|
10159
|
+
...col,
|
|
10160
|
+
widget: widgetType,
|
|
10161
|
+
'widget-type': col['widget-type'] || 'input',
|
|
10162
|
+
'widget-id': cellWidgetId,
|
|
10163
|
+
'widget-label': col['widget-label'],
|
|
10164
|
+
'widget-readonly': isReadonly || col['widget-readonly'] === true,
|
|
10165
|
+
'widget-data-path': undefined,
|
|
10166
|
+
'widget-data-default': col['widget-data-default'],
|
|
10167
|
+
'widget-data-options': undefined,
|
|
10168
|
+
'widget-required': shouldRequireWidget(col['widget-data-options'], dialogConditionValues, col['widget-required']),
|
|
10169
|
+
};
|
|
10170
|
+
}, [col, cellWidgetId, dialogConditionValues, isReadonly, widgetType]);
|
|
10171
|
+
return (jsxRuntimeExports.jsx("div", { className: "min-w-0", children: jsxRuntimeExports.jsx(WidgetRenderer, { config: fieldConfig }) }));
|
|
10172
|
+
});
|
|
10100
10173
|
/**
|
|
10101
10174
|
* Dialog table widget:
|
|
10102
10175
|
* - Table displays a subset of columns (n out of x)
|
|
10103
10176
|
* - Add/Edit happens in a modal dialog that shows ALL columns as a form
|
|
10104
|
-
*
|
|
10105
|
-
* Usage in schema:
|
|
10106
|
-
* {
|
|
10107
|
-
* "widget": "dialog-table",
|
|
10108
|
-
* "widget-type": "table",
|
|
10109
|
-
* "widget-label": "Household Members",
|
|
10110
|
-
* "widget-id": "householdMembers",
|
|
10111
|
-
* "widget-data-path": "household.members",
|
|
10112
|
-
* "widget-data-columns": [ ...all columns... ],
|
|
10113
|
-
* "widget-data-visible-columns": ["firstName", "lastName", "dob"], // optional override; default = by column flag
|
|
10114
|
-
* // Per-column control (recommended): set "column-visible-in-table": false to hide it in the table
|
|
10115
|
-
* "widget-data-operations": { "add": true, "edit": true, "remove": true }
|
|
10116
|
-
* }
|
|
10117
10177
|
*/
|
|
10118
10178
|
const DialogTableWidget = ({ config }) => {
|
|
10119
10179
|
const { value, error, touched, isEnabled, onChange, config: widgetConfig } = useBaseWidget({ config });
|
|
@@ -10123,23 +10183,22 @@ const DialogTableWidget = ({ config }) => {
|
|
|
10123
10183
|
const columns = widgetConfig['widget-data-columns'] || [];
|
|
10124
10184
|
const operations = widgetConfig['widget-data-operations'] || {};
|
|
10125
10185
|
const isReadonly = widgetConfig['widget-readonly'] || false;
|
|
10186
|
+
// Soft-delete (keep row, red + strikethrough) whenever remove is allowed — matches TableWidget
|
|
10187
|
+
const shouldSoftDeleteOnRemove = !isReadonly && !!operations.remove;
|
|
10126
10188
|
const visibleColumnKeys = widgetConfig['widget-data-visible-columns'];
|
|
10127
10189
|
const visibleColumns = React.useMemo(() => {
|
|
10128
|
-
// 1) If explicit list provided, it wins
|
|
10129
10190
|
if (Array.isArray(visibleColumnKeys) && visibleColumnKeys.length > 0) {
|
|
10130
10191
|
const keySet = new Set(visibleColumnKeys);
|
|
10131
10192
|
return columns.filter((c) => keySet.has(c['column-key']));
|
|
10132
10193
|
}
|
|
10133
|
-
// 2) Otherwise decide per column (default = visible)
|
|
10134
10194
|
return columns.filter((c) => c['column-visible-in-table'] !== false);
|
|
10135
10195
|
}, [columns, visibleColumnKeys]);
|
|
10136
10196
|
const [dialogOpen, setDialogOpen] = React.useState(false);
|
|
10137
10197
|
const [dialogMode, setDialogMode] = React.useState('add');
|
|
10138
10198
|
const [activeRowIndex, setActiveRowIndex] = React.useState(null);
|
|
10139
|
-
const [formData, setFormData] = React.useState({});
|
|
10140
|
-
/** Unique per dialog open so Redux widget ids don't reuse stale values across rows/add sessions */
|
|
10141
10199
|
const dialogSessionRef = React.useRef(0);
|
|
10142
10200
|
const [dialogSessionId, setDialogSessionId] = React.useState(0);
|
|
10201
|
+
const membersWidgetId = widgetConfig['widget-id'];
|
|
10143
10202
|
const addDialogTitle = translateConfig(widgetConfig['widget-data-dialog-title-add']) ||
|
|
10144
10203
|
translate('table.addRecordDialog') ||
|
|
10145
10204
|
'Add record';
|
|
@@ -10159,15 +10218,26 @@ const DialogTableWidget = ({ config }) => {
|
|
|
10159
10218
|
});
|
|
10160
10219
|
return emptyRow;
|
|
10161
10220
|
}, [columns]);
|
|
10162
|
-
const dialogFieldWidgetId = React.useCallback((columnKey) => `${
|
|
10221
|
+
const dialogFieldWidgetId = React.useCallback((sessionId, columnKey) => `${membersWidgetId}-dlg-${sessionId}-${columnKey}`, [membersWidgetId]);
|
|
10163
10222
|
const resetDialogWidgets = React.useCallback((sessionId) => {
|
|
10164
10223
|
if (sessionId <= 0)
|
|
10165
10224
|
return;
|
|
10166
10225
|
columns.forEach((col) => {
|
|
10167
|
-
|
|
10168
|
-
dispatch(resetWidget(wid));
|
|
10226
|
+
dispatch(resetWidget(dialogFieldWidgetId(sessionId, col['column-key'])));
|
|
10169
10227
|
});
|
|
10170
|
-
}, [columns,
|
|
10228
|
+
}, [columns, dialogFieldWidgetId, dispatch]);
|
|
10229
|
+
const seedDialogReduxValues = React.useCallback((sessionId, rowData) => {
|
|
10230
|
+
const seeds = {};
|
|
10231
|
+
columns.forEach((col) => {
|
|
10232
|
+
const key = col['column-key'];
|
|
10233
|
+
if (rowData[key] !== undefined) {
|
|
10234
|
+
seeds[dialogFieldWidgetId(sessionId, key)] = rowData[key];
|
|
10235
|
+
}
|
|
10236
|
+
});
|
|
10237
|
+
if (Object.keys(seeds).length > 0) {
|
|
10238
|
+
dispatch(setValues(seeds));
|
|
10239
|
+
}
|
|
10240
|
+
}, [columns, dialogFieldWidgetId, dispatch]);
|
|
10171
10241
|
const beginDialogSession = React.useCallback(() => {
|
|
10172
10242
|
dialogSessionRef.current += 1;
|
|
10173
10243
|
const nextSession = dialogSessionRef.current;
|
|
@@ -10176,15 +10246,21 @@ const DialogTableWidget = ({ config }) => {
|
|
|
10176
10246
|
}, []);
|
|
10177
10247
|
const openAddDialog = React.useCallback(() => {
|
|
10178
10248
|
resetDialogWidgets(dialogSessionId);
|
|
10179
|
-
beginDialogSession();
|
|
10249
|
+
const sessionId = beginDialogSession();
|
|
10250
|
+
seedDialogReduxValues(sessionId, buildEmptyRow());
|
|
10180
10251
|
setDialogMode('add');
|
|
10181
10252
|
setActiveRowIndex(null);
|
|
10182
|
-
setFormData(buildEmptyRow());
|
|
10183
10253
|
setDialogOpen(true);
|
|
10184
|
-
}, [
|
|
10254
|
+
}, [
|
|
10255
|
+
buildEmptyRow,
|
|
10256
|
+
beginDialogSession,
|
|
10257
|
+
resetDialogWidgets,
|
|
10258
|
+
dialogSessionId,
|
|
10259
|
+
seedDialogReduxValues,
|
|
10260
|
+
]);
|
|
10185
10261
|
const openEditDialog = React.useCallback((rowIndex) => {
|
|
10186
10262
|
resetDialogWidgets(dialogSessionId);
|
|
10187
|
-
beginDialogSession();
|
|
10263
|
+
const sessionId = beginDialogSession();
|
|
10188
10264
|
const row = rows[rowIndex] || {};
|
|
10189
10265
|
const nextFormData = buildEmptyRow();
|
|
10190
10266
|
columns.forEach((col) => {
|
|
@@ -10192,23 +10268,26 @@ const DialogTableWidget = ({ config }) => {
|
|
|
10192
10268
|
if (row[key] !== undefined)
|
|
10193
10269
|
nextFormData[key] = row[key];
|
|
10194
10270
|
});
|
|
10271
|
+
seedDialogReduxValues(sessionId, nextFormData);
|
|
10195
10272
|
setDialogMode('edit');
|
|
10196
10273
|
setActiveRowIndex(rowIndex);
|
|
10197
|
-
setFormData(nextFormData);
|
|
10198
10274
|
setDialogOpen(true);
|
|
10199
|
-
}, [
|
|
10275
|
+
}, [
|
|
10276
|
+
rows,
|
|
10277
|
+
columns,
|
|
10278
|
+
buildEmptyRow,
|
|
10279
|
+
resetDialogWidgets,
|
|
10280
|
+
dialogSessionId,
|
|
10281
|
+
beginDialogSession,
|
|
10282
|
+
seedDialogReduxValues,
|
|
10283
|
+
]);
|
|
10200
10284
|
const closeDialog = React.useCallback(() => {
|
|
10201
10285
|
const sessionToClear = dialogSessionId;
|
|
10202
10286
|
setDialogOpen(false);
|
|
10203
10287
|
setActiveRowIndex(null);
|
|
10204
|
-
setFormData({});
|
|
10205
10288
|
resetDialogWidgets(sessionToClear);
|
|
10206
10289
|
setDialogSessionId(0);
|
|
10207
10290
|
}, [dialogSessionId, resetDialogWidgets]);
|
|
10208
|
-
const updateField = React.useCallback((columnKey, newValue) => {
|
|
10209
|
-
setFormData((prev) => ({ ...prev, [columnKey]: newValue }));
|
|
10210
|
-
}, []);
|
|
10211
|
-
const membersWidgetId = widgetConfig['widget-id'];
|
|
10212
10291
|
const dialogStoreValues = reactRedux.useSelector((state) => {
|
|
10213
10292
|
if (dialogSessionId <= 0) {
|
|
10214
10293
|
return {};
|
|
@@ -10217,30 +10296,22 @@ const DialogTableWidget = ({ config }) => {
|
|
|
10217
10296
|
const row = {};
|
|
10218
10297
|
columns.forEach((col) => {
|
|
10219
10298
|
const k = col['column-key'];
|
|
10220
|
-
const wid =
|
|
10299
|
+
const wid = dialogFieldWidgetId(dialogSessionId, k);
|
|
10221
10300
|
if (values[wid] !== undefined) {
|
|
10222
10301
|
row[k] = values[wid];
|
|
10223
10302
|
}
|
|
10224
10303
|
});
|
|
10225
10304
|
return row;
|
|
10226
|
-
}
|
|
10227
|
-
const
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
const k = col['column-key'];
|
|
10231
|
-
if (storeSlice[k] !== undefined) {
|
|
10232
|
-
row[k] = storeSlice[k];
|
|
10233
|
-
}
|
|
10234
|
-
});
|
|
10235
|
-
return row;
|
|
10236
|
-
}, [formData, columns]);
|
|
10237
|
-
const dialogRowValues = React.useMemo(() => buildDialogRowValues(dialogStoreValues), [buildDialogRowValues, dialogStoreValues]);
|
|
10238
|
-
const collectMergedRowPayload = React.useCallback(() => buildDialogRowValues(dialogStoreValues), [buildDialogRowValues, dialogStoreValues]);
|
|
10305
|
+
});
|
|
10306
|
+
const dialogRowValues = dialogStoreValues;
|
|
10307
|
+
const dialogConditionValues = React.useMemo(() => buildDialogConditionValues(dialogRowValues, columns), [dialogRowValues, columns]);
|
|
10308
|
+
const collectMergedRowPayload = React.useCallback(() => dialogStoreValues, [dialogStoreValues]);
|
|
10239
10309
|
const finalizeDialogRowPayload = React.useCallback((raw) => {
|
|
10310
|
+
const conditionValues = buildDialogConditionValues(raw, columns);
|
|
10240
10311
|
const result = {};
|
|
10241
10312
|
columns.forEach((col) => {
|
|
10242
10313
|
const key = col['column-key'];
|
|
10243
|
-
if (!shouldShowWidget(col['widget-data-options'],
|
|
10314
|
+
if (!shouldShowWidget(col['widget-data-options'], conditionValues)) {
|
|
10244
10315
|
return;
|
|
10245
10316
|
}
|
|
10246
10317
|
const val = raw[key];
|
|
@@ -10252,17 +10323,18 @@ const DialogTableWidget = ({ config }) => {
|
|
|
10252
10323
|
}, [columns]);
|
|
10253
10324
|
const saveDialog = React.useCallback(() => {
|
|
10254
10325
|
const payload = collectMergedRowPayload();
|
|
10326
|
+
const conditionValues = buildDialogConditionValues(payload, columns);
|
|
10255
10327
|
let hasErrors = false;
|
|
10256
10328
|
columns.forEach((col) => {
|
|
10257
10329
|
const key = col['column-key'];
|
|
10258
|
-
const cellWidgetId = dialogFieldWidgetId(key);
|
|
10330
|
+
const cellWidgetId = dialogFieldWidgetId(dialogSessionId, key);
|
|
10259
10331
|
const isColReadonly = isReadonly || col['widget-readonly'] === true;
|
|
10260
10332
|
if (isColReadonly)
|
|
10261
10333
|
return;
|
|
10262
|
-
if (!shouldShowWidget(col['widget-data-options'],
|
|
10334
|
+
if (!shouldShowWidget(col['widget-data-options'], conditionValues))
|
|
10263
10335
|
return;
|
|
10264
10336
|
const cellValue = payload[key];
|
|
10265
|
-
const isRequired = shouldRequireWidget(col['widget-data-options'],
|
|
10337
|
+
const isRequired = shouldRequireWidget(col['widget-data-options'], conditionValues, col['widget-required']);
|
|
10266
10338
|
const validationErrors = validateWidget(cellValue, col['widget-data-validation'], isRequired);
|
|
10267
10339
|
if (validationErrors && validationErrors.length > 0) {
|
|
10268
10340
|
hasErrors = true;
|
|
@@ -10299,11 +10371,32 @@ const DialogTableWidget = ({ config }) => {
|
|
|
10299
10371
|
onChange(newRows);
|
|
10300
10372
|
closeDialog();
|
|
10301
10373
|
}
|
|
10302
|
-
}, [
|
|
10374
|
+
}, [
|
|
10375
|
+
collectMergedRowPayload,
|
|
10376
|
+
finalizeDialogRowPayload,
|
|
10377
|
+
dialogMode,
|
|
10378
|
+
onChange,
|
|
10379
|
+
rows,
|
|
10380
|
+
closeDialog,
|
|
10381
|
+
activeRowIndex,
|
|
10382
|
+
columns,
|
|
10383
|
+
dialogSessionId,
|
|
10384
|
+
dialogFieldWidgetId,
|
|
10385
|
+
isReadonly,
|
|
10386
|
+
dispatch,
|
|
10387
|
+
]);
|
|
10303
10388
|
const deleteRow = React.useCallback((rowIndex) => {
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
|
|
10389
|
+
if (shouldSoftDeleteOnRemove) {
|
|
10390
|
+
const newRows = [...rows];
|
|
10391
|
+
newRows[rowIndex] = {
|
|
10392
|
+
...newRows[rowIndex],
|
|
10393
|
+
edit_action: 'DELETE',
|
|
10394
|
+
};
|
|
10395
|
+
onChange(newRows);
|
|
10396
|
+
return;
|
|
10397
|
+
}
|
|
10398
|
+
onChange(rows.filter((_, i) => i !== rowIndex));
|
|
10399
|
+
}, [rows, onChange, shouldSoftDeleteOnRemove]);
|
|
10307
10400
|
const getDisplayValue = React.useCallback((rowIndex, column) => {
|
|
10308
10401
|
const key = column['column-key'];
|
|
10309
10402
|
const cellValue = rows[rowIndex]?.[key];
|
|
@@ -10311,11 +10404,33 @@ const DialogTableWidget = ({ config }) => {
|
|
|
10311
10404
|
if (cellValue === null || cellValue === undefined || cellValue === '')
|
|
10312
10405
|
return '-';
|
|
10313
10406
|
if (widgetType === 'select')
|
|
10314
|
-
return null;
|
|
10407
|
+
return null;
|
|
10315
10408
|
if (column['widget-data-format'])
|
|
10316
10409
|
return formatValue(cellValue, column['widget-data-format'], column.widget);
|
|
10317
10410
|
return String(cellValue);
|
|
10318
10411
|
}, [rows]);
|
|
10412
|
+
const dialogColumnSegments = React.useMemo(() => {
|
|
10413
|
+
return buildDialogColumnSegments(columns)
|
|
10414
|
+
.map((segment) => {
|
|
10415
|
+
if (segment.type === 'single') {
|
|
10416
|
+
if (!shouldShowWidget(segment.col['widget-data-options'], dialogConditionValues)) {
|
|
10417
|
+
return null;
|
|
10418
|
+
}
|
|
10419
|
+
return segment;
|
|
10420
|
+
}
|
|
10421
|
+
const visibleCols = segment.cols.filter((col) => shouldShowWidget(col['widget-data-options'], dialogConditionValues));
|
|
10422
|
+
if (visibleCols.length === 0) {
|
|
10423
|
+
return null;
|
|
10424
|
+
}
|
|
10425
|
+
return { type: 'group', group: segment.group, cols: visibleCols };
|
|
10426
|
+
})
|
|
10427
|
+
.filter((segment) => segment !== null);
|
|
10428
|
+
}, [columns, dialogConditionValues]);
|
|
10429
|
+
const renderDialogField = (col) => {
|
|
10430
|
+
const key = col['column-key'];
|
|
10431
|
+
const cellWidgetId = dialogFieldWidgetId(dialogSessionId, key);
|
|
10432
|
+
return (jsxRuntimeExports.jsx(DialogTableField, { col: col, cellWidgetId: cellWidgetId, dialogConditionValues: dialogConditionValues, isReadonly: isReadonly }, `${dialogSessionId}-${key}`));
|
|
10433
|
+
};
|
|
10319
10434
|
const tableWidgetId = `dialog-table-widget-${widgetConfig['widget-id']}`;
|
|
10320
10435
|
const columnSpan = widgetConfig['widget-column-span'] || 2;
|
|
10321
10436
|
const minWidth = columnSpan * 200;
|
|
@@ -10343,37 +10458,40 @@ const DialogTableWidget = ({ config }) => {
|
|
|
10343
10458
|
}, children: translate('table.addRecord') || 'Add New Record' }) })), jsxRuntimeExports.jsx("div", { className: "overflow-x-auto border", style: {
|
|
10344
10459
|
borderRadius: 'var(--owt-widget-table-border-radius, 15px)',
|
|
10345
10460
|
borderColor: 'var(--owt-widget-table-border-color, #C4C4C4)',
|
|
10346
|
-
}, children: jsxRuntimeExports.jsxs("table", { className: "min-w-full", style: { borderCollapse: 'separate', borderSpacing: 0 }, children: [jsxRuntimeExports.jsx("thead", { style: { backgroundColor: 'var(--owt-widget-table-header-bg, #F6F6F6)' }, children: jsxRuntimeExports.jsxs("tr", { style: { borderBottom: '1px solid var(--owt-widget-table-row-divider, #E4E4E4)' }, children: [visibleColumns.map((col) => (jsxRuntimeExports.jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider", style: { color: 'var(--owt-widget-table-header-color, #727474)' }, children: translateConfig(col['widget-label']) }, col['column-key']))), ((operations.edit || operations.remove) && !isReadonly) && (jsxRuntimeExports.jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider", style: { color: 'var(--owt-widget-table-header-color, #727474)' }, children: translate('common.actions') || 'Actions' }))] }) }), jsxRuntimeExports.jsxs("tbody", { style: { backgroundColor: 'var(--owt-widget-table-body-bg, #FFFFFF)' }, children: [rows.length === 0 && (jsxRuntimeExports.jsx("tr", { children: jsxRuntimeExports.jsxs("td", { colSpan: visibleColumns.length + (((operations.edit || operations.remove) && !isReadonly) ? 1 : 0), className: "px-4 py-6 text-center text-sm", style: { color: 'var(--owt-widget-table-empty-color, #727474)' }, children: [translate('table.noData') || 'No records available.', operations.add && !isReadonly && ` ${translate('table.clickToAdd') || 'Click "Add New Record" to add one.'}`] }) })), rows.map((row, rowIndex) =>
|
|
10347
|
-
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
:
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
|
|
10356
|
-
const
|
|
10357
|
-
|
|
10358
|
-
|
|
10359
|
-
|
|
10360
|
-
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
10367
|
-
|
|
10368
|
-
|
|
10369
|
-
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
|
|
10373
|
-
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10461
|
+
}, children: jsxRuntimeExports.jsxs("table", { className: "min-w-full", style: { borderCollapse: 'separate', borderSpacing: 0 }, children: [jsxRuntimeExports.jsx("thead", { style: { backgroundColor: 'var(--owt-widget-table-header-bg, #F6F6F6)' }, children: jsxRuntimeExports.jsxs("tr", { style: { borderBottom: '1px solid var(--owt-widget-table-row-divider, #E4E4E4)' }, children: [visibleColumns.map((col) => (jsxRuntimeExports.jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider", style: { color: 'var(--owt-widget-table-header-color, #727474)' }, children: translateConfig(col['widget-label']) }, col['column-key']))), ((operations.edit || operations.remove) && !isReadonly) && (jsxRuntimeExports.jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider", style: { color: 'var(--owt-widget-table-header-color, #727474)' }, children: translate('common.actions') || 'Actions' }))] }) }), jsxRuntimeExports.jsxs("tbody", { style: { backgroundColor: 'var(--owt-widget-table-body-bg, #FFFFFF)' }, children: [rows.length === 0 && (jsxRuntimeExports.jsx("tr", { children: jsxRuntimeExports.jsxs("td", { colSpan: visibleColumns.length + (((operations.edit || operations.remove) && !isReadonly) ? 1 : 0), className: "px-4 py-6 text-center text-sm", style: { color: 'var(--owt-widget-table-empty-color, #727474)' }, children: [translate('table.noData') || 'No records available.', operations.add && !isReadonly && ` ${translate('table.clickToAdd') || 'Click "Add New Record" to add one.'}`] }) })), rows.map((row, rowIndex) => {
|
|
10462
|
+
const cellStyle = getRowCellStyle(row?.edit_action);
|
|
10463
|
+
return (jsxRuntimeExports.jsxs("tr", { style: {
|
|
10464
|
+
borderBottom: '1px solid var(--owt-widget-table-row-divider, #E4E4E4)',
|
|
10465
|
+
backgroundColor: row?.edit_action === 'DELETE'
|
|
10466
|
+
? 'var(--owt-widget-table-deleted-row-bg, #FEE2E2)'
|
|
10467
|
+
: undefined,
|
|
10468
|
+
}, children: [visibleColumns.map((col) => {
|
|
10469
|
+
const key = col['column-key'];
|
|
10470
|
+
const widgetType = col.widget || 'text';
|
|
10471
|
+
const displayValue = getDisplayValue(rowIndex, col);
|
|
10472
|
+
if (widgetType === 'select' && displayValue === null) {
|
|
10473
|
+
const displayConfig = {
|
|
10474
|
+
...col,
|
|
10475
|
+
'widget-id': `${widgetConfig['widget-id']}-view-row-${rowIndex}-col-${key}`,
|
|
10476
|
+
'widget-label': '',
|
|
10477
|
+
'widget-readonly': true,
|
|
10478
|
+
'widget-data-path': undefined,
|
|
10479
|
+
};
|
|
10480
|
+
return (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: jsxRuntimeExports.jsx("div", { className: "text-sm", style: cellStyle, children: jsxRuntimeExports.jsx(SelectDisplayValue, { config: displayConfig, value: row?.[key] }) }) }, key));
|
|
10481
|
+
}
|
|
10482
|
+
return (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: jsxRuntimeExports.jsx("div", { className: "text-sm", style: cellStyle, children: displayValue }) }, key));
|
|
10483
|
+
}), ((operations.edit || operations.remove) && !isReadonly) && (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", style: { minWidth: '120px' }, children: jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [operations.edit && (jsxRuntimeExports.jsx("button", { type: "button", onClick: () => openEditDialog(rowIndex), disabled: !isEnabled, className: "px-3 py-1 text-xs disabled:opacity-50 disabled:cursor-not-allowed", style: {
|
|
10484
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
10485
|
+
color: 'var(--owt-color-primary-dark, #F07B1A)',
|
|
10486
|
+
backgroundColor: 'transparent',
|
|
10487
|
+
border: 'none',
|
|
10488
|
+
}, children: translate('common.edit') || 'Edit' })), operations.remove && (jsxRuntimeExports.jsx("button", { type: "button", onClick: () => deleteRow(rowIndex), disabled: !isEnabled, className: "px-3 py-1 text-xs disabled:opacity-50 disabled:cursor-not-allowed", style: {
|
|
10489
|
+
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
10490
|
+
color: 'var(--owt-color-error, #B91C1C)',
|
|
10491
|
+
backgroundColor: 'transparent',
|
|
10492
|
+
border: 'none',
|
|
10493
|
+
}, children: translate('common.remove') || 'Delete' }))] }) }))] }, rowIndex));
|
|
10494
|
+
})] })] }) }), touched && error.length > 0 && (jsxRuntimeExports.jsx("p", { className: "text-sm mt-1", style: { color: 'var(--owt-widget-error-color, #B91C1C)' }, children: error[0] }))] }), dialogOpen && (jsxRuntimeExports.jsx("div", { className: "fixed inset-0 flex items-center justify-center z-50", style: { backgroundColor: 'rgba(0,0,0,0.5)' }, children: jsxRuntimeExports.jsxs("div", { className: "rounded-lg p-6 w-full mx-4", style: {
|
|
10377
10495
|
maxWidth: '900px',
|
|
10378
10496
|
backgroundColor: 'var(--owt-color-bg, #FFFFFF)',
|
|
10379
10497
|
borderRadius: 'var(--owt-widget-card-border-radius, 20px)',
|
|
@@ -10384,27 +10502,11 @@ const DialogTableWidget = ({ config }) => {
|
|
|
10384
10502
|
cursor: 'pointer',
|
|
10385
10503
|
fontSize: '20px',
|
|
10386
10504
|
lineHeight: 1,
|
|
10387
|
-
}, "aria-label": "Close", children: "\u00D7" })] }), jsxRuntimeExports.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", style: { maxHeight: '70vh', overflow: 'auto' }, children:
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
return null;
|
|
10505
|
+
}, "aria-label": "Close", children: "\u00D7" })] }), jsxRuntimeExports.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", style: { maxHeight: '70vh', overflow: 'auto' }, children: dialogColumnSegments.map((segment) => {
|
|
10506
|
+
if (segment.type === 'single') {
|
|
10507
|
+
return renderDialogField(segment.col);
|
|
10391
10508
|
}
|
|
10392
|
-
|
|
10393
|
-
const cellWidgetId = dialogFieldWidgetId(key);
|
|
10394
|
-
const initialValue = formData[key] ?? col['widget-data-default'];
|
|
10395
|
-
const fieldConfig = {
|
|
10396
|
-
...col,
|
|
10397
|
-
widget: widgetType,
|
|
10398
|
-
'widget-type': col['widget-type'] || 'input',
|
|
10399
|
-
'widget-id': cellWidgetId,
|
|
10400
|
-
'widget-label': col['widget-label'],
|
|
10401
|
-
'widget-readonly': isReadonly || col['widget-readonly'] === true,
|
|
10402
|
-
'widget-data-path': undefined,
|
|
10403
|
-
'widget-data-default': initialValue,
|
|
10404
|
-
'widget-data-options': undefined,
|
|
10405
|
-
'widget-required': shouldRequireWidget(col['widget-data-options'], dialogRowValues, col['widget-required']),
|
|
10406
|
-
};
|
|
10407
|
-
return (jsxRuntimeExports.jsx("div", { className: "min-w-0", children: jsxRuntimeExports.jsx(WidgetRenderer, { config: fieldConfig, schemaData: { [cellWidgetId]: initialValue }, onValueChange: (_widgetId, newValue) => updateField(key, newValue) }) }, `${dialogSessionId}-${key}`));
|
|
10509
|
+
return (jsxRuntimeExports.jsx("div", { className: "md:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-4", children: segment.cols.map((col) => renderDialogField(col)) }, `${dialogSessionId}-group-${segment.group}`));
|
|
10408
10510
|
}) }, `dialog-fields-${dialogSessionId}`), jsxRuntimeExports.jsxs("div", { className: "flex justify-end gap-3 mt-6", children: [jsxRuntimeExports.jsx("button", { type: "button", onClick: closeDialog, className: "px-4 py-2 text-sm font-medium", style: {
|
|
10409
10511
|
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
10410
10512
|
border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
|