@openg2p/registry-widgets 1.1.2-dev.8 → 1.1.2

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/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createSlice, configureStore } from '@reduxjs/toolkit';
2
- import React, { useContext, createContext, useMemo, useEffect, useRef, useCallback, useState, useId } from 'react';
2
+ import React, { useContext, createContext, useMemo, useEffect, useRef, useCallback, useState, useId, memo } from 'react';
3
3
  import { Provider, useDispatch, useSelector, useStore } from 'react-redux';
4
4
  import { z } from 'zod';
5
5
  import { createPortal } from 'react-dom';
@@ -2243,12 +2243,145 @@ const geoHierarchyBuilder = new GeoHierarchyBuilder();
2243
2243
  /** Sentinel written to Redux when a geo level is cleared by cascade (distinct from "never set"). */
2244
2244
  const GEO_LEVEL_CLEARED = null;
2245
2245
  const geoWidgetParentRegistry = new Map();
2246
+ const geoWidgetConfigRegistry = new Map();
2246
2247
  function registerGeoWidgetParent(widgetId, parentWidgetId) {
2247
2248
  geoWidgetParentRegistry.set(widgetId, parentWidgetId || null);
2248
2249
  }
2249
2250
  function unregisterGeoWidgetParent(widgetId) {
2250
2251
  geoWidgetParentRegistry.delete(widgetId);
2251
2252
  }
2253
+ function registerGeoWidget(widgetId, geoConfig, dataPath) {
2254
+ if (typeof dataPath !== 'string') {
2255
+ return;
2256
+ }
2257
+ const parentWidgetId = geoConfig.parentWidgetId?.trim() ? geoConfig.parentWidgetId : null;
2258
+ registerGeoWidgetParent(widgetId, parentWidgetId);
2259
+ geoWidgetConfigRegistry.set(widgetId, {
2260
+ widgetId,
2261
+ parentWidgetId,
2262
+ level: geoConfig.level,
2263
+ geoConfig,
2264
+ dataPath,
2265
+ groupId: getGeoGroupId(dataPath),
2266
+ });
2267
+ }
2268
+ function unregisterGeoWidget(widgetId) {
2269
+ unregisterGeoWidgetParent(widgetId);
2270
+ geoWidgetConfigRegistry.delete(widgetId);
2271
+ }
2272
+ function orderGeoWidgetRegistrations(registrations) {
2273
+ if (registrations.length <= 1) {
2274
+ return registrations;
2275
+ }
2276
+ const roots = registrations.filter((entry) => !entry.parentWidgetId);
2277
+ if (roots.length === 0) {
2278
+ return registrations;
2279
+ }
2280
+ const ordered = [];
2281
+ let current = roots[0];
2282
+ const visited = new Set();
2283
+ while (current && !visited.has(current.widgetId)) {
2284
+ visited.add(current.widgetId);
2285
+ ordered.push(current);
2286
+ current = registrations.find((entry) => entry.parentWidgetId === current.widgetId);
2287
+ }
2288
+ return ordered.length > 0 ? ordered : registrations;
2289
+ }
2290
+ function resolveLevelValueId(rawValue) {
2291
+ if (rawValue === null || rawValue === undefined || rawValue === '') {
2292
+ return null;
2293
+ }
2294
+ if (typeof rawValue === 'string' || typeof rawValue === 'number') {
2295
+ return String(rawValue);
2296
+ }
2297
+ if (typeof rawValue === 'object') {
2298
+ const id = rawValue.level_value_id || rawValue.id || rawValue.value;
2299
+ return id != null && id !== '' ? String(id) : null;
2300
+ }
2301
+ return null;
2302
+ }
2303
+ function resolveStoredMnemonic(values, registration, valueId) {
2304
+ const stored = getWidgetValue(values, registration.dataPath, registration.widgetId);
2305
+ const hierarchy = stored?.hierarchy || stored?.geo_code_hierarchy_json?.hierarchy;
2306
+ if (!Array.isArray(hierarchy)) {
2307
+ return undefined;
2308
+ }
2309
+ const levelData = hierarchy.find((entry) => entry.level === registration.level);
2310
+ if (levelData && String(levelData.level_value_id) === String(valueId)) {
2311
+ return levelData.level_value_mnemonic ? String(levelData.level_value_mnemonic) : undefined;
2312
+ }
2313
+ return undefined;
2314
+ }
2315
+ /** Resolve display mnemonic from cached dropdown options, then stored hierarchy. */
2316
+ function createGeoLevelMnemonicResolver(values, dataSources) {
2317
+ return (registration, valueId) => {
2318
+ const options = dataSources[registration.widgetId];
2319
+ const option = options?.find((entry) => String(entry.value) === String(valueId));
2320
+ if (option?.label) {
2321
+ return option.label;
2322
+ }
2323
+ return resolveStoredMnemonic(values, registration, valueId);
2324
+ };
2325
+ }
2326
+ /** Rebuild group hierarchy from widget values in parent→child order; stop at first missing level. */
2327
+ function rebuildGeoHierarchyFromRegistrations(groupId, values, registrations, resolveMnemonic) {
2328
+ const ordered = orderGeoWidgetRegistrations(registrations.filter((entry) => entry.groupId === groupId));
2329
+ geoHierarchyBuilder.clear(groupId);
2330
+ for (const registration of ordered) {
2331
+ const rawValue = resolveGeoWidgetLevelValue(values, registration.widgetId, registration.dataPath, registration.geoConfig);
2332
+ const valueId = resolveLevelValueId(rawValue);
2333
+ if (!valueId) {
2334
+ break;
2335
+ }
2336
+ const mnemonic = resolveMnemonic?.(registration, valueId) ??
2337
+ resolveStoredMnemonic(values, registration, valueId) ??
2338
+ valueId;
2339
+ geoHierarchyBuilder.addLevel(registration.level, valueId, mnemonic, groupId);
2340
+ }
2341
+ return geoHierarchyBuilder.buildHierarchyJson(groupId) !== null;
2342
+ }
2343
+ function collectGeoWidgetRegistrationsFromWidgets(widgets, namespace) {
2344
+ return widgets
2345
+ .filter((widget) => widget['widget-geo-config'] && typeof widget['widget-data-path'] === 'string')
2346
+ .map((widget) => {
2347
+ const originalWidgetId = widget['widget-id'];
2348
+ const originalDataPath = widget['widget-data-path'];
2349
+ const geoConfig = widget['widget-geo-config'];
2350
+ const widgetId = namespace ? `${namespace}__${originalWidgetId}` : originalWidgetId;
2351
+ const parentWidgetId = geoConfig.parentWidgetId?.trim()
2352
+ ? (namespace ? `${namespace}__${geoConfig.parentWidgetId}` : geoConfig.parentWidgetId)
2353
+ : null;
2354
+ const dataPath = namespace ? `${namespace}.${originalDataPath}` : originalDataPath;
2355
+ return {
2356
+ widgetId,
2357
+ parentWidgetId,
2358
+ level: geoConfig.level,
2359
+ geoConfig,
2360
+ dataPath,
2361
+ groupId: getGeoGroupId(dataPath),
2362
+ };
2363
+ });
2364
+ }
2365
+ /** Reconcile all geo groups in section values before save. */
2366
+ function reconcileGeoHierarchiesInValues(values, registrations, dataSources = {}) {
2367
+ const groupIds = [...new Set(registrations.map((entry) => entry.groupId))];
2368
+ let updatedValues = values;
2369
+ const resolveMnemonic = createGeoLevelMnemonicResolver(updatedValues, dataSources);
2370
+ for (const groupId of groupIds) {
2371
+ const groupRegistrations = registrations.filter((entry) => entry.groupId === groupId);
2372
+ const dataPath = groupRegistrations[0]?.dataPath;
2373
+ const widgetId = groupRegistrations[0]?.widgetId;
2374
+ if (!dataPath || !widgetId) {
2375
+ continue;
2376
+ }
2377
+ rebuildGeoHierarchyFromRegistrations(groupId, updatedValues, groupRegistrations, resolveMnemonic);
2378
+ updatedValues = applySharedGeoHierarchyToValues(updatedValues, groupId, dataPath, widgetId);
2379
+ }
2380
+ return updatedValues;
2381
+ }
2382
+ function getGeoWidgetRegistrationsInGroup(groupId) {
2383
+ return orderGeoWidgetRegistrations([...geoWidgetConfigRegistry.values()].filter((entry) => entry.groupId === groupId));
2384
+ }
2252
2385
  /** True when changedWidgetId is any upstream geo parent of widgetId (not only immediate parent). */
2253
2386
  function isUpstreamGeoAncestor(changedWidgetId, widgetId, immediateParentWidgetId) {
2254
2387
  if (changedWidgetId === widgetId) {
@@ -2343,7 +2476,7 @@ function resetAndSeedGeoHierarchyFromValues(values, dataPath, widgetId, groupId)
2343
2476
 
2344
2477
  // Define stable empty arrays to avoid selector reference issues
2345
2478
  const EMPTY_ERRORS = [];
2346
- const EMPTY_DATA_SOURCE$1 = [];
2479
+ const EMPTY_DATA_SOURCE = [];
2347
2480
  const useBaseWidget = (options) => {
2348
2481
  const { config, dataSourceRequestHandler: propHandler, schemaData, onValueChange } = options;
2349
2482
  const dispatch = useDispatch();
@@ -2358,7 +2491,7 @@ const useBaseWidget = (options) => {
2358
2491
  const errors = useSelector((state) => state.widget.errors[widgetId] ?? EMPTY_ERRORS);
2359
2492
  const touched = useSelector((state) => state.widget.touched[widgetId] || false);
2360
2493
  const loading = useSelector((state) => state.widget.loading[widgetId] || false);
2361
- const dataSourceOptions = useSelector((state) => state.widget.dataSources[widgetId] ?? EMPTY_DATA_SOURCE$1);
2494
+ const dataSourceOptions = useSelector((state) => state.widget.dataSources[widgetId] ?? EMPTY_DATA_SOURCE);
2362
2495
  // Skip value handling for layout widgets (they don't store data values)
2363
2496
  // Infer layout from widget-type
2364
2497
  const isLayoutWidget = config['widget-type'] === 'layout';
@@ -2680,6 +2813,8 @@ const useBaseWidget = (options) => {
2680
2813
  const apiService = dataSource?.type === 'api' ? dataSource.service : '';
2681
2814
  const apiEndpoint = dataSource?.type === 'api' ? dataSource.endpoint : '';
2682
2815
  const configKey = `${widgetId}-${isReadonly}-${dataSource?.type || 'none'}-${apiService}-${apiEndpoint}`;
2816
+ // Stable key so inline schemaData objects (e.g. dialog-table fields) don't retrigger loads every render
2817
+ const schemaDataKey = useMemo(() => (schemaData ? JSON.stringify(schemaData) : ''), [schemaData]);
2683
2818
  // Extract dependency value using a granular selector to prevent unnecessary re-renders
2684
2819
  // and infinite loops when other unrelated values in the state change.
2685
2820
  const dependencyValue = useSelector((state) => {
@@ -2797,7 +2932,7 @@ const useBaseWidget = (options) => {
2797
2932
  loadDataSource();
2798
2933
  // Use configKey and dependencyValue to ensure effect runs only when relevant state changes
2799
2934
  // eslint-disable-next-line react-hooks/exhaustive-deps
2800
- }, [configKey, dependencyValue, dataSourceRequestHandler, schemaData, widgetId, dispatch]);
2935
+ }, [configKey, dependencyValue, dataSourceRequestHandler, schemaDataKey, widgetId, dispatch]);
2801
2936
  const geoDisplayLabel = useMemo(() => {
2802
2937
  if (!geoConfig) {
2803
2938
  return undefined;
@@ -2886,8 +3021,6 @@ const useWidgetCascade = (options) => {
2886
3021
  }, [cascadeConfig, eventBus, dataSource, widgetId, dispatch]);
2887
3022
  };
2888
3023
 
2889
- // Define stable empty array to avoid selector reference issues
2890
- const EMPTY_DATA_SOURCE = [];
2891
3024
  /**
2892
3025
  * Hook for geo widget cascade functionality
2893
3026
  * Handles geo hierarchy building and cascade behavior
@@ -2917,15 +3050,15 @@ const useGeoWidgetCascade = (options) => {
2917
3050
  ? resolveGeoWidgetLevelValue(state.widget.values, widgetId, dataPath, geoConfig)
2918
3051
  : state.widget.values[widgetId]);
2919
3052
  // Memoize selector to avoid returning new array reference
2920
- const dataSourceOptions = useSelector((state) => state.widget.dataSources[widgetId] ?? EMPTY_DATA_SOURCE);
3053
+ const allDataSources = useSelector((state) => state.widget.dataSources);
2921
3054
  // Register parent chain for upstream-ancestor detection (grandparent → grandchild reset)
2922
3055
  useEffect(() => {
2923
- if (!geoConfig) {
3056
+ if (!geoConfig || typeof dataPath !== 'string') {
2924
3057
  return;
2925
3058
  }
2926
- registerGeoWidgetParent(widgetId, geoConfig.parentWidgetId);
2927
- return () => unregisterGeoWidgetParent(widgetId);
2928
- }, [widgetId, geoConfig]);
3059
+ registerGeoWidget(widgetId, geoConfig, dataPath);
3060
+ return () => unregisterGeoWidget(widgetId);
3061
+ }, [widgetId, geoConfig, dataPath]);
2929
3062
  // Keep in-memory builder in sync with persisted hierarchy (reload, cancel→re-edit, etc.)
2930
3063
  useEffect(() => {
2931
3064
  if (!geoConfig || typeof dataPath !== 'string') {
@@ -3017,18 +3150,20 @@ const useGeoWidgetCascade = (options) => {
3017
3150
  }, [geoConfig, eventBus, dataSource, widgetId, dataPath, dispatch, groupId]);
3018
3151
  // Handle value changes to build hierarchy
3019
3152
  useEffect(() => {
3020
- if (!geoConfig) {
3153
+ if (!geoConfig || typeof dataPath !== 'string') {
3021
3154
  return;
3022
3155
  }
3023
- // Skip if value is undefined (it might still be loading or rehydrating)
3156
+ const { level, isLastLevel } = geoConfig;
3157
+ const groupRegistrations = getGeoWidgetRegistrationsInGroup(groupId);
3158
+ const applyGroupRebuild = () => {
3159
+ const resolveMnemonic = createGeoLevelMnemonicResolver(valuesRef.current, allDataSources);
3160
+ rebuildGeoHierarchyFromRegistrations(groupId, valuesRef.current, groupRegistrations, resolveMnemonic);
3161
+ dispatch(setValues(applySharedGeoHierarchyToValues(valuesRef.current, groupId, dataPath, widgetId)));
3162
+ };
3024
3163
  // ONLY clear hierarchy if the value is explicitly null or empty string (user action)
3025
3164
  if (currentValue === null || currentValue === '') {
3026
- const { level, isLastLevel } = geoConfig;
3027
3165
  geoHierarchyBuilder.removeLevelAndBelow(level, groupId);
3028
- // If we have a dataPath, we need to update Redux with the cleared hierarchy
3029
- if (dataPath) {
3030
- dispatch(setValues(applySharedGeoHierarchyToValues(valuesRef.current, groupId, dataPath, widgetId)));
3031
- }
3166
+ applyGroupRebuild();
3032
3167
  if (!isLastLevel && eventBus && lastCascadePublishRef.current !== GEO_LEVEL_CLEARED) {
3033
3168
  lastCascadePublishRef.current = GEO_LEVEL_CLEARED;
3034
3169
  eventBus.publish({
@@ -3041,56 +3176,13 @@ const useGeoWidgetCascade = (options) => {
3041
3176
  return;
3042
3177
  }
3043
3178
  if (currentValue === undefined) {
3044
- return; // Skip if undefined (still initializing)
3045
- }
3046
- const { level, isLastLevel } = geoConfig;
3047
- // Check if hierarchy is already built to prevent endless loops
3048
- if (dataPath) {
3049
- const currentHierarchy = getWidgetValue(valuesRef.current, dataPath, widgetId);
3050
- // If hierarchy JSON is already set and matches current value, skip rebuilding
3051
- if (currentHierarchy && typeof currentHierarchy === 'object') {
3052
- // Check if this specific level's value matches the hierarchy
3053
- const hierarchyArray = currentHierarchy.hierarchy || currentHierarchy.geo_code_hierarchy_json?.hierarchy;
3054
- if (Array.isArray(hierarchyArray)) {
3055
- const currentLevelValue = typeof currentValue === 'object'
3056
- ? (currentValue.level_value_id || currentValue.id || currentValue.value)
3057
- : currentValue;
3058
- const levelData = hierarchyArray.find((l) => l.level === geoConfig.level);
3059
- // If this level is already correctly represented in the hierarchy, skip rebuilding
3060
- // String conversion ensures comparison works for mixed types
3061
- if (levelData && String(levelData.level_value_id) === String(currentLevelValue)) {
3062
- return;
3063
- }
3064
- }
3179
+ const hasOwnValue = Object.prototype.hasOwnProperty.call(valuesRef.current, widgetId);
3180
+ if (!hasOwnValue) {
3181
+ return;
3065
3182
  }
3066
3183
  }
3067
- // Extract level_value_id and level_value_mnemonic from current value
3068
- // The value could be the ID itself or an object with id/name
3069
- let level_value_id;
3070
- let level_value_mnemonic;
3071
- if (typeof currentValue === 'string' || typeof currentValue === 'number') {
3072
- // Value is just the ID, need to find mnemonic from data source
3073
- level_value_id = String(currentValue);
3074
- // Try to get mnemonic from data source options
3075
- const option = dataSourceOptions.find((opt) => opt.value === currentValue);
3076
- level_value_mnemonic = option?.label || String(currentValue);
3077
- }
3078
- else if (currentValue && typeof currentValue === 'object') {
3079
- level_value_id = currentValue.level_value_id || currentValue.id || currentValue.value;
3080
- level_value_mnemonic = currentValue.level_value_mnemonic || currentValue.name || currentValue.label;
3081
- }
3082
- else {
3083
- return;
3084
- }
3085
- // When a widget's own value changes, remove this level and all below from hierarchy first
3086
- geoHierarchyBuilder.removeLevelAndBelow(level, groupId);
3087
- // Add level to hierarchy
3088
- geoHierarchyBuilder.addLevel(level, level_value_id, level_value_mnemonic, groupId);
3089
- // Build and store hierarchy JSON on every change
3090
- if (dataPath && geoHierarchyBuilder.buildHierarchyJson(groupId)) {
3091
- dispatch(setValues(applySharedGeoHierarchyToValues(valuesRef.current, groupId, dataPath, widgetId)));
3092
- }
3093
- }, [geoConfig, currentValue, widgetId, dataPath, dispatch, dataSourceOptions, groupId]);
3184
+ applyGroupRebuild();
3185
+ }, [geoConfig, currentValue, widgetId, dataPath, dispatch, allDataSources, groupId, eventBus]);
3094
3186
  };
3095
3187
 
3096
3188
  class WidgetRegistry {
@@ -4992,7 +5084,12 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4992
5084
  // This ensures we use the original widget IDs and data paths
4993
5085
  const sectionWidgets = collectWidgets(originalSection.panels);
4994
5086
  const currentState = store.getState().widget;
4995
- const currentSchemaData = currentState.values || {};
5087
+ let currentSchemaData = currentState.values || {};
5088
+ const geoRegistrations = collectGeoWidgetRegistrationsFromWidgets(sectionWidgets, namespace);
5089
+ if (geoRegistrations.length > 0) {
5090
+ currentSchemaData = reconcileGeoHierarchiesInValues(currentSchemaData, geoRegistrations, currentState.dataSources || {});
5091
+ dispatch(setValues(currentSchemaData));
5092
+ }
4996
5093
  const isSectionValid = sectionValidate(originalSection, currentSchemaData, dispatch, true);
4997
5094
  if (!isSectionValid) {
4998
5095
  return;
@@ -5058,7 +5155,12 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
5058
5155
  if (isDraft !== false && store && onSectionSave) {
5059
5156
  const sectionWidgets = collectWidgets(originalSection.panels);
5060
5157
  const currentState = store.getState().widget;
5061
- const currentSchemaData = currentState.values || {};
5158
+ let currentSchemaData = currentState.values || {};
5159
+ const geoRegistrations = collectGeoWidgetRegistrationsFromWidgets(sectionWidgets, namespace);
5160
+ if (geoRegistrations.length > 0) {
5161
+ currentSchemaData = reconcileGeoHierarchiesInValues(currentSchemaData, geoRegistrations, currentState.dataSources || {});
5162
+ dispatch(setValues(currentSchemaData));
5163
+ }
5062
5164
  const isSectionValid = sectionValidate(originalSection, currentSchemaData, dispatch, true);
5063
5165
  if (!isSectionValid)
5064
5166
  return;
@@ -9986,6 +10088,22 @@ const TableWidget = ({ config }) => {
9986
10088
  };
9987
10089
 
9988
10090
  const isUnsetRowValue = (value) => value === null || value === undefined || value === '';
10091
+ /** Match TableWidget cell styling for add / update / delete rows */
10092
+ const getRowCellStyle = (editAction) => {
10093
+ if (editAction === 'ADD') {
10094
+ return { color: 'var(--owt-color-success, #16A34A)' };
10095
+ }
10096
+ if (editAction === 'DELETE') {
10097
+ return {
10098
+ color: 'var(--owt-color-error, #B91C1C)',
10099
+ textDecoration: 'line-through',
10100
+ };
10101
+ }
10102
+ if (editAction === 'UPDATE') {
10103
+ return { color: 'var(--owt-color-warning, #F59E0B)' };
10104
+ }
10105
+ return {};
10106
+ };
9989
10107
  // Display select value label in view mode
9990
10108
  const SelectDisplayValue = ({ config, value }) => {
9991
10109
  const { dataSourceOptions, loading } = useBaseWidget({ config });
@@ -9996,23 +10114,29 @@ const SelectDisplayValue = ({ config, value }) => {
9996
10114
  const selectedOption = dataSourceOptions.find((option) => option.value === value || String(option.value) === String(value));
9997
10115
  return jsxRuntimeExports.jsx("span", { children: selectedOption ? selectedOption.label : String(value) });
9998
10116
  };
10117
+ /** Isolated dialog field — avoids re-running data-source effects when sibling fields update. */
10118
+ const DialogTableField = memo(function DialogTableField({ col, cellWidgetId, dialogRowValues, isReadonly, }) {
10119
+ const widgetType = col.widget || 'text';
10120
+ const fieldConfig = useMemo(() => {
10121
+ return {
10122
+ ...col,
10123
+ widget: widgetType,
10124
+ 'widget-type': col['widget-type'] || 'input',
10125
+ 'widget-id': cellWidgetId,
10126
+ 'widget-label': col['widget-label'],
10127
+ 'widget-readonly': isReadonly || col['widget-readonly'] === true,
10128
+ 'widget-data-path': undefined,
10129
+ 'widget-data-default': col['widget-data-default'],
10130
+ 'widget-data-options': undefined,
10131
+ 'widget-required': shouldRequireWidget(col['widget-data-options'], dialogRowValues, col['widget-required']),
10132
+ };
10133
+ }, [col, cellWidgetId, dialogRowValues, isReadonly, widgetType]);
10134
+ return (jsxRuntimeExports.jsx("div", { className: "min-w-0", children: jsxRuntimeExports.jsx(WidgetRenderer, { config: fieldConfig }) }));
10135
+ });
9999
10136
  /**
10000
10137
  * Dialog table widget:
10001
10138
  * - Table displays a subset of columns (n out of x)
10002
10139
  * - Add/Edit happens in a modal dialog that shows ALL columns as a form
10003
- *
10004
- * Usage in schema:
10005
- * {
10006
- * "widget": "dialog-table",
10007
- * "widget-type": "table",
10008
- * "widget-label": "Household Members",
10009
- * "widget-id": "householdMembers",
10010
- * "widget-data-path": "household.members",
10011
- * "widget-data-columns": [ ...all columns... ],
10012
- * "widget-data-visible-columns": ["firstName", "lastName", "dob"], // optional override; default = by column flag
10013
- * // Per-column control (recommended): set "column-visible-in-table": false to hide it in the table
10014
- * "widget-data-operations": { "add": true, "edit": true, "remove": true }
10015
- * }
10016
10140
  */
10017
10141
  const DialogTableWidget = ({ config }) => {
10018
10142
  const { value, error, touched, isEnabled, onChange, config: widgetConfig } = useBaseWidget({ config });
@@ -10022,23 +10146,22 @@ const DialogTableWidget = ({ config }) => {
10022
10146
  const columns = widgetConfig['widget-data-columns'] || [];
10023
10147
  const operations = widgetConfig['widget-data-operations'] || {};
10024
10148
  const isReadonly = widgetConfig['widget-readonly'] || false;
10149
+ // Soft-delete (keep row, red + strikethrough) whenever remove is allowed — matches TableWidget
10150
+ const shouldSoftDeleteOnRemove = !isReadonly && !!operations.remove;
10025
10151
  const visibleColumnKeys = widgetConfig['widget-data-visible-columns'];
10026
10152
  const visibleColumns = useMemo(() => {
10027
- // 1) If explicit list provided, it wins
10028
10153
  if (Array.isArray(visibleColumnKeys) && visibleColumnKeys.length > 0) {
10029
10154
  const keySet = new Set(visibleColumnKeys);
10030
10155
  return columns.filter((c) => keySet.has(c['column-key']));
10031
10156
  }
10032
- // 2) Otherwise decide per column (default = visible)
10033
10157
  return columns.filter((c) => c['column-visible-in-table'] !== false);
10034
10158
  }, [columns, visibleColumnKeys]);
10035
10159
  const [dialogOpen, setDialogOpen] = useState(false);
10036
10160
  const [dialogMode, setDialogMode] = useState('add');
10037
10161
  const [activeRowIndex, setActiveRowIndex] = useState(null);
10038
- const [formData, setFormData] = useState({});
10039
- /** Unique per dialog open so Redux widget ids don't reuse stale values across rows/add sessions */
10040
10162
  const dialogSessionRef = useRef(0);
10041
10163
  const [dialogSessionId, setDialogSessionId] = useState(0);
10164
+ const membersWidgetId = widgetConfig['widget-id'];
10042
10165
  const addDialogTitle = translateConfig(widgetConfig['widget-data-dialog-title-add']) ||
10043
10166
  translate('table.addRecordDialog') ||
10044
10167
  'Add record';
@@ -10058,15 +10181,26 @@ const DialogTableWidget = ({ config }) => {
10058
10181
  });
10059
10182
  return emptyRow;
10060
10183
  }, [columns]);
10061
- const dialogFieldWidgetId = useCallback((columnKey) => `${widgetConfig['widget-id']}-dlg-${dialogSessionId}-${columnKey}`, [widgetConfig, dialogSessionId]);
10184
+ const dialogFieldWidgetId = useCallback((sessionId, columnKey) => `${membersWidgetId}-dlg-${sessionId}-${columnKey}`, [membersWidgetId]);
10062
10185
  const resetDialogWidgets = useCallback((sessionId) => {
10063
10186
  if (sessionId <= 0)
10064
10187
  return;
10065
10188
  columns.forEach((col) => {
10066
- const wid = `${widgetConfig['widget-id']}-dlg-${sessionId}-${col['column-key']}`;
10067
- dispatch(resetWidget(wid));
10189
+ dispatch(resetWidget(dialogFieldWidgetId(sessionId, col['column-key'])));
10190
+ });
10191
+ }, [columns, dialogFieldWidgetId, dispatch]);
10192
+ const seedDialogReduxValues = useCallback((sessionId, rowData) => {
10193
+ const seeds = {};
10194
+ columns.forEach((col) => {
10195
+ const key = col['column-key'];
10196
+ if (rowData[key] !== undefined) {
10197
+ seeds[dialogFieldWidgetId(sessionId, key)] = rowData[key];
10198
+ }
10068
10199
  });
10069
- }, [columns, widgetConfig, dispatch]);
10200
+ if (Object.keys(seeds).length > 0) {
10201
+ dispatch(setValues(seeds));
10202
+ }
10203
+ }, [columns, dialogFieldWidgetId, dispatch]);
10070
10204
  const beginDialogSession = useCallback(() => {
10071
10205
  dialogSessionRef.current += 1;
10072
10206
  const nextSession = dialogSessionRef.current;
@@ -10075,15 +10209,21 @@ const DialogTableWidget = ({ config }) => {
10075
10209
  }, []);
10076
10210
  const openAddDialog = useCallback(() => {
10077
10211
  resetDialogWidgets(dialogSessionId);
10078
- beginDialogSession();
10212
+ const sessionId = beginDialogSession();
10213
+ seedDialogReduxValues(sessionId, buildEmptyRow());
10079
10214
  setDialogMode('add');
10080
10215
  setActiveRowIndex(null);
10081
- setFormData(buildEmptyRow());
10082
10216
  setDialogOpen(true);
10083
- }, [buildEmptyRow, beginDialogSession, resetDialogWidgets, dialogSessionId]);
10217
+ }, [
10218
+ buildEmptyRow,
10219
+ beginDialogSession,
10220
+ resetDialogWidgets,
10221
+ dialogSessionId,
10222
+ seedDialogReduxValues,
10223
+ ]);
10084
10224
  const openEditDialog = useCallback((rowIndex) => {
10085
10225
  resetDialogWidgets(dialogSessionId);
10086
- beginDialogSession();
10226
+ const sessionId = beginDialogSession();
10087
10227
  const row = rows[rowIndex] || {};
10088
10228
  const nextFormData = buildEmptyRow();
10089
10229
  columns.forEach((col) => {
@@ -10091,23 +10231,26 @@ const DialogTableWidget = ({ config }) => {
10091
10231
  if (row[key] !== undefined)
10092
10232
  nextFormData[key] = row[key];
10093
10233
  });
10234
+ seedDialogReduxValues(sessionId, nextFormData);
10094
10235
  setDialogMode('edit');
10095
10236
  setActiveRowIndex(rowIndex);
10096
- setFormData(nextFormData);
10097
10237
  setDialogOpen(true);
10098
- }, [rows, columns, buildEmptyRow, resetDialogWidgets, dialogSessionId, beginDialogSession]);
10238
+ }, [
10239
+ rows,
10240
+ columns,
10241
+ buildEmptyRow,
10242
+ resetDialogWidgets,
10243
+ dialogSessionId,
10244
+ beginDialogSession,
10245
+ seedDialogReduxValues,
10246
+ ]);
10099
10247
  const closeDialog = useCallback(() => {
10100
10248
  const sessionToClear = dialogSessionId;
10101
10249
  setDialogOpen(false);
10102
10250
  setActiveRowIndex(null);
10103
- setFormData({});
10104
10251
  resetDialogWidgets(sessionToClear);
10105
10252
  setDialogSessionId(0);
10106
10253
  }, [dialogSessionId, resetDialogWidgets]);
10107
- const updateField = useCallback((columnKey, newValue) => {
10108
- setFormData((prev) => ({ ...prev, [columnKey]: newValue }));
10109
- }, []);
10110
- const membersWidgetId = widgetConfig['widget-id'];
10111
10254
  const dialogStoreValues = useSelector((state) => {
10112
10255
  if (dialogSessionId <= 0) {
10113
10256
  return {};
@@ -10116,25 +10259,15 @@ const DialogTableWidget = ({ config }) => {
10116
10259
  const row = {};
10117
10260
  columns.forEach((col) => {
10118
10261
  const k = col['column-key'];
10119
- const wid = `${membersWidgetId}-dlg-${dialogSessionId}-${k}`;
10262
+ const wid = dialogFieldWidgetId(dialogSessionId, k);
10120
10263
  if (values[wid] !== undefined) {
10121
10264
  row[k] = values[wid];
10122
10265
  }
10123
10266
  });
10124
10267
  return row;
10125
- }, (a, b) => JSON.stringify(a) === JSON.stringify(b));
10126
- const buildDialogRowValues = useCallback((storeSlice) => {
10127
- const row = { ...formData };
10128
- columns.forEach((col) => {
10129
- const k = col['column-key'];
10130
- if (storeSlice[k] !== undefined) {
10131
- row[k] = storeSlice[k];
10132
- }
10133
- });
10134
- return row;
10135
- }, [formData, columns]);
10136
- const dialogRowValues = useMemo(() => buildDialogRowValues(dialogStoreValues), [buildDialogRowValues, dialogStoreValues]);
10137
- const collectMergedRowPayload = useCallback(() => buildDialogRowValues(dialogStoreValues), [buildDialogRowValues, dialogStoreValues]);
10268
+ });
10269
+ const dialogRowValues = dialogStoreValues;
10270
+ const collectMergedRowPayload = useCallback(() => dialogStoreValues, [dialogStoreValues]);
10138
10271
  const finalizeDialogRowPayload = useCallback((raw) => {
10139
10272
  const result = {};
10140
10273
  columns.forEach((col) => {
@@ -10154,7 +10287,7 @@ const DialogTableWidget = ({ config }) => {
10154
10287
  let hasErrors = false;
10155
10288
  columns.forEach((col) => {
10156
10289
  const key = col['column-key'];
10157
- const cellWidgetId = dialogFieldWidgetId(key);
10290
+ const cellWidgetId = dialogFieldWidgetId(dialogSessionId, key);
10158
10291
  const isColReadonly = isReadonly || col['widget-readonly'] === true;
10159
10292
  if (isColReadonly)
10160
10293
  return;
@@ -10198,11 +10331,32 @@ const DialogTableWidget = ({ config }) => {
10198
10331
  onChange(newRows);
10199
10332
  closeDialog();
10200
10333
  }
10201
- }, [collectMergedRowPayload, finalizeDialogRowPayload, dialogMode, onChange, rows, closeDialog, activeRowIndex, columns, dialogFieldWidgetId, isReadonly, dispatch]);
10334
+ }, [
10335
+ collectMergedRowPayload,
10336
+ finalizeDialogRowPayload,
10337
+ dialogMode,
10338
+ onChange,
10339
+ rows,
10340
+ closeDialog,
10341
+ activeRowIndex,
10342
+ columns,
10343
+ dialogSessionId,
10344
+ dialogFieldWidgetId,
10345
+ isReadonly,
10346
+ dispatch,
10347
+ ]);
10202
10348
  const deleteRow = useCallback((rowIndex) => {
10203
- const newRows = rows.filter((_, i) => i !== rowIndex);
10204
- onChange(newRows);
10205
- }, [rows, onChange]);
10349
+ if (shouldSoftDeleteOnRemove) {
10350
+ const newRows = [...rows];
10351
+ newRows[rowIndex] = {
10352
+ ...newRows[rowIndex],
10353
+ edit_action: 'DELETE',
10354
+ };
10355
+ onChange(newRows);
10356
+ return;
10357
+ }
10358
+ onChange(rows.filter((_, i) => i !== rowIndex));
10359
+ }, [rows, onChange, shouldSoftDeleteOnRemove]);
10206
10360
  const getDisplayValue = useCallback((rowIndex, column) => {
10207
10361
  const key = column['column-key'];
10208
10362
  const cellValue = rows[rowIndex]?.[key];
@@ -10210,11 +10364,12 @@ const DialogTableWidget = ({ config }) => {
10210
10364
  if (cellValue === null || cellValue === undefined || cellValue === '')
10211
10365
  return '-';
10212
10366
  if (widgetType === 'select')
10213
- return null; // handled by SelectDisplayValue
10367
+ return null;
10214
10368
  if (column['widget-data-format'])
10215
10369
  return formatValue(cellValue, column['widget-data-format'], column.widget);
10216
10370
  return String(cellValue);
10217
10371
  }, [rows]);
10372
+ const visibleDialogColumns = useMemo(() => columns.filter((col) => shouldShowWidget(col['widget-data-options'], dialogRowValues)), [columns, dialogRowValues]);
10218
10373
  const tableWidgetId = `dialog-table-widget-${widgetConfig['widget-id']}`;
10219
10374
  const columnSpan = widgetConfig['widget-column-span'] || 2;
10220
10375
  const minWidth = columnSpan * 200;
@@ -10242,37 +10397,40 @@ const DialogTableWidget = ({ config }) => {
10242
10397
  }, children: translate('table.addRecord') || 'Add New Record' }) })), jsxRuntimeExports.jsx("div", { className: "overflow-x-auto border", style: {
10243
10398
  borderRadius: 'var(--owt-widget-table-border-radius, 15px)',
10244
10399
  borderColor: 'var(--owt-widget-table-border-color, #C4C4C4)',
10245
- }, 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) => (jsxRuntimeExports.jsxs("tr", { style: {
10246
- borderBottom: '1px solid var(--owt-widget-table-row-divider, #E4E4E4)',
10247
- backgroundColor: row?.edit_action === 'DELETE'
10248
- ? 'var(--owt-widget-table-deleted-row-bg, #FEE2E2)'
10249
- : undefined,
10250
- }, children: [visibleColumns.map((col) => {
10251
- const key = col['column-key'];
10252
- const widgetType = col.widget || 'text';
10253
- const displayValue = getDisplayValue(rowIndex, col);
10254
- if (widgetType === 'select' && displayValue === null) {
10255
- const displayConfig = {
10256
- ...col,
10257
- 'widget-id': `${widgetConfig['widget-id']}-view-row-${rowIndex}-col-${key}`,
10258
- 'widget-label': '',
10259
- 'widget-readonly': true,
10260
- 'widget-data-path': undefined,
10261
- };
10262
- return (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: jsxRuntimeExports.jsx("div", { className: "text-sm", children: jsxRuntimeExports.jsx(SelectDisplayValue, { config: displayConfig, value: row?.[key] }) }) }, key));
10263
- }
10264
- return (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: jsxRuntimeExports.jsx("div", { className: "text-sm", children: displayValue }) }, key));
10265
- }), ((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: {
10266
- borderRadius: 'var(--owt-btn-border-radius, 10px)',
10267
- color: 'var(--owt-color-primary-dark, #F07B1A)',
10268
- backgroundColor: 'transparent',
10269
- border: 'none',
10270
- }, 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: {
10271
- borderRadius: 'var(--owt-btn-border-radius, 10px)',
10272
- color: 'var(--owt-color-error, #B91C1C)',
10273
- backgroundColor: 'transparent',
10274
- border: 'none',
10275
- }, children: translate('common.remove') || 'Delete' }))] }) }))] }, rowIndex)))] })] }) }), 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: {
10400
+ }, 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) => {
10401
+ const cellStyle = getRowCellStyle(row?.edit_action);
10402
+ return (jsxRuntimeExports.jsxs("tr", { style: {
10403
+ borderBottom: '1px solid var(--owt-widget-table-row-divider, #E4E4E4)',
10404
+ backgroundColor: row?.edit_action === 'DELETE'
10405
+ ? 'var(--owt-widget-table-deleted-row-bg, #FEE2E2)'
10406
+ : undefined,
10407
+ }, children: [visibleColumns.map((col) => {
10408
+ const key = col['column-key'];
10409
+ const widgetType = col.widget || 'text';
10410
+ const displayValue = getDisplayValue(rowIndex, col);
10411
+ if (widgetType === 'select' && displayValue === null) {
10412
+ const displayConfig = {
10413
+ ...col,
10414
+ 'widget-id': `${widgetConfig['widget-id']}-view-row-${rowIndex}-col-${key}`,
10415
+ 'widget-label': '',
10416
+ 'widget-readonly': true,
10417
+ 'widget-data-path': undefined,
10418
+ };
10419
+ 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));
10420
+ }
10421
+ return (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: jsxRuntimeExports.jsx("div", { className: "text-sm", style: cellStyle, children: displayValue }) }, key));
10422
+ }), ((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: {
10423
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
10424
+ color: 'var(--owt-color-primary-dark, #F07B1A)',
10425
+ backgroundColor: 'transparent',
10426
+ border: 'none',
10427
+ }, 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: {
10428
+ borderRadius: 'var(--owt-btn-border-radius, 10px)',
10429
+ color: 'var(--owt-color-error, #B91C1C)',
10430
+ backgroundColor: 'transparent',
10431
+ border: 'none',
10432
+ }, children: translate('common.remove') || 'Delete' }))] }) }))] }, rowIndex));
10433
+ })] })] }) }), 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: {
10276
10434
  maxWidth: '900px',
10277
10435
  backgroundColor: 'var(--owt-color-bg, #FFFFFF)',
10278
10436
  borderRadius: 'var(--owt-widget-card-border-radius, 20px)',
@@ -10283,27 +10441,10 @@ const DialogTableWidget = ({ config }) => {
10283
10441
  cursor: 'pointer',
10284
10442
  fontSize: '20px',
10285
10443
  lineHeight: 1,
10286
- }, "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: columns.map((col) => {
10444
+ }, "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: visibleDialogColumns.map((col) => {
10287
10445
  const key = col['column-key'];
10288
- if (!shouldShowWidget(col['widget-data-options'], dialogRowValues)) {
10289
- return null;
10290
- }
10291
- const widgetType = col.widget || 'text';
10292
- const cellWidgetId = dialogFieldWidgetId(key);
10293
- const initialValue = formData[key] ?? col['widget-data-default'];
10294
- const fieldConfig = {
10295
- ...col,
10296
- widget: widgetType,
10297
- 'widget-type': col['widget-type'] || 'input',
10298
- 'widget-id': cellWidgetId,
10299
- 'widget-label': col['widget-label'],
10300
- 'widget-readonly': isReadonly || col['widget-readonly'] === true,
10301
- 'widget-data-path': undefined,
10302
- 'widget-data-default': initialValue,
10303
- 'widget-data-options': undefined,
10304
- 'widget-required': shouldRequireWidget(col['widget-data-options'], dialogRowValues, col['widget-required']),
10305
- };
10306
- 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}`));
10446
+ const cellWidgetId = dialogFieldWidgetId(dialogSessionId, key);
10447
+ return (jsxRuntimeExports.jsx(DialogTableField, { col: col, cellWidgetId: cellWidgetId, dialogRowValues: dialogRowValues, isReadonly: isReadonly }, `${dialogSessionId}-${key}`));
10307
10448
  }) }, `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: {
10308
10449
  borderRadius: 'var(--owt-btn-border-radius, 10px)',
10309
10450
  border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
@@ -12946,5 +13087,5 @@ const translateUISchema = (schema, translate) => {
12946
13087
  };
12947
13088
  };
12948
13089
 
12949
- export { ArrayWidget, BooleanWidget, CheckboxWidget, CurrencyInputWidget, DateInputWidget, DateTimeInputWidget, DialogTableWidget, DisplayWidget, FileInputWidget, GEO_LEVEL_CLEARED, HeaderSectionWidget, IdAuthenticationWidget, IterableAccordionWidget, JSONEditorPanel, MultiSelectWidget, NumberInputWidget, PanelRenderer, PhoneInputWidget, ProfileWidget, PropertyEditor, RadioWidget, RegisterLookupWidget, ScoresDisplayWidget, SectionBuilder, SectionRenderer, SectionTree, SectionsContainer, SelectWidget, SimpleTableWidget, TableWidget, TextAreaWidget, TextInputWidget, VisualBuilderPanel, WidgetEventBus, WidgetProvider, WidgetRenderer, applyCaseControl, applyDecimalPrecision, applyMask, applySharedGeoHierarchyToValues, createWidgetStore, createZodSchema, defaultTheme, evaluateCondition, evaluateWidgetConditions, filterByCharacterType, formatCurrency, formatDate, formatNumber, formatPhone, formatValue, geoHierarchyBuilder, getApiDataSource, getCachedApiDataSource, getFormattedNumberLength, getGeoDescendantWidgetIds, getGeoGroupId, getSchemaDataSource, getStaticDataSource, getValueByPath, getWidgetValue, hasVisibilityRules, initI18n, isAllowedKey, isUpstreamGeoAncestor, normalizeNumericDefault, normalizeOptionRules, parseDataPath, parseNumber, registerDefaultWidgets, registerGeoWidgetParent, removeMask, resetAll, resetAndSeedGeoHierarchyFromValues, resetWidget, resolveGeoWidgetLevelLabel, resolveGeoWidgetLevelValue, resolveTheme, resolveWidgetIdValue, seedGeoHierarchyFromValues, setDataSource, setError, setLoading, setTouched, setValue, setValueByPath, setValues, setWidgetValue, shouldEnableWidget, shouldRequireWidget, shouldShowWidget, transformDataSourceOptions, translatePanelConfig, translateUISchema, translateWidgetConfig, unregisterGeoWidgetParent, useBaseWidget, useGeoWidgetCascade, useWidgetCascade, useWidgetContext, useWidgetEventBus, useWidgetTheme, useWidgetTranslation, validateNumericValue, validateWidget, widgetRegistry };
13090
+ export { ArrayWidget, BooleanWidget, CheckboxWidget, CurrencyInputWidget, DateInputWidget, DateTimeInputWidget, DialogTableWidget, DisplayWidget, FileInputWidget, GEO_LEVEL_CLEARED, HeaderSectionWidget, IdAuthenticationWidget, IterableAccordionWidget, JSONEditorPanel, MultiSelectWidget, NumberInputWidget, PanelRenderer, PhoneInputWidget, ProfileWidget, PropertyEditor, RadioWidget, RegisterLookupWidget, ScoresDisplayWidget, SectionBuilder, SectionRenderer, SectionTree, SectionsContainer, SelectWidget, SimpleTableWidget, TableWidget, TextAreaWidget, TextInputWidget, VisualBuilderPanel, WidgetEventBus, WidgetProvider, WidgetRenderer, applyCaseControl, applyDecimalPrecision, applyMask, applySharedGeoHierarchyToValues, collectGeoWidgetRegistrationsFromWidgets, createGeoLevelMnemonicResolver, createWidgetStore, createZodSchema, defaultTheme, evaluateCondition, evaluateWidgetConditions, filterByCharacterType, formatCurrency, formatDate, formatNumber, formatPhone, formatValue, geoHierarchyBuilder, getApiDataSource, getCachedApiDataSource, getFormattedNumberLength, getGeoDescendantWidgetIds, getGeoGroupId, getGeoWidgetRegistrationsInGroup, getSchemaDataSource, getStaticDataSource, getValueByPath, getWidgetValue, hasVisibilityRules, initI18n, isAllowedKey, isUpstreamGeoAncestor, normalizeNumericDefault, normalizeOptionRules, orderGeoWidgetRegistrations, parseDataPath, parseNumber, rebuildGeoHierarchyFromRegistrations, reconcileGeoHierarchiesInValues, registerDefaultWidgets, registerGeoWidget, registerGeoWidgetParent, removeMask, resetAll, resetAndSeedGeoHierarchyFromValues, resetWidget, resolveGeoWidgetLevelLabel, resolveGeoWidgetLevelValue, resolveTheme, resolveWidgetIdValue, seedGeoHierarchyFromValues, setDataSource, setError, setLoading, setTouched, setValue, setValueByPath, setValues, setWidgetValue, shouldEnableWidget, shouldRequireWidget, shouldShowWidget, transformDataSourceOptions, translatePanelConfig, translateUISchema, translateWidgetConfig, unregisterGeoWidget, unregisterGeoWidgetParent, useBaseWidget, useGeoWidgetCascade, useWidgetCascade, useWidgetContext, useWidgetEventBus, useWidgetTheme, useWidgetTranslation, validateNumericValue, validateWidget, widgetRegistry };
12950
13091
  //# sourceMappingURL=index.esm.js.map