trotl-table 1.0.67 → 1.0.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Table.cjs.js +156 -2
- package/dist/Table.cjs.js.map +1 -1
- package/dist/Table.esm.js +157 -3
- package/dist/Table.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/Table.cjs.js
CHANGED
|
@@ -9672,6 +9672,7 @@ function TableInner({
|
|
|
9672
9672
|
enableExternalRowDrop = false,
|
|
9673
9673
|
onExternalRowDrop = () => {},
|
|
9674
9674
|
useExternalDndContext = false,
|
|
9675
|
+
enableMouseRightClick = null,
|
|
9675
9676
|
customColumns = [],
|
|
9676
9677
|
groupDefaultOpen = false,
|
|
9677
9678
|
showIcons = true,
|
|
@@ -9730,9 +9731,49 @@ function TableInner({
|
|
|
9730
9731
|
onCellChangeRef.current = onCellChange;
|
|
9731
9732
|
cellCallbackRef.current = cellCallback;
|
|
9732
9733
|
});
|
|
9734
|
+
|
|
9735
|
+
// Context menu right click state
|
|
9736
|
+
const [contextMenu, setContextMenu] = React.useState({
|
|
9737
|
+
visible: false,
|
|
9738
|
+
x: 0,
|
|
9739
|
+
y: 0,
|
|
9740
|
+
row: null
|
|
9741
|
+
});
|
|
9742
|
+
const [contextMenuModal, setContextMenuModal] = React.useState({
|
|
9743
|
+
visible: false,
|
|
9744
|
+
title: '',
|
|
9745
|
+
component: null
|
|
9746
|
+
});
|
|
9733
9747
|
React.useEffect(() => {
|
|
9734
9748
|
shareCallbackRef.current = shareCallback;
|
|
9735
9749
|
}, [shareCallback]);
|
|
9750
|
+
React.useEffect(() => {
|
|
9751
|
+
if (!contextMenu.visible) return;
|
|
9752
|
+
const handleClick = () => setContextMenu({
|
|
9753
|
+
visible: false,
|
|
9754
|
+
x: 0,
|
|
9755
|
+
y: 0,
|
|
9756
|
+
row: null
|
|
9757
|
+
});
|
|
9758
|
+
const handleEscape = event => {
|
|
9759
|
+
if (event.key === 'Escape') {
|
|
9760
|
+
setContextMenu({
|
|
9761
|
+
visible: false,
|
|
9762
|
+
x: 0,
|
|
9763
|
+
y: 0,
|
|
9764
|
+
row: null
|
|
9765
|
+
});
|
|
9766
|
+
}
|
|
9767
|
+
};
|
|
9768
|
+
window.addEventListener('click', handleClick);
|
|
9769
|
+
window.addEventListener('contextmenu', handleClick);
|
|
9770
|
+
window.addEventListener('keydown', handleEscape);
|
|
9771
|
+
return () => {
|
|
9772
|
+
window.removeEventListener('click', handleClick);
|
|
9773
|
+
window.removeEventListener('contextmenu', handleClick);
|
|
9774
|
+
window.removeEventListener('keydown', handleEscape);
|
|
9775
|
+
};
|
|
9776
|
+
}, [contextMenu.visible]);
|
|
9736
9777
|
React.useEffect(() => {
|
|
9737
9778
|
duplicateCallbackRef.current = duplicateCallback;
|
|
9738
9779
|
}, [duplicateCallback]);
|
|
@@ -9845,6 +9886,43 @@ function TableInner({
|
|
|
9845
9886
|
setSelectedRows(prev => prev.includes(rowId) ? prev.filter(r => r !== rowId) : [...prev, rowId]);
|
|
9846
9887
|
}, []);
|
|
9847
9888
|
const clearSelection = React.useCallback(() => setSelectedRows([]), []);
|
|
9889
|
+
const performContextMenuAction = React.useCallback((action, row) => {
|
|
9890
|
+
setContextMenu({
|
|
9891
|
+
visible: false,
|
|
9892
|
+
x: 0,
|
|
9893
|
+
y: 0,
|
|
9894
|
+
row: null
|
|
9895
|
+
});
|
|
9896
|
+
if (!action) return;
|
|
9897
|
+
if (action.onClick && typeof action.onClick === "function") {
|
|
9898
|
+
action.onClick(row, action);
|
|
9899
|
+
return;
|
|
9900
|
+
}
|
|
9901
|
+
if (action.isModal) {
|
|
9902
|
+
setContextMenuModal({
|
|
9903
|
+
visible: true,
|
|
9904
|
+
title: action.label || "",
|
|
9905
|
+
component: action.component || null
|
|
9906
|
+
});
|
|
9907
|
+
return;
|
|
9908
|
+
}
|
|
9909
|
+
if (action.link) {
|
|
9910
|
+
window.open(action.link, action.target || "_blank");
|
|
9911
|
+
return;
|
|
9912
|
+
}
|
|
9913
|
+
|
|
9914
|
+
// fallback: provide simple event for the row itself.
|
|
9915
|
+
if (action.label) {
|
|
9916
|
+
console.log(`context action ${action.label} invoked`, row);
|
|
9917
|
+
}
|
|
9918
|
+
}, []);
|
|
9919
|
+
const closeContextMenuModal = React.useCallback(() => {
|
|
9920
|
+
setContextMenuModal({
|
|
9921
|
+
visible: false,
|
|
9922
|
+
title: '',
|
|
9923
|
+
component: null
|
|
9924
|
+
});
|
|
9925
|
+
}, []);
|
|
9848
9926
|
const setSort = column => {
|
|
9849
9927
|
setSorting(prev => {
|
|
9850
9928
|
if (!prev || prev.column !== column) return {
|
|
@@ -10389,6 +10467,32 @@ function TableInner({
|
|
|
10389
10467
|
});
|
|
10390
10468
|
}
|
|
10391
10469
|
|
|
10470
|
+
// Number column type (format decimals) - default two decimals
|
|
10471
|
+
if (col && col.type === 'number') {
|
|
10472
|
+
if (isNoData) {
|
|
10473
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
10474
|
+
title: translate("noData")
|
|
10475
|
+
}, "...");
|
|
10476
|
+
}
|
|
10477
|
+
const rawValue = Number(v);
|
|
10478
|
+
if (Number.isNaN(rawValue)) {
|
|
10479
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
10480
|
+
title: String(v)
|
|
10481
|
+
}, String(v));
|
|
10482
|
+
}
|
|
10483
|
+
let precision = 2;
|
|
10484
|
+
if (col.numberFormat != null) {
|
|
10485
|
+
const nf = Number(col.numberFormat);
|
|
10486
|
+
if (!Number.isNaN(nf) && nf >= 0) {
|
|
10487
|
+
precision = nf;
|
|
10488
|
+
}
|
|
10489
|
+
}
|
|
10490
|
+
const formatted = rawValue.toFixed(precision);
|
|
10491
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
10492
|
+
title: formatted
|
|
10493
|
+
}, formatted);
|
|
10494
|
+
}
|
|
10495
|
+
|
|
10392
10496
|
// If column has dateFormat, format value as date/time
|
|
10393
10497
|
if (col && col.dateFormat && v) {
|
|
10394
10498
|
let dateObj = null;
|
|
@@ -10746,7 +10850,18 @@ function TableInner({
|
|
|
10746
10850
|
const content = /*#__PURE__*/React.createElement("div", {
|
|
10747
10851
|
key: key,
|
|
10748
10852
|
style: style,
|
|
10749
|
-
className: "table-row"
|
|
10853
|
+
className: "table-row",
|
|
10854
|
+
onContextMenu: e => {
|
|
10855
|
+
if (!Array.isArray(enableMouseRightClick) || enableMouseRightClick.length === 0) return;
|
|
10856
|
+
e.preventDefault();
|
|
10857
|
+
e.stopPropagation();
|
|
10858
|
+
setContextMenu({
|
|
10859
|
+
visible: true,
|
|
10860
|
+
x: e.clientX,
|
|
10861
|
+
y: e.clientY,
|
|
10862
|
+
row
|
|
10863
|
+
});
|
|
10864
|
+
}
|
|
10750
10865
|
}, /*#__PURE__*/React.createElement("div", {
|
|
10751
10866
|
className: "row-main",
|
|
10752
10867
|
onDoubleClick: doubleClickEnable ? handleRowDoubleClick : undefined,
|
|
@@ -10861,6 +10976,7 @@ function TableInner({
|
|
|
10861
10976
|
}
|
|
10862
10977
|
return content;
|
|
10863
10978
|
}, [tableDataFlat, columns, selectedRows, toggleRowSelection, groupRowsById, renderCell, showActions, showDelete, showEdit, showKey, showView, translate, enableDragRow, moveRow, enableMultiSelect, rowHeight, tableId, customColumns, doubleClickEnable, keyWidth, actionColumnStyle, showDuplicate, showDownload, showIcons, showShare, triggerCellCallback, getAccessorKey, getAccessorValue]);
|
|
10979
|
+
const rightClickActions = Array.isArray(enableMouseRightClick) ? enableMouseRightClick : [];
|
|
10864
10980
|
const rowHeightGetter = ({
|
|
10865
10981
|
index
|
|
10866
10982
|
}) => tableDataFlat[index]?.type === "group" ? groupHeaderHeight : rowHeight;
|
|
@@ -10989,7 +11105,45 @@ function TableInner({
|
|
|
10989
11105
|
showCancel: true,
|
|
10990
11106
|
showConfirm: true
|
|
10991
11107
|
}, /*#__PURE__*/React.createElement("p", null, translate("areYouSureYouWantToDelete"), " ", /*#__PURE__*/React.createElement("strong", null, pendingDelete ? pendingDelete[deleteLabelKey] ?? pendingDelete.name ?? pendingDelete.id : ''), "?")));
|
|
10992
|
-
|
|
11108
|
+
const contextMenuMarkup = contextMenu.visible && rightClickActions.length > 0 ? /*#__PURE__*/React.createElement("div", {
|
|
11109
|
+
style: {
|
|
11110
|
+
position: 'fixed',
|
|
11111
|
+
top: contextMenu.y,
|
|
11112
|
+
left: contextMenu.x,
|
|
11113
|
+
backgroundColor: '#fff',
|
|
11114
|
+
border: '1px solid #ccc',
|
|
11115
|
+
boxShadow: '0 2px 8px rgba(0,0,0,.15)',
|
|
11116
|
+
zIndex: 9999,
|
|
11117
|
+
minWidth: 160,
|
|
11118
|
+
padding: 0,
|
|
11119
|
+
borderRadius: 4
|
|
11120
|
+
},
|
|
11121
|
+
onContextMenu: e => e.preventDefault()
|
|
11122
|
+
}, rightClickActions.map((action, i) => /*#__PURE__*/React.createElement("div", {
|
|
11123
|
+
key: i,
|
|
11124
|
+
style: {
|
|
11125
|
+
padding: '8px 12px',
|
|
11126
|
+
cursor: 'pointer',
|
|
11127
|
+
borderBottom: i < rightClickActions.length - 1 ? '1px solid #eee' : 'none'
|
|
11128
|
+
},
|
|
11129
|
+
onClick: () => performContextMenuAction(action, contextMenu.row)
|
|
11130
|
+
}, action.label || action.text || `Action ${i + 1}`))) : null;
|
|
11131
|
+
const contextMenuModalMarkup = contextMenuModal.visible && contextMenuModal.component ? /*#__PURE__*/React.createElement(Modal.default, {
|
|
11132
|
+
isOpen: true,
|
|
11133
|
+
title: contextMenuModal.title || '',
|
|
11134
|
+
onConfirm: () => setContextMenuModal({
|
|
11135
|
+
visible: false,
|
|
11136
|
+
title: '',
|
|
11137
|
+
component: null
|
|
11138
|
+
}),
|
|
11139
|
+
onCancel: () => closeContextMenuModal(),
|
|
11140
|
+
showConfirm: false,
|
|
11141
|
+
showCancel: true,
|
|
11142
|
+
cancelLabel: translate('cancel')
|
|
11143
|
+
}, typeof contextMenuModal.component === 'function' ? /*#__PURE__*/React.createElement(contextMenuModal.component, {
|
|
11144
|
+
row: contextMenu.row
|
|
11145
|
+
}) : contextMenuModal.component) : null;
|
|
11146
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, tableMarkup, contextMenuMarkup, contextMenuModalMarkup);
|
|
10993
11147
|
}
|
|
10994
11148
|
function Table(props) {
|
|
10995
11149
|
const {
|