@wavemaker-ai/react-runtime 1.0.0-rc.647655 → 1.0.0-rc.647684

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.
Files changed (112) hide show
  1. package/actions/notification-action.js +3 -3
  2. package/actions/toast.js +2 -1
  3. package/components/basic/icon/index.js +36 -5
  4. package/components/basic/iframe/index.js +18 -8
  5. package/components/basic/label/index.js +4 -3
  6. package/components/basic/message/index.js +1 -0
  7. package/components/basic/search/index.d.ts +72 -3
  8. package/components/basic/search/index.js +84 -32
  9. package/components/basic/search/props.d.ts +4 -0
  10. package/components/basic/search/providers.d.ts +1 -1
  11. package/components/basic/search/providers.js +6 -3
  12. package/components/common/WmAppIcon/index.js +11 -8
  13. package/components/common/WmAppIcon/props.d.ts +2 -0
  14. package/components/container/accordion/accordion-pane/index.d.ts +1 -0
  15. package/components/container/accordion/accordion-pane/index.js +7 -3
  16. package/components/container/accordion/accordion-pane/props.d.ts +1 -0
  17. package/components/container/index.js +13 -5
  18. package/components/container/layout-grid/index.js +1 -0
  19. package/components/container/linear-layout/index.js +0 -1
  20. package/components/container/panel/components/panel-header/index.js +1 -3
  21. package/components/container/tabs/tab-pane/index.d.ts +1 -0
  22. package/components/container/tabs/tab-pane/index.js +2 -2
  23. package/components/container/tabs/tab-pane/props.d.ts +1 -0
  24. package/components/container/wizard/index.js +11 -10
  25. package/components/container/wizard/utils.js +1 -0
  26. package/components/data/form/base-form/hooks/useFormOperations.js +9 -15
  27. package/components/data/form/base-form/index.js +17 -14
  28. package/components/data/form/base-form/utils.js +5 -4
  29. package/components/data/form/dynamic-fields/WmxDynamicFormField.d.ts +11 -0
  30. package/components/data/form/dynamic-fields/WmxDynamicFormField.js +77 -0
  31. package/components/data/form/dynamic-fields/index.js +12 -1
  32. package/components/data/form/form-action/index.d.ts +2 -2
  33. package/components/data/form/form-action/index.js +2 -2
  34. package/components/data/form/form-context.d.ts +12 -13
  35. package/components/data/form/form-context.js +4 -6
  36. package/components/data/form/form-controller/withFormController.js +4 -18
  37. package/components/data/form/form-field/index.js +10 -6
  38. package/components/data/list/components/ListItems.js +1 -3
  39. package/components/data/list/index.js +5 -4
  40. package/components/data/pagination/hooks/usePagination.js +2 -2
  41. package/components/data/table/components/RowCells.js +3 -1
  42. package/components/data/table/components/TableBody.js +2 -1
  43. package/components/data/table/components/TableDataRow.js +1 -1
  44. package/components/data/table/components/TableHeader.js +5 -1
  45. package/components/data/table/hooks/useRowHandlers.d.ts +4 -2
  46. package/components/data/table/hooks/useRowHandlers.js +23 -11
  47. package/components/data/table/hooks/useRowSelection.d.ts +1 -1
  48. package/components/data/table/hooks/useRowSelection.js +93 -74
  49. package/components/data/table/hooks/useTableColumns.js +5 -5
  50. package/components/data/table/hooks/useTableState.js +14 -2
  51. package/components/data/table/index.js +54 -50
  52. package/components/data/table/props.d.ts +12 -8
  53. package/components/data/table/utils/buildSelectionColumns.js +31 -31
  54. package/components/data/table/utils/columnBuilder.js +1 -1
  55. package/components/data/table/utils/index.d.ts +9 -1
  56. package/components/data/table/utils/index.js +30 -2
  57. package/components/data/table/utils/selectionUtils.d.ts +7 -0
  58. package/components/data/table/utils/selectionUtils.js +28 -1
  59. package/components/dialogs/dialog-actions/index.js +11 -2
  60. package/components/dialogs/dialog-header/index.js +1 -1
  61. package/components/dialogs/index.js +14 -2
  62. package/components/input/chips/index.js +29 -5
  63. package/components/input/color-picker/index.js +4 -6
  64. package/components/input/epoch/date/index.js +3 -2
  65. package/components/input/epoch/date/utils.js +4 -2
  66. package/components/input/epoch/datetime/index.js +2 -2
  67. package/components/input/epoch/datetime/props.d.ts +2 -2
  68. package/components/input/epoch/time/utils.d.ts +1 -1
  69. package/components/input/epoch/time/utils.js +2 -2
  70. package/components/input/fileupload/useFileUpload.js +19 -24
  71. package/components/input/select/index.js +8 -6
  72. package/components/input/text/index.js +2 -2
  73. package/components/input/textarea/index.js +41 -16
  74. package/components/navbar/nav/index.js +10 -5
  75. package/components/navigation/breadcrumb/index.js +2 -1
  76. package/components/navigation/popover/index.d.ts +1 -1
  77. package/components/navigation/popover/index.js +10 -2
  78. package/components/navigation/popover/props.d.ts +1 -1
  79. package/components/page/page-content/index.js +24 -4
  80. package/components/page/page-content/props.d.ts +1 -0
  81. package/components/page/partial-container/index.js +1 -1
  82. package/components/wmx/WmxRenderer.d.ts +8 -0
  83. package/components/wmx/WmxRenderer.js +57 -0
  84. package/core/appstore.js +1 -1
  85. package/core/proxy-service.d.ts +16 -1
  86. package/core/proxy-service.js +39 -12
  87. package/core/util/index.d.ts +0 -2
  88. package/core/util/index.js +0 -29
  89. package/higherOrder/BaseDateTime.js +8 -1
  90. package/higherOrder/BasePage.js +31 -65
  91. package/higherOrder/DataNav.js +4 -1
  92. package/higherOrder/withBaseWrapper.js +3 -4
  93. package/hooks/useHttp.js +4 -2
  94. package/hooks/useLayoutSize.js +1 -1
  95. package/package-lock.json +360 -696
  96. package/package.json +3 -3
  97. package/runtime-dynamic/app-initializer.js +2 -1
  98. package/runtime-dynamic/components/partial-content.js +2 -1
  99. package/runtime-dynamic/components/wmx-placeholder.d.ts +18 -0
  100. package/runtime-dynamic/components/wmx-placeholder.js +48 -0
  101. package/runtime-dynamic/main.js +6 -0
  102. package/runtime-dynamic/services/compile-render.js +75 -12
  103. package/store/slices/i18nSlice.d.ts +0 -1
  104. package/store/slices/i18nSlice.js +0 -2
  105. package/utils/layoutsize-util.js +12 -7
  106. package/utils/style-utils.d.ts +6 -0
  107. package/utils/style-utils.js +10 -0
  108. package/utils/wmx.utils.d.ts +6 -0
  109. package/utils/wmx.utils.js +41 -0
  110. package/variables/crud-variable.js +1 -1
  111. package/variables/live-variable.js +1 -1
  112. package/variables/service-variable.js +6 -3
@@ -233,7 +233,7 @@ const withFormController = (WrappedComponent) => {
233
233
  rules: validationRules,
234
234
  defaultValue: effectiveDataValue !== void 0 ? effectiveDataValue : defaultvalue,
235
235
  render: ({ field, fieldState }) => {
236
- var _a2, _b;
236
+ var _a2, _b, _c;
237
237
  fieldRef.current = field;
238
238
  const processedValue = processFieldValue(field.value, type, props.datafield);
239
239
  const errorState = getErrorState(fieldState, validationType, touched);
@@ -292,8 +292,8 @@ const withFormController = (WrappedComponent) => {
292
292
  delete remapped.displayValue;
293
293
  }
294
294
  props.onChangeHandler(name2, remapped);
295
- } : props.onChangeHandler,
296
- Widgets: ((_a2 = props.listener) == null ? void 0 : _a2.Widgets) || {}
295
+ } : props.onChangeHandler || ((_a2 = props.listener) == null ? void 0 : _a2.onChange),
296
+ Widgets: ((_b = props.listener) == null ? void 0 : _b.Widgets) || {}
297
297
  }
298
298
  });
299
299
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -325,20 +325,6 @@ const withFormController = (WrappedComponent) => {
325
325
  })()
326
326
  }
327
327
  ),
328
- hint && !shouldShowErrorMessage(validationType, fieldState, touched) && /* @__PURE__ */ jsx(
329
- "p",
330
- {
331
- className: "help-block",
332
- "aria-hidden": "true",
333
- role: "alert",
334
- "aria-live": "polite",
335
- style: {
336
- textAlign: "start",
337
- width: "100%"
338
- },
339
- children: hint
340
- }
341
- ),
342
328
  shouldShowErrorMessage(validationType, fieldState, touched) && /* @__PURE__ */ jsx(
343
329
  "p",
344
330
  {
@@ -350,7 +336,7 @@ const withFormController = (WrappedComponent) => {
350
336
  textAlign: "start",
351
337
  width: "100%"
352
338
  },
353
- children: (_b = fieldState.error) == null ? void 0 : _b.message
339
+ children: (_c = fieldState.error) == null ? void 0 : _c.message
354
340
  }
355
341
  )
356
342
  ] });
@@ -50,7 +50,7 @@ const WmFormField = memo(
50
50
  const fieldKey = props.formKey || props.name;
51
51
  const defaultValueRegisteredRef = useRef(false);
52
52
  const showfield = (_b = (_a = overriddenItemsRef == null ? void 0 : overriddenItemsRef.current) == null ? void 0 : _a.show) != null ? _b : show;
53
- const formReady = (formProxy == null ? void 0 : formProxy.listener) !== void 0;
53
+ const formReady = (formProxy == null ? void 0 : formProxy.listener) !== void 0 || ((_c = props.formRef) == null ? void 0 : _c.name) === props.formName;
54
54
  const reset = useCallback(
55
55
  (value) => {
56
56
  const field = fieldProxyRef.current;
@@ -86,7 +86,8 @@ const WmFormField = memo(
86
86
  mutableTarget,
87
87
  setProxyProps,
88
88
  overriddenItemsRef,
89
- formProxy
89
+ formProxy,
90
+ props.formRef
90
91
  );
91
92
  fieldProxyRef.current = fieldProxy;
92
93
  }, [formReady]);
@@ -110,17 +111,20 @@ const WmFormField = memo(
110
111
  });
111
112
  }, [props.dataset, props.datafield, props.displayfield, props.displaylabel, props.searchkey]);
112
113
  function renderFormFields() {
113
- var _a2, _b2, _c2, _d2, _e, _f, _g;
114
+ var _a2, _b2, _c2, _d2, _e, _f, _g, _h;
114
115
  if (props.formRef) {
115
116
  const errors = (_a2 = props.formRef) == null ? void 0 : _a2.errors;
116
117
  const formKey = (_b2 = props.formKey) != null ? _b2 : props.name;
117
118
  const fieldError = formKey && errors ? get(errors, formKey) : void 0;
118
119
  const invalid = Boolean(fieldError);
119
120
  const invalidCls = invalid ? " text-danger " : "";
120
- return /* @__PURE__ */ jsx(Fragment, { children: (_g = props == null ? void 0 : props.renderFormFields) == null ? void 0 : _g.call(props, __spreadProps(__spreadValues(__spreadValues({}, proxyProps), overriddenItemsRef.current), {
121
+ return /* @__PURE__ */ jsx(Fragment, { children: (_h = props == null ? void 0 : props.renderFormFields) == null ? void 0 : _h.call(props, __spreadProps(__spreadValues(__spreadValues({}, proxyProps), overriddenItemsRef.current), {
121
122
  show: showfield,
122
123
  disabled: (_d2 = (_c2 = overriddenItemsRef == null ? void 0 : overriddenItemsRef.current) == null ? void 0 : _c2.disabled) != null ? _d2 : props == null ? void 0 : props.disabled,
123
124
  readonly: (_f = (_e = overriddenItemsRef == null ? void 0 : overriddenItemsRef.current) == null ? void 0 : _e.readonly) != null ? _f : props == null ? void 0 : props.readonly,
125
+ // BaseField derives this from live validators. A direct field-proxy write wins,
126
+ // but never fall back to the initial proxyProps.required snapshot.
127
+ required: (_g = overriddenItemsRef.current.required) != null ? _g : props.required,
124
128
  fieldError,
125
129
  validators: props.validators,
126
130
  asyncValidators: props.asyncValidators,
@@ -135,12 +139,12 @@ const WmFormField = memo(
135
139
  }
136
140
  }
137
141
  const isDynamicFormField = typeof props.className === "string" && props.className.includes("app-dynamic-form-field");
138
- const itemsPerRowClass = !isDynamicFormField && ((_c = props.formRef) == null ? void 0 : _c.itemsPerRow) || "";
142
+ const itemsPerRowClass = !isDynamicFormField && ((_d = props.formRef) == null ? void 0 : _d.itemsPerRow) || "";
139
143
  if (!fieldProxyRef.current) {
140
144
  return null;
141
145
  }
142
146
  const isDeferLoad = deferload === true;
143
- const showValue = ((_d = proxyProps == null ? void 0 : proxyProps.show) == null ? void 0 : _d.toString()) !== "false";
147
+ const showValue = (showfield == null ? void 0 : showfield.toString()) !== "false";
144
148
  if ((!showValue || showfield) && isDeferLoad) {
145
149
  return null;
146
150
  }
@@ -98,8 +98,6 @@ const ListItems = ({
98
98
  if (onBeforedatarender && widgetInstance) {
99
99
  onBeforedatarender(widgetInstance, rawCurrentPageItems.currentItems);
100
100
  }
101
- }, [rawCurrentItemsKey, groupby]);
102
- useEffect(() => {
103
101
  if (onRender) {
104
102
  if (groupby) {
105
103
  const currentPageGroupedItems = paginatedGroupedData.reduce((acc, group) => {
@@ -110,7 +108,7 @@ const ListItems = ({
110
108
  onRender(widgetInstance, currentPageItems.currentItems);
111
109
  }
112
110
  }
113
- }, []);
111
+ }, [rawCurrentItemsKey, groupby, currentPage]);
114
112
  const totalGroupedItems = useMemo(() => {
115
113
  if (!groupedData || !Array.isArray(groupedData)) return 0;
116
114
  return groupedData.reduce((total, group) => {
@@ -393,7 +393,7 @@ const WmList = (props) => {
393
393
  } else {
394
394
  widgetMethods.selectItem(selecteditem);
395
395
  }
396
- }, [selecteditem, widgetMethods, listState]);
396
+ }, [selecteditem]);
397
397
  useListEffects({
398
398
  name,
399
399
  navigation,
@@ -511,7 +511,7 @@ const WmList = (props) => {
511
511
  );
512
512
  return /* @__PURE__ */ jsxs(
513
513
  Box,
514
- __spreadProps(__spreadValues({
514
+ __spreadProps(__spreadValues(__spreadProps(__spreadValues({
515
515
  className: clsx(
516
516
  DEFAULT_CLS,
517
517
  "wm-position-relative",
@@ -523,7 +523,8 @@ const WmList = (props) => {
523
523
  "data-name": name
524
524
  }, { name }), {
525
525
  "data-navigation": navigation,
526
- ref: ListWrapperRef,
526
+ ref: ListWrapperRef
527
+ }), direction ? { direction } : {}), {
527
528
  children: [
528
529
  /* @__PURE__ */ jsx(
529
530
  ListHeader,
@@ -648,7 +649,7 @@ const WmList = (props) => {
648
649
  listDirection: direction,
649
650
  scrollContainerRef: listScrollContainerRef,
650
651
  sentinelRef: scrollSentinelRef,
651
- orderedDataset: groupby ? Array(paginationState.totalItems).fill(null) : items,
652
+ orderedDataset: groupby && navigation !== LIST_NAVIGATION_TYPES.SCROLL ? Array(paginationState.totalItems).fill(null) : items,
652
653
  pagesize: paginationState.currentPageSize,
653
654
  navigationalign,
654
655
  showrecordcount,
@@ -530,7 +530,7 @@ const usePagination = ({
530
530
  }
531
531
  setPaginationState((prev) => __spreadProps(__spreadValues({}, prev), { currentPage: newPage }));
532
532
  if (isServerSidePagination) {
533
- datasourceInvoke(newPage).then(() => {
533
+ datasourceInvoke(newPage).then((response) => {
534
534
  if (onPaginationChange) {
535
535
  onPaginationChange(
536
536
  event || createDummyEvent("paginationchange"),
@@ -541,7 +541,7 @@ const usePagination = ({
541
541
  if (onSetRecord) {
542
542
  const firstRow = (newPage - 1) * paginationState.currentMaxResults;
543
543
  const startIndex = firstRow;
544
- const data = isArray(dataState.fullData) ? dataState.fullData.slice(
544
+ const data = response && isArray(response.data) ? addUniqueRowIds(response.data) : isArray(dataState.fullData) ? dataState.fullData.slice(
545
545
  startIndex,
546
546
  startIndex + paginationState.currentMaxResults
547
547
  ) : dataState.fullData;
@@ -71,7 +71,7 @@ const RowCells = memo(
71
71
  tabIndex: 0,
72
72
  "data-col-id": cellIndex,
73
73
  className: `${TABLE_CSS_CLASSES.tableCell} ${colClass || ""} ${((_e = cell.column.columnDef.meta) == null ? void 0 : _e.className) || ""}`.trim(),
74
- style: __spreadProps(__spreadValues(__spreadValues({
74
+ style: __spreadValues(__spreadProps(__spreadValues(__spreadValues({
75
75
  width: cell.column.getSize(),
76
76
  textAlign: (_f = cell.column.columnDef.meta) == null ? void 0 : _f.textAlign,
77
77
  backgroundColor: (_g = cell.column.columnDef.meta) == null ? void 0 : _g.backgroundColor
@@ -95,6 +95,8 @@ const RowCells = memo(
95
95
  })()), getDomHiddenCellStyle(cell.column.columnDef.meta)), {
96
96
  fontSize: "inherit",
97
97
  color: "inherit"
98
+ }), hasCustomCellContent && {
99
+ textOverflow: "clip"
98
100
  }),
99
101
  children: customRender ? /* @__PURE__ */ jsx(CustomExpressionRenderBody, { rowData, render: customRender }) : ((_h = cell.column.columnDef.meta) == null ? void 0 : _h.renderCellContent) && !isEditingRow ? (_i = cell.column.columnDef.meta) == null ? void 0 : _i.renderCellContent(rowData, cell.column.columnDef) : flexRender(cell.column.columnDef.cell, cell.getContext())
100
102
  },
@@ -109,7 +109,7 @@ const ExpandedContent = memo(({ rowId, rowData, config, colSpan, onInstanceLoad
109
109
  return /* @__PURE__ */ jsx(
110
110
  TableRow,
111
111
  {
112
- className: "expanded-row-content",
112
+ className: "expanded-row-content app-datagrid-detail-row",
113
113
  "data-row-id": rowId,
114
114
  role: "row",
115
115
  tabIndex: 0,
@@ -121,6 +121,7 @@ const ExpandedContent = memo(({ rowId, rowData, config, colSpan, onInstanceLoad
121
121
  role: "cell",
122
122
  "data-col-id": "expanded-content",
123
123
  tabIndex: 0,
124
+ className: "app-datagrid-row-details-cell",
124
125
  style: {
125
126
  padding: "16px",
126
127
  borderBottom: "1px solid #e0e0e0"
@@ -68,7 +68,7 @@ const TableDataRowComponent = ({
68
68
  /* @__PURE__ */ jsx(
69
69
  TableRow,
70
70
  {
71
- className: `${TABLE_CSS_CLASSES.tableRow} ${isActive ? "active" : ""} ${rowClass}`,
71
+ className: `${TABLE_CSS_CLASSES.tableRow} ${isActive ? "active" : ""} ${hasExpansion && rowIsExpanded ? "expanded" : ""} ${rowClass}`,
72
72
  onClick: handleClick,
73
73
  "data-row-id": row.index,
74
74
  role: "row",
@@ -380,6 +380,7 @@ const TableHeaderComponent = memo(
380
380
  const isClickable = enablecolumnselection && !isSystemColumn || enablesort && header.column.getCanSort();
381
381
  const headerCellResizableClass = header.column.getCanResize() ? " ui-resizable" : "";
382
382
  const headerMeta = header.column.columnDef.meta;
383
+ const isMultiSelectHeader = columnId === "multiSelect";
383
384
  cells.push(
384
385
  /* @__PURE__ */ jsxs(
385
386
  TableCell,
@@ -402,7 +403,10 @@ const TableHeaderComponent = memo(
402
403
  tabIndex: 0,
403
404
  "data-col-field": header.column.id,
404
405
  children: [
405
- /* @__PURE__ */ jsx("span", { className: "header-data", children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }),
406
+ isMultiSelectHeader && !header.isPlaceholder ? /* @__PURE__ */ jsxs(Fragment, { children: [
407
+ flexRender(header.column.columnDef.header, header.getContext()),
408
+ /* @__PURE__ */ jsx("span", { className: "header-data", children: "\xA0" })
409
+ ] }) : /* @__PURE__ */ jsx("span", { className: "header-data", children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }),
406
410
  enablesort && !enablecolumnselection && header.column.getCanSort() && /* @__PURE__ */ jsx(
407
411
  Box,
408
412
  {
@@ -1,5 +1,7 @@
1
1
  import { UseRowHandlersProps, UseRowHandlersReturn } from "../props";
2
2
  /**
3
- * Hook to consolidate all row click handlers
3
+ * Hook to consolidate all row click handlers.
4
+ * Angular rowSelectionHandler: callOnRowClickEvent first, then toggle + onRowSelect.
5
+ * Checkbox/radio clicks bubble to the row (rowclick), then onChange fires rowselect.
4
6
  */
5
- export declare const useRowHandlers: ({ editingRowId, isAddingNewRow, handleRowSelectionClick, handleTableEditRowClick, handleRowActiveClick, onRowclick, useRadioSelect, useMultiSelect, isrowselectable, listener, name, }: UseRowHandlersProps) => UseRowHandlersReturn;
7
+ export declare const useRowHandlers: ({ editingRowId, isAddingNewRow, handleRowSelectionClick, handleTableEditRowClick, handleRowActiveClick, onRowclick, useRadioSelect, useMultiSelect, isrowselectable, listener, viewParent, name, widgetRegistrationKey, }: UseRowHandlersProps) => UseRowHandlersReturn;
@@ -1,5 +1,6 @@
1
1
  import { useCallback } from "react";
2
2
  import { cleanRowData } from "../utils";
3
+ import { getWidgetForCallback, toNativeEvent } from "../utils/selectionUtils";
3
4
  const useRowHandlers = ({
4
5
  editingRowId,
5
6
  isAddingNewRow,
@@ -11,18 +12,29 @@ const useRowHandlers = ({
11
12
  useMultiSelect = false,
12
13
  isrowselectable = false,
13
14
  listener,
14
- name
15
+ viewParent,
16
+ name,
17
+ widgetRegistrationKey
15
18
  }) => {
19
+ const widgetKey = widgetRegistrationKey != null ? widgetRegistrationKey : name;
20
+ const getWidgetRef = useCallback(
21
+ () => getWidgetForCallback(listener, viewParent, widgetKey),
22
+ [viewParent, widgetKey]
23
+ );
24
+ const invokeRowClick = useCallback(
25
+ (event, rowData) => {
26
+ if (!onRowclick) return;
27
+ const widget = getWidgetRef();
28
+ if (widget) {
29
+ widget.nativeElement = event.target;
30
+ }
31
+ onRowclick(toNativeEvent(event), widget, cleanRowData(rowData));
32
+ },
33
+ [onRowclick, getWidgetRef]
34
+ );
16
35
  const handleRowClick = useCallback(
17
36
  (event, rowData, rowId) => {
18
- var _a, _b;
19
37
  const hasSelectionMode = useRadioSelect || useMultiSelect;
20
- if (onRowclick) {
21
- if ((_a = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _a[name]) {
22
- listener.Widgets[name].nativeElement = event.target;
23
- }
24
- onRowclick(event, (_b = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _b[name], cleanRowData(rowData));
25
- }
26
38
  let isSelectionHandled = false;
27
39
  if (hasSelectionMode && isrowselectable) {
28
40
  isSelectionHandled = handleRowSelectionClick(event, rowId, rowData);
@@ -35,6 +47,7 @@ const useRowHandlers = ({
35
47
  return;
36
48
  }
37
49
  handleRowActiveClick(rowId, isSelectionHandled, isEditingOrAdding);
50
+ invokeRowClick(event, rowData);
38
51
  },
39
52
  [
40
53
  editingRowId,
@@ -42,11 +55,10 @@ const useRowHandlers = ({
42
55
  handleRowSelectionClick,
43
56
  handleTableEditRowClick,
44
57
  handleRowActiveClick,
45
- onRowclick,
58
+ invokeRowClick,
46
59
  useRadioSelect,
47
60
  useMultiSelect,
48
- isrowselectable,
49
- name
61
+ isrowselectable
50
62
  ]
51
63
  );
52
64
  return {
@@ -1,2 +1,2 @@
1
1
  import { UseRowSelectionProps, UseRowSelectionReturn } from "../props";
2
- export declare const useRowSelection: ({ radioselect, multiselect, gridfirstrowselect, internalDataset, cellState, name, statehandler, initialActualPageSize, getTableState: getTableCurrentState, onRowselect, onRowdeselect, listener, navigation, onSyncSelectedItems, }: UseRowSelectionProps) => UseRowSelectionReturn;
2
+ export declare const useRowSelection: ({ radioselect, multiselect, gridfirstrowselect, internalDataset, cellState, name, statehandler, initialActualPageSize, getTableState: getTableCurrentState, onRowselect, onRowdeselect, listener, navigation, viewParent, widgetRegistrationKey, onSyncSelectedItems, }: UseRowSelectionProps) => UseRowSelectionReturn;
@@ -3,10 +3,21 @@ import {
3
3
  isInteractiveElement,
4
4
  getRowIdsFromDataset,
5
5
  rowExistsInDataset,
6
- selectionStateHelpers
6
+ selectionStateHelpers,
7
+ getWidgetForCallback,
8
+ toNativeEvent,
9
+ createSelectionEventStub
7
10
  } from "../utils/selectionUtils";
8
11
  import { saveTableState, getTableState } from "../utils/table-helpers";
9
12
  import { cleanRowData, UNSUPPORTED_STATE_PERSISTENCE_TYPES } from "../utils";
13
+ const getRowFallbackId = (row) => row._wmTableRowId || String(row.id) || String(0);
14
+ const getSelectedIndices = (selectedIds, dataset) => selectedIds.reduce((indices, rowId) => {
15
+ const index = dataset.findIndex((row) => row._wmTableRowId === rowId || row.id === rowId);
16
+ if (index >= 0) {
17
+ indices.push(index);
18
+ }
19
+ return indices;
20
+ }, []);
10
21
  const useRowSelection = ({
11
22
  radioselect = false,
12
23
  multiselect = false,
@@ -21,6 +32,8 @@ const useRowSelection = ({
21
32
  onRowdeselect,
22
33
  listener,
23
34
  navigation = "Basic",
35
+ viewParent,
36
+ widgetRegistrationKey,
24
37
  onSyncSelectedItems
25
38
  }) => {
26
39
  const datasetRef = useRef(internalDataset);
@@ -31,22 +44,36 @@ const useRowSelection = ({
31
44
  const [updateTrigger, forceUpdate] = useState({});
32
45
  const useMultiSelect = multiselect;
33
46
  const useRadioSelect = radioselect && !multiselect;
34
- const hasSelectionMode = useRadioSelect || useMultiSelect;
47
+ const prevMultiselectRef = useRef(multiselect);
48
+ useEffect(() => {
49
+ const prev = prevMultiselectRef.current;
50
+ prevMultiselectRef.current = multiselect;
51
+ if (prev === multiselect) return;
52
+ selectionStateHelpers.clearSelection(cellState);
53
+ forceUpdate({});
54
+ onSyncSelectedItems == null ? void 0 : onSyncSelectedItems([]);
55
+ if (statehandler && getTableCurrentState) {
56
+ saveTableState(name, statehandler, {});
57
+ }
58
+ }, [multiselect, cellState, onSyncSelectedItems, statehandler, name, getTableCurrentState]);
59
+ const applySelectionForMode = useCallback(
60
+ (rowIds) => {
61
+ if (rowIds.length === 0) return;
62
+ if (useMultiSelect) {
63
+ rowIds.forEach((rowId) => selectionStateHelpers.addToSelection(cellState, rowId));
64
+ } else {
65
+ selectionStateHelpers.setSelection(cellState, rowIds[0]);
66
+ }
67
+ },
68
+ [useMultiSelect, cellState]
69
+ );
35
70
  const saveStateImmediate = useCallback(() => {
36
71
  if (!statehandler || !getTableCurrentState) {
37
72
  return;
38
73
  }
39
74
  const { currentPage, currentPageSize } = getTableCurrentState();
40
75
  const selectedIds = selectionStateHelpers.getSelection(cellState);
41
- const selectedIndices = [];
42
- selectedIds.forEach((rowId) => {
43
- const index = internalDataset.findIndex(
44
- (row) => row._wmTableRowId === rowId || row.id === rowId
45
- );
46
- if (index >= 0) {
47
- selectedIndices.push(index);
48
- }
49
- });
76
+ const selectedIndices = getSelectedIndices(selectedIds, internalDataset);
50
77
  const selectedItemsWithPage = selectedIndices.map((idx) => ({
51
78
  page: currentPage,
52
79
  index: idx
@@ -91,22 +118,39 @@ const useRowSelection = ({
91
118
  internalDataset,
92
119
  initialActualPageSize
93
120
  ]);
94
- const getWidgetRef = useCallback(() => {
95
- var _a;
96
- return (_a = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _a[name];
97
- }, [name]);
121
+ const widgetKey = widgetRegistrationKey != null ? widgetRegistrationKey : name;
122
+ const getWidgetRef = useCallback(
123
+ () => getWidgetForCallback(listener, viewParent, widgetKey),
124
+ [viewParent, widgetKey]
125
+ );
126
+ const syncSelectionToWidget = useCallback(
127
+ (selectedIds) => {
128
+ const ids = selectedIds != null ? selectedIds : selectionStateHelpers.getSelection(cellState);
129
+ onSyncSelectedItems == null ? void 0 : onSyncSelectedItems(ids);
130
+ },
131
+ [onSyncSelectedItems, cellState]
132
+ );
133
+ const commitSelectionChange = useCallback(
134
+ (syncIds) => {
135
+ forceUpdate({});
136
+ saveStateImmediate();
137
+ syncSelectionToWidget(syncIds);
138
+ },
139
+ [saveStateImmediate, syncSelectionToWidget]
140
+ );
98
141
  const triggerSelectionCallback = useCallback(
99
142
  (event, rowData, callback) => {
143
+ var _a;
100
144
  if (callback && rowData) {
101
- onSyncSelectedItems == null ? void 0 : onSyncSelectedItems(selectionStateHelpers.getSelection(cellState));
145
+ const widget = getWidgetRef();
102
146
  const cleanedRow = cleanRowData([rowData])[0];
103
- callback(event, getWidgetRef(), cleanedRow);
147
+ callback((_a = toNativeEvent(event)) != null ? _a : createSelectionEventStub(), widget, cleanedRow);
104
148
  }
105
149
  },
106
- [getWidgetRef, onSyncSelectedItems, cellState]
150
+ [getWidgetRef]
107
151
  );
108
152
  const handleRadioSelection = useCallback(
109
- (rowId, rowData) => {
153
+ (rowId, rowData, event) => {
110
154
  const previousSelection = selectionStateHelpers.getSelection(cellState);
111
155
  const previousRowId = previousSelection.length > 0 ? previousSelection[0] : null;
112
156
  let previousRowData = null;
@@ -116,16 +160,15 @@ const useRowSelection = ({
116
160
  );
117
161
  }
118
162
  selectionStateHelpers.setSelection(cellState, rowId);
119
- forceUpdate({});
120
- saveStateImmediate();
163
+ commitSelectionChange();
121
164
  if (previousRowData) {
122
- triggerSelectionCallback(null, previousRowData, onRowdeselect);
165
+ triggerSelectionCallback(event, previousRowData, onRowdeselect);
123
166
  }
124
- triggerSelectionCallback(null, rowData, onRowselect);
167
+ triggerSelectionCallback(event, rowData, onRowselect);
125
168
  },
126
169
  [
127
170
  cellState,
128
- saveStateImmediate,
171
+ commitSelectionChange,
129
172
  onRowselect,
130
173
  onRowdeselect,
131
174
  internalDataset,
@@ -133,20 +176,20 @@ const useRowSelection = ({
133
176
  ]
134
177
  );
135
178
  const handleMultiSelection = useCallback(
136
- (rowId, rowData, isSelected) => {
179
+ (rowId, rowData, isSelected, event) => {
137
180
  if (isSelected) {
138
181
  selectionStateHelpers.addToSelection(cellState, rowId);
139
182
  } else {
140
183
  selectionStateHelpers.removeFromSelection(cellState, rowId);
141
184
  }
142
- forceUpdate({});
143
- saveStateImmediate();
144
- triggerSelectionCallback(null, rowData, isSelected ? onRowselect : onRowdeselect);
185
+ commitSelectionChange();
186
+ triggerSelectionCallback(event, rowData, isSelected ? onRowselect : onRowdeselect);
145
187
  },
146
- [cellState, saveStateImmediate, onRowselect, onRowdeselect, triggerSelectionCallback]
188
+ [cellState, commitSelectionChange, onRowselect, onRowdeselect, triggerSelectionCallback]
147
189
  );
148
190
  const handleSelectAll = useCallback(
149
- (isSelected) => {
191
+ (isSelected, event) => {
192
+ var _a;
150
193
  let newIds = [];
151
194
  if (isSelected) {
152
195
  newIds = getRowIdsFromDataset(datasetRef.current);
@@ -154,19 +197,18 @@ const useRowSelection = ({
154
197
  } else {
155
198
  selectionStateHelpers.clearSelection(cellState);
156
199
  }
157
- forceUpdate({});
158
- saveStateImmediate();
159
- onSyncSelectedItems == null ? void 0 : onSyncSelectedItems(newIds);
200
+ commitSelectionChange(newIds);
160
201
  const rows = datasetRef.current;
161
202
  const callback = isSelected ? onRowselect : onRowdeselect;
162
203
  if (callback && rows.length > 0) {
204
+ const sharedEvent = (_a = toNativeEvent(event)) != null ? _a : createSelectionEventStub();
163
205
  rows.forEach((row) => {
164
206
  const cleanedRow = cleanRowData([row])[0];
165
- callback(null, getWidgetRef(), cleanedRow);
207
+ callback(sharedEvent, getWidgetRef(), cleanedRow);
166
208
  });
167
209
  }
168
210
  },
169
- [cellState, saveStateImmediate, onSyncSelectedItems, onRowselect, onRowdeselect, getWidgetRef]
211
+ [cellState, commitSelectionChange, onRowselect, onRowdeselect, getWidgetRef]
170
212
  );
171
213
  const handleRowSelectionClick = useCallback(
172
214
  (event, rowId, rowData) => {
@@ -177,20 +219,18 @@ const useRowSelection = ({
177
219
  const isCurrentlySelected = selectionStateHelpers.isRowSelected(cellState, rowId);
178
220
  const willBeSelected = !isCurrentlySelected;
179
221
  selectionStateHelpers.toggleSelection(cellState, rowId);
180
- forceUpdate({});
181
- saveStateImmediate();
222
+ commitSelectionChange();
182
223
  triggerSelectionCallback(event, rowData, willBeSelected ? onRowselect : onRowdeselect);
183
224
  return true;
184
- } else {
185
- handleRadioSelection(rowId, rowData);
186
- return true;
187
225
  }
226
+ handleRadioSelection(rowId, rowData);
227
+ return true;
188
228
  },
189
229
  [
190
230
  useMultiSelect,
191
231
  handleRadioSelection,
192
232
  cellState,
193
- saveStateImmediate,
233
+ commitSelectionChange,
194
234
  triggerSelectionCallback,
195
235
  onRowselect,
196
236
  onRowdeselect
@@ -202,26 +242,22 @@ const useRowSelection = ({
202
242
  }
203
243
  if (gridfirstrowselect && internalDataset.length > 0) {
204
244
  const firstRowData = internalDataset[0];
205
- const firstRowId = firstRowData._wmTableRowId || String(firstRowData.id) || String(0);
245
+ const firstRowId = getRowFallbackId(firstRowData);
206
246
  const currentSelection = selectionStateHelpers.getSelection(cellState);
207
247
  if (currentSelection.length === 0) {
208
- if (useMultiSelect) {
209
- selectionStateHelpers.addToSelection(cellState, firstRowId);
210
- } else {
211
- selectionStateHelpers.setSelection(cellState, firstRowId);
212
- }
248
+ applySelectionForMode([firstRowId]);
213
249
  forceUpdate({});
214
250
  initialSelectionDoneRef.current = true;
215
251
  } else if (!useMultiSelect) {
216
252
  const selectedId = currentSelection[0];
217
253
  if (!rowExistsInDataset(selectedId, internalDataset)) {
218
- selectionStateHelpers.setSelection(cellState, firstRowId);
254
+ applySelectionForMode([firstRowId]);
219
255
  forceUpdate({});
220
256
  initialSelectionDoneRef.current = true;
221
257
  }
222
258
  }
223
259
  }
224
- }, [gridfirstrowselect, internalDataset, useMultiSelect, cellState]);
260
+ }, [gridfirstrowselect, internalDataset, useMultiSelect, cellState, applySelectionForMode]);
225
261
  useEffect(() => {
226
262
  var _a;
227
263
  if (!gridfirstrowselect || internalDataset.length === 0 || !initialSelectionDoneRef.current) {
@@ -239,15 +275,11 @@ const useRowSelection = ({
239
275
  );
240
276
  if (!hasSelectionInCurrentPage) {
241
277
  const firstRowData = internalDataset[0];
242
- const firstRowId = firstRowData._wmTableRowId || String(firstRowData.id) || String(0);
243
- if (useMultiSelect) {
244
- selectionStateHelpers.addToSelection(cellState, firstRowId);
245
- } else {
246
- selectionStateHelpers.setSelection(cellState, firstRowId);
247
- }
278
+ const firstRowId = getRowFallbackId(firstRowData);
279
+ applySelectionForMode([firstRowId]);
248
280
  forceUpdate({});
249
281
  if (onRowselect) {
250
- triggerSelectionCallback(null, firstRowData, onRowselect);
282
+ triggerSelectionCallback(void 0, firstRowData, onRowselect);
251
283
  }
252
284
  }
253
285
  }, [
@@ -259,7 +291,8 @@ const useRowSelection = ({
259
291
  name,
260
292
  statehandler,
261
293
  onRowselect,
262
- triggerSelectionCallback
294
+ triggerSelectionCallback,
295
+ applySelectionForMode
263
296
  ]);
264
297
  const isRowSelected = useCallback(
265
298
  (rowId) => {
@@ -302,23 +335,8 @@ const useRowSelection = ({
302
335
  if (!isAlreadyRestored && expectedRowIds.length > 0) {
303
336
  if (useMultiSelect) {
304
337
  selectionStateHelpers.clearSelection(cellState);
305
- currentPageSelections.forEach((index) => {
306
- if (index >= 0 && index < internalDataset.length) {
307
- const row = internalDataset[index];
308
- if (row && row._wmTableRowId) {
309
- selectionStateHelpers.addToSelection(cellState, row._wmTableRowId);
310
- }
311
- }
312
- });
313
- } else {
314
- const firstIndex = currentPageSelections[0];
315
- if (firstIndex >= 0 && firstIndex < internalDataset.length) {
316
- const row = internalDataset[firstIndex];
317
- if (row && row._wmTableRowId) {
318
- selectionStateHelpers.setSelection(cellState, row._wmTableRowId);
319
- }
320
- }
321
338
  }
339
+ applySelectionForMode(expectedRowIds);
322
340
  forceUpdate({});
323
341
  }
324
342
  }
@@ -329,7 +347,8 @@ const useRowSelection = ({
329
347
  navigation,
330
348
  internalDataset,
331
349
  cellState,
332
- useMultiSelect
350
+ useMultiSelect,
351
+ applySelectionForMode
333
352
  ]);
334
353
  return {
335
354
  selectedRowIds,