@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.
- package/actions/notification-action.js +3 -3
- package/actions/toast.js +2 -1
- package/components/basic/message/index.js +1 -0
- package/components/basic/search/index.js +9 -11
- package/components/basic/search/providers.d.ts +1 -1
- package/components/basic/search/providers.js +6 -3
- package/components/container/layout-grid/index.js +1 -0
- package/components/container/linear-layout/index.js +0 -1
- package/components/data/form/base-form/hooks/useFormOperations.js +9 -15
- package/components/data/form/base-form/index.js +17 -14
- package/components/data/form/base-form/utils.js +5 -4
- package/components/data/form/form-action/index.d.ts +2 -2
- package/components/data/form/form-action/index.js +2 -2
- package/components/data/form/form-context.d.ts +12 -13
- package/components/data/form/form-context.js +4 -6
- package/components/data/form/form-controller/withFormController.js +4 -4
- package/components/data/form/form-field/index.js +6 -5
- package/components/data/list/components/ListItems.js +1 -3
- package/components/data/list/index.js +2 -2
- package/components/data/pagination/hooks/usePagination.js +2 -2
- package/components/data/table/components/TableBody.js +2 -1
- package/components/data/table/components/TableDataRow.js +1 -1
- package/components/data/table/hooks/useRowHandlers.js +2 -2
- package/components/data/table/hooks/useRowSelection.js +15 -10
- package/components/data/table/hooks/useTableColumns.js +5 -5
- package/components/data/table/index.js +2 -2
- package/components/data/table/props.d.ts +8 -8
- package/components/data/table/utils/buildSelectionColumns.js +30 -30
- package/components/data/table/utils/index.js +15 -1
- package/components/data/table/utils/selectionUtils.d.ts +2 -0
- package/components/data/table/utils/selectionUtils.js +23 -1
- package/components/dialogs/dialog-actions/index.js +11 -2
- package/components/input/epoch/date/index.js +2 -1
- package/components/input/epoch/date/utils.js +4 -2
- package/components/input/epoch/datetime/index.js +2 -2
- package/components/input/epoch/datetime/props.d.ts +2 -2
- package/components/input/epoch/time/utils.d.ts +1 -1
- package/components/input/epoch/time/utils.js +2 -2
- package/components/input/fileupload/useFileUpload.js +19 -24
- package/components/input/select/index.js +6 -3
- package/components/navigation/popover/index.d.ts +1 -1
- package/components/navigation/popover/index.js +1 -1
- package/components/navigation/popover/props.d.ts +1 -1
- package/core/proxy-service.d.ts +16 -1
- package/core/proxy-service.js +39 -12
- package/higherOrder/BaseDateTime.js +8 -1
- package/higherOrder/BasePage.js +7 -2
- package/higherOrder/withBaseWrapper.js +3 -4
- package/package-lock.json +241 -221
- 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],
|
|
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,
|
|
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__ */
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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__ */
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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) ?
|
|
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(
|
|
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) || "
|
|
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
|
-
|
|
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) || "
|
|
100
|
-
const timePart = defaultTimeFormat || ((_b2 = listener == null ? void 0 : listener.localeFormats) == null ? void 0 : _b2.time) || "
|
|
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 `"
|
|
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 `"
|
|
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 = "
|
|
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 = "
|
|
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
|
-
[
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
}, [
|
|
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
|
|
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
|
-
|
|
247
|
-
|
|
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
|
|
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:
|
|
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(
|
|
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
|
}
|
package/core/proxy-service.d.ts
CHANGED
|
@@ -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
|
-
|
|
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;
|
package/core/proxy-service.js
CHANGED
|
@@ -550,28 +550,52 @@ const createStateProxy = (obj, path = [], setPageContext, overriddenPropsRegistr
|
|
|
550
550
|
}
|
|
551
551
|
});
|
|
552
552
|
};
|
|
553
|
-
const
|
|
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
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
571
|
-
|
|
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
|
-
|
|
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);
|