@wavemaker-ai/react-runtime 1.0.0-rc.647712 → 12.0.0-rc.335
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/components/basic/richtexteditor/index.d.ts +1 -0
- package/components/basic/search/index.js +5 -4
- package/components/basic/search/utils.d.ts +1 -0
- package/components/basic/search/utils.js +9 -0
- package/components/common/index.d.ts +2 -0
- package/components/common/index.js +2 -0
- package/components/common/partial-content-wrapper.d.ts +15 -0
- package/components/common/partial-content-wrapper.js +11 -0
- package/components/container/index.js +5 -2
- package/components/container/tabs/index.js +5 -3
- package/components/container/wizard/index.js +36 -3
- package/components/container/wizard/props.d.ts +2 -2
- package/components/data/form/dynamic-fields/WmxDynamicFormField.js +9 -23
- package/components/data/form/form-controller/props.d.ts +2 -0
- package/components/data/form/form-controller/utils.js +3 -2
- package/components/data/form/form-controller/validation-contrustor.js +112 -1
- package/components/data/form/form-controller/withFormController.js +1 -1
- package/components/data/form/form-field/index.js +6 -3
- package/components/data/form/form-field/props.d.ts +1 -0
- package/components/data/list/components/ListItemWithTemplate.js +1 -1
- package/components/data/list/index.js +1 -1
- package/components/data/table/components/EditableCell.js +47 -24
- package/components/data/table/components/FieldValidationError.js +1 -1
- package/components/data/table/components/TableHeader.js +9 -3
- package/components/data/table/hooks/useFormWidget.js +11 -0
- package/components/data/table/hooks/useRowSelection.js +58 -1
- package/components/data/table/hooks/useTableEdit.d.ts +1 -1
- package/components/data/table/hooks/useTableEdit.js +115 -75
- package/components/data/table/hooks/useTableEditForms.d.ts +25 -0
- package/components/data/table/hooks/useTableEditForms.js +30 -0
- package/components/data/table/index.js +68 -32
- package/components/data/table/props.d.ts +42 -23
- package/components/data/table/utils/buildSelectionColumns.js +3 -3
- package/components/data/table/utils/columnProxy.d.ts +7 -1
- package/components/data/table/utils/columnProxy.js +21 -1
- package/components/data/table/utils/columnValidation.d.ts +19 -0
- package/components/data/table/utils/columnValidation.js +76 -0
- package/components/data/table/utils/constants.d.ts +2 -0
- package/components/data/table/utils/constants.js +2 -0
- package/components/data/table/utils/index.d.ts +4 -12
- package/components/data/table/utils/index.js +13 -77
- package/components/data/table/utils/selectionUtils.js +13 -5
- package/components/input/chips/index.d.ts +1 -0
- package/components/input/color-picker/index.d.ts +1 -0
- package/components/input/currency/index.d.ts +1 -0
- package/components/input/default/checkbox/index.d.ts +1 -0
- package/components/input/default/checkboxset/index.d.ts +1 -0
- package/components/input/default/radioset/index.d.ts +1 -0
- package/components/input/default/switch/index.d.ts +1 -0
- package/components/input/epoch/datetime/index.js +10 -2
- package/components/input/number/index.d.ts +1 -0
- package/components/input/rating/index.d.ts +1 -0
- package/components/input/select/index.d.ts +1 -0
- package/components/input/slider/index.d.ts +1 -0
- package/components/input/text/index.d.ts +1 -0
- package/components/input/textarea/index.d.ts +1 -0
- package/components/input/upload/index.d.ts +1 -0
- package/components/layout/footer/index.js +4 -2
- package/components/layout/footer/props.d.ts +1 -0
- package/components/layout/header/index.js +29 -3
- package/components/layout/header/props.d.ts +1 -0
- package/components/layout/leftnav/index.js +22 -6
- package/components/layout/leftnav/props.d.ts +1 -0
- package/components/layout/leftnav/utils/page-class-util.d.ts +1 -0
- package/components/layout/leftnav/utils/page-class-util.js +4 -3
- package/components/layout/rightnav/index.js +4 -2
- package/components/layout/rightnav/props.d.ts +1 -0
- package/components/layout/topnav/index.js +4 -2
- package/components/layout/topnav/props.d.ts +1 -0
- package/components/navbar/index.js +32 -7
- package/components/navigation/menu/index.js +6 -2
- package/components/page/index.js +60 -19
- package/components/page/page-context.d.ts +4 -0
- package/core/proxy-service.js +86 -19
- package/higherOrder/BaseApp.js +1 -1
- package/higherOrder/BasePage.js +2 -1
- package/higherOrder/withBaseWrapper.js +10 -2
- package/hooks/useHttp.d.ts +14 -4
- package/hooks/useHttp.js +47 -9
- package/package-lock.json +314 -308
- package/package.json +3 -3
- package/runtime-dynamic/App.js +21 -2
- package/runtime-dynamic/app-initializer.js +8 -1
- package/runtime-dynamic/factories/dynamic-component.js +4 -3
- package/runtime-dynamic/main.d.ts +1 -0
- package/runtime-dynamic/main.js +9 -1
- package/runtime-dynamic/services/compile-render.js +7 -0
- package/runtime-dynamic/services/css-scoping.d.ts +1 -1
- package/runtime-dynamic/services/css-scoping.js +2 -2
- package/runtime-dynamic/services/variable-factory.js +2 -1
- package/runtime-dynamic/services/variable-transpiler.js +4 -1
- package/runtime-dynamic/wmx-shared.d.ts +40 -0
- package/runtime-dynamic/wmx-shared.js +33 -0
- package/utils/style-utils.js +1 -1
- package/utils/wmx.utils.d.ts +0 -1
- package/utils/wmx.utils.js +0 -25
- package/variables/crud-variable.d.ts +10 -0
- package/variables/crud-variable.js +53 -2
- package/variables/live-variable.d.ts +1 -0
- package/variables/live-variable.js +2 -1
- package/variables/operation-params.d.ts +29 -0
- package/variables/operation-params.js +69 -0
- package/variables/service-variable.d.ts +9 -0
- package/variables/service-variable.js +21 -2
- package/components/data/table/utils/validation.d.ts +0 -13
- package/components/data/table/utils/validation.js +0 -82
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { useForm } from "react-hook-form";
|
|
3
|
+
const EDIT_FORM_OPTIONS = {
|
|
4
|
+
mode: "onChange",
|
|
5
|
+
// Validate on blur (widgets use updateon="blur")
|
|
6
|
+
shouldUnregister: true
|
|
7
|
+
// Drop field on unmount; prevents orphaned errors
|
|
8
|
+
};
|
|
9
|
+
const useTableEditForm = (tableName) => {
|
|
10
|
+
const { control, trigger, setValue, setError, reset, getFieldState } = useForm(EDIT_FORM_OPTIONS);
|
|
11
|
+
return useMemo(
|
|
12
|
+
() => ({
|
|
13
|
+
formRef: { control, trigger, name: tableName, validationtype: "default" },
|
|
14
|
+
validate: () => trigger(),
|
|
15
|
+
getInvalidFields: (fieldNames) => fieldNames.filter((fieldName) => getFieldState(fieldName).invalid),
|
|
16
|
+
setFieldValue: (fieldName, value) => setValue(fieldName, value, { shouldValidate: false, shouldDirty: true }),
|
|
17
|
+
setFieldError: (fieldName, message) => setError(fieldName, { type: "native", message }),
|
|
18
|
+
reset: () => reset()
|
|
19
|
+
}),
|
|
20
|
+
[control, trigger, setValue, setError, reset, getFieldState, tableName]
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
const useTableEditForms = (tableName) => {
|
|
24
|
+
const editForm = useTableEditForm(tableName);
|
|
25
|
+
const newRowForm = useTableEditForm(tableName);
|
|
26
|
+
return { editForm, newRowForm };
|
|
27
|
+
};
|
|
28
|
+
export {
|
|
29
|
+
useTableEditForms
|
|
30
|
+
};
|
|
@@ -446,7 +446,9 @@ const WmTableComponent = memo(
|
|
|
446
446
|
handleMultiSelection,
|
|
447
447
|
handleSelectAll,
|
|
448
448
|
handleRowSelectionClick,
|
|
449
|
-
isRowSelected
|
|
449
|
+
isRowSelected,
|
|
450
|
+
selectItem,
|
|
451
|
+
deselectItem
|
|
450
452
|
} = useRowSelection({
|
|
451
453
|
radioselect,
|
|
452
454
|
multiselect: effectiveMultiselect,
|
|
@@ -532,6 +534,7 @@ const WmTableComponent = memo(
|
|
|
532
534
|
}),
|
|
533
535
|
[wmTableColumns, columnOverrides]
|
|
534
536
|
);
|
|
537
|
+
const columnValidatorsRef = useRef({});
|
|
535
538
|
const {
|
|
536
539
|
editingRowId,
|
|
537
540
|
isRowEditing,
|
|
@@ -577,7 +580,8 @@ const WmTableComponent = memo(
|
|
|
577
580
|
onRowdelete,
|
|
578
581
|
tableRef,
|
|
579
582
|
isServerSidePagination: isServerSidePagination(),
|
|
580
|
-
tableName: name
|
|
583
|
+
tableName: name,
|
|
584
|
+
columnValidatorsRef
|
|
581
585
|
});
|
|
582
586
|
const { handleRowClick } = useRowHandlers({
|
|
583
587
|
editingRowId,
|
|
@@ -756,7 +760,13 @@ const WmTableComponent = memo(
|
|
|
756
760
|
[]
|
|
757
761
|
);
|
|
758
762
|
const columnsProxy = useMemo(
|
|
759
|
-
() => createColumnsProxy(
|
|
763
|
+
() => createColumnsProxy(
|
|
764
|
+
wmTableColumns,
|
|
765
|
+
applyOverride,
|
|
766
|
+
setColumnsVersion,
|
|
767
|
+
setSummaryRowDef,
|
|
768
|
+
columnValidatorsRef.current
|
|
769
|
+
),
|
|
760
770
|
[wmTableColumns, applyOverride, setColumnsVersion, setSummaryRowDef]
|
|
761
771
|
);
|
|
762
772
|
const {
|
|
@@ -969,6 +979,23 @@ const WmTableComponent = memo(
|
|
|
969
979
|
},
|
|
970
980
|
[name]
|
|
971
981
|
);
|
|
982
|
+
const selectItemRef = useRef(selectItem);
|
|
983
|
+
const deselectItemRef = useRef(deselectItem);
|
|
984
|
+
selectItemRef.current = selectItem;
|
|
985
|
+
deselectItemRef.current = deselectItem;
|
|
986
|
+
const widgetSelectItem = useCallback((itemOrIndex) => {
|
|
987
|
+
selectItemRef.current(itemOrIndex);
|
|
988
|
+
}, []);
|
|
989
|
+
const widgetDeselectItem = useCallback((itemOrIndex) => {
|
|
990
|
+
deselectItemRef.current(itemOrIndex);
|
|
991
|
+
}, []);
|
|
992
|
+
useEffect(() => {
|
|
993
|
+
var _a2;
|
|
994
|
+
(_a2 = listener == null ? void 0 : listener.onChange) == null ? void 0 : _a2.call(listener, widgetRegistrationKey, {
|
|
995
|
+
selectItem: widgetSelectItem,
|
|
996
|
+
deselectItem: widgetDeselectItem
|
|
997
|
+
});
|
|
998
|
+
});
|
|
972
999
|
const sortInfoForExport = useMemo(() => {
|
|
973
1000
|
if (sorting.length > 0) {
|
|
974
1001
|
return {
|
|
@@ -1355,7 +1382,10 @@ const WmTableComponent = memo(
|
|
|
1355
1382
|
datasource,
|
|
1356
1383
|
dataset,
|
|
1357
1384
|
selectPageSize,
|
|
1358
|
-
rowDefInstances
|
|
1385
|
+
rowDefInstances,
|
|
1386
|
+
// Angular parity: table.selectItem / table.deselectItem (accepts a row or an index).
|
|
1387
|
+
selectItem: widgetSelectItem,
|
|
1388
|
+
deselectItem: widgetDeselectItem
|
|
1359
1389
|
};
|
|
1360
1390
|
const getRowId = (row) => row._wmTableRowId || String(row.id);
|
|
1361
1391
|
const pushSelectedItemsToWidget = (selectedIds) => {
|
|
@@ -1525,34 +1555,40 @@ const WmTableComponent = memo(
|
|
|
1525
1555
|
} : {})
|
|
1526
1556
|
}, { name }), {
|
|
1527
1557
|
children: [
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1558
|
+
colGroupSpec.length > 0 && /* @__PURE__ */ jsx("colgroup", { children: colGroupSpec.map((c) => /* @__PURE__ */ jsx(
|
|
1559
|
+
"col",
|
|
1560
|
+
__spreadValues({
|
|
1561
|
+
style: c.style,
|
|
1562
|
+
width: c.width
|
|
1563
|
+
}, c.domHidden ? { "data-wm-col-hidden": "" } : {}),
|
|
1564
|
+
c.key
|
|
1565
|
+
)) }),
|
|
1566
|
+
showheader && wmTableColumns.length > 0 && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
1567
|
+
TableHeaderComponent,
|
|
1568
|
+
{
|
|
1569
|
+
table,
|
|
1570
|
+
enablesort,
|
|
1571
|
+
enablecolumnselection,
|
|
1572
|
+
rowClass,
|
|
1573
|
+
ColClassSignature,
|
|
1574
|
+
sorting,
|
|
1575
|
+
columnSizing,
|
|
1576
|
+
rowSelection,
|
|
1577
|
+
rowExpansionConfig: visibleRowExpansionConfig,
|
|
1578
|
+
columnsVersion,
|
|
1579
|
+
filterMode: filtermode,
|
|
1580
|
+
columnFilters,
|
|
1581
|
+
onColumnFilterChange: setColumnFilter,
|
|
1582
|
+
renderFormWidget,
|
|
1583
|
+
listener,
|
|
1584
|
+
viewParent,
|
|
1585
|
+
tableStructure,
|
|
1586
|
+
onColumnSelect: handleColumnSelect,
|
|
1587
|
+
onColumnDeselect: handleColumnDeselect,
|
|
1588
|
+
onHeaderclick,
|
|
1589
|
+
tableName: name
|
|
1590
|
+
}
|
|
1591
|
+
) }),
|
|
1556
1592
|
(internalDataset.length > 0 || !isTableLoading) && /* @__PURE__ */ jsx(
|
|
1557
1593
|
TableBodyComponent,
|
|
1558
1594
|
{
|
|
@@ -6,6 +6,9 @@ import { IAlignment, INavigation } from "../list/props";
|
|
|
6
6
|
import { EditWidgetType } from "./utils";
|
|
7
7
|
import { StorageType } from "../../../utils/state-persistance";
|
|
8
8
|
import { LiveVariableConfig } from "@wavemaker-ai/react-runtime/variables/live-variable";
|
|
9
|
+
import { ValidatorConfig } from "@wavemaker-ai/react-runtime/components/data/form/form-controller/props";
|
|
10
|
+
import { ColumnValidatorRegistry } from "./utils/columnValidation";
|
|
11
|
+
import { TableEditFormRef } from "./hooks/useTableEditForms";
|
|
9
12
|
export type TableEditMode = "inline" | "dialog" | "form" | "quickedit" | "none";
|
|
10
13
|
export type TableActionPosition = "header" | "footer";
|
|
11
14
|
export type TableFormPosition = "top" | "bottom";
|
|
@@ -820,6 +823,7 @@ export interface TableHeaderProps {
|
|
|
820
823
|
columnsVersion?: number;
|
|
821
824
|
filterMode?: TableFilterMode;
|
|
822
825
|
listener: any;
|
|
826
|
+
viewParent?: any;
|
|
823
827
|
columnFilters?: Record<string, any>;
|
|
824
828
|
onColumnFilterChange?: (columnId: string, value: string, matchMode?: string) => void;
|
|
825
829
|
renderFormWidget: (fieldName: string, widgetType: string, value: any, onChange: (value: any) => void, additionalProps?: any) => React.ReactNode;
|
|
@@ -854,7 +858,7 @@ export interface AddNewRowProps {
|
|
|
854
858
|
sessionKey: number;
|
|
855
859
|
editingRowData: Record<string, any>;
|
|
856
860
|
renderEditableCell: (column: WmTableColumnProps, fieldName: string, widgetType: string, editValue: any, rowId: string) => ReactElement;
|
|
857
|
-
onKeyDown?: (e: KeyboardEvent, sourceRowId?: string) => void;
|
|
861
|
+
onKeyDown?: (e: React.KeyboardEvent, sourceRowId?: string) => void;
|
|
858
862
|
handleSave: () => void;
|
|
859
863
|
handleCancel: () => void;
|
|
860
864
|
listener?: any;
|
|
@@ -868,13 +872,17 @@ export interface EditableCellProps {
|
|
|
868
872
|
fieldName: string;
|
|
869
873
|
widgetType: string;
|
|
870
874
|
editValue: any;
|
|
871
|
-
|
|
872
|
-
|
|
875
|
+
/** The react-hook-form instance for this edit session, handed to the cell's widget. */
|
|
876
|
+
formRef: TableEditFormRef;
|
|
877
|
+
/** Shared `${rowId}_${fieldName}` -> true map of cells currently in error. */
|
|
878
|
+
cellErrorsRef?: RefObject<Record<string, boolean>>;
|
|
879
|
+
/** Cell containers, keyed `${rowId}_${fieldName}`. */
|
|
873
880
|
fieldRefs: RefObject<Record<string, HTMLElement | null>>;
|
|
874
|
-
|
|
881
|
+
columnValidatorsRef?: RefObject<ColumnValidatorRegistry>;
|
|
882
|
+
renderFormWidget: (name: string, type: string, value: any, onChange: (newValue: any) => void, props: TableEditWidgetProps) => ReactElement;
|
|
875
883
|
updateFieldValue: (fieldName: string, newValue: any, rowId?: string) => void;
|
|
876
884
|
sessionKey?: number;
|
|
877
|
-
onKeyDown?: (e: KeyboardEvent, sourceRowId?: string) => void;
|
|
885
|
+
onKeyDown?: (e: React.KeyboardEvent, sourceRowId?: string) => void;
|
|
878
886
|
editMode?: TableEditMode;
|
|
879
887
|
validationmessage?: string;
|
|
880
888
|
}
|
|
@@ -980,14 +988,32 @@ export interface UseTableDataReturn {
|
|
|
980
988
|
export interface UseFormWidgetProps {
|
|
981
989
|
listener?: any;
|
|
982
990
|
}
|
|
991
|
+
/** Everything an editable cell hands to its edit widget beyond the value itself. */
|
|
992
|
+
export interface TableEditWidgetProps {
|
|
993
|
+
required?: boolean;
|
|
994
|
+
disabled?: boolean;
|
|
995
|
+
placeholder?: string;
|
|
996
|
+
defaultvalue?: string | number | boolean;
|
|
997
|
+
sessionKey?: string | number;
|
|
998
|
+
rowData?: any;
|
|
999
|
+
column?: any;
|
|
1000
|
+
/**
|
|
1001
|
+
* The edit session's react-hook-form instance. `withFormController` validates the widget
|
|
1002
|
+
* against it and, from the same validators, derives the date/time bounds the picker enforces
|
|
1003
|
+
* on its own input.
|
|
1004
|
+
*/
|
|
1005
|
+
formRef?: TableEditFormRef;
|
|
1006
|
+
/** Form field name for the cell — the column field, independent of the row. */
|
|
1007
|
+
formKey?: string;
|
|
1008
|
+
/** Validators set by a page script via `columns.<name>.setValidators([...])`. */
|
|
1009
|
+
validators?: ValidatorConfig[];
|
|
1010
|
+
/** Validators set via `columns.<name>.setAsyncValidators([...])`. */
|
|
1011
|
+
asyncValidators?: ValidatorConfig[];
|
|
1012
|
+
/** Keep the widget out of the form entirely (hidden columns). */
|
|
1013
|
+
ignoreInForm?: boolean;
|
|
1014
|
+
}
|
|
983
1015
|
export interface UseFormWidgetReturn {
|
|
984
|
-
renderFormWidget: (fieldName: string, widgetType: string, value: any, onFieldChange?: (newValue: any) => void, widgetProps?:
|
|
985
|
-
required?: boolean;
|
|
986
|
-
disabled?: boolean;
|
|
987
|
-
placeholder?: string;
|
|
988
|
-
defaultvalue?: string | number | boolean;
|
|
989
|
-
sessionKey?: string | number;
|
|
990
|
-
}) => ReactElement;
|
|
1016
|
+
renderFormWidget: (fieldName: string, widgetType: string, value: any, onFieldChange?: (newValue: any) => void, widgetProps?: TableEditWidgetProps) => ReactElement;
|
|
991
1017
|
}
|
|
992
1018
|
export interface UseTableEditProps {
|
|
993
1019
|
editMode?: TableEditMode;
|
|
@@ -1020,6 +1046,8 @@ export interface UseTableEditProps {
|
|
|
1020
1046
|
onRowupdate?: (event: any, widget: any, data: any) => void;
|
|
1021
1047
|
tableRef?: React.RefObject<any>;
|
|
1022
1048
|
isServerSidePagination?: boolean;
|
|
1049
|
+
/** Validators set by a page script via `columns.<name>.setValidators([...])`. */
|
|
1050
|
+
columnValidatorsRef?: RefObject<Record<string, any>>;
|
|
1023
1051
|
}
|
|
1024
1052
|
export interface UseTableEditReturn {
|
|
1025
1053
|
editingRowId: string | null;
|
|
@@ -1128,6 +1156,8 @@ export interface UseRowSelectionReturn {
|
|
|
1128
1156
|
handleRowSelectionClick: (event: MouseEvent, rowId: string, rowData: any) => boolean;
|
|
1129
1157
|
isRowSelected: (rowId: string) => boolean;
|
|
1130
1158
|
isInteractiveElement: (event: MouseEvent) => boolean;
|
|
1159
|
+
selectItem: (itemOrIndex: any) => void;
|
|
1160
|
+
deselectItem: (itemOrIndex: any) => void;
|
|
1131
1161
|
}
|
|
1132
1162
|
export interface UseTableStateProps {
|
|
1133
1163
|
editMode?: TableEditMode;
|
|
@@ -1302,17 +1332,6 @@ export interface UseRowExpansionReturn {
|
|
|
1302
1332
|
registerRowDefInstance: (rowId: string, instance: any, rowData?: any) => void;
|
|
1303
1333
|
rowDefInstances: Record<string, any>;
|
|
1304
1334
|
}
|
|
1305
|
-
export interface FieldValidationState {
|
|
1306
|
-
fieldRefs: RefObject<Record<string, HTMLElement | null>>;
|
|
1307
|
-
fieldValidationErrors: RefObject<Record<string, boolean>>;
|
|
1308
|
-
cellUpdateCallbacks: RefObject<Record<string, () => void>>;
|
|
1309
|
-
}
|
|
1310
|
-
export interface ValidationResult {
|
|
1311
|
-
isValid: boolean;
|
|
1312
|
-
invalidElements: HTMLElement[];
|
|
1313
|
-
invalidFieldKeys?: string[];
|
|
1314
|
-
firstInvalidElement?: HTMLElement;
|
|
1315
|
-
}
|
|
1316
1335
|
/**
|
|
1317
1336
|
* Interface for summary row value with optional styling
|
|
1318
1337
|
*/
|
|
@@ -10,7 +10,7 @@ function RadioSelectCell(ctx) {
|
|
|
10
10
|
const rowId = row.id;
|
|
11
11
|
const isSelected = row.getIsSelected();
|
|
12
12
|
const { handleRadioSelection, radioselecttitle, radioselectarialabel, tableName } = getSelectionMeta(ctx);
|
|
13
|
-
return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsx(Tooltip, { title: radioselecttitle != null ? radioselecttitle : "", placement: "top", children: /* @__PURE__ */ jsx(Box, { className: "radio app-radio", children: /* @__PURE__ */ jsxs(Box, { component: "label", children: [
|
|
13
|
+
return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center" }, "data-role": "select-row", children: /* @__PURE__ */ jsx(Tooltip, { title: radioselecttitle != null ? radioselecttitle : "", placement: "top", children: /* @__PURE__ */ jsx(Box, { className: "radio app-radio", children: /* @__PURE__ */ jsxs(Box, { component: "label", children: [
|
|
14
14
|
/* @__PURE__ */ jsx(
|
|
15
15
|
Box,
|
|
16
16
|
{
|
|
@@ -33,7 +33,7 @@ function MultiSelectCell(ctx) {
|
|
|
33
33
|
const rowId = row.id;
|
|
34
34
|
const isSelected = row.getIsSelected();
|
|
35
35
|
const { handleMultiSelection, multiselecttitle, multiselectarialabel } = getSelectionMeta(ctx);
|
|
36
|
-
return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex" }, children: [
|
|
36
|
+
return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex" }, "data-role": "select-row", children: [
|
|
37
37
|
/* @__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: [
|
|
38
38
|
/* @__PURE__ */ jsx(Box, { component: "span", className: "sr-only", "aria-live": "assertive", children: "Select row" }),
|
|
39
39
|
/* @__PURE__ */ jsx(
|
|
@@ -59,7 +59,7 @@ function MultiSelectHeader({ table, column }) {
|
|
|
59
59
|
var _a, _b;
|
|
60
60
|
const isAllSelected = table.getIsAllRowsSelected();
|
|
61
61
|
const { handleSelectAll } = (_b = (_a = column.columnDef.meta) == null ? void 0 : _a.selection) != null ? _b : {};
|
|
62
|
-
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: [
|
|
62
|
+
return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", width: "100%" }, "data-role": "select-all", children: /* @__PURE__ */ jsx(Box, { className: "app-checkbox checkbox", children: /* @__PURE__ */ jsxs(Box, { component: "label", className: isAllSelected ? "" : "unchecked", children: [
|
|
63
63
|
/* @__PURE__ */ jsx(
|
|
64
64
|
Box,
|
|
65
65
|
{
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ValidatorConfig } from "@wavemaker-ai/react-runtime/components/data/form/form-controller/props";
|
|
2
|
+
import { ColumnValidatorRegistry } from "./columnValidation";
|
|
1
3
|
export declare const keyMap: {
|
|
2
4
|
[key: string]: string;
|
|
3
5
|
};
|
|
@@ -17,5 +19,9 @@ export interface ColumnAggregate {
|
|
|
17
19
|
export interface EnhancedColumnProxy {
|
|
18
20
|
aggregate: ColumnAggregate;
|
|
19
21
|
setSummaryRowData: (data: SummaryRowData | SummaryRowData[]) => void;
|
|
22
|
+
setValidators: (validators: ValidatorConfig[]) => void;
|
|
23
|
+
setAsyncValidators: (asyncValidators: ValidatorConfig[]) => void;
|
|
20
24
|
}
|
|
21
|
-
export declare function createColumnsProxy(wmTableColumns: any[], applyOverride: (field: string, key: string, value: any) => void, setColumnsVersion?: (updater: (v: number) => number) => void, setSummaryRowDef?: (columnKey: string, data: any, rowIndex: number, refresh: boolean, show?: boolean) => void
|
|
25
|
+
export declare function createColumnsProxy(wmTableColumns: any[], applyOverride: (field: string, key: string, value: any) => void, setColumnsVersion?: (updater: (v: number) => number) => void, setSummaryRowDef?: (columnKey: string, data: any, rowIndex: number, refresh: boolean, show?: boolean) => void,
|
|
26
|
+
/** Live validator store, held in a ref so script calls survive column-def rebuilds. */
|
|
27
|
+
validatorRegistry?: ColumnValidatorRegistry): Record<string, any>;
|
|
@@ -17,6 +17,9 @@ var __spreadValues = (a, b) => {
|
|
|
17
17
|
return a;
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
import {
|
|
21
|
+
storeColumnValidators
|
|
22
|
+
} from "./columnValidation";
|
|
20
23
|
const keyMap = {
|
|
21
24
|
caption: "header",
|
|
22
25
|
name: "accessorKey",
|
|
@@ -29,7 +32,7 @@ const keyMap = {
|
|
|
29
32
|
"col-class": "meta.className",
|
|
30
33
|
style: "meta"
|
|
31
34
|
};
|
|
32
|
-
function createColumnsProxy(wmTableColumns, applyOverride, setColumnsVersion, setSummaryRowDef) {
|
|
35
|
+
function createColumnsProxy(wmTableColumns, applyOverride, setColumnsVersion, setSummaryRowDef, validatorRegistry) {
|
|
33
36
|
const proxy = {};
|
|
34
37
|
wmTableColumns.forEach((col, idx) => {
|
|
35
38
|
const key = col.field;
|
|
@@ -39,11 +42,28 @@ function createColumnsProxy(wmTableColumns, applyOverride, setColumnsVersion, se
|
|
|
39
42
|
const newData = Array.isArray(data) ? data : [data];
|
|
40
43
|
invokeSummaryRowData(key, newData, setSummaryRowDef, columnShow);
|
|
41
44
|
};
|
|
45
|
+
const storeValidators = (kind, method) => (validators) => {
|
|
46
|
+
if (!validatorRegistry) {
|
|
47
|
+
console.warn(
|
|
48
|
+
`${method} called on column "${key}" before the table wired up validation.`
|
|
49
|
+
);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
storeColumnValidators(validatorRegistry, key, kind, validators);
|
|
53
|
+
};
|
|
54
|
+
const setValidators = storeValidators("validators", "setValidators");
|
|
55
|
+
const setAsyncValidators = storeValidators("asyncValidators", "setAsyncValidators");
|
|
42
56
|
proxy[key] = new Proxy(col, {
|
|
43
57
|
get(target, prop) {
|
|
44
58
|
if (prop === "setSummaryRowData") {
|
|
45
59
|
return setSummaryRowData;
|
|
46
60
|
}
|
|
61
|
+
if (prop === "setValidators") {
|
|
62
|
+
return setValidators;
|
|
63
|
+
}
|
|
64
|
+
if (prop === "setAsyncValidators") {
|
|
65
|
+
return setAsyncValidators;
|
|
66
|
+
}
|
|
47
67
|
return target[prop];
|
|
48
68
|
},
|
|
49
69
|
set(target, prop, value) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ValidatorConfig } from "@wavemaker-ai/react-runtime/components/data/form/form-controller/props";
|
|
2
|
+
import { WmTableColumnProps } from "../props";
|
|
3
|
+
export interface ColumnValidators {
|
|
4
|
+
/** From `columns.<field>.setValidators([...])`. */
|
|
5
|
+
validators: ValidatorConfig[];
|
|
6
|
+
/** From `columns.<field>.setAsyncValidators([...])`. */
|
|
7
|
+
asyncValidators: ValidatorConfig[];
|
|
8
|
+
}
|
|
9
|
+
export type ColumnValidatorRegistry = Record<string, ColumnValidators>;
|
|
10
|
+
export declare const isColumnValidatable: (column: WmTableColumnProps | undefined) => boolean;
|
|
11
|
+
export declare const cloneValidators: (validators: ValidatorConfig[]) => ValidatorConfig[];
|
|
12
|
+
export declare const storeColumnValidators: (registry: ColumnValidatorRegistry, field: string, kind: keyof ColumnValidators, validators: ValidatorConfig[]) => void;
|
|
13
|
+
export interface NativeValidityError {
|
|
14
|
+
/** The column field, i.e. the react-hook-form field name for the cell. */
|
|
15
|
+
fieldName: string;
|
|
16
|
+
message: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const collectNativeValidityErrors: (cellElements: Record<string, HTMLElement | null>, rowId: string) => NativeValidityError[];
|
|
19
|
+
export declare const focusFirstInvalidCell: (cellElements: Record<string, HTMLElement | null>, rowId: string, invalidFieldNames: string[]) => void;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
import { cloneDeep } from "lodash-es";
|
|
21
|
+
const isColumnValidatable = (column) => {
|
|
22
|
+
if (!column || !column.field) return false;
|
|
23
|
+
if (column.readonly) return false;
|
|
24
|
+
if (column.show === false) return false;
|
|
25
|
+
return true;
|
|
26
|
+
};
|
|
27
|
+
const cloneValidators = (validators) => Array.isArray(validators) ? cloneDeep(validators) : [];
|
|
28
|
+
const storeColumnValidators = (registry, field, kind, validators) => {
|
|
29
|
+
const current = registry[field] || { validators: [], asyncValidators: [] };
|
|
30
|
+
registry[field] = __spreadProps(__spreadValues({}, current), { [kind]: cloneValidators(validators) });
|
|
31
|
+
};
|
|
32
|
+
const NATIVE_VALIDITY_FLAGS = [
|
|
33
|
+
"badInput",
|
|
34
|
+
"typeMismatch",
|
|
35
|
+
"stepMismatch",
|
|
36
|
+
"rangeOverflow",
|
|
37
|
+
"rangeUnderflow",
|
|
38
|
+
"tooLong",
|
|
39
|
+
"tooShort"
|
|
40
|
+
];
|
|
41
|
+
const hasNativeError = (input) => !input.validity.valid && NATIVE_VALIDITY_FLAGS.some((flag) => input.validity[flag]);
|
|
42
|
+
const collectNativeValidityErrors = (cellElements, rowId) => {
|
|
43
|
+
const errors = [];
|
|
44
|
+
const prefix = `${rowId}_`;
|
|
45
|
+
for (const [fieldKey, element] of Object.entries(cellElements)) {
|
|
46
|
+
if (!element || !fieldKey.startsWith(prefix)) continue;
|
|
47
|
+
const fieldName = element.getAttribute("data-field-name") || fieldKey.slice(prefix.length);
|
|
48
|
+
const inputs = Array.from(element.querySelectorAll("input, select, textarea"));
|
|
49
|
+
const invalid = inputs.find(
|
|
50
|
+
(input) => !input.disabled && !("readOnly" in input && input.readOnly) && hasNativeError(input)
|
|
51
|
+
);
|
|
52
|
+
if (invalid) {
|
|
53
|
+
errors.push({ fieldName, message: invalid.validationMessage || "Value is not valid" });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return errors;
|
|
57
|
+
};
|
|
58
|
+
const focusFirstInvalidCell = (cellElements, rowId, invalidFieldNames) => {
|
|
59
|
+
var _a;
|
|
60
|
+
for (const fieldName of invalidFieldNames) {
|
|
61
|
+
const target = (_a = cellElements[`${rowId}_${fieldName}`]) == null ? void 0 : _a.querySelector(
|
|
62
|
+
"[focus-target], input, textarea, select"
|
|
63
|
+
);
|
|
64
|
+
if (target) {
|
|
65
|
+
target.focus();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
export {
|
|
71
|
+
cloneValidators,
|
|
72
|
+
collectNativeValidityErrors,
|
|
73
|
+
focusFirstInvalidCell,
|
|
74
|
+
isColumnValidatable,
|
|
75
|
+
storeColumnValidators
|
|
76
|
+
};
|
|
@@ -44,5 +44,7 @@ export declare const TABLE_MESSAGES: {
|
|
|
44
44
|
export declare const INTERACTIVE_CLASSES: readonly ["MuiInputBase", "MuiSelect", "MuiButton", "MuiCheckbox", "MuiRadio", "MuiSlider", "MuiSwitch", "MuiTextField", "MuiAutocomplete", "MuiChip", "MuiRating", "MuiToggleButton", "MuiPickersDay", "MuiDatePicker", "MuiTimePicker", "MuiDateTimePicker", "MuiCalendarPicker", "MuiClockPicker", "MuiColorPicker", "MuiFormControl", "MuiFormGroup", "MuiFormControlLabel", "app-text", "app-textarea", "app-checkbox", "app-slider", "app-currency", "app-switch", "app-select", "app-checkboxset", "app-radioset", "app-date", "app-time", "app-timestamp", "app-rating", "app-datetime", "app-search", "app-chips", "app-colorpicker", "app-calendar", "app-editor"];
|
|
45
45
|
export declare const INTERACTIVE_ROLES: readonly ["button", "textbox", "combobox", "listbox"];
|
|
46
46
|
export declare const INTERACTIVE_DATA_ROLES: readonly ["input", "select", "date", "time", "color", "editor", "checkbox", "radio", "slider", "chips", "rating"];
|
|
47
|
+
/** data-role values on the table selection column. Clicks here must not count as interactive widgets. */
|
|
48
|
+
export declare const SELECTION_COLUMN_DATA_ROLES: readonly ["select-all", "select-row"];
|
|
47
49
|
export declare const INTERACTIVE_TAG_NAMES: readonly ["INPUT", "BUTTON", "SELECT", "TEXTAREA", "A", "LABEL"];
|
|
48
50
|
export declare const UNSUPPORTED_STATE_PERSISTENCE_TYPES: readonly string[];
|
|
@@ -104,6 +104,7 @@ const INTERACTIVE_DATA_ROLES = [
|
|
|
104
104
|
"chips",
|
|
105
105
|
"rating"
|
|
106
106
|
];
|
|
107
|
+
const SELECTION_COLUMN_DATA_ROLES = ["select-all", "select-row"];
|
|
107
108
|
const INTERACTIVE_TAG_NAMES = [
|
|
108
109
|
"INPUT",
|
|
109
110
|
"BUTTON",
|
|
@@ -122,6 +123,7 @@ export {
|
|
|
122
123
|
INTERACTIVE_DATA_ROLES,
|
|
123
124
|
INTERACTIVE_ROLES,
|
|
124
125
|
INTERACTIVE_TAG_NAMES,
|
|
126
|
+
SELECTION_COLUMN_DATA_ROLES,
|
|
125
127
|
TABLE_CSS_CLASSES,
|
|
126
128
|
TABLE_DATA_STATES,
|
|
127
129
|
TABLE_MESSAGES,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { type CSSProperties } from "react";
|
|
2
|
-
import { WmTableColumnProps, WmTableRowActionProps, WmTableRowProps, WmTableActionProps
|
|
2
|
+
import { WmTableColumnProps, WmTableRowActionProps, WmTableRowProps, WmTableActionProps } from "../props";
|
|
3
3
|
declare const formWidgets: readonly ["WmText", "WmTextarea", "WmCheckbox", "WmSlider", "WmCurrency", "WmSwitch", "WmSelect", "WmCheckboxSet", "WmRadioSet", "WmDate", "WmTime", "WmTimestamp", "WmRating", "WmDatetime", "WmSearch", "WmChips", "WmColorPicker"];
|
|
4
4
|
type FormWidgetType = (typeof formWidgets)[number];
|
|
5
5
|
export type EditWidgetType = FormWidgetType;
|
|
@@ -69,15 +69,6 @@ export declare const isDeleteAction: (actionKey: string) => boolean;
|
|
|
69
69
|
export declare const isAddNewAction: (actionKey: string) => boolean;
|
|
70
70
|
export declare const getActionButtonClass: (action: WmTableRowActionProps) => string;
|
|
71
71
|
export declare const getTableActionButtonClass: (action: WmTableActionProps) => string;
|
|
72
|
-
/**
|
|
73
|
-
* Validates editing fields and focuses first invalid field if validation fails
|
|
74
|
-
* Can be used across different edit modes (inline, dialog, quick edit)
|
|
75
|
-
*
|
|
76
|
-
* @param fieldRefs - Record of field references from editing form
|
|
77
|
-
* @param editingRowId - Optional ID for logging/debugging purposes
|
|
78
|
-
* @returns ValidationResult object with validation status and invalid elements
|
|
79
|
-
*/
|
|
80
|
-
export declare const validateEditingFields: (fieldRefs: Record<string, HTMLElement | null>, editingRowId?: string) => ValidationResult;
|
|
81
72
|
export declare const getButtonClasses: (action: any, spacing?: string, isGridEditMode?: boolean, isLoading?: boolean) => string;
|
|
82
73
|
export declare const getSpacingClasses: (spacing?: string) => string;
|
|
83
74
|
export declare const shouldShowPagination: ({ shownavigation, onDemandLoad, internalDataset, pagesize, allowpagesizechange, datasource, showrecordcount, }: {
|
|
@@ -123,10 +114,11 @@ export declare function getDomHiddenColStyle(meta?: Record<string, unknown>): CS
|
|
|
123
114
|
/** Inline style for hidden th/td — display:none and zero box so flex sizing cannot leak width. */
|
|
124
115
|
export declare function getDomHiddenCellStyle(meta?: Record<string, unknown>): CSSProperties | undefined;
|
|
125
116
|
export declare const getColClass: (colClass: string, rowData: any, columnName: string) => string;
|
|
126
|
-
export { TABLE_CSS_CLASSES, TABLE_DATA_STATES, TABLE_MESSAGES, INTERACTIVE_CLASSES, INTERACTIVE_ROLES, INTERACTIVE_DATA_ROLES, INTERACTIVE_TAG_NAMES, UNSUPPORTED_STATE_PERSISTENCE_TYPES, } from "./constants";
|
|
117
|
+
export { TABLE_CSS_CLASSES, TABLE_DATA_STATES, TABLE_MESSAGES, INTERACTIVE_CLASSES, INTERACTIVE_ROLES, INTERACTIVE_DATA_ROLES, INTERACTIVE_TAG_NAMES, SELECTION_COLUMN_DATA_ROLES, UNSUPPORTED_STATE_PERSISTENCE_TYPES, } from "./constants";
|
|
127
118
|
export { renderDisplayCell } from "./renderDisplayCell";
|
|
128
119
|
export { buildSelectionColumns } from "./buildSelectionColumns";
|
|
129
|
-
export {
|
|
120
|
+
export { cloneValidators, collectNativeValidityErrors, focusFirstInvalidCell, isColumnValidatable, } from "./columnValidation";
|
|
121
|
+
export type { ColumnValidatorRegistry, NativeValidityError } from "./columnValidation";
|
|
130
122
|
export { hasInteractiveClass, hasInteractiveAttributes, isInteractiveElement, getRowIdsFromDataset, rowExistsInDataset, selectionStateHelpers, } from "./selectionUtils";
|
|
131
123
|
export { createRowIndexColumn, createDataColumn, createDataColumns, createEditingActionButtons, createDefaultColumnProps, getActionColumnSize, } from "./columnBuilder";
|
|
132
124
|
export { isDataColumn, hasExplicitWidth, distributeColumnWidths } from "./columnWidthDistribution";
|