@wavemaker-ai/react-runtime 1.0.0-rc.328 → 1.0.0-rc.332

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 (50) hide show
  1. package/actions/notification-action.js +3 -3
  2. package/actions/toast.js +2 -1
  3. package/components/basic/message/index.js +1 -0
  4. package/components/basic/search/index.js +9 -11
  5. package/components/basic/search/providers.d.ts +1 -1
  6. package/components/basic/search/providers.js +6 -3
  7. package/components/container/layout-grid/index.js +1 -0
  8. package/components/container/linear-layout/index.js +0 -1
  9. package/components/data/form/base-form/hooks/useFormOperations.js +9 -15
  10. package/components/data/form/base-form/index.js +17 -14
  11. package/components/data/form/base-form/utils.js +5 -4
  12. package/components/data/form/form-action/index.d.ts +2 -2
  13. package/components/data/form/form-action/index.js +2 -2
  14. package/components/data/form/form-context.d.ts +12 -13
  15. package/components/data/form/form-context.js +4 -6
  16. package/components/data/form/form-controller/withFormController.js +4 -4
  17. package/components/data/form/form-field/index.js +6 -5
  18. package/components/data/list/components/ListItems.js +1 -3
  19. package/components/data/list/index.js +2 -2
  20. package/components/data/pagination/hooks/usePagination.js +2 -2
  21. package/components/data/table/components/TableBody.js +2 -1
  22. package/components/data/table/components/TableDataRow.js +1 -1
  23. package/components/data/table/hooks/useRowHandlers.js +2 -2
  24. package/components/data/table/hooks/useRowSelection.js +15 -10
  25. package/components/data/table/hooks/useTableColumns.js +5 -5
  26. package/components/data/table/index.js +2 -2
  27. package/components/data/table/props.d.ts +8 -8
  28. package/components/data/table/utils/buildSelectionColumns.js +30 -30
  29. package/components/data/table/utils/index.js +15 -1
  30. package/components/data/table/utils/selectionUtils.d.ts +2 -0
  31. package/components/data/table/utils/selectionUtils.js +23 -1
  32. package/components/dialogs/dialog-actions/index.js +11 -2
  33. package/components/input/epoch/date/index.js +2 -1
  34. package/components/input/epoch/date/utils.js +4 -2
  35. package/components/input/epoch/datetime/index.js +2 -2
  36. package/components/input/epoch/datetime/props.d.ts +2 -2
  37. package/components/input/epoch/time/utils.d.ts +1 -1
  38. package/components/input/epoch/time/utils.js +2 -2
  39. package/components/input/fileupload/useFileUpload.js +19 -24
  40. package/components/input/select/index.js +6 -3
  41. package/components/navigation/popover/index.d.ts +1 -1
  42. package/components/navigation/popover/index.js +1 -1
  43. package/components/navigation/popover/props.d.ts +1 -1
  44. package/core/proxy-service.d.ts +16 -1
  45. package/core/proxy-service.js +39 -12
  46. package/higherOrder/BaseDateTime.js +8 -1
  47. package/higherOrder/BasePage.js +7 -2
  48. package/higherOrder/withBaseWrapper.js +3 -4
  49. package/package-lock.json +241 -221
  50. package/package.json +3 -3
@@ -45,7 +45,7 @@ import {
45
45
  import { distributeColumnWidths } from "../utils/columnWidthDistribution";
46
46
  import { useResponsiveColumns } from "./useResponsiveColumns";
47
47
  import WmTableRowAction from "../table-row-action";
48
- const handleActionSelection = (rowId, rowData, handlers) => {
48
+ const handleActionSelection = (rowId, rowData, handlers, event) => {
49
49
  const {
50
50
  useMultiSelect,
51
51
  handleMultiSelection,
@@ -55,9 +55,9 @@ const handleActionSelection = (rowId, rowData, handlers) => {
55
55
  } = handlers;
56
56
  if (useMultiSelect && handleMultiSelection && isRowSelected) {
57
57
  const currentlySelected = isRowSelected(rowId);
58
- handleMultiSelection(rowId, rowData, !currentlySelected);
58
+ handleMultiSelection(rowId, rowData, !currentlySelected, event);
59
59
  } else if (useRadioSelect && handleRadioSelection) {
60
- handleRadioSelection(rowId, rowData);
60
+ handleRadioSelection(rowId, rowData, event);
61
61
  }
62
62
  };
63
63
  const createActionClickHandler = (rowData, rowId, handlers, actionOnClick) => {
@@ -65,7 +65,7 @@ const createActionClickHandler = (rowData, rowId, handlers, actionOnClick) => {
65
65
  if (handlers.handleRowClick && event) {
66
66
  handlers.handleRowClick(event, rowData, rowId);
67
67
  }
68
- handleActionSelection(rowId, rowData, handlers);
68
+ handleActionSelection(rowId, rowData, handlers, event);
69
69
  actionOnClick == null ? void 0 : actionOnClick(event, widget, newVal);
70
70
  };
71
71
  };
@@ -123,7 +123,7 @@ const EditingActionButtons = React.memo(
123
123
  const isDeleteButton = button.key === "delete-edit";
124
124
  if (isDeleteButton && event) {
125
125
  (_a = selectionHandlers.handleRowClick) == null ? void 0 : _a.call(selectionHandlers, event, rowData, rowId);
126
- handleActionSelection(rowId, rowData, selectionHandlers);
126
+ handleActionSelection(rowId, rowData, selectionHandlers, event);
127
127
  }
128
128
  switch (button.key) {
129
129
  case "save-edit":
@@ -778,8 +778,8 @@ const WmTableComponent = memo(
778
778
  if (name && (listener == null ? void 0 : listener.Widgets[name]) && tableContainerRef.current) {
779
779
  listener.Widgets[name].nativeElement = tableContainerRef.current;
780
780
  }
781
- const data = internalDataset;
782
- onDatarender((_a2 = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _a2[name], { $data: data, data });
781
+ const data = internalDataset && internalDataset.length > 0 ? internalDataset : table.getRowModel().rows.map((row) => row.original) || [];
782
+ onDatarender((_a2 = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _a2[name], data);
783
783
  }, [onDatarender, name]);
784
784
  columnsStateRef.current = columns;
785
785
  const columnsForTable = useMemo(() => {
@@ -942,9 +942,9 @@ export interface BuildSelectionColumnsProps {
942
942
  useMultiSelect: boolean;
943
943
  /** @deprecated Header now reads from table.getIsAllRowsSelected() — no longer used internally. */
944
944
  selectedRowIds?: string[];
945
- handleRadioSelection: (rowId: string, rowData?: any) => void;
946
- handleMultiSelection: (rowId: string, rowData: any, isSelected: boolean) => void;
947
- handleSelectAll: (isSelected: boolean) => void;
945
+ handleRadioSelection: (rowId: string, rowData?: any, event?: any) => void;
946
+ handleMultiSelection: (rowId: string, rowData: any, isSelected: boolean, event?: any) => void;
947
+ handleSelectAll: (isSelected: boolean, event?: any) => void;
948
948
  /** @deprecated Header now reads from table.getIsAllRowsSelected() — no longer used internally. */
949
949
  internalDataset?: any[];
950
950
  radioselecttitle?: string;
@@ -1056,8 +1056,8 @@ export interface UseTableColumnsProps {
1056
1056
  cellState?: CellStateReturn;
1057
1057
  isResizing?: boolean;
1058
1058
  handleRowClick?: (event: React.MouseEvent, rowData: any, rowId: string) => void;
1059
- handleRadioSelection?: (rowId: string, rowData: any) => void;
1060
- handleMultiSelection?: (rowId: string, rowData: any, checked: boolean) => void;
1059
+ handleRadioSelection?: (rowId: string, rowData: any, event?: any) => void;
1060
+ handleMultiSelection?: (rowId: string, rowData: any, checked: boolean, event?: any) => void;
1061
1061
  useRadioSelect?: boolean;
1062
1062
  useMultiSelect?: boolean;
1063
1063
  isRowSelected?: (rowId: string) => boolean;
@@ -1121,9 +1121,9 @@ export interface UseRowSelectionReturn {
1121
1121
  selectedRowIds: string[];
1122
1122
  useMultiSelect: boolean;
1123
1123
  useRadioSelect: boolean;
1124
- handleRadioSelection: (rowId: string, rowData?: any) => void;
1125
- handleMultiSelection: (rowId: string, rowData: any, isSelected: boolean) => void;
1126
- handleSelectAll: (isSelected: boolean) => void;
1124
+ handleRadioSelection: (rowId: string, rowData?: any, event?: any) => void;
1125
+ handleMultiSelection: (rowId: string, rowData: any, isSelected: boolean, event?: any) => void;
1126
+ handleSelectAll: (isSelected: boolean, event?: any) => void;
1127
1127
  handleRowSelectionClick: (event: MouseEvent, rowId: string, rowData: any) => boolean;
1128
1128
  isRowSelected: (rowId: string) => boolean;
1129
1129
  isInteractiveElement: (event: MouseEvent) => boolean;
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Box, Radio, Checkbox, FormControlLabel, Tooltip } from "@mui/material";
2
+ import { Box, Radio, FormControlLabel, Tooltip } from "@mui/material";
3
3
  import { TABLE_MESSAGES } from "./constants";
4
4
  const getSelectionMeta = (ctx) => {
5
5
  var _a, _b, _c, _d;
@@ -17,7 +17,7 @@ function RadioSelectCell(ctx) {
17
17
  Radio,
18
18
  {
19
19
  checked: isSelected,
20
- onChange: () => handleRadioSelection == null ? void 0 : handleRadioSelection(rowId, row.original),
20
+ onChange: (e) => handleRadioSelection == null ? void 0 : handleRadioSelection(rowId, row.original, e),
21
21
  value: rowId,
22
22
  name: `wmRadioselect-${tableName != null ? tableName : "table"}`,
23
23
  inputProps: {
@@ -39,24 +39,23 @@ function MultiSelectCell(ctx) {
39
39
  const isSelected = row.getIsSelected();
40
40
  const { handleMultiSelection, multiselecttitle, multiselectarialabel } = getSelectionMeta(ctx);
41
41
  return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex" }, children: [
42
- /* @__PURE__ */ jsx(Tooltip, { title: multiselecttitle != null ? multiselecttitle : "", placement: "top", children: /* @__PURE__ */ jsx(Box, { className: "app-checkbox checkbox", children: /* @__PURE__ */ jsx(
43
- Checkbox,
44
- {
45
- checked: isSelected,
46
- onChange: (e) => handleMultiSelection == null ? void 0 : handleMultiSelection(rowId, row.original, e.target.checked),
47
- value: rowId,
48
- name: "gridMultiSelect",
49
- inputProps: {
50
- "aria-label": multiselectarialabel,
42
+ /* @__PURE__ */ jsx(Tooltip, { title: multiselecttitle != null ? multiselecttitle : "", placement: "top", children: /* @__PURE__ */ jsx(Box, { className: "app-checkbox checkbox", children: /* @__PURE__ */ jsxs(Box, { component: "label", className: isSelected ? "" : "unchecked", children: [
43
+ /* @__PURE__ */ jsx(Box, { component: "span", className: "sr-only", "aria-live": "assertive", children: "Select row" }),
44
+ /* @__PURE__ */ jsx(
45
+ Box,
46
+ {
47
+ component: "input",
48
+ type: "checkbox",
51
49
  role: "checkbox",
52
- "aria-live": "assertive"
53
- },
54
- size: "small",
55
- sx: {
56
- padding: 0
50
+ checked: isSelected,
51
+ onChange: (e) => handleMultiSelection == null ? void 0 : handleMultiSelection(rowId, row.original, e.target.checked, e),
52
+ value: rowId,
53
+ name: "gridMultiSelect",
54
+ "aria-label": multiselectarialabel
57
55
  }
58
- }
59
- ) }) }),
56
+ ),
57
+ /* @__PURE__ */ jsx(Box, { component: "span", className: "caption" })
58
+ ] }) }) }),
60
59
  isSelected ? /* @__PURE__ */ jsx("span", { className: "sr-only", "aria-live": "assertive", children: "Row Selected" }) : /* @__PURE__ */ jsx("span", { className: "sr-only", "aria-live": "assertive", children: "Row Deselected" })
61
60
  ] });
62
61
  }
@@ -65,20 +64,21 @@ function MultiSelectHeader({ table, column }) {
65
64
  var _a, _b;
66
65
  const isAllSelected = table.getIsAllRowsSelected();
67
66
  const { handleSelectAll } = (_b = (_a = column.columnDef.meta) == null ? void 0 : _a.selection) != null ? _b : {};
68
- return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", width: "100%" }, children: /* @__PURE__ */ jsx(Box, { className: "app-checkbox checkbox", children: /* @__PURE__ */ jsx(
69
- Checkbox,
70
- {
71
- checked: isAllSelected,
72
- onChange: (e) => handleSelectAll == null ? void 0 : handleSelectAll(e.target.checked),
73
- size: "small",
74
- inputProps: {
67
+ return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", width: "100%" }, children: /* @__PURE__ */ jsx(Box, { className: "app-checkbox checkbox", children: /* @__PURE__ */ jsxs(Box, { component: "label", className: isAllSelected ? "" : "unchecked", children: [
68
+ /* @__PURE__ */ jsx(
69
+ Box,
70
+ {
71
+ component: "input",
72
+ type: "checkbox",
73
+ role: "checkbox",
74
+ checked: isAllSelected,
75
+ onChange: (e) => handleSelectAll == null ? void 0 : handleSelectAll(e.target.checked, e),
76
+ name: "gridMultiSelectAll",
75
77
  "aria-label": "Select all rows"
76
- },
77
- sx: {
78
- padding: 0
79
78
  }
80
- }
81
- ) }) });
79
+ ),
80
+ /* @__PURE__ */ jsx(Box, { component: "span", className: "caption" })
81
+ ] }) }) });
82
82
  }
83
83
  MultiSelectHeader.displayName = "MultiSelectHeader";
84
84
  const buildSelectionColumns = ({
@@ -70,12 +70,26 @@ const hashString = (str, index) => {
70
70
  }
71
71
  return `row_${Math.abs(hash)}_${index}`;
72
72
  };
73
+ const safeStringify = (value) => {
74
+ const seen = /* @__PURE__ */ new WeakSet();
75
+ try {
76
+ return JSON.stringify(value, (_key, val) => {
77
+ if (typeof val === "object" && val !== null) {
78
+ if (seen.has(val)) return "[Circular]";
79
+ seen.add(val);
80
+ }
81
+ return val;
82
+ });
83
+ } catch (e) {
84
+ return String(value);
85
+ }
86
+ };
73
87
  const generateDeterministicHash = (obj, index) => {
74
88
  const hashSource = index.toString() + (isObject(obj) ? transform(
75
89
  omit(obj, "_wmTableRowId"),
76
90
  (result, value, key) => {
77
91
  if (!isNil(value)) {
78
- result.push(`${key}:${isObject(value) ? JSON.stringify(value) : String(value)}`);
92
+ result.push(`${key}:${isObject(value) ? safeStringify(value) : String(value)}`);
79
93
  }
80
94
  },
81
95
  []
@@ -11,6 +11,8 @@ export declare const hasInteractiveAttributes: (element: HTMLElement) => boolean
11
11
  * Check if element or its ancestors are interactive
12
12
  */
13
13
  export declare const isInteractiveElement: (event: React.MouseEvent) => boolean;
14
+ export declare const toNativeEvent: (event: any) => any;
15
+ export declare const createSelectionEventStub: () => any;
14
16
  /**
15
17
  * Widget passed to user callbacks must come from the page proxy (viewParent), which
16
18
  * listener.onChange updates synchronously. listener.Widgets lags one React commit behind.
@@ -47,6 +47,26 @@ const isInteractiveElement = (event) => {
47
47
  }
48
48
  return false;
49
49
  };
50
+ const toNativeEvent = (event) => {
51
+ var _a;
52
+ return (_a = event == null ? void 0 : event.nativeEvent) != null ? _a : event;
53
+ };
54
+ const createSelectionEventStub = () => ({
55
+ target: {
56
+ closest: () => null,
57
+ matches: () => false,
58
+ querySelector: () => null
59
+ },
60
+ currentTarget: null,
61
+ preventDefault: () => {
62
+ },
63
+ stopPropagation: () => {
64
+ },
65
+ stopImmediatePropagation: () => {
66
+ },
67
+ isDefaultPrevented: () => false,
68
+ isPropagationStopped: () => false
69
+ });
50
70
  const getWidgetForCallback = (listener, viewParent, widgetKey) => {
51
71
  var _a, _b, _c;
52
72
  return (_c = (_a = viewParent == null ? void 0 : viewParent.Widgets) == null ? void 0 : _a[widgetKey]) != null ? _c : (_b = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _b[widgetKey];
@@ -106,11 +126,13 @@ const selectionStateHelpers = {
106
126
  }
107
127
  };
108
128
  export {
129
+ createSelectionEventStub,
109
130
  getRowIdsFromDataset,
110
131
  getWidgetForCallback,
111
132
  hasInteractiveAttributes,
112
133
  hasInteractiveClass,
113
134
  isInteractiveElement,
114
135
  rowExistsInDataset,
115
- selectionStateHelpers
136
+ selectionStateHelpers,
137
+ toNativeEvent
116
138
  };
@@ -1,9 +1,18 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
+ import clsx from "clsx";
2
3
  import DialogActions from "@mui/material/DialogActions";
3
4
  import withBaseWrapper from "../../../higherOrder/withBaseWrapper";
4
5
  const WmDialogFooter = (props) => {
5
- const { children } = props;
6
- return /* @__PURE__ */ jsx(DialogActions, { className: "app-dialog-footer modal-footer", children });
6
+ const { children, className, styles, hidden } = props;
7
+ return /* @__PURE__ */ jsx(
8
+ DialogActions,
9
+ {
10
+ className: clsx("app-dialog-footer modal-footer", className),
11
+ style: styles,
12
+ hidden: hidden != null ? hidden : false,
13
+ children
14
+ }
15
+ );
7
16
  };
8
17
  WmDialogFooter.displayName = "WmDialogFooter";
9
18
  var dialog_actions_default = withBaseWrapper(WmDialogFooter);
@@ -153,7 +153,7 @@ const WmDate = forwardRef((props, ref) => {
153
153
  () => {
154
154
  var _a2;
155
155
  return [
156
- defaultDateFormat || ((_a2 = listener == null ? void 0 : listener.localeFormats) == null ? void 0 : _a2.date) || "MMM d, y",
156
+ defaultDateFormat || ((_a2 = listener == null ? void 0 : listener.localeFormats) == null ? void 0 : _a2.date) || "yyyy-MM-dd",
157
157
  selectedLocale || (listener == null ? void 0 : listener.selectedLocale) || "en"
158
158
  ];
159
159
  },
@@ -255,6 +255,7 @@ const WmDate = forwardRef((props, ref) => {
255
255
  if (!dateValue) return "";
256
256
  try {
257
257
  const momentDate = moment(dateValue).locale(currentLocale);
258
+ if (!momentDate.isValid()) return "";
258
259
  const momentPattern = convertToMomentFormat(datepattern);
259
260
  return momentDate.format(momentPattern);
260
261
  } catch (e) {
@@ -57,10 +57,12 @@ const parseExcludedDates = (excludedates, getDateObj) => {
57
57
  };
58
58
  const defaultGetDateObj = (date) => {
59
59
  if (!date) return null;
60
- if (date instanceof Date) return date;
60
+ if (date instanceof Date) return isNaN(date.getTime()) ? null : date;
61
61
  if (typeof date === "string") {
62
62
  const parsedDate = moment(date).toDate();
63
- return isNaN(parsedDate.getTime()) ? new Date(date) : parsedDate;
63
+ if (!isNaN(parsedDate.getTime())) return parsedDate;
64
+ const fallbackDate = new Date(date);
65
+ return isNaN(fallbackDate.getTime()) ? null : fallbackDate;
64
66
  }
65
67
  return null;
66
68
  };
@@ -96,8 +96,8 @@ const WmDateTime = memo(
96
96
  const defaultDateTimeFormat = useMemo(() => {
97
97
  const combinedFromParts = () => {
98
98
  var _a2, _b2;
99
- const datePart = defaultDateFormat || ((_a2 = listener == null ? void 0 : listener.localeFormats) == null ? void 0 : _a2.date) || "MMM d, y";
100
- const timePart = defaultTimeFormat || ((_b2 = listener == null ? void 0 : listener.localeFormats) == null ? void 0 : _b2.time) || "h:mm:ss a";
99
+ const datePart = defaultDateFormat || ((_a2 = listener == null ? void 0 : listener.localeFormats) == null ? void 0 : _a2.date) || "yyyy-MM-dd";
100
+ const timePart = defaultTimeFormat || ((_b2 = listener == null ? void 0 : listener.localeFormats) == null ? void 0 : _b2.time) || "hh:mm a";
101
101
  return `${datePart} ${timePart}`;
102
102
  };
103
103
  return combinedFromParts();
@@ -45,12 +45,12 @@ export interface DateTimeProps {
45
45
  defaultDateTimeFormat?: string;
46
46
  /**
47
47
  * Default date segment for display when `datepattern` is unset and `defaultDateTimeFormat` is not set.
48
- * Falls back to `listener.localeFormats.date`, then `"MMM d, y"`.
48
+ * Falls back to `listener.localeFormats.date`, then `"yyyy-MM-dd"`.
49
49
  */
50
50
  defaultDateFormat?: string;
51
51
  /**
52
52
  * Default time segment for display when `datepattern` is unset and `defaultDateTimeFormat` is not set.
53
- * Falls back to `listener.localeFormats.time`, then `"h:mm:ss a"`.
53
+ * Falls back to `listener.localeFormats.time`, then `"hh:mm a"`.
54
54
  */
55
55
  defaultTimeFormat?: string;
56
56
  /**
@@ -9,7 +9,7 @@ export declare function validateTimeRange(timeValue: Date | moment.Moment | null
9
9
  export declare function validateTimeFormat(inputValue: string, pattern: string, required: boolean, validationmessage?: string): ValidationResult;
10
10
  export declare function parseTimeObj(timeValue: string | Date | null | undefined): Date | null;
11
11
  export declare const DEFAULT_CLASS = "input-group app-timeinput";
12
- export declare const DEFAULT_TIMEPATTERN = "h:mm:ss A";
12
+ export declare const DEFAULT_TIMEPATTERN = "hh:mm a";
13
13
  export declare const DEFAULT_OUTPUT_FORMAT = "HH:mm:ss";
14
14
  export declare const READONLY_STYLES: {
15
15
  cursor: string;
@@ -76,7 +76,7 @@ function formatDisplayTimeValue(value, pattern) {
76
76
  if (pattern === "timestamp") {
77
77
  return momentObj.valueOf().toString();
78
78
  }
79
- return momentObj.isValid() ? momentObj.format(pattern) : "";
79
+ return momentObj.isValid() ? momentObj.format(pattern.replace(/\ba\b/g, "A")) : "";
80
80
  } catch (error) {
81
81
  console.warn("Error formatting display value:", error);
82
82
  return "";
@@ -178,7 +178,7 @@ function parseTimeObj(timeValue) {
178
178
  }
179
179
  }
180
180
  const DEFAULT_CLASS = "input-group app-timeinput";
181
- const DEFAULT_TIMEPATTERN = "h:mm:ss A";
181
+ const DEFAULT_TIMEPATTERN = "hh:mm a";
182
182
  const DEFAULT_OUTPUT_FORMAT = "HH:mm:ss";
183
183
  const READONLY_STYLES = {
184
184
  cursor: "not-allowed"
@@ -30,7 +30,6 @@ const useFileUpload = (props) => {
30
30
  disabled = !fileUploadConstants.DEFAULT_VALUES.ENABLED,
31
31
  contenttype = "",
32
32
  maxfilesize,
33
- uploadpath,
34
33
  datasource,
35
34
  extensions,
36
35
  filetype,
@@ -104,7 +103,7 @@ const useFileUpload = (props) => {
104
103
  const eventHandler = (_b2 = (_a2 = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _a2[name]) == null ? void 0 : _b2[eventName];
105
104
  return eventHandler ? eventHandler(payload.$event, listener.Widgets[name], payload.files) || true : true;
106
105
  },
107
- [listener, name]
106
+ [name]
108
107
  );
109
108
  const fileUploadProgress = (progress) => {
110
109
  setUploadedFiles((prevFiles) => {
@@ -125,26 +124,18 @@ const useFileUpload = (props) => {
125
124
  });
126
125
  });
127
126
  };
128
- useEffect(() => {
129
- const progressObs = datasource && datasource._progressObservable;
130
- if (progressObs) {
131
- progressObs.subscribe((progress) => {
132
- var _a2, _b2;
133
- fileUploadProgress(progress);
134
- if (progress.progress === 100) {
135
- (_a2 = listener == null ? void 0 : listener.App) == null ? void 0 : _a2.notifyApp("File uploaded successfully", "Success");
136
- } else if (progress.errMsg) {
137
- (_b2 = listener == null ? void 0 : listener.App) == null ? void 0 : _b2.notifyApp("File upload failed", "Error");
138
- }
139
- });
140
- }
141
- return () => {
142
- const progressObs2 = datasource && datasource._progressObservable;
143
- if (progressObs2 == null ? void 0 : progressObs2.unsubscribe) {
144
- progressObs2.unsubscribe();
127
+ const subscribeToProgress = useCallback((progressObs) => {
128
+ if (!progressObs) return;
129
+ progressObs.subscribe((progress) => {
130
+ var _a2, _b2;
131
+ fileUploadProgress(progress);
132
+ if (progress.progress === 100) {
133
+ (_a2 = listener == null ? void 0 : listener.App) == null ? void 0 : _a2.notifyApp("File uploaded successfully", "Success");
134
+ } else if (progress.errMsg) {
135
+ (_b2 = listener == null ? void 0 : listener.App) == null ? void 0 : _b2.notifyApp("File upload failed", "Error");
145
136
  }
146
- };
147
- }, [invokeEventCallback]);
137
+ });
138
+ }, []);
148
139
  useEffect(() => {
149
140
  const selected = getChooseFilter();
150
141
  setChooseFilter(selected);
@@ -193,7 +184,7 @@ const useFileUpload = (props) => {
193
184
  window.removeEventListener("focus", disableDropZone);
194
185
  };
195
186
  const onBeforeSelectEventCall = ($event, $files) => {
196
- var _a2, _b2, _c, _d;
187
+ var _a2, _b2;
197
188
  const files = getValidFiles(
198
189
  $files,
199
190
  contenttype,
@@ -237,14 +228,18 @@ const useFileUpload = (props) => {
237
228
  });
238
229
  if (datasource) {
239
230
  datasource._progressObservable = eventObserver();
231
+ subscribeToProgress(datasource._progressObservable);
240
232
  datasource.dataBinding = datasource.dataBinding || {};
241
233
  datasource.dataBinding.files = filesWithIds;
242
234
  datasource.dataSet = filesWithIds;
243
235
  }
244
236
  setUploadedFiles((prev) => multiple ? [...prev, ...filesWithIds] : [...filesWithIds]);
245
237
  listener == null ? void 0 : listener.onChange(name, { selectedFiles: filesWithIds });
246
- const selectedFile = (_d = filesWithIds[0]) != null ? _d : (_c = (_b2 = fileInputRef.current) == null ? void 0 : _b2.files) == null ? void 0 : _c[0];
247
- onSelect == null ? void 0 : onSelect($event, selectedFile, filesWithIds);
238
+ onSelect == null ? void 0 : onSelect(
239
+ $event,
240
+ (_b2 = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _b2[name],
241
+ filesWithIds
242
+ );
248
243
  }
249
244
  }
250
245
  };
@@ -334,7 +334,7 @@ const WmSelect = React.memo(
334
334
  }
335
335
  prevComputedValueRef.current = currentValue;
336
336
  }, [computedSelectValue, multiple, listener, props.fieldName, name, localDatavalue]);
337
- return /* @__PURE__ */ jsx("div", { className: clsx(DEFAULT_CLASS, className), hidden: props.hidden, style: styles, children: /* @__PURE__ */ jsxs(
337
+ return /* @__PURE__ */ jsx("div", { className: clsx(DEFAULT_CLASS), hidden: props.hidden, style: styles, children: /* @__PURE__ */ jsxs(
338
338
  NativeSelect,
339
339
  __spreadProps(__spreadValues({
340
340
  name,
@@ -342,7 +342,6 @@ const WmSelect = React.memo(
342
342
  className: clsx(
343
343
  isTouched ? "ng-touched" : "ng-untouched",
344
344
  isDirty ? "ng-invalid" : "ng-valid",
345
- className,
346
345
  "wm-native-select-root"
347
346
  ),
348
347
  value: multiple ? computedSelectValue : (_b = (_a = computedSelectValue.key) != null ? _a : placeholder) != null ? _b : ""
@@ -365,7 +364,11 @@ const WmSelect = React.memo(
365
364
  multiple,
366
365
  disabled,
367
366
  "aria-readonly": readonly,
368
- className: `app-select ${className} ${DEFAULT_CLASS} form-control ng-valid ng-touched ng-dirty wm-app `,
367
+ className: clsx(
368
+ "app-select",
369
+ className || "",
370
+ "form-control ng-valid ng-touched ng-dirty wm-app"
371
+ ),
369
372
  accessKey: shortcutkey,
370
373
  title: hint
371
374
  },
@@ -25,7 +25,7 @@ declare const _default: React.ComponentType<{
25
25
  onLoad?: (widget: WmPopoverProps) => void | Function;
26
26
  onShow?: (event: Event, widget: WmPopoverProps) => void;
27
27
  onHide?: (event: Event, widget: WmPopoverProps) => void;
28
- render?: (props: WmPopoverProps, onLoad: () => void) => React.ReactNode;
28
+ render?: (props: WmPopoverProps, onLoad: (widget?: any) => void) => React.ReactNode;
29
29
  disabled?: boolean;
30
30
  isOpen?: boolean;
31
31
  caption: string;
@@ -306,7 +306,7 @@ const WmPopover = (Props) => {
306
306
  }
307
307
  ),
308
308
  props.title && /* @__PURE__ */ jsx("div", { className: "popover-title popover-header", children: props.title }),
309
- /* @__PURE__ */ jsx("div", { className: "popover-content popover-body", children: props.render && props.content ? /* @__PURE__ */ jsx(Suspense, { fallback: null, children: props.render(props, () => handleLoad(__spreadValues({}, props))) }) : props.children })
309
+ /* @__PURE__ */ jsx("div", { className: "popover-content popover-body", children: props.render && props.content ? /* @__PURE__ */ jsx(Suspense, { fallback: null, children: props.render(props, (widget) => handleLoad(widget)) }) : props.children })
310
310
  ]
311
311
  }
312
312
  )
@@ -19,7 +19,7 @@ interface PopoverProps extends WmAnchorProps {
19
19
  onLoad?: (widget: WmPopoverProps) => void | Function;
20
20
  onShow?: (event: Event, widget: WmPopoverProps) => void;
21
21
  onHide?: (event: Event, widget: WmPopoverProps) => void;
22
- render?: (props: WmPopoverProps, onLoad: () => void) => React.ReactNode;
22
+ render?: (props: WmPopoverProps, onLoad: (widget?: any) => void) => React.ReactNode;
23
23
  disabled?: boolean;
24
24
  isOpen?: boolean;
25
25
  }
@@ -2,8 +2,23 @@ import { PageContextState, ProxyTarget } from "@wavemaker-ai/react-runtime/types
2
2
  import { OverriddenPropsRegistry } from "@wavemaker-ai/react-runtime/core/script-registry";
3
3
  import BaseAppProps from "../higherOrder/BaseAppProps";
4
4
  import { FormFieldProps } from "../components/data/form/form-field/props";
5
+ import type { UseFormSetValue } from "react-hook-form";
5
6
  export declare function clearPageWidgetProxyCache(widgetsProxy: object | null | undefined): void;
6
7
  export declare const createWidgetProxy: (widget: any, widgetName: string, setPageContext: any, overriddenPropsRegistry?: OverriddenPropsRegistry) => any;
7
8
  export declare const createPageProxy: (target: ProxyTarget, setPageContext: React.Dispatch<React.SetStateAction<PageContextState>>, overriddenPropsRegistry?: OverriddenPropsRegistry) => ProxyTarget;
8
9
  export declare const createStateProxy: (obj: PageContextState | BaseAppProps, path: string[], setPageContext: React.Dispatch<React.SetStateAction<PageContextState>> | React.Dispatch<React.SetStateAction<BaseAppProps>>, overriddenPropsRegistry?: OverriddenPropsRegistry) => ProxyTarget;
9
- export declare const createFormFieldProxy: (formField: FormFieldProps, setState: React.Dispatch<React.SetStateAction<FormFieldProps>>, overriddenItemsRef: React.MutableRefObject<Record<string, any>>, formProxy: any) => any;
10
+ /**
11
+ * Distinct fields with their canonical registry key - a field is stored under several keys,
12
+ * so dedupe by identity and keep the first (canonical) key. Iterate this, not Object.keys().
13
+ */
14
+ export declare const getFormFieldEntries: (formfields: Record<string, any> | undefined) => {
15
+ key: string;
16
+ field: any;
17
+ }[];
18
+ /** Distinct field objects in registration order. */
19
+ export declare const getFormFieldList: (formfields: Record<string, any> | undefined) => any[];
20
+ /** Hidden `<name>_formWidget` lookup alias, so registry iteration yields one entry per field (as in Angular). */
21
+ export declare const defineFieldAlias: (alias: string, widget: any, ...registries: any[]) => void;
22
+ export declare const createFormFieldProxy: (formField: FormFieldProps, setState: React.Dispatch<React.SetStateAction<FormFieldProps>>, overriddenItemsRef: React.MutableRefObject<Record<string, any>>, formProxy: any, formRef?: {
23
+ setValue?: UseFormSetValue<any>;
24
+ }) => any;
@@ -550,28 +550,52 @@ const createStateProxy = (obj, path = [], setPageContext, overriddenPropsRegistr
550
550
  }
551
551
  });
552
552
  };
553
- const createFormFieldProxy = (formField, setState, overriddenItemsRef, formProxy) => {
553
+ const getFormFieldEntries = (formfields) => {
554
+ const canonicalKeyByField = /* @__PURE__ */ new Map();
555
+ Object.entries(formfields != null ? formfields : {}).forEach(([key, field]) => {
556
+ if (field && !canonicalKeyByField.has(field)) canonicalKeyByField.set(field, key);
557
+ });
558
+ return [...canonicalKeyByField].map(([field, key]) => ({ key, field }));
559
+ };
560
+ const getFormFieldList = (formfields) => getFormFieldEntries(formfields).map(({ field }) => field);
561
+ const defineFieldAlias = (alias, widget, ...registries) => registries.forEach(
562
+ (registry) => registry && Object.defineProperty(registry, alias, {
563
+ value: widget,
564
+ enumerable: false,
565
+ configurable: true,
566
+ writable: true
567
+ })
568
+ );
569
+ const createFormFieldProxy = (formField, setState, overriddenItemsRef, formProxy, formRef) => {
570
+ const { name, formKey } = formField;
571
+ const rhfKey = formKey || name;
554
572
  const fieldProxy = new Proxy(formField, {
555
573
  get: (target, prop) => {
574
+ if (prop === "setProperty") {
575
+ return function(key, value) {
576
+ fieldProxy[key] = value;
577
+ return this;
578
+ };
579
+ }
556
580
  return target[prop];
557
581
  },
558
582
  set: (target, prop, value) => {
559
583
  target[prop] = value;
560
584
  overriddenItemsRef.current[prop] = value;
561
585
  setState(__spreadValues({}, target));
586
+ if ((prop === "datavalue" || prop === "value") && rhfKey && (formRef == null ? void 0 : formRef.setValue)) {
587
+ formRef.setValue(rhfKey, value, { shouldValidate: false, shouldDirty: true });
588
+ }
562
589
  return true;
563
590
  }
564
591
  });
565
- const name = formField.name;
566
- const key = formField.formKey;
567
- if (key) {
568
- formProxy.formfields[key] = fieldProxy;
569
- formProxy.formWidgets[key] = fieldProxy;
570
- }
571
- formProxy.formfields[`${name}_formWidget`] = fieldProxy;
572
- formProxy.formWidgets[`${name}_formWidget`] = fieldProxy;
573
- formProxy.formfields[`${name}`] = fieldProxy;
574
- formProxy.formWidgets[`${name}`] = fieldProxy;
592
+ const { formfields, formWidgets } = formProxy;
593
+ [formKey, name].forEach((fieldKey) => {
594
+ if (!fieldKey) return;
595
+ formfields[fieldKey] = fieldProxy;
596
+ formWidgets[fieldKey] = fieldProxy;
597
+ });
598
+ defineFieldAlias(`${name}_formWidget`, fieldProxy, formfields, formWidgets);
575
599
  return fieldProxy;
576
600
  };
577
601
  export {
@@ -579,5 +603,8 @@ export {
579
603
  createFormFieldProxy,
580
604
  createPageProxy,
581
605
  createStateProxy,
582
- createWidgetProxy
606
+ createWidgetProxy,
607
+ defineFieldAlias,
608
+ getFormFieldEntries,
609
+ getFormFieldList
583
610
  };
@@ -235,7 +235,14 @@ const withBaseDateTime = (WrappedComponent) => {
235
235
  if (date == "CURRENT_DATE") {
236
236
  return /* @__PURE__ */ new Date();
237
237
  }
238
- return typeof date === "string" ? moment(date).toDate() : date;
238
+ if (typeof date === "string") {
239
+ const parsed = moment(date).toDate();
240
+ return isNaN(parsed.getTime()) ? void 0 : parsed;
241
+ }
242
+ if (date instanceof Date) {
243
+ return isNaN(date.getTime()) ? void 0 : date;
244
+ }
245
+ return date;
239
246
  }, []);
240
247
  const handleKeyDown = useCallback((event) => {
241
248
  const arrowKeys = Object.values(ARROW_KEYS);