@linzjs/step-ag-grid 29.13.0 → 29.14.1
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/index.css +26 -2
- package/dist/src/components/Grid.d.ts +36 -61
- package/dist/src/components/GridRangeSelectContextMenu.d.ts +10 -0
- package/dist/src/components/gridForm/GridFormDropDown.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormPopoverMenu.d.ts +2 -1
- package/dist/src/components/gridHook/useGridContextMenu.d.ts +12 -7
- package/dist/src/components/gridHook/useGridCopy.d.ts +15 -0
- package/dist/src/components/gridHook/useGridCopySettings.d.ts +11 -0
- package/dist/src/components/gridHook/useGridRangeSelection.d.ts +25 -0
- package/dist/src/components/gridPopoverEdit/GridPopoverEditBearing.d.ts +2 -0
- package/dist/src/components/types.d.ts +1 -0
- package/dist/src/contexts/GridContext.d.ts +1 -0
- package/dist/src/lui/timeoutHook.d.ts +0 -6
- package/dist/src/lui/tsUtils.d.ts +5 -0
- package/dist/src/utils/__tests__/random.ts +19 -0
- package/dist/src/utils/util.d.ts +1 -0
- package/dist/step-ag-grid.cjs +560 -79
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +561 -82
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Grid.tsx +249 -179
- package/src/components/GridRangeSelectContextMenu.tsx +73 -0
- package/src/components/gridForm/GridFormDropDown.tsx +1 -3
- package/src/components/gridForm/GridFormPopoverMenu.tsx +2 -1
- package/src/components/gridHook/useGridContextMenu.tsx +22 -9
- package/src/components/gridHook/useGridCopy.ts +279 -0
- package/src/components/gridHook/useGridCopySettings.ts +28 -0
- package/src/components/gridHook/useGridRangeSelection.ts +235 -0
- package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +3 -0
- package/src/components/types.ts +2 -0
- package/src/contexts/GridContext.tsx +2 -0
- package/src/contexts/GridContextProvider.tsx +5 -2
- package/src/lui/timeoutHook.tsx +0 -19
- package/src/lui/tsUtils.ts +8 -0
- package/src/stories/grid/GridCopy.stories.tsx +175 -0
- package/src/stories/grid/GridPopoverEditBearing.stories.tsx +4 -4
- package/src/stories/grid/GridReadOnly.stories.tsx +1 -0
- package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +2 -2
- package/src/styles/ContextMenu.scss +61 -0
- package/src/styles/Grid.scss +26 -2
- package/src/utils/__tests__/random.ts +19 -0
- package/src/utils/bearing.ts +2 -2
- package/src/utils/util.ts +2 -0
package/dist/step-ag-grid.cjs
CHANGED
|
@@ -419,6 +419,9 @@ function useInterval(callback, delay) {
|
|
|
419
419
|
savedCallback.current = callback;
|
|
420
420
|
}, [callback]);
|
|
421
421
|
React.useEffect(() => {
|
|
422
|
+
if (delay === null) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
422
425
|
const id = setInterval(() => {
|
|
423
426
|
savedCallback.current();
|
|
424
427
|
}, delay);
|
|
@@ -435,6 +438,7 @@ const NoContext = () => {
|
|
|
435
438
|
const GridContext = React.createContext({
|
|
436
439
|
gridReady: false,
|
|
437
440
|
gridRenderState: () => null,
|
|
441
|
+
getCellValue: NoContext,
|
|
438
442
|
getColDef: NoContext,
|
|
439
443
|
getColumns: NoContext,
|
|
440
444
|
getColumnIds: NoContext,
|
|
@@ -756,6 +760,36 @@ const GridHeaderSelect = ({ api }) => {
|
|
|
756
760
|
} }) }));
|
|
757
761
|
};
|
|
758
762
|
|
|
763
|
+
function styleInject(css, ref) {
|
|
764
|
+
if ( ref === void 0 ) ref = {};
|
|
765
|
+
var insertAt = ref.insertAt;
|
|
766
|
+
|
|
767
|
+
if (!css || typeof document === 'undefined') { return; }
|
|
768
|
+
|
|
769
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
770
|
+
var style = document.createElement('style');
|
|
771
|
+
style.type = 'text/css';
|
|
772
|
+
|
|
773
|
+
if (insertAt === 'top') {
|
|
774
|
+
if (head.firstChild) {
|
|
775
|
+
head.insertBefore(style, head.firstChild);
|
|
776
|
+
} else {
|
|
777
|
+
head.appendChild(style);
|
|
778
|
+
}
|
|
779
|
+
} else {
|
|
780
|
+
head.appendChild(style);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
if (style.styleSheet) {
|
|
784
|
+
style.styleSheet.cssText = css;
|
|
785
|
+
} else {
|
|
786
|
+
style.appendChild(document.createTextNode(css));
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
var css_248z$4 = ".GridContextMenu li.szh-menu__header{color:#6b6966;font-size:14px;font-weight:600;padding-left:16px;padding-right:16px;text-transform:none}.GridContextMenu li.szh-menu__item{padding-left:16px;padding-right:16px}.GridContextMenu li.szh-menu__item .copyMenuMenuItem{align-items:center;display:flex;gap:8px}.GridContextMenu li.szh-menu__item .copyMenuMenuItem__text{color:#2a292c;font-size:16px;font-weight:400;width:80px}.GridContextMenu li.szh-menu__item .copyMenuMenuItem__buttonDefault{background:none;border:2px solid #0000;display:flex;padding:6px}.GridContextMenu li.szh-menu__item .copyMenuMenuItem__buttonDefault.copyMenuMenuItem__buttonDefault--hidden:hover{border:2px solid #2a292c}.GridContextMenu li.szh-menu__item .copyMenuMenuItem__buttonDefault--hidden .LuiIcon{fill:#0000}.GridContextMenu li.szh-menu__item .LuiIcon,.GridContextMenu li.szh-menu__item .copyMenuMenuItem__buttonDefault--hidden:hover .LuiIcon{fill:#6b6966}.GridContextMenu li.szh-menu__item .LuiIcon[data-icon=ic_tick]{padding-left:4px;padding-right:4px}.GridContextMenu li.szh-menu__item--hover{background-color:#e2f3f7}";
|
|
791
|
+
styleInject(css_248z$4);
|
|
792
|
+
|
|
759
793
|
const EventHandlersContext = React.createContext({
|
|
760
794
|
handleClick: () => { },
|
|
761
795
|
});
|
|
@@ -2590,7 +2624,7 @@ const SubMenuFr = ({ 'aria-label': ariaLabel, className, disabled, direction, la
|
|
|
2590
2624
|
};
|
|
2591
2625
|
const SubMenu = withHovering('SubMenu', SubMenuFr);
|
|
2592
2626
|
|
|
2593
|
-
const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, }) => {
|
|
2627
|
+
const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, context, }) => {
|
|
2594
2628
|
const { redrawRows, prePopupOps, resetFocusedCellAfterCellEditing, getSelectedRows } = React.useContext(GridContext);
|
|
2595
2629
|
const [isOpen, setOpen] = React.useState(false);
|
|
2596
2630
|
const [anchorPoint, setAnchorPoint] = React.useState({ x: 0, y: 0 });
|
|
@@ -2598,6 +2632,7 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
|
|
|
2598
2632
|
const clickedColDefRef = React.useRef(null);
|
|
2599
2633
|
const selectedRowsRef = React.useRef([]);
|
|
2600
2634
|
const clickedRowRef = React.useRef(null);
|
|
2635
|
+
const eventRef = React.useRef(undefined);
|
|
2601
2636
|
const openMenu = React.useCallback((e) => {
|
|
2602
2637
|
if (!e)
|
|
2603
2638
|
return;
|
|
@@ -2617,15 +2652,423 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
|
|
|
2617
2652
|
clickedColDefRef.current = event.colDef;
|
|
2618
2653
|
selectedRowsRef.current = getSelectedRows();
|
|
2619
2654
|
clickedRowRef.current = event.data;
|
|
2655
|
+
eventRef.current = event;
|
|
2620
2656
|
// This is actually a pointer event
|
|
2621
2657
|
openMenu(event.event);
|
|
2622
2658
|
}, [contextMenuSelectRow, getSelectedRows, openMenu]);
|
|
2623
2659
|
return {
|
|
2624
2660
|
openMenu,
|
|
2625
2661
|
cellContextMenu,
|
|
2626
|
-
|
|
2662
|
+
contextMenuComponent: ContextMenu ? (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(ControlledMenu, { className: 'GridContextMenu', anchorPoint: anchorPoint, state: isOpen ? 'open' : 'closed', direction: "right", onClose: closeMenu, children: isOpen && (jsxRuntime.jsx(ContextMenu, { selectedRows: selectedRowsRef.current, clickedRow: clickedRowRef.current, colDef: clickedColDefRef.current, event: eventRef.current, close: closeMenu, context: context })) }) })) : null,
|
|
2663
|
+
};
|
|
2664
|
+
};
|
|
2665
|
+
|
|
2666
|
+
const typedEntries = (obj) => Object.entries(obj);
|
|
2667
|
+
|
|
2668
|
+
const gridCopyOptions = {
|
|
2669
|
+
html: { text: 'Text\xa0/\xa0HTML', icon: 'ic_product_list' },
|
|
2670
|
+
csv: { text: 'CSV', icon: 'ic_csv_file' },
|
|
2671
|
+
json: { text: 'Json', icon: 'ic_file_attached_outline', developer: true },
|
|
2672
|
+
};
|
|
2673
|
+
const CopyOptionsStorageKey = 'stepAgGrid_defaultCopy';
|
|
2674
|
+
const useGridCopySettings = () => {
|
|
2675
|
+
const [copyType, _setCopyType] = React.useState(() => {
|
|
2676
|
+
const defaultCopy = window.localStorage.getItem(CopyOptionsStorageKey) ?? '';
|
|
2677
|
+
return Object.keys(gridCopyOptions).includes(defaultCopy) ? defaultCopy : 'html';
|
|
2678
|
+
});
|
|
2679
|
+
const setCopyType = React.useCallback((key) => {
|
|
2680
|
+
window.localStorage.setItem(CopyOptionsStorageKey, key);
|
|
2681
|
+
_setCopyType(key);
|
|
2682
|
+
}, []);
|
|
2683
|
+
return {
|
|
2684
|
+
copyType,
|
|
2685
|
+
setCopyType,
|
|
2686
|
+
};
|
|
2687
|
+
};
|
|
2688
|
+
|
|
2689
|
+
const GridRangeSelectContextMenu = ({ event, context, }) => {
|
|
2690
|
+
const developerContextMenu = !!event?.event?.ctrlKey && !!event?.event?.shiftKey;
|
|
2691
|
+
const onCopy = React.useMemo(() => context?.onCopy, [context?.onCopy]);
|
|
2692
|
+
const onClick = React.useCallback((type) => {
|
|
2693
|
+
onCopy?.(type);
|
|
2694
|
+
}, [onCopy]);
|
|
2695
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(MenuHeader, { children: "Copy as" }), typedEntries(gridCopyOptions).map(([key, { icon, text, developer }]) => {
|
|
2696
|
+
return ((!developer || developerContextMenu) && (jsxRuntime.jsx(MenuItem, { onClick: () => void onClick(key), children: jsxRuntime.jsxs("div", { className: 'copyMenuMenuItem', children: [jsxRuntime.jsx(lui.LuiIcon, { name: icon, alt: text, size: 'md' }), jsxRuntime.jsx("div", { className: 'copyMenuMenuItem__text', children: text })] }) }, key)));
|
|
2697
|
+
}), jsxRuntime.jsx(MenuDivider, {}), jsxRuntime.jsx(MenuHeader, { children: "Set copy default" }), typedEntries(gridCopyOptions).map(([key, { text, developer }]) => {
|
|
2698
|
+
return (!developer && (jsxRuntime.jsx(MenuItem, { onClick: (e) => {
|
|
2699
|
+
context?.setCopyType(key);
|
|
2700
|
+
e.keepOpen = true;
|
|
2701
|
+
}, children: jsxRuntime.jsxs("div", { className: clsx('copyMenuMenuItem', context?.copyType === key ? '' : 'copyMenuMenuItem__buttonDefault--hidden'), children: [jsxRuntime.jsx(lui.LuiIcon, { name: 'ic_tick', alt: 'CSV', size: 'sm' }), jsxRuntime.jsx("div", { className: 'copyMenuMenuItem__text', children: text })] }) }, 'default_' + key)));
|
|
2702
|
+
})] }));
|
|
2703
|
+
};
|
|
2704
|
+
|
|
2705
|
+
const agGridSelectRowColId = 'ag-Grid-SelectionColumn';
|
|
2706
|
+
|
|
2707
|
+
const useGridCopy = ({ ranges, rangeStartRef, rangeEndRef, hasSelectedMoreThanOneCellRef, cellContextMenu, }) => {
|
|
2708
|
+
const showToast = lui.useShowLUIMessage();
|
|
2709
|
+
const { getSelectedRowIds } = useGridContext();
|
|
2710
|
+
const { getColDef, getCellValue } = useGridContext();
|
|
2711
|
+
const { copyType, setCopyType } = useGridCopySettings();
|
|
2712
|
+
const onCopy = React.useCallback((type = copyType) => {
|
|
2713
|
+
const rangeStart = rangeStartRef.current;
|
|
2714
|
+
const rangeEnd = rangeEndRef.current;
|
|
2715
|
+
if (rangeStart === null || rangeEnd === null || !hasSelectedMoreThanOneCellRef.current) {
|
|
2716
|
+
return;
|
|
2717
|
+
}
|
|
2718
|
+
if (rangeStart.rowId === rangeEnd.rowId && rangeStart.colId === rangeEnd.colId) {
|
|
2719
|
+
type = 'html';
|
|
2720
|
+
}
|
|
2721
|
+
const json = type === 'json';
|
|
2722
|
+
const { selectedColIds, selectedNodes } = ranges();
|
|
2723
|
+
const filteredSelectedColIds = selectedColIds.filter((colId) => colId === agGridSelectRowColId ||
|
|
2724
|
+
(colId !== 'gridCellFiller' && getColDef(colId)?.headerComponentParams?.exportable !== false));
|
|
2725
|
+
const selectedRowIds = getSelectedRowIds();
|
|
2726
|
+
const formatters = lodashEs.compact(filteredSelectedColIds.map((colKey) => {
|
|
2727
|
+
return (rowNode) => {
|
|
2728
|
+
if (colKey === agGridSelectRowColId) {
|
|
2729
|
+
return selectedRowIds.includes(rowNode.data.id);
|
|
2730
|
+
}
|
|
2731
|
+
else {
|
|
2732
|
+
const v = getCellValue({ rowNode, colKey });
|
|
2733
|
+
if (json && v !== undefined) {
|
|
2734
|
+
return v;
|
|
2735
|
+
}
|
|
2736
|
+
const f = getCellValue({ rowNode, colKey, useFormatter: true });
|
|
2737
|
+
// If it's a number, and it matches value return the original type
|
|
2738
|
+
return v == f ? v : f;
|
|
2739
|
+
}
|
|
2740
|
+
};
|
|
2741
|
+
}));
|
|
2742
|
+
// Get and apply headers
|
|
2743
|
+
const headers = filteredSelectedColIds.map((colId) => {
|
|
2744
|
+
if (colId === agGridSelectRowColId)
|
|
2745
|
+
return type === 'json' ? 'selected' : 'Selected';
|
|
2746
|
+
if (json) {
|
|
2747
|
+
return colId;
|
|
2748
|
+
}
|
|
2749
|
+
return getColDef(colId)?.headerName ?? '?';
|
|
2750
|
+
});
|
|
2751
|
+
const maxCellLength = {};
|
|
2752
|
+
headers.forEach((headerName, i) => {
|
|
2753
|
+
const colId = filteredSelectedColIds[i];
|
|
2754
|
+
maxCellLength[colId] = headerName.length;
|
|
2755
|
+
});
|
|
2756
|
+
const rows = [];
|
|
2757
|
+
if (type === 'csv' || type === 'html') {
|
|
2758
|
+
rows.push(headers);
|
|
2759
|
+
}
|
|
2760
|
+
selectedNodes.forEach((node) => {
|
|
2761
|
+
const row = [];
|
|
2762
|
+
rows.push(row);
|
|
2763
|
+
formatters.forEach((formatter, i) => {
|
|
2764
|
+
const colId = filteredSelectedColIds[i];
|
|
2765
|
+
let value = formatter(node);
|
|
2766
|
+
if (typeof value === 'string') {
|
|
2767
|
+
value = value.replaceAll('\xa0', ' ');
|
|
2768
|
+
}
|
|
2769
|
+
if (!json) {
|
|
2770
|
+
if (value === '-' || value === '–' || value == null) {
|
|
2771
|
+
value = '';
|
|
2772
|
+
}
|
|
2773
|
+
value = String(value);
|
|
2774
|
+
if (value === '-' || value === '–') {
|
|
2775
|
+
value = '';
|
|
2776
|
+
}
|
|
2777
|
+
maxCellLength[colId] = Math.max(maxCellLength[colId], value.length);
|
|
2778
|
+
}
|
|
2779
|
+
switch (type) {
|
|
2780
|
+
case 'json':
|
|
2781
|
+
value =
|
|
2782
|
+
value === 'undefined' || (value !== null && typeof value === 'object') || typeof value === 'string'
|
|
2783
|
+
? JSON.stringify(value)
|
|
2784
|
+
: value;
|
|
2785
|
+
break;
|
|
2786
|
+
case 'markdown':
|
|
2787
|
+
value = encodeMarkdownValue(value);
|
|
2788
|
+
break;
|
|
2789
|
+
case 'csv':
|
|
2790
|
+
value = encodeCSVValue(value);
|
|
2791
|
+
break;
|
|
2792
|
+
}
|
|
2793
|
+
row.push(String(value));
|
|
2794
|
+
});
|
|
2795
|
+
});
|
|
2796
|
+
let result = '';
|
|
2797
|
+
let html = `<table style="
|
|
2798
|
+
font-family: 'Open Sans', system-ui, sans-serif;
|
|
2799
|
+
font-size: 10px;
|
|
2800
|
+
line-height: 10px;
|
|
2801
|
+
border: 1px solid #d1d9e0;
|
|
2802
|
+
border-collapse: collapse;
|
|
2803
|
+
">`;
|
|
2804
|
+
if (json) {
|
|
2805
|
+
result += '[\n';
|
|
2806
|
+
}
|
|
2807
|
+
rows.forEach((row, rowIndex) => {
|
|
2808
|
+
if (json) {
|
|
2809
|
+
result += ' { ';
|
|
2810
|
+
}
|
|
2811
|
+
if (rowIndex == 1) {
|
|
2812
|
+
html += '<tbody style="font-weight: 400;">';
|
|
2813
|
+
}
|
|
2814
|
+
if (rowIndex == 0) {
|
|
2815
|
+
html += '<thead style="font-weight: 600;">';
|
|
2816
|
+
}
|
|
2817
|
+
if (rowIndex === 0 || (rowIndex & 1) === 1) {
|
|
2818
|
+
html += '<tr>';
|
|
2819
|
+
}
|
|
2820
|
+
else {
|
|
2821
|
+
html += '<tr style="background-color: #f6f8fa;">';
|
|
2822
|
+
}
|
|
2823
|
+
if (rowIndex === 1 && type === 'html') {
|
|
2824
|
+
Object.values(maxCellLength).forEach((maxLength) => {
|
|
2825
|
+
result += '|' + '-'.repeat(maxLength + 2);
|
|
2826
|
+
});
|
|
2827
|
+
result += '|\n';
|
|
2828
|
+
}
|
|
2829
|
+
row.forEach((cell, i) => {
|
|
2830
|
+
switch (type) {
|
|
2831
|
+
case 'csv':
|
|
2832
|
+
if (i !== 0) {
|
|
2833
|
+
result += ', ';
|
|
2834
|
+
}
|
|
2835
|
+
result += cell;
|
|
2836
|
+
break;
|
|
2837
|
+
case 'html':
|
|
2838
|
+
if (i === 0) {
|
|
2839
|
+
result += '|';
|
|
2840
|
+
}
|
|
2841
|
+
const colId = filteredSelectedColIds[i];
|
|
2842
|
+
result += ' ' + cell.padEnd(maxCellLength[colId], ' ') + ' ';
|
|
2843
|
+
result += '|';
|
|
2844
|
+
html +=
|
|
2845
|
+
rowIndex === 0
|
|
2846
|
+
? '<th style="border: 1px solid #d1d9e0; padding:6px 13px; text-align: left;">'
|
|
2847
|
+
: '<td style="border: 1px solid #d1d9e0; padding:6px 13px;">';
|
|
2848
|
+
html += cell;
|
|
2849
|
+
html += rowIndex === 0 ? '</th>' : '</td>';
|
|
2850
|
+
break;
|
|
2851
|
+
case 'json':
|
|
2852
|
+
if (i !== 0) {
|
|
2853
|
+
result += ', ';
|
|
2854
|
+
}
|
|
2855
|
+
result += JSON.stringify(headers[i]) + ': ' + cell;
|
|
2856
|
+
break;
|
|
2857
|
+
}
|
|
2858
|
+
});
|
|
2859
|
+
html += '</tr>';
|
|
2860
|
+
if (rowIndex == 0) {
|
|
2861
|
+
html += '</thead>';
|
|
2862
|
+
}
|
|
2863
|
+
if (rowIndex == rows.length - 1) {
|
|
2864
|
+
html += '</tbody>';
|
|
2865
|
+
}
|
|
2866
|
+
if (json) {
|
|
2867
|
+
result += ' }';
|
|
2868
|
+
}
|
|
2869
|
+
result += '\n';
|
|
2870
|
+
});
|
|
2871
|
+
if (json) {
|
|
2872
|
+
result += ']\n';
|
|
2873
|
+
}
|
|
2874
|
+
html += '</table>';
|
|
2875
|
+
showToast({
|
|
2876
|
+
message: `${gridCopyOptions[type].text} copied`,
|
|
2877
|
+
messageType: 'toast',
|
|
2878
|
+
messageLevel: 'info',
|
|
2879
|
+
});
|
|
2880
|
+
if (type === 'html') {
|
|
2881
|
+
const clipboardItem = new ClipboardItem({
|
|
2882
|
+
'text/html': new Blob([html], { type: 'text/html' }),
|
|
2883
|
+
'text/plain': new Blob([result], { type: 'text/plain' }), // fallback
|
|
2884
|
+
});
|
|
2885
|
+
void navigator.clipboard.write([clipboardItem]).catch((err) => console.error('Failed to copy: ', err));
|
|
2886
|
+
}
|
|
2887
|
+
else {
|
|
2888
|
+
void navigator.clipboard.writeText(result).catch((err) => console.error('Failed to copy: ', err));
|
|
2889
|
+
}
|
|
2890
|
+
}, [getCellValue, ranges, copyType]);
|
|
2891
|
+
const onCopyEvent = React.useCallback((e) => {
|
|
2892
|
+
const rangeStart = rangeStartRef.current;
|
|
2893
|
+
const rangeEnd = rangeEndRef.current;
|
|
2894
|
+
if (rangeStart === null ||
|
|
2895
|
+
rangeEnd === null ||
|
|
2896
|
+
(rangeStart.colId === rangeEnd.colId &&
|
|
2897
|
+
rangeStart.rowId === rangeEnd.rowId &&
|
|
2898
|
+
!hasSelectedMoreThanOneCellRef.current)) {
|
|
2899
|
+
return;
|
|
2900
|
+
}
|
|
2901
|
+
e.preventDefault();
|
|
2902
|
+
onCopy();
|
|
2903
|
+
}, [onCopy]);
|
|
2904
|
+
const { cellContextMenu: rangeSelectContextMenu, contextMenuComponent: rangeSelectContextMenuComponent } = useGridContextMenu({
|
|
2905
|
+
contextMenu: (GridRangeSelectContextMenu),
|
|
2906
|
+
context: { onCopy, copyType, setCopyType },
|
|
2907
|
+
});
|
|
2908
|
+
const rangeSelectInterceptContextMenu = React.useCallback((event) => rangeStartRef.current == null ? cellContextMenu(event) : rangeSelectContextMenu(event), [cellContextMenu, rangeSelectContextMenu]);
|
|
2909
|
+
return {
|
|
2910
|
+
onCopyEvent,
|
|
2911
|
+
rangeSelectInterceptContextMenu,
|
|
2912
|
+
rangeSelectContextMenuComponent,
|
|
2627
2913
|
};
|
|
2628
2914
|
};
|
|
2915
|
+
const encodeMarkdownValue = (value) => {
|
|
2916
|
+
return value.replaceAll('|', '\\|');
|
|
2917
|
+
};
|
|
2918
|
+
const encodeCSVValue = (value) => {
|
|
2919
|
+
let str = String(value);
|
|
2920
|
+
// Check if it needs quoting
|
|
2921
|
+
if (/[",\n]/.test(str)) {
|
|
2922
|
+
// Escape double quotes by doubling them
|
|
2923
|
+
str = '"' + str.replace(/"/g, '""') + '"';
|
|
2924
|
+
}
|
|
2925
|
+
return str;
|
|
2926
|
+
};
|
|
2927
|
+
|
|
2928
|
+
const useGridRangeSelection = ({ enableRangeSelection, gridDivRef, rangeStartRef, rangeEndRef, hasSelectedMoreThanOneCellRef, rangeSortedNodesRef, }) => {
|
|
2929
|
+
const [refreshIntervalEnabled, setRefreshIntervalEnabled] = React.useState(false);
|
|
2930
|
+
const ranges = React.useCallback(() => {
|
|
2931
|
+
const gridElement = gridDivRef.current;
|
|
2932
|
+
const rangeStart = rangeStartRef.current;
|
|
2933
|
+
const rangeEnd = rangeEndRef.current;
|
|
2934
|
+
const rangeSortedNodes = rangeSortedNodesRef.current;
|
|
2935
|
+
if (!gridElement || !rangeStart || !rangeEnd || !rangeSortedNodes) {
|
|
2936
|
+
return {
|
|
2937
|
+
selectedColIds: [],
|
|
2938
|
+
selectedNodes: [],
|
|
2939
|
+
};
|
|
2940
|
+
}
|
|
2941
|
+
const elStyleLeftComparator = (el1, el2) => elStyleLeft(el1) - elStyleLeft(el2);
|
|
2942
|
+
const elStyleLeft = (el) => parseFloat(el.style.left) ?? 0;
|
|
2943
|
+
const getSortedColIds = () => {
|
|
2944
|
+
//
|
|
2945
|
+
const leftHeaders = [...gridElement.querySelectorAll('.ag-pinned-left-header .ag-header-cell')].sort(elStyleLeftComparator);
|
|
2946
|
+
const centerHeaders = [...gridElement.querySelectorAll('.ag-header-viewport .ag-header-cell')].sort(elStyleLeftComparator);
|
|
2947
|
+
const rightHeaders = [...gridElement.querySelectorAll('.ag-pinned-right-header .ag-header-cell')].sort(elStyleLeftComparator);
|
|
2948
|
+
return [...leftHeaders, ...centerHeaders, ...rightHeaders].map((el, i) => el.getAttribute('col-id') ?? String(i));
|
|
2949
|
+
};
|
|
2950
|
+
const sortedColIds = getSortedColIds();
|
|
2951
|
+
const startColIndex = sortedColIds.indexOf(rangeStart.colId);
|
|
2952
|
+
const endColIndex = sortedColIds.indexOf(rangeEnd.colId);
|
|
2953
|
+
const selectedColIds = sortedColIds.slice(Math.min(startColIndex, endColIndex), Math.max(startColIndex, endColIndex) + 1);
|
|
2954
|
+
const startRowIndex = rangeSortedNodes.findIndex((node) => node.data.id === rangeStart.rowId);
|
|
2955
|
+
const endRowIndex = rangeSortedNodes.findIndex((node) => node.data.id === rangeEnd.rowId);
|
|
2956
|
+
const selectedNodes = rangeSortedNodes.slice(Math.min(startRowIndex, endRowIndex), Math.max(startRowIndex, endRowIndex) + 1);
|
|
2957
|
+
return { selectedColIds, selectedNodes };
|
|
2958
|
+
}, []);
|
|
2959
|
+
const redrawSelectedRanges = React.useCallback(() => {
|
|
2960
|
+
const gridElement = gridDivRef.current;
|
|
2961
|
+
const { selectedColIds, selectedNodes } = ranges();
|
|
2962
|
+
selectedColIds.forEach((colId, colIndex) => {
|
|
2963
|
+
selectedNodes.forEach((node, rowIndex) => {
|
|
2964
|
+
const rowId = node.data.id;
|
|
2965
|
+
const cell = gridElement.querySelector(`.ag-row[row-id=${JSON.stringify(String(rowId))}] .ag-cell[col-id=${JSON.stringify(colId)}`);
|
|
2966
|
+
cell?.classList.add('rangeSelect');
|
|
2967
|
+
if (colIndex === 0) {
|
|
2968
|
+
cell?.classList.add('rangeSelectLeft');
|
|
2969
|
+
}
|
|
2970
|
+
if (colIndex === selectedColIds.length - 1) {
|
|
2971
|
+
cell?.classList.add('rangeSelectRight');
|
|
2972
|
+
}
|
|
2973
|
+
if (rowIndex === 0) {
|
|
2974
|
+
cell?.classList.add('rangeSelectTop');
|
|
2975
|
+
}
|
|
2976
|
+
if (rowIndex === selectedNodes.length - 1) {
|
|
2977
|
+
cell?.classList.add('rangeSelectBottom');
|
|
2978
|
+
}
|
|
2979
|
+
});
|
|
2980
|
+
});
|
|
2981
|
+
}, []);
|
|
2982
|
+
const updateRangeSelectionCellClasses = React.useCallback((justRefresh) => {
|
|
2983
|
+
//
|
|
2984
|
+
// Get all grid cols, sort by pinned, then style: left
|
|
2985
|
+
const gridElement = gridDivRef.current;
|
|
2986
|
+
if (!gridElement) {
|
|
2987
|
+
return;
|
|
2988
|
+
}
|
|
2989
|
+
// Clear all selections
|
|
2990
|
+
if (!justRefresh) {
|
|
2991
|
+
gridElement
|
|
2992
|
+
.querySelectorAll('.rangeSelect,.rangeSelectLeft,.rangeSelectTop,.rangeSelectRight,.rangeSelectBottom')
|
|
2993
|
+
.forEach((el) => {
|
|
2994
|
+
el.classList.remove('rangeSelect', 'rangeSelectLeft', 'rangeSelectTop', 'rangeSelectRight', 'rangeSelectBottom');
|
|
2995
|
+
});
|
|
2996
|
+
}
|
|
2997
|
+
// if range selection multiple add .Grid-container.rangeSelectingMultiple
|
|
2998
|
+
const rangeStart = rangeStartRef.current;
|
|
2999
|
+
const rangeEnd = rangeEndRef.current;
|
|
3000
|
+
if (rangeStart !== null &&
|
|
3001
|
+
rangeEnd !== null &&
|
|
3002
|
+
(hasSelectedMoreThanOneCellRef.current ||
|
|
3003
|
+
rangeStart.colId !== rangeEnd.colId ||
|
|
3004
|
+
rangeStart.rowId !== rangeEnd.rowId)) {
|
|
3005
|
+
gridElement.classList.add('rangeSelectingMultiple');
|
|
3006
|
+
gridElement.querySelectorAll('.ag-cell-focus').forEach((el) => {
|
|
3007
|
+
el.classList.remove('ag-cell-focus');
|
|
3008
|
+
});
|
|
3009
|
+
}
|
|
3010
|
+
else {
|
|
3011
|
+
gridElement.classList.remove('rangeSelectingMultiple');
|
|
3012
|
+
return;
|
|
3013
|
+
}
|
|
3014
|
+
const rangeSortedNodes = rangeSortedNodesRef.current;
|
|
3015
|
+
if (!rangeSortedNodes) {
|
|
3016
|
+
return;
|
|
3017
|
+
}
|
|
3018
|
+
redrawSelectedRanges();
|
|
3019
|
+
}, [ranges, redrawSelectedRanges]);
|
|
3020
|
+
// Handle updates after scroll / grid refresh
|
|
3021
|
+
useInterval(() => {
|
|
3022
|
+
updateRangeSelectionCellClasses(true);
|
|
3023
|
+
}, refreshIntervalEnabled ? 150 : null);
|
|
3024
|
+
const clearRangeSelection = React.useCallback(() => {
|
|
3025
|
+
hasSelectedMoreThanOneCellRef.current = false;
|
|
3026
|
+
setRefreshIntervalEnabled(false);
|
|
3027
|
+
hasSelectedMoreThanOneCellRef.current = false;
|
|
3028
|
+
rangeStartRef.current = null;
|
|
3029
|
+
rangeEndRef.current = null;
|
|
3030
|
+
updateRangeSelectionCellClasses();
|
|
3031
|
+
}, [updateRangeSelectionCellClasses]);
|
|
3032
|
+
const onCellMouseOver = React.useCallback((e, mouseDown) => {
|
|
3033
|
+
if (!enableRangeSelection) {
|
|
3034
|
+
return;
|
|
3035
|
+
}
|
|
3036
|
+
const button = e.event.buttons;
|
|
3037
|
+
if (button !== 1) {
|
|
3038
|
+
// TODO fix this?
|
|
3039
|
+
//rangeSortedNodesRef.current = null;
|
|
3040
|
+
return;
|
|
3041
|
+
}
|
|
3042
|
+
rangeEndRef.current = {
|
|
3043
|
+
rowId: e.node.data.id,
|
|
3044
|
+
colId: e.column.getColId(),
|
|
3045
|
+
timestamp: Date.now(),
|
|
3046
|
+
};
|
|
3047
|
+
if (mouseDown) {
|
|
3048
|
+
const sortedNodes = [];
|
|
3049
|
+
e.api.forEachNodeAfterFilterAndSort((node) => sortedNodes.push(node));
|
|
3050
|
+
rangeSortedNodesRef.current = sortedNodes;
|
|
3051
|
+
setRefreshIntervalEnabled(true);
|
|
3052
|
+
rangeStartRef.current = { ...rangeEndRef.current };
|
|
3053
|
+
}
|
|
3054
|
+
if (rangeStartRef.current &&
|
|
3055
|
+
rangeEndRef.current &&
|
|
3056
|
+
(rangeStartRef.current.rowId !== rangeEndRef.current.rowId ||
|
|
3057
|
+
rangeStartRef.current.colId !== rangeEndRef.current.colId)) {
|
|
3058
|
+
hasSelectedMoreThanOneCellRef.current = true;
|
|
3059
|
+
window.getSelection()?.removeAllRanges();
|
|
3060
|
+
}
|
|
3061
|
+
updateRangeSelectionCellClasses();
|
|
3062
|
+
}, [enableRangeSelection, updateRangeSelectionCellClasses]);
|
|
3063
|
+
const onCellMouseDown = React.useCallback((e) => {
|
|
3064
|
+
const button = e.event.buttons;
|
|
3065
|
+
if (button === 1) {
|
|
3066
|
+
clearRangeSelection();
|
|
3067
|
+
}
|
|
3068
|
+
onCellMouseOver(e, true);
|
|
3069
|
+
}, [onCellMouseOver]);
|
|
3070
|
+
return { clearRangeSelection, ranges, onCellMouseDown, onCellMouseOver };
|
|
3071
|
+
};
|
|
2629
3072
|
|
|
2630
3073
|
const GridLoadingOverlayComponentFr = (props, externalRef) => (jsxRuntime.jsx("div", { ref: externalRef, style: {
|
|
2631
3074
|
left: 0,
|
|
@@ -2808,8 +3251,26 @@ agGridCommunity.ModuleRegistry.registerModules([agGridCommunity.AllCommunityModu
|
|
|
2808
3251
|
/**
|
|
2809
3252
|
* Wrapper for AgGrid to add commonly used functionality.
|
|
2810
3253
|
*/
|
|
2811
|
-
const Grid = ({
|
|
2812
|
-
|
|
3254
|
+
const Grid = ({ theme = 'ag-theme-step-default', 'data-testid': dataTestId,
|
|
3255
|
+
// ─── Grid State ───────────────────────────────
|
|
3256
|
+
suppressReadOnlyStyle = false,
|
|
3257
|
+
// ─── Data & Columns ───────────────────────────
|
|
3258
|
+
defaultPostSort = true, rowData, rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40, rowSelection = 'multiple', sizeColumns = 'auto',
|
|
3259
|
+
// ─── Selection ────────────────────────────────
|
|
3260
|
+
autoSelectFirstRow, enableRangeSelection = false, externalSelectedIds, externalSelectedItems, selectColumnPinned = 'left', selectable, setExternalSelectedIds, setExternalSelectedItems,
|
|
3261
|
+
// ─── Editing ──────────────────────────────────
|
|
3262
|
+
singleClickEdit = false,
|
|
3263
|
+
// ─── Context Menu ─────────────────────────────
|
|
3264
|
+
contextMenuSelectRow = false, contextMenu,
|
|
3265
|
+
// ─── Callbacks / Events ───────────────────────
|
|
3266
|
+
onCellFocused: paramsOnCellFocused, onColumnMoved,
|
|
3267
|
+
// ─── Row Behavior ─────────────────────────────
|
|
3268
|
+
suppressColumnVirtualization = true,
|
|
3269
|
+
// ─── Miscellaneous ────────────────────────────
|
|
3270
|
+
maxInitialWidth,
|
|
3271
|
+
// ─── Spread Remaining Params ──────────────────
|
|
3272
|
+
...params }) => {
|
|
3273
|
+
const { setApis, setExternallySelectedItemsAreInSync, setOnBulkEditingComplete, gridReady, gridRenderState, externallySelectedItemsAreInSync, showNoRowsOverlay, autoSizeColumns, sizeColumnsToFit, doesExternalFilterPass, ensureRowVisible, ensureSelectedRowIsVisible, focusByRowById, getColDef, getFirstRowId, isExternalFilterPresent, prePopupOps, selectRowsById, startCellEditing: propStartCellEditing, } = useGridContext();
|
|
2813
3274
|
// CellEditingStop event happens too much for one edit
|
|
2814
3275
|
const startedEditRef = React.useRef(false);
|
|
2815
3276
|
const startCellEditing = React.useCallback((props) => {
|
|
@@ -2948,7 +3409,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
2948
3409
|
return;
|
|
2949
3410
|
}
|
|
2950
3411
|
hasSelectedFirstItem.current = true;
|
|
2951
|
-
if (isNotEmpty(rowData) && lodashEs.isEmpty(externalSelectedItems)) {
|
|
3412
|
+
if (isNotEmpty(rowData) && lodashEs.isEmpty(externalSelectedItems) && lodashEs.isEmpty(externalSelectedIds)) {
|
|
2952
3413
|
const firstRowId = getFirstRowId();
|
|
2953
3414
|
if (autoSelectFirstRow && selectable) {
|
|
2954
3415
|
selectRowsById([firstRowId]);
|
|
@@ -2967,6 +3428,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
2967
3428
|
selectRowsById,
|
|
2968
3429
|
getFirstRowId,
|
|
2969
3430
|
selectable,
|
|
3431
|
+
externalSelectedIds,
|
|
2970
3432
|
]);
|
|
2971
3433
|
/**
|
|
2972
3434
|
* Ensure external selected items list is in sync with panel.
|
|
@@ -3130,15 +3592,6 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3130
3592
|
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3131
3593
|
}
|
|
3132
3594
|
}, [startCellEditing]);
|
|
3133
|
-
/**
|
|
3134
|
-
* Handle single click edits
|
|
3135
|
-
*/
|
|
3136
|
-
const onCellClicked = React.useCallback((event) => {
|
|
3137
|
-
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3138
|
-
if ((editable && event.colDef.singleClickEdit) ?? singleClickEdit) {
|
|
3139
|
-
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3140
|
-
}
|
|
3141
|
-
}, [singleClickEdit, startCellEditing]);
|
|
3142
3595
|
const onCellEditingStopped = React.useCallback((event) => {
|
|
3143
3596
|
if (!startedEditRef.current) {
|
|
3144
3597
|
return;
|
|
@@ -3187,6 +3640,78 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3187
3640
|
prePopupOps();
|
|
3188
3641
|
}
|
|
3189
3642
|
}, [prePopupOps, startCellEditing]);
|
|
3643
|
+
const { cellContextMenu, contextMenuComponent } = useGridContextMenu({
|
|
3644
|
+
contextMenu,
|
|
3645
|
+
contextMenuSelectRow,
|
|
3646
|
+
});
|
|
3647
|
+
const hasSelectedMoreThanOneCellRef = React.useRef(false);
|
|
3648
|
+
const rangeStartRef = React.useRef(null);
|
|
3649
|
+
const rangeEndRef = React.useRef(null);
|
|
3650
|
+
const rangeSortedNodesRef = React.useRef(null);
|
|
3651
|
+
const { clearRangeSelection, ranges, onCellMouseDown, onCellMouseOver } = useGridRangeSelection({
|
|
3652
|
+
enableRangeSelection,
|
|
3653
|
+
gridDivRef,
|
|
3654
|
+
rangeStartRef,
|
|
3655
|
+
rangeEndRef,
|
|
3656
|
+
hasSelectedMoreThanOneCellRef,
|
|
3657
|
+
rangeSortedNodesRef,
|
|
3658
|
+
});
|
|
3659
|
+
const { onCopyEvent, rangeSelectInterceptContextMenu, rangeSelectContextMenuComponent } = useGridCopy({
|
|
3660
|
+
ranges,
|
|
3661
|
+
rangeStartRef,
|
|
3662
|
+
rangeEndRef,
|
|
3663
|
+
hasSelectedMoreThanOneCellRef,
|
|
3664
|
+
cellContextMenu,
|
|
3665
|
+
});
|
|
3666
|
+
const onSortChanged = React.useCallback(() => {
|
|
3667
|
+
clearRangeSelection();
|
|
3668
|
+
ensureSelectedRowIsVisible();
|
|
3669
|
+
}, [clearRangeSelection, ensureSelectedRowIsVisible]);
|
|
3670
|
+
/**
|
|
3671
|
+
* Handle single click edits
|
|
3672
|
+
*/
|
|
3673
|
+
const onCellClicked = React.useCallback((event) => {
|
|
3674
|
+
if (rangeStartRef.current && rangeEndRef.current) {
|
|
3675
|
+
// This is to detect difference between a single click and a click drag return to cell.
|
|
3676
|
+
if (rangeEndRef.current.timestamp - rangeStartRef.current.timestamp < 100) {
|
|
3677
|
+
clearRangeSelection();
|
|
3678
|
+
}
|
|
3679
|
+
return;
|
|
3680
|
+
}
|
|
3681
|
+
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3682
|
+
if ((editable && event.colDef.singleClickEdit) ?? singleClickEdit) {
|
|
3683
|
+
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3684
|
+
}
|
|
3685
|
+
}, [clearRangeSelection, singleClickEdit, startCellEditing]);
|
|
3686
|
+
/**
|
|
3687
|
+
* Set of column I'd's that are prevented from auto-sizing as they are user set
|
|
3688
|
+
*/
|
|
3689
|
+
const userSizedColIds = React.useRef(new Map());
|
|
3690
|
+
/**
|
|
3691
|
+
* Lock/unlock column width on user edit/reset.
|
|
3692
|
+
*/
|
|
3693
|
+
const onColumnResized = React.useCallback((e) => {
|
|
3694
|
+
const colId = e.column?.getColId();
|
|
3695
|
+
if (colId == null) {
|
|
3696
|
+
return;
|
|
3697
|
+
}
|
|
3698
|
+
const width = e.column?.getActualWidth();
|
|
3699
|
+
if (width == null) {
|
|
3700
|
+
return;
|
|
3701
|
+
}
|
|
3702
|
+
switch (e.source) {
|
|
3703
|
+
case 'uiColumnResized':
|
|
3704
|
+
userSizedColIds.current.set(colId, width);
|
|
3705
|
+
break;
|
|
3706
|
+
case 'autosizeColumns':
|
|
3707
|
+
userSizedColIds.current.delete(colId);
|
|
3708
|
+
break;
|
|
3709
|
+
}
|
|
3710
|
+
}, []);
|
|
3711
|
+
const columnMoved = React.useCallback((e) => {
|
|
3712
|
+
clearRangeSelection();
|
|
3713
|
+
onColumnMoved?.(e);
|
|
3714
|
+
}, [clearRangeSelection, onColumnMoved]);
|
|
3190
3715
|
/**
|
|
3191
3716
|
* Once the grid has auto-sized we want to run fit to fit the grid in its container,
|
|
3192
3717
|
* but we don't want the non-flex auto-sized columns to "fit" size, so suppressSizeToFit is set to true.
|
|
@@ -3294,37 +3819,6 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3294
3819
|
}
|
|
3295
3820
|
prevLoading.current = newLoading;
|
|
3296
3821
|
}, [params.loading, rowData, showNoRowsOverlay]);
|
|
3297
|
-
/**
|
|
3298
|
-
* Set of column I'd's that are prevented from auto-sizing as they are user set
|
|
3299
|
-
*/
|
|
3300
|
-
const userSizedColIds = React.useRef(new Map());
|
|
3301
|
-
/**
|
|
3302
|
-
* Lock/unlock column width on user edit/reset.
|
|
3303
|
-
*/
|
|
3304
|
-
const onColumnResized = React.useCallback((e) => {
|
|
3305
|
-
const colId = e.column?.getColId();
|
|
3306
|
-
if (colId == null) {
|
|
3307
|
-
return;
|
|
3308
|
-
}
|
|
3309
|
-
const width = e.column?.getActualWidth();
|
|
3310
|
-
if (width == null) {
|
|
3311
|
-
return;
|
|
3312
|
-
}
|
|
3313
|
-
switch (e.source) {
|
|
3314
|
-
case 'uiColumnResized':
|
|
3315
|
-
userSizedColIds.current.set(colId, width);
|
|
3316
|
-
/*const colDef = e.column?.getColDef();
|
|
3317
|
-
if (!colDef?.flex) {
|
|
3318
|
-
onGridResize(e);
|
|
3319
|
-
}*/
|
|
3320
|
-
break;
|
|
3321
|
-
case 'autosizeColumns':
|
|
3322
|
-
userSizedColIds.current.delete(colId);
|
|
3323
|
-
//onGridResize(e);
|
|
3324
|
-
break;
|
|
3325
|
-
}
|
|
3326
|
-
}, []);
|
|
3327
|
-
const gridContextMenu = useGridContextMenu({ contextMenu: params.contextMenu, contextMenuSelectRow });
|
|
3328
3822
|
const startDragYRef = React.useRef(null);
|
|
3329
3823
|
const clearHighlightRowClasses = React.useCallback(() => {
|
|
3330
3824
|
document.querySelectorAll(`.ag-row-highlight-above`)?.forEach((el) => {
|
|
@@ -3452,15 +3946,24 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3452
3946
|
}
|
|
3453
3947
|
return false;
|
|
3454
3948
|
},
|
|
3455
|
-
|
|
3949
|
+
// enableClickSelection = true means ag-grid auto selects row if you click outside the checkbox
|
|
3950
|
+
// if it's false we have to do it.
|
|
3951
|
+
onCellClicked: params.enableClickSelection ? undefined : clickInputWhenContainingCellClicked,
|
|
3456
3952
|
};
|
|
3457
|
-
}, [
|
|
3953
|
+
}, [
|
|
3954
|
+
params.hideSelectColumn,
|
|
3955
|
+
params.onRowDragEnd,
|
|
3956
|
+
rowSelection,
|
|
3957
|
+
selectColumnPinned,
|
|
3958
|
+
selectable,
|
|
3959
|
+
params.enableClickSelection,
|
|
3960
|
+
]);
|
|
3458
3961
|
const onGridSizeChanged = React.useCallback((event) => {
|
|
3459
3962
|
if (sizeColumns === 'fit' || (['auto', 'auto-skip-headers'].includes(sizeColumns) && hasSetContentSize.current)) {
|
|
3460
3963
|
event.api.sizeColumnsToFit();
|
|
3461
3964
|
}
|
|
3462
3965
|
}, [sizeColumns]);
|
|
3463
|
-
return (jsxRuntime.jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [
|
|
3966
|
+
return (jsxRuntime.jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [contextMenuComponent, rangeSelectContextMenuComponent, jsxRuntime.jsx("div", { style: { flex: 1 }, ref: gridDivRef, onCopy: onCopyEvent, children: jsxRuntime.jsx(agGridReact.AgGridReact, { theme: 'legacy', domLayout: params.domLayout, defaultColDef: defaultColDef, columnDefs: columnDefsAdjusted, getRowId: getRowId, rowData: rowData, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, animateRows: params.animateRows ?? false, doesExternalFilterPass: doesExternalFilterPass, isExternalFilterPresent: isExternalFilterPresent, maintainColumnOrder: true, noRowsOverlayComponent: noRowsOverlayComponent, onCellClicked: onCellClicked, onCellContextMenu: rangeSelectInterceptContextMenu, onCellDoubleClicked: onCellDoubleClick, onCellEditingStopped: onCellEditingStopped, onCellFocused: onCellFocused, onCellKeyDown: onCellKeyPress, onCellMouseDown: onCellMouseDown, onCellMouseOver: onCellMouseOver, onColumnMoved: columnMoved, onColumnResized: onColumnResized, onColumnVisible: () => void setInitialContentSize(), onGridReady: onGridReady, onGridSizeChanged: onGridSizeChanged, onModelUpdated: onModelUpdated, onRowClicked: params.onRowClicked, onRowDataUpdated: onRowDataUpdated, onRowDoubleClicked: params.onRowDoubleClicked, onRowDragCancel: clearHighlightRowClasses, onRowDragEnd: onRowDragEnd, onRowDragMove: onRowDragMove, onSelectionChanged: synchroniseExternalStateToGridSelection, onSortChanged: onSortChanged, pinnedBottomRowData: params.pinnedBottomRowData, pinnedTopRowData: params.pinnedTopRowData, postSortRows: params.onRowDragEnd || !defaultPostSort ? undefined : postSortRows, preventDefaultOnContextMenu: true, quickFilterParser: quickFilterParser, rowClassRules: params.rowClassRules, rowDragText: params.rowDragText, rowHeight: rowHeight, rowSelection: selectable
|
|
3464
3967
|
? {
|
|
3465
3968
|
enableSelectionWithoutKeys: params.enableSelectionWithoutKeys ?? false,
|
|
3466
3969
|
enableClickSelection: params.enableClickSelection ?? false,
|
|
@@ -3470,7 +3973,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3470
3973
|
headerCheckbox: false,
|
|
3471
3974
|
}),
|
|
3472
3975
|
}
|
|
3473
|
-
: undefined, selectionColumnDef: selectionColumnDef,
|
|
3976
|
+
: undefined, selectionColumnDef: selectionColumnDef, suppressCellFocus: params.suppressCellFocus, suppressClickEdit: true, suppressColumnVirtualisation: suppressColumnVirtualization, suppressStartEditOnTab: true }) })] }));
|
|
3474
3977
|
};
|
|
3475
3978
|
const quickFilterParser = (filterStr) => {
|
|
3476
3979
|
// filter is exact matches exactly groups separated by commas
|
|
@@ -3711,33 +4214,6 @@ const GridFilterButtons = ({ className, luiButtonProps, options, }) => {
|
|
|
3711
4214
|
return (jsxRuntime.jsx("div", { className: clsx(className, 'flex-col-center'), children: jsxRuntime.jsx(lui.LuiButtonGroup, { children: options.map((option, index) => (jsxRuntime.jsx(lui.LuiButton, { ...luiButtonProps, className: clsx(`lui-button lui-button-secondary`, selectedOption?.label === option.label && `lui-button-active`, luiButtonProps?.className), onClick: () => setSelectedOption(option), children: option.label }, `${index}`))) }) }));
|
|
3712
4215
|
};
|
|
3713
4216
|
|
|
3714
|
-
function styleInject(css, ref) {
|
|
3715
|
-
if ( ref === void 0 ) ref = {};
|
|
3716
|
-
var insertAt = ref.insertAt;
|
|
3717
|
-
|
|
3718
|
-
if (!css || typeof document === 'undefined') { return; }
|
|
3719
|
-
|
|
3720
|
-
var head = document.head || document.getElementsByTagName('head')[0];
|
|
3721
|
-
var style = document.createElement('style');
|
|
3722
|
-
style.type = 'text/css';
|
|
3723
|
-
|
|
3724
|
-
if (insertAt === 'top') {
|
|
3725
|
-
if (head.firstChild) {
|
|
3726
|
-
head.insertBefore(style, head.firstChild);
|
|
3727
|
-
} else {
|
|
3728
|
-
head.appendChild(style);
|
|
3729
|
-
}
|
|
3730
|
-
} else {
|
|
3731
|
-
head.appendChild(style);
|
|
3732
|
-
}
|
|
3733
|
-
|
|
3734
|
-
if (style.styleSheet) {
|
|
3735
|
-
style.styleSheet.cssText = css;
|
|
3736
|
-
} else {
|
|
3737
|
-
style.appendChild(document.createTextNode(css));
|
|
3738
|
-
}
|
|
3739
|
-
}
|
|
3740
|
-
|
|
3741
4217
|
var css_248z$3 = ".GridFilterColsMultiSelect{background:#fff;font-family:Open Sans,system-ui,sans-serif;font-style:normal;font-weight:600;padding:8px}.GridFilterColsMultiSelect .LuiSelect-label-text{color:#6b6966;display:inline-block}.GridFilterColsMultiSelect .LuiCheckboxInput-item,.GridFilterColsMultiSelect .LuiCheckboxInput-selectAll{color:#2a292c;font-size:16px;font-weight:600;letter-spacing:0;line-height:20px;line-height:24px;margin-bottom:0}";
|
|
3742
4218
|
styleInject(css_248z$3);
|
|
3743
4219
|
|
|
@@ -4545,14 +5021,14 @@ const TextInputFormatted = (props) => {
|
|
|
4545
5021
|
|
|
4546
5022
|
const bearingValueFormatter = (value) => {
|
|
4547
5023
|
const safeValue = typeof value === 'string' ? parseFloat(value) : value;
|
|
4548
|
-
if (safeValue == null) {
|
|
5024
|
+
if (safeValue == null || Number.isNaN(safeValue)) {
|
|
4549
5025
|
return '–';
|
|
4550
5026
|
}
|
|
4551
5027
|
return convertDDToDMS(safeValue, false);
|
|
4552
5028
|
};
|
|
4553
5029
|
const bearingCorrectionValueFormatter = (value) => {
|
|
4554
5030
|
const safeValue = value;
|
|
4555
|
-
if (safeValue == null) {
|
|
5031
|
+
if (safeValue == null || Number.isNaN(safeValue)) {
|
|
4556
5032
|
return '–';
|
|
4557
5033
|
}
|
|
4558
5034
|
if (typeof safeValue === 'string') {
|
|
@@ -5348,6 +5824,7 @@ const GridPopoutEditMultiSelectGrid = (colDef, props) => GridCell(colDef, {
|
|
|
5348
5824
|
},
|
|
5349
5825
|
});
|
|
5350
5826
|
|
|
5827
|
+
const GridCellBearingValueFormatter = (params) => bearingValueFormatter(params.value) ?? '';
|
|
5351
5828
|
const GridPopoverEditBearingLike = (colDef, props) => GridCell({
|
|
5352
5829
|
valueFormatter: (params) => props.editorParams?.formatValue(params.value) ?? '',
|
|
5353
5830
|
...colDef,
|
|
@@ -5500,6 +5977,7 @@ const GridContextProvider = (props) => {
|
|
|
5500
5977
|
}
|
|
5501
5978
|
return gridApi && !gridApi.isDestroyed() ? hasApiFn(gridApi) : noApiFn();
|
|
5502
5979
|
}, [gridApi]);
|
|
5980
|
+
const getCellValue = React.useCallback((...props) => gridApi?.getCellValue(...props), [gridApi]);
|
|
5503
5981
|
/**
|
|
5504
5982
|
* Scroll row into view by Id.
|
|
5505
5983
|
*
|
|
@@ -5659,7 +6137,7 @@ const GridContextProvider = (props) => {
|
|
|
5659
6137
|
// It may be that the first cell is the selection cell, this doesn't exist as a colDef
|
|
5660
6138
|
// so instead, I just try and select it. If it doesn't exist selection will stay on the
|
|
5661
6139
|
// previously focused cell
|
|
5662
|
-
gridApi.setFocusedCell(rowIndex,
|
|
6140
|
+
gridApi.setFocusedCell(rowIndex, agGridSelectRowColId);
|
|
5663
6141
|
}
|
|
5664
6142
|
}, 100);
|
|
5665
6143
|
}
|
|
@@ -6098,6 +6576,7 @@ const GridContextProvider = (props) => {
|
|
|
6098
6576
|
getSelectedRowIds,
|
|
6099
6577
|
getFilteredSelectedRowIds,
|
|
6100
6578
|
getFirstRowId,
|
|
6579
|
+
getCellValue,
|
|
6101
6580
|
editingCells,
|
|
6102
6581
|
ensureRowVisible,
|
|
6103
6582
|
ensureSelectedRowIsVisible,
|
|
@@ -6288,6 +6767,7 @@ exports.GenericCellEditorComponentWrapper = GenericCellEditorComponentWrapper;
|
|
|
6288
6767
|
exports.Grid = Grid;
|
|
6289
6768
|
exports.GridButton = GridButton;
|
|
6290
6769
|
exports.GridCell = GridCell;
|
|
6770
|
+
exports.GridCellBearingValueFormatter = GridCellBearingValueFormatter;
|
|
6291
6771
|
exports.GridCellFiller = GridCellFiller;
|
|
6292
6772
|
exports.GridCellFillerColId = GridCellFillerColId;
|
|
6293
6773
|
exports.GridCellMultiEditor = GridCellMultiEditor;
|
|
@@ -6351,6 +6831,7 @@ exports.SubMenu = SubMenu;
|
|
|
6351
6831
|
exports.TextAreaInput = TextAreaInput;
|
|
6352
6832
|
exports.TextInputFormatted = TextInputFormatted;
|
|
6353
6833
|
exports.TextInputValidator = TextInputValidator;
|
|
6834
|
+
exports.agGridSelectRowColId = agGridSelectRowColId;
|
|
6354
6835
|
exports.bearingCorrectionRangeValidator = bearingCorrectionRangeValidator;
|
|
6355
6836
|
exports.bearingCorrectionValueFormatter = bearingCorrectionValueFormatter;
|
|
6356
6837
|
exports.bearingNumberParser = bearingNumberParser;
|