@linzjs/step-ag-grid 29.13.0 → 29.14.0
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.esm.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { LuiMiniSpinner,
|
|
2
|
+
import { LuiMiniSpinner, LuiIcon, useShowLUIMessage, LuiStatusSpinner, LuiButtonGroup, LuiButton, LuiCheckboxInput } from '@linzjs/lui';
|
|
3
3
|
import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community';
|
|
4
4
|
import { AgGridReact } from 'ag-grid-react';
|
|
5
|
-
import { negate, isEmpty, findIndex, defer, debounce as debounce$1, xorBy, last, difference, delay, omit, sortBy, partition,
|
|
5
|
+
import { negate, isEmpty, findIndex, defer, debounce as debounce$1, compact, xorBy, last, difference, delay, omit, sortBy, partition, pick, groupBy, fromPairs, toPairs, isEqual, pull, filter, sumBy, remove, flatten, castArray } from 'lodash-es';
|
|
6
6
|
import React, { useRef, useLayoutEffect, useEffect, createContext, useContext, useState, useMemo, memo, forwardRef, useCallback, useReducer, cloneElement, useImperativeHandle, Fragment as Fragment$1, useId } from 'react';
|
|
7
7
|
import { unstable_batchedUpdates, flushSync, createPortal } from 'react-dom';
|
|
8
8
|
import { createRoot } from 'react-dom/client';
|
|
@@ -417,6 +417,9 @@ function useInterval(callback, delay) {
|
|
|
417
417
|
savedCallback.current = callback;
|
|
418
418
|
}, [callback]);
|
|
419
419
|
useEffect(() => {
|
|
420
|
+
if (delay === null) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
420
423
|
const id = setInterval(() => {
|
|
421
424
|
savedCallback.current();
|
|
422
425
|
}, delay);
|
|
@@ -433,6 +436,7 @@ const NoContext = () => {
|
|
|
433
436
|
const GridContext = createContext({
|
|
434
437
|
gridReady: false,
|
|
435
438
|
gridRenderState: () => null,
|
|
439
|
+
getCellValue: NoContext,
|
|
436
440
|
getColDef: NoContext,
|
|
437
441
|
getColumns: NoContext,
|
|
438
442
|
getColumnIds: NoContext,
|
|
@@ -754,6 +758,36 @@ const GridHeaderSelect = ({ api }) => {
|
|
|
754
758
|
} }) }));
|
|
755
759
|
};
|
|
756
760
|
|
|
761
|
+
function styleInject(css, ref) {
|
|
762
|
+
if ( ref === void 0 ) ref = {};
|
|
763
|
+
var insertAt = ref.insertAt;
|
|
764
|
+
|
|
765
|
+
if (!css || typeof document === 'undefined') { return; }
|
|
766
|
+
|
|
767
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
768
|
+
var style = document.createElement('style');
|
|
769
|
+
style.type = 'text/css';
|
|
770
|
+
|
|
771
|
+
if (insertAt === 'top') {
|
|
772
|
+
if (head.firstChild) {
|
|
773
|
+
head.insertBefore(style, head.firstChild);
|
|
774
|
+
} else {
|
|
775
|
+
head.appendChild(style);
|
|
776
|
+
}
|
|
777
|
+
} else {
|
|
778
|
+
head.appendChild(style);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
if (style.styleSheet) {
|
|
782
|
+
style.styleSheet.cssText = css;
|
|
783
|
+
} else {
|
|
784
|
+
style.appendChild(document.createTextNode(css));
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
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}";
|
|
789
|
+
styleInject(css_248z$4);
|
|
790
|
+
|
|
757
791
|
const EventHandlersContext = createContext({
|
|
758
792
|
handleClick: () => { },
|
|
759
793
|
});
|
|
@@ -2588,7 +2622,7 @@ const SubMenuFr = ({ 'aria-label': ariaLabel, className, disabled, direction, la
|
|
|
2588
2622
|
};
|
|
2589
2623
|
const SubMenu = withHovering('SubMenu', SubMenuFr);
|
|
2590
2624
|
|
|
2591
|
-
const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, }) => {
|
|
2625
|
+
const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, context, }) => {
|
|
2592
2626
|
const { redrawRows, prePopupOps, resetFocusedCellAfterCellEditing, getSelectedRows } = useContext(GridContext);
|
|
2593
2627
|
const [isOpen, setOpen] = useState(false);
|
|
2594
2628
|
const [anchorPoint, setAnchorPoint] = useState({ x: 0, y: 0 });
|
|
@@ -2596,6 +2630,7 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
|
|
|
2596
2630
|
const clickedColDefRef = useRef(null);
|
|
2597
2631
|
const selectedRowsRef = useRef([]);
|
|
2598
2632
|
const clickedRowRef = useRef(null);
|
|
2633
|
+
const eventRef = useRef(undefined);
|
|
2599
2634
|
const openMenu = useCallback((e) => {
|
|
2600
2635
|
if (!e)
|
|
2601
2636
|
return;
|
|
@@ -2615,15 +2650,423 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
|
|
|
2615
2650
|
clickedColDefRef.current = event.colDef;
|
|
2616
2651
|
selectedRowsRef.current = getSelectedRows();
|
|
2617
2652
|
clickedRowRef.current = event.data;
|
|
2653
|
+
eventRef.current = event;
|
|
2618
2654
|
// This is actually a pointer event
|
|
2619
2655
|
openMenu(event.event);
|
|
2620
2656
|
}, [contextMenuSelectRow, getSelectedRows, openMenu]);
|
|
2621
2657
|
return {
|
|
2622
2658
|
openMenu,
|
|
2623
2659
|
cellContextMenu,
|
|
2624
|
-
|
|
2660
|
+
contextMenuComponent: ContextMenu ? (jsx(Fragment, { children: jsx(ControlledMenu, { className: 'GridContextMenu', anchorPoint: anchorPoint, state: isOpen ? 'open' : 'closed', direction: "right", onClose: closeMenu, children: isOpen && (jsx(ContextMenu, { selectedRows: selectedRowsRef.current, clickedRow: clickedRowRef.current, colDef: clickedColDefRef.current, event: eventRef.current, close: closeMenu, context: context })) }) })) : null,
|
|
2661
|
+
};
|
|
2662
|
+
};
|
|
2663
|
+
|
|
2664
|
+
const typedEntries = (obj) => Object.entries(obj);
|
|
2665
|
+
|
|
2666
|
+
const gridCopyOptions = {
|
|
2667
|
+
html: { text: 'Text\xa0/\xa0HTML', icon: 'ic_product_list' },
|
|
2668
|
+
csv: { text: 'CSV', icon: 'ic_csv_file' },
|
|
2669
|
+
json: { text: 'Json', icon: 'ic_file_attached_outline', developer: true },
|
|
2670
|
+
};
|
|
2671
|
+
const CopyOptionsStorageKey = 'stepAgGrid_defaultCopy';
|
|
2672
|
+
const useGridCopySettings = () => {
|
|
2673
|
+
const [copyType, _setCopyType] = useState(() => {
|
|
2674
|
+
const defaultCopy = window.localStorage.getItem(CopyOptionsStorageKey) ?? '';
|
|
2675
|
+
return Object.keys(gridCopyOptions).includes(defaultCopy) ? defaultCopy : 'html';
|
|
2676
|
+
});
|
|
2677
|
+
const setCopyType = useCallback((key) => {
|
|
2678
|
+
window.localStorage.setItem(CopyOptionsStorageKey, key);
|
|
2679
|
+
_setCopyType(key);
|
|
2680
|
+
}, []);
|
|
2681
|
+
return {
|
|
2682
|
+
copyType,
|
|
2683
|
+
setCopyType,
|
|
2684
|
+
};
|
|
2685
|
+
};
|
|
2686
|
+
|
|
2687
|
+
const GridRangeSelectContextMenu = ({ event, context, }) => {
|
|
2688
|
+
const developerContextMenu = !!event?.event?.ctrlKey && !!event?.event?.shiftKey;
|
|
2689
|
+
const onCopy = useMemo(() => context?.onCopy, [context?.onCopy]);
|
|
2690
|
+
const onClick = useCallback((type) => {
|
|
2691
|
+
onCopy?.(type);
|
|
2692
|
+
}, [onCopy]);
|
|
2693
|
+
return (jsxs(Fragment, { children: [jsx(MenuHeader, { children: "Copy as" }), typedEntries(gridCopyOptions).map(([key, { icon, text, developer }]) => {
|
|
2694
|
+
return ((!developer || developerContextMenu) && (jsx(MenuItem, { onClick: () => void onClick(key), children: jsxs("div", { className: 'copyMenuMenuItem', children: [jsx(LuiIcon, { name: icon, alt: text, size: 'md' }), jsx("div", { className: 'copyMenuMenuItem__text', children: text })] }) }, key)));
|
|
2695
|
+
}), jsx(MenuDivider, {}), jsx(MenuHeader, { children: "Set copy default" }), typedEntries(gridCopyOptions).map(([key, { text, developer }]) => {
|
|
2696
|
+
return (!developer && (jsx(MenuItem, { onClick: (e) => {
|
|
2697
|
+
context?.setCopyType(key);
|
|
2698
|
+
e.keepOpen = true;
|
|
2699
|
+
}, children: jsxs("div", { className: clsx('copyMenuMenuItem', context?.copyType === key ? '' : 'copyMenuMenuItem__buttonDefault--hidden'), children: [jsx(LuiIcon, { name: 'ic_tick', alt: 'CSV', size: 'sm' }), jsx("div", { className: 'copyMenuMenuItem__text', children: text })] }) }, 'default_' + key)));
|
|
2700
|
+
})] }));
|
|
2701
|
+
};
|
|
2702
|
+
|
|
2703
|
+
const agGridSelectRowColId = 'ag-Grid-SelectionColumn';
|
|
2704
|
+
|
|
2705
|
+
const useGridCopy = ({ ranges, rangeStartRef, rangeEndRef, hasSelectedMoreThanOneCellRef, cellContextMenu, }) => {
|
|
2706
|
+
const showToast = useShowLUIMessage();
|
|
2707
|
+
const { getSelectedRowIds } = useGridContext();
|
|
2708
|
+
const { getColDef, getCellValue } = useGridContext();
|
|
2709
|
+
const { copyType, setCopyType } = useGridCopySettings();
|
|
2710
|
+
const onCopy = useCallback((type = copyType) => {
|
|
2711
|
+
const rangeStart = rangeStartRef.current;
|
|
2712
|
+
const rangeEnd = rangeEndRef.current;
|
|
2713
|
+
if (rangeStart === null || rangeEnd === null || !hasSelectedMoreThanOneCellRef.current) {
|
|
2714
|
+
return;
|
|
2715
|
+
}
|
|
2716
|
+
if (rangeStart.rowId === rangeEnd.rowId && rangeStart.colId === rangeEnd.colId) {
|
|
2717
|
+
type = 'html';
|
|
2718
|
+
}
|
|
2719
|
+
const json = type === 'json';
|
|
2720
|
+
const { selectedColIds, selectedNodes } = ranges();
|
|
2721
|
+
const filteredSelectedColIds = selectedColIds.filter((colId) => colId === agGridSelectRowColId ||
|
|
2722
|
+
(colId !== 'gridCellFiller' && getColDef(colId)?.headerComponentParams?.exportable !== false));
|
|
2723
|
+
const selectedRowIds = getSelectedRowIds();
|
|
2724
|
+
const formatters = compact(filteredSelectedColIds.map((colKey) => {
|
|
2725
|
+
return (rowNode) => {
|
|
2726
|
+
if (colKey === agGridSelectRowColId) {
|
|
2727
|
+
return selectedRowIds.includes(rowNode.data.id);
|
|
2728
|
+
}
|
|
2729
|
+
else {
|
|
2730
|
+
const v = getCellValue({ rowNode, colKey });
|
|
2731
|
+
if (json && v !== undefined) {
|
|
2732
|
+
return v;
|
|
2733
|
+
}
|
|
2734
|
+
const f = getCellValue({ rowNode, colKey, useFormatter: true });
|
|
2735
|
+
// If it's a number, and it matches value return the original type
|
|
2736
|
+
return v == f ? v : f;
|
|
2737
|
+
}
|
|
2738
|
+
};
|
|
2739
|
+
}));
|
|
2740
|
+
// Get and apply headers
|
|
2741
|
+
const headers = filteredSelectedColIds.map((colId) => {
|
|
2742
|
+
if (colId === agGridSelectRowColId)
|
|
2743
|
+
return type === 'json' ? 'selected' : 'Selected';
|
|
2744
|
+
if (json) {
|
|
2745
|
+
return colId;
|
|
2746
|
+
}
|
|
2747
|
+
return getColDef(colId)?.headerName ?? '?';
|
|
2748
|
+
});
|
|
2749
|
+
const maxCellLength = {};
|
|
2750
|
+
headers.forEach((headerName, i) => {
|
|
2751
|
+
const colId = filteredSelectedColIds[i];
|
|
2752
|
+
maxCellLength[colId] = headerName.length;
|
|
2753
|
+
});
|
|
2754
|
+
const rows = [];
|
|
2755
|
+
if (type === 'csv' || type === 'html') {
|
|
2756
|
+
rows.push(headers);
|
|
2757
|
+
}
|
|
2758
|
+
selectedNodes.forEach((node) => {
|
|
2759
|
+
const row = [];
|
|
2760
|
+
rows.push(row);
|
|
2761
|
+
formatters.forEach((formatter, i) => {
|
|
2762
|
+
const colId = filteredSelectedColIds[i];
|
|
2763
|
+
let value = formatter(node);
|
|
2764
|
+
if (typeof value === 'string') {
|
|
2765
|
+
value = value.replaceAll('\xa0', ' ');
|
|
2766
|
+
}
|
|
2767
|
+
if (!json) {
|
|
2768
|
+
if (value === '-' || value === '–' || value == null) {
|
|
2769
|
+
value = '';
|
|
2770
|
+
}
|
|
2771
|
+
value = String(value);
|
|
2772
|
+
if (value === '-' || value === '–') {
|
|
2773
|
+
value = '';
|
|
2774
|
+
}
|
|
2775
|
+
maxCellLength[colId] = Math.max(maxCellLength[colId], value.length);
|
|
2776
|
+
}
|
|
2777
|
+
switch (type) {
|
|
2778
|
+
case 'json':
|
|
2779
|
+
value =
|
|
2780
|
+
value === 'undefined' || (value !== null && typeof value === 'object') || typeof value === 'string'
|
|
2781
|
+
? JSON.stringify(value)
|
|
2782
|
+
: value;
|
|
2783
|
+
break;
|
|
2784
|
+
case 'markdown':
|
|
2785
|
+
value = encodeMarkdownValue(value);
|
|
2786
|
+
break;
|
|
2787
|
+
case 'csv':
|
|
2788
|
+
value = encodeCSVValue(value);
|
|
2789
|
+
break;
|
|
2790
|
+
}
|
|
2791
|
+
row.push(String(value));
|
|
2792
|
+
});
|
|
2793
|
+
});
|
|
2794
|
+
let result = '';
|
|
2795
|
+
let html = `<table style="
|
|
2796
|
+
font-family: 'Open Sans', system-ui, sans-serif;
|
|
2797
|
+
font-size: 10px;
|
|
2798
|
+
line-height: 10px;
|
|
2799
|
+
border: 1px solid #d1d9e0;
|
|
2800
|
+
border-collapse: collapse;
|
|
2801
|
+
">`;
|
|
2802
|
+
if (json) {
|
|
2803
|
+
result += '[\n';
|
|
2804
|
+
}
|
|
2805
|
+
rows.forEach((row, rowIndex) => {
|
|
2806
|
+
if (json) {
|
|
2807
|
+
result += ' { ';
|
|
2808
|
+
}
|
|
2809
|
+
if (rowIndex == 1) {
|
|
2810
|
+
html += '<tbody style="font-weight: 400;">';
|
|
2811
|
+
}
|
|
2812
|
+
if (rowIndex == 0) {
|
|
2813
|
+
html += '<thead style="font-weight: 600;">';
|
|
2814
|
+
}
|
|
2815
|
+
if (rowIndex === 0 || (rowIndex & 1) === 1) {
|
|
2816
|
+
html += '<tr>';
|
|
2817
|
+
}
|
|
2818
|
+
else {
|
|
2819
|
+
html += '<tr style="background-color: #f6f8fa;">';
|
|
2820
|
+
}
|
|
2821
|
+
if (rowIndex === 1 && type === 'html') {
|
|
2822
|
+
Object.values(maxCellLength).forEach((maxLength) => {
|
|
2823
|
+
result += '|' + '-'.repeat(maxLength + 2);
|
|
2824
|
+
});
|
|
2825
|
+
result += '|\n';
|
|
2826
|
+
}
|
|
2827
|
+
row.forEach((cell, i) => {
|
|
2828
|
+
switch (type) {
|
|
2829
|
+
case 'csv':
|
|
2830
|
+
if (i !== 0) {
|
|
2831
|
+
result += ', ';
|
|
2832
|
+
}
|
|
2833
|
+
result += cell;
|
|
2834
|
+
break;
|
|
2835
|
+
case 'html':
|
|
2836
|
+
if (i === 0) {
|
|
2837
|
+
result += '|';
|
|
2838
|
+
}
|
|
2839
|
+
const colId = filteredSelectedColIds[i];
|
|
2840
|
+
result += ' ' + cell.padEnd(maxCellLength[colId], ' ') + ' ';
|
|
2841
|
+
result += '|';
|
|
2842
|
+
html +=
|
|
2843
|
+
rowIndex === 0
|
|
2844
|
+
? '<th style="border: 1px solid #d1d9e0; padding:6px 13px; text-align: left;">'
|
|
2845
|
+
: '<td style="border: 1px solid #d1d9e0; padding:6px 13px;">';
|
|
2846
|
+
html += cell;
|
|
2847
|
+
html += rowIndex === 0 ? '</th>' : '</td>';
|
|
2848
|
+
break;
|
|
2849
|
+
case 'json':
|
|
2850
|
+
if (i !== 0) {
|
|
2851
|
+
result += ', ';
|
|
2852
|
+
}
|
|
2853
|
+
result += JSON.stringify(headers[i]) + ': ' + cell;
|
|
2854
|
+
break;
|
|
2855
|
+
}
|
|
2856
|
+
});
|
|
2857
|
+
html += '</tr>';
|
|
2858
|
+
if (rowIndex == 0) {
|
|
2859
|
+
html += '</thead>';
|
|
2860
|
+
}
|
|
2861
|
+
if (rowIndex == rows.length - 1) {
|
|
2862
|
+
html += '</tbody>';
|
|
2863
|
+
}
|
|
2864
|
+
if (json) {
|
|
2865
|
+
result += ' }';
|
|
2866
|
+
}
|
|
2867
|
+
result += '\n';
|
|
2868
|
+
});
|
|
2869
|
+
if (json) {
|
|
2870
|
+
result += ']\n';
|
|
2871
|
+
}
|
|
2872
|
+
html += '</table>';
|
|
2873
|
+
showToast({
|
|
2874
|
+
message: `${gridCopyOptions[type].text} copied`,
|
|
2875
|
+
messageType: 'toast',
|
|
2876
|
+
messageLevel: 'info',
|
|
2877
|
+
});
|
|
2878
|
+
if (type === 'html') {
|
|
2879
|
+
const clipboardItem = new ClipboardItem({
|
|
2880
|
+
'text/html': new Blob([html], { type: 'text/html' }),
|
|
2881
|
+
'text/plain': new Blob([result], { type: 'text/plain' }), // fallback
|
|
2882
|
+
});
|
|
2883
|
+
void navigator.clipboard.write([clipboardItem]).catch((err) => console.error('Failed to copy: ', err));
|
|
2884
|
+
}
|
|
2885
|
+
else {
|
|
2886
|
+
void navigator.clipboard.writeText(result).catch((err) => console.error('Failed to copy: ', err));
|
|
2887
|
+
}
|
|
2888
|
+
}, [getCellValue, ranges, copyType]);
|
|
2889
|
+
const onCopyEvent = useCallback((e) => {
|
|
2890
|
+
const rangeStart = rangeStartRef.current;
|
|
2891
|
+
const rangeEnd = rangeEndRef.current;
|
|
2892
|
+
if (rangeStart === null ||
|
|
2893
|
+
rangeEnd === null ||
|
|
2894
|
+
(rangeStart.colId === rangeEnd.colId &&
|
|
2895
|
+
rangeStart.rowId === rangeEnd.rowId &&
|
|
2896
|
+
!hasSelectedMoreThanOneCellRef.current)) {
|
|
2897
|
+
return;
|
|
2898
|
+
}
|
|
2899
|
+
e.preventDefault();
|
|
2900
|
+
onCopy();
|
|
2901
|
+
}, [onCopy]);
|
|
2902
|
+
const { cellContextMenu: rangeSelectContextMenu, contextMenuComponent: rangeSelectContextMenuComponent } = useGridContextMenu({
|
|
2903
|
+
contextMenu: (GridRangeSelectContextMenu),
|
|
2904
|
+
context: { onCopy, copyType, setCopyType },
|
|
2905
|
+
});
|
|
2906
|
+
const rangeSelectInterceptContextMenu = useCallback((event) => rangeStartRef.current == null ? cellContextMenu(event) : rangeSelectContextMenu(event), [cellContextMenu, rangeSelectContextMenu]);
|
|
2907
|
+
return {
|
|
2908
|
+
onCopyEvent,
|
|
2909
|
+
rangeSelectInterceptContextMenu,
|
|
2910
|
+
rangeSelectContextMenuComponent,
|
|
2625
2911
|
};
|
|
2626
2912
|
};
|
|
2913
|
+
const encodeMarkdownValue = (value) => {
|
|
2914
|
+
return value.replaceAll('|', '\\|');
|
|
2915
|
+
};
|
|
2916
|
+
const encodeCSVValue = (value) => {
|
|
2917
|
+
let str = String(value);
|
|
2918
|
+
// Check if it needs quoting
|
|
2919
|
+
if (/[",\n]/.test(str)) {
|
|
2920
|
+
// Escape double quotes by doubling them
|
|
2921
|
+
str = '"' + str.replace(/"/g, '""') + '"';
|
|
2922
|
+
}
|
|
2923
|
+
return str;
|
|
2924
|
+
};
|
|
2925
|
+
|
|
2926
|
+
const useGridRangeSelection = ({ enableRangeSelection, gridDivRef, rangeStartRef, rangeEndRef, hasSelectedMoreThanOneCellRef, rangeSortedNodesRef, }) => {
|
|
2927
|
+
const [refreshIntervalEnabled, setRefreshIntervalEnabled] = useState(false);
|
|
2928
|
+
const ranges = useCallback(() => {
|
|
2929
|
+
const gridElement = gridDivRef.current;
|
|
2930
|
+
const rangeStart = rangeStartRef.current;
|
|
2931
|
+
const rangeEnd = rangeEndRef.current;
|
|
2932
|
+
const rangeSortedNodes = rangeSortedNodesRef.current;
|
|
2933
|
+
if (!gridElement || !rangeStart || !rangeEnd || !rangeSortedNodes) {
|
|
2934
|
+
return {
|
|
2935
|
+
selectedColIds: [],
|
|
2936
|
+
selectedNodes: [],
|
|
2937
|
+
};
|
|
2938
|
+
}
|
|
2939
|
+
const elStyleLeftComparator = (el1, el2) => elStyleLeft(el1) - elStyleLeft(el2);
|
|
2940
|
+
const elStyleLeft = (el) => parseFloat(el.style.left) ?? 0;
|
|
2941
|
+
const getSortedColIds = () => {
|
|
2942
|
+
//
|
|
2943
|
+
const leftHeaders = [...gridElement.querySelectorAll('.ag-pinned-left-header .ag-header-cell')].sort(elStyleLeftComparator);
|
|
2944
|
+
const centerHeaders = [...gridElement.querySelectorAll('.ag-header-viewport .ag-header-cell')].sort(elStyleLeftComparator);
|
|
2945
|
+
const rightHeaders = [...gridElement.querySelectorAll('.ag-pinned-right-header .ag-header-cell')].sort(elStyleLeftComparator);
|
|
2946
|
+
return [...leftHeaders, ...centerHeaders, ...rightHeaders].map((el, i) => el.getAttribute('col-id') ?? String(i));
|
|
2947
|
+
};
|
|
2948
|
+
const sortedColIds = getSortedColIds();
|
|
2949
|
+
const startColIndex = sortedColIds.indexOf(rangeStart.colId);
|
|
2950
|
+
const endColIndex = sortedColIds.indexOf(rangeEnd.colId);
|
|
2951
|
+
const selectedColIds = sortedColIds.slice(Math.min(startColIndex, endColIndex), Math.max(startColIndex, endColIndex) + 1);
|
|
2952
|
+
const startRowIndex = rangeSortedNodes.findIndex((node) => node.data.id === rangeStart.rowId);
|
|
2953
|
+
const endRowIndex = rangeSortedNodes.findIndex((node) => node.data.id === rangeEnd.rowId);
|
|
2954
|
+
const selectedNodes = rangeSortedNodes.slice(Math.min(startRowIndex, endRowIndex), Math.max(startRowIndex, endRowIndex) + 1);
|
|
2955
|
+
return { selectedColIds, selectedNodes };
|
|
2956
|
+
}, []);
|
|
2957
|
+
const redrawSelectedRanges = useCallback(() => {
|
|
2958
|
+
const gridElement = gridDivRef.current;
|
|
2959
|
+
const { selectedColIds, selectedNodes } = ranges();
|
|
2960
|
+
selectedColIds.forEach((colId, colIndex) => {
|
|
2961
|
+
selectedNodes.forEach((node, rowIndex) => {
|
|
2962
|
+
const rowId = node.data.id;
|
|
2963
|
+
const cell = gridElement.querySelector(`.ag-row[row-id=${JSON.stringify(String(rowId))}] .ag-cell[col-id=${JSON.stringify(colId)}`);
|
|
2964
|
+
cell?.classList.add('rangeSelect');
|
|
2965
|
+
if (colIndex === 0) {
|
|
2966
|
+
cell?.classList.add('rangeSelectLeft');
|
|
2967
|
+
}
|
|
2968
|
+
if (colIndex === selectedColIds.length - 1) {
|
|
2969
|
+
cell?.classList.add('rangeSelectRight');
|
|
2970
|
+
}
|
|
2971
|
+
if (rowIndex === 0) {
|
|
2972
|
+
cell?.classList.add('rangeSelectTop');
|
|
2973
|
+
}
|
|
2974
|
+
if (rowIndex === selectedNodes.length - 1) {
|
|
2975
|
+
cell?.classList.add('rangeSelectBottom');
|
|
2976
|
+
}
|
|
2977
|
+
});
|
|
2978
|
+
});
|
|
2979
|
+
}, []);
|
|
2980
|
+
const updateRangeSelectionCellClasses = useCallback((justRefresh) => {
|
|
2981
|
+
//
|
|
2982
|
+
// Get all grid cols, sort by pinned, then style: left
|
|
2983
|
+
const gridElement = gridDivRef.current;
|
|
2984
|
+
if (!gridElement) {
|
|
2985
|
+
return;
|
|
2986
|
+
}
|
|
2987
|
+
// Clear all selections
|
|
2988
|
+
if (!justRefresh) {
|
|
2989
|
+
gridElement
|
|
2990
|
+
.querySelectorAll('.rangeSelect,.rangeSelectLeft,.rangeSelectTop,.rangeSelectRight,.rangeSelectBottom')
|
|
2991
|
+
.forEach((el) => {
|
|
2992
|
+
el.classList.remove('rangeSelect', 'rangeSelectLeft', 'rangeSelectTop', 'rangeSelectRight', 'rangeSelectBottom');
|
|
2993
|
+
});
|
|
2994
|
+
}
|
|
2995
|
+
// if range selection multiple add .Grid-container.rangeSelectingMultiple
|
|
2996
|
+
const rangeStart = rangeStartRef.current;
|
|
2997
|
+
const rangeEnd = rangeEndRef.current;
|
|
2998
|
+
if (rangeStart !== null &&
|
|
2999
|
+
rangeEnd !== null &&
|
|
3000
|
+
(hasSelectedMoreThanOneCellRef.current ||
|
|
3001
|
+
rangeStart.colId !== rangeEnd.colId ||
|
|
3002
|
+
rangeStart.rowId !== rangeEnd.rowId)) {
|
|
3003
|
+
gridElement.classList.add('rangeSelectingMultiple');
|
|
3004
|
+
gridElement.querySelectorAll('.ag-cell-focus').forEach((el) => {
|
|
3005
|
+
el.classList.remove('ag-cell-focus');
|
|
3006
|
+
});
|
|
3007
|
+
}
|
|
3008
|
+
else {
|
|
3009
|
+
gridElement.classList.remove('rangeSelectingMultiple');
|
|
3010
|
+
return;
|
|
3011
|
+
}
|
|
3012
|
+
const rangeSortedNodes = rangeSortedNodesRef.current;
|
|
3013
|
+
if (!rangeSortedNodes) {
|
|
3014
|
+
return;
|
|
3015
|
+
}
|
|
3016
|
+
redrawSelectedRanges();
|
|
3017
|
+
}, [ranges, redrawSelectedRanges]);
|
|
3018
|
+
// Handle updates after scroll / grid refresh
|
|
3019
|
+
useInterval(() => {
|
|
3020
|
+
updateRangeSelectionCellClasses(true);
|
|
3021
|
+
}, refreshIntervalEnabled ? 150 : null);
|
|
3022
|
+
const clearRangeSelection = useCallback(() => {
|
|
3023
|
+
hasSelectedMoreThanOneCellRef.current = false;
|
|
3024
|
+
setRefreshIntervalEnabled(false);
|
|
3025
|
+
hasSelectedMoreThanOneCellRef.current = false;
|
|
3026
|
+
rangeStartRef.current = null;
|
|
3027
|
+
rangeEndRef.current = null;
|
|
3028
|
+
updateRangeSelectionCellClasses();
|
|
3029
|
+
}, [updateRangeSelectionCellClasses]);
|
|
3030
|
+
const onCellMouseOver = useCallback((e, mouseDown) => {
|
|
3031
|
+
if (!enableRangeSelection) {
|
|
3032
|
+
return;
|
|
3033
|
+
}
|
|
3034
|
+
const button = e.event.buttons;
|
|
3035
|
+
if (button !== 1) {
|
|
3036
|
+
// TODO fix this?
|
|
3037
|
+
//rangeSortedNodesRef.current = null;
|
|
3038
|
+
return;
|
|
3039
|
+
}
|
|
3040
|
+
rangeEndRef.current = {
|
|
3041
|
+
rowId: e.node.data.id,
|
|
3042
|
+
colId: e.column.getColId(),
|
|
3043
|
+
timestamp: Date.now(),
|
|
3044
|
+
};
|
|
3045
|
+
if (mouseDown) {
|
|
3046
|
+
const sortedNodes = [];
|
|
3047
|
+
e.api.forEachNodeAfterFilterAndSort((node) => sortedNodes.push(node));
|
|
3048
|
+
rangeSortedNodesRef.current = sortedNodes;
|
|
3049
|
+
setRefreshIntervalEnabled(true);
|
|
3050
|
+
rangeStartRef.current = { ...rangeEndRef.current };
|
|
3051
|
+
}
|
|
3052
|
+
if (rangeStartRef.current &&
|
|
3053
|
+
rangeEndRef.current &&
|
|
3054
|
+
(rangeStartRef.current.rowId !== rangeEndRef.current.rowId ||
|
|
3055
|
+
rangeStartRef.current.colId !== rangeEndRef.current.colId)) {
|
|
3056
|
+
hasSelectedMoreThanOneCellRef.current = true;
|
|
3057
|
+
window.getSelection()?.removeAllRanges();
|
|
3058
|
+
}
|
|
3059
|
+
updateRangeSelectionCellClasses();
|
|
3060
|
+
}, [enableRangeSelection, updateRangeSelectionCellClasses]);
|
|
3061
|
+
const onCellMouseDown = useCallback((e) => {
|
|
3062
|
+
const button = e.event.buttons;
|
|
3063
|
+
if (button === 1) {
|
|
3064
|
+
clearRangeSelection();
|
|
3065
|
+
}
|
|
3066
|
+
onCellMouseOver(e, true);
|
|
3067
|
+
}, [onCellMouseOver]);
|
|
3068
|
+
return { clearRangeSelection, ranges, onCellMouseDown, onCellMouseOver };
|
|
3069
|
+
};
|
|
2627
3070
|
|
|
2628
3071
|
const GridLoadingOverlayComponentFr = (props, externalRef) => (jsx("div", { ref: externalRef, style: {
|
|
2629
3072
|
left: 0,
|
|
@@ -2806,8 +3249,26 @@ ModuleRegistry.registerModules([AllCommunityModule]);
|
|
|
2806
3249
|
/**
|
|
2807
3250
|
* Wrapper for AgGrid to add commonly used functionality.
|
|
2808
3251
|
*/
|
|
2809
|
-
const Grid = ({
|
|
2810
|
-
|
|
3252
|
+
const Grid = ({ theme = 'ag-theme-step-default', 'data-testid': dataTestId,
|
|
3253
|
+
// ─── Grid State ───────────────────────────────
|
|
3254
|
+
suppressReadOnlyStyle = false,
|
|
3255
|
+
// ─── Data & Columns ───────────────────────────
|
|
3256
|
+
defaultPostSort = true, rowData, rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40, rowSelection = 'multiple', sizeColumns = 'auto',
|
|
3257
|
+
// ─── Selection ────────────────────────────────
|
|
3258
|
+
autoSelectFirstRow, enableRangeSelection = true, externalSelectedIds, externalSelectedItems, selectColumnPinned = 'left', selectable, setExternalSelectedIds, setExternalSelectedItems,
|
|
3259
|
+
// ─── Editing ──────────────────────────────────
|
|
3260
|
+
singleClickEdit = false,
|
|
3261
|
+
// ─── Context Menu ─────────────────────────────
|
|
3262
|
+
contextMenuSelectRow = false, contextMenu,
|
|
3263
|
+
// ─── Callbacks / Events ───────────────────────
|
|
3264
|
+
onCellFocused: paramsOnCellFocused, onColumnMoved,
|
|
3265
|
+
// ─── Row Behavior ─────────────────────────────
|
|
3266
|
+
suppressColumnVirtualization = true,
|
|
3267
|
+
// ─── Miscellaneous ────────────────────────────
|
|
3268
|
+
maxInitialWidth,
|
|
3269
|
+
// ─── Spread Remaining Params ──────────────────
|
|
3270
|
+
...params }) => {
|
|
3271
|
+
const { setApis, setExternallySelectedItemsAreInSync, setOnBulkEditingComplete, gridReady, gridRenderState, externallySelectedItemsAreInSync, showNoRowsOverlay, autoSizeColumns, sizeColumnsToFit, doesExternalFilterPass, ensureRowVisible, ensureSelectedRowIsVisible, focusByRowById, getColDef, getFirstRowId, isExternalFilterPresent, prePopupOps, selectRowsById, startCellEditing: propStartCellEditing, } = useGridContext();
|
|
2811
3272
|
// CellEditingStop event happens too much for one edit
|
|
2812
3273
|
const startedEditRef = useRef(false);
|
|
2813
3274
|
const startCellEditing = useCallback((props) => {
|
|
@@ -2946,7 +3407,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
2946
3407
|
return;
|
|
2947
3408
|
}
|
|
2948
3409
|
hasSelectedFirstItem.current = true;
|
|
2949
|
-
if (isNotEmpty(rowData) && isEmpty(externalSelectedItems)) {
|
|
3410
|
+
if (isNotEmpty(rowData) && isEmpty(externalSelectedItems) && isEmpty(externalSelectedIds)) {
|
|
2950
3411
|
const firstRowId = getFirstRowId();
|
|
2951
3412
|
if (autoSelectFirstRow && selectable) {
|
|
2952
3413
|
selectRowsById([firstRowId]);
|
|
@@ -2965,6 +3426,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
2965
3426
|
selectRowsById,
|
|
2966
3427
|
getFirstRowId,
|
|
2967
3428
|
selectable,
|
|
3429
|
+
externalSelectedIds,
|
|
2968
3430
|
]);
|
|
2969
3431
|
/**
|
|
2970
3432
|
* Ensure external selected items list is in sync with panel.
|
|
@@ -3128,15 +3590,6 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3128
3590
|
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3129
3591
|
}
|
|
3130
3592
|
}, [startCellEditing]);
|
|
3131
|
-
/**
|
|
3132
|
-
* Handle single click edits
|
|
3133
|
-
*/
|
|
3134
|
-
const onCellClicked = useCallback((event) => {
|
|
3135
|
-
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3136
|
-
if ((editable && event.colDef.singleClickEdit) ?? singleClickEdit) {
|
|
3137
|
-
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3138
|
-
}
|
|
3139
|
-
}, [singleClickEdit, startCellEditing]);
|
|
3140
3593
|
const onCellEditingStopped = useCallback((event) => {
|
|
3141
3594
|
if (!startedEditRef.current) {
|
|
3142
3595
|
return;
|
|
@@ -3185,6 +3638,78 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3185
3638
|
prePopupOps();
|
|
3186
3639
|
}
|
|
3187
3640
|
}, [prePopupOps, startCellEditing]);
|
|
3641
|
+
const { cellContextMenu, contextMenuComponent } = useGridContextMenu({
|
|
3642
|
+
contextMenu,
|
|
3643
|
+
contextMenuSelectRow,
|
|
3644
|
+
});
|
|
3645
|
+
const hasSelectedMoreThanOneCellRef = useRef(false);
|
|
3646
|
+
const rangeStartRef = useRef(null);
|
|
3647
|
+
const rangeEndRef = useRef(null);
|
|
3648
|
+
const rangeSortedNodesRef = useRef(null);
|
|
3649
|
+
const { clearRangeSelection, ranges, onCellMouseDown, onCellMouseOver } = useGridRangeSelection({
|
|
3650
|
+
enableRangeSelection,
|
|
3651
|
+
gridDivRef,
|
|
3652
|
+
rangeStartRef,
|
|
3653
|
+
rangeEndRef,
|
|
3654
|
+
hasSelectedMoreThanOneCellRef,
|
|
3655
|
+
rangeSortedNodesRef,
|
|
3656
|
+
});
|
|
3657
|
+
const { onCopyEvent, rangeSelectInterceptContextMenu, rangeSelectContextMenuComponent } = useGridCopy({
|
|
3658
|
+
ranges,
|
|
3659
|
+
rangeStartRef,
|
|
3660
|
+
rangeEndRef,
|
|
3661
|
+
hasSelectedMoreThanOneCellRef,
|
|
3662
|
+
cellContextMenu,
|
|
3663
|
+
});
|
|
3664
|
+
const onSortChanged = useCallback(() => {
|
|
3665
|
+
clearRangeSelection();
|
|
3666
|
+
ensureSelectedRowIsVisible();
|
|
3667
|
+
}, [clearRangeSelection, ensureSelectedRowIsVisible]);
|
|
3668
|
+
/**
|
|
3669
|
+
* Handle single click edits
|
|
3670
|
+
*/
|
|
3671
|
+
const onCellClicked = useCallback((event) => {
|
|
3672
|
+
if (rangeStartRef.current && rangeEndRef.current) {
|
|
3673
|
+
// This is to detect difference between a single click and a click drag return to cell.
|
|
3674
|
+
if (rangeEndRef.current.timestamp - rangeStartRef.current.timestamp < 100) {
|
|
3675
|
+
clearRangeSelection();
|
|
3676
|
+
}
|
|
3677
|
+
return;
|
|
3678
|
+
}
|
|
3679
|
+
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3680
|
+
if ((editable && event.colDef.singleClickEdit) ?? singleClickEdit) {
|
|
3681
|
+
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3682
|
+
}
|
|
3683
|
+
}, [clearRangeSelection, singleClickEdit, startCellEditing]);
|
|
3684
|
+
/**
|
|
3685
|
+
* Set of column I'd's that are prevented from auto-sizing as they are user set
|
|
3686
|
+
*/
|
|
3687
|
+
const userSizedColIds = useRef(new Map());
|
|
3688
|
+
/**
|
|
3689
|
+
* Lock/unlock column width on user edit/reset.
|
|
3690
|
+
*/
|
|
3691
|
+
const onColumnResized = useCallback((e) => {
|
|
3692
|
+
const colId = e.column?.getColId();
|
|
3693
|
+
if (colId == null) {
|
|
3694
|
+
return;
|
|
3695
|
+
}
|
|
3696
|
+
const width = e.column?.getActualWidth();
|
|
3697
|
+
if (width == null) {
|
|
3698
|
+
return;
|
|
3699
|
+
}
|
|
3700
|
+
switch (e.source) {
|
|
3701
|
+
case 'uiColumnResized':
|
|
3702
|
+
userSizedColIds.current.set(colId, width);
|
|
3703
|
+
break;
|
|
3704
|
+
case 'autosizeColumns':
|
|
3705
|
+
userSizedColIds.current.delete(colId);
|
|
3706
|
+
break;
|
|
3707
|
+
}
|
|
3708
|
+
}, []);
|
|
3709
|
+
const columnMoved = useCallback((e) => {
|
|
3710
|
+
clearRangeSelection();
|
|
3711
|
+
onColumnMoved?.(e);
|
|
3712
|
+
}, [clearRangeSelection, onColumnMoved]);
|
|
3188
3713
|
/**
|
|
3189
3714
|
* Once the grid has auto-sized we want to run fit to fit the grid in its container,
|
|
3190
3715
|
* but we don't want the non-flex auto-sized columns to "fit" size, so suppressSizeToFit is set to true.
|
|
@@ -3292,37 +3817,6 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3292
3817
|
}
|
|
3293
3818
|
prevLoading.current = newLoading;
|
|
3294
3819
|
}, [params.loading, rowData, showNoRowsOverlay]);
|
|
3295
|
-
/**
|
|
3296
|
-
* Set of column I'd's that are prevented from auto-sizing as they are user set
|
|
3297
|
-
*/
|
|
3298
|
-
const userSizedColIds = useRef(new Map());
|
|
3299
|
-
/**
|
|
3300
|
-
* Lock/unlock column width on user edit/reset.
|
|
3301
|
-
*/
|
|
3302
|
-
const onColumnResized = useCallback((e) => {
|
|
3303
|
-
const colId = e.column?.getColId();
|
|
3304
|
-
if (colId == null) {
|
|
3305
|
-
return;
|
|
3306
|
-
}
|
|
3307
|
-
const width = e.column?.getActualWidth();
|
|
3308
|
-
if (width == null) {
|
|
3309
|
-
return;
|
|
3310
|
-
}
|
|
3311
|
-
switch (e.source) {
|
|
3312
|
-
case 'uiColumnResized':
|
|
3313
|
-
userSizedColIds.current.set(colId, width);
|
|
3314
|
-
/*const colDef = e.column?.getColDef();
|
|
3315
|
-
if (!colDef?.flex) {
|
|
3316
|
-
onGridResize(e);
|
|
3317
|
-
}*/
|
|
3318
|
-
break;
|
|
3319
|
-
case 'autosizeColumns':
|
|
3320
|
-
userSizedColIds.current.delete(colId);
|
|
3321
|
-
//onGridResize(e);
|
|
3322
|
-
break;
|
|
3323
|
-
}
|
|
3324
|
-
}, []);
|
|
3325
|
-
const gridContextMenu = useGridContextMenu({ contextMenu: params.contextMenu, contextMenuSelectRow });
|
|
3326
3820
|
const startDragYRef = useRef(null);
|
|
3327
3821
|
const clearHighlightRowClasses = useCallback(() => {
|
|
3328
3822
|
document.querySelectorAll(`.ag-row-highlight-above`)?.forEach((el) => {
|
|
@@ -3450,15 +3944,24 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3450
3944
|
}
|
|
3451
3945
|
return false;
|
|
3452
3946
|
},
|
|
3453
|
-
|
|
3947
|
+
// enableClickSelection = true means ag-grid auto selects row if you click outside the checkbox
|
|
3948
|
+
// if it's false we have to do it.
|
|
3949
|
+
onCellClicked: params.enableClickSelection ? undefined : clickInputWhenContainingCellClicked,
|
|
3454
3950
|
};
|
|
3455
|
-
}, [
|
|
3951
|
+
}, [
|
|
3952
|
+
params.hideSelectColumn,
|
|
3953
|
+
params.onRowDragEnd,
|
|
3954
|
+
rowSelection,
|
|
3955
|
+
selectColumnPinned,
|
|
3956
|
+
selectable,
|
|
3957
|
+
params.enableClickSelection,
|
|
3958
|
+
]);
|
|
3456
3959
|
const onGridSizeChanged = useCallback((event) => {
|
|
3457
3960
|
if (sizeColumns === 'fit' || (['auto', 'auto-skip-headers'].includes(sizeColumns) && hasSetContentSize.current)) {
|
|
3458
3961
|
event.api.sizeColumnsToFit();
|
|
3459
3962
|
}
|
|
3460
3963
|
}, [sizeColumns]);
|
|
3461
|
-
return (jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [
|
|
3964
|
+
return (jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [contextMenuComponent, rangeSelectContextMenuComponent, jsx("div", { style: { flex: 1 }, ref: gridDivRef, onCopy: onCopyEvent, children: jsx(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
|
|
3462
3965
|
? {
|
|
3463
3966
|
enableSelectionWithoutKeys: params.enableSelectionWithoutKeys ?? false,
|
|
3464
3967
|
enableClickSelection: params.enableClickSelection ?? false,
|
|
@@ -3468,7 +3971,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3468
3971
|
headerCheckbox: false,
|
|
3469
3972
|
}),
|
|
3470
3973
|
}
|
|
3471
|
-
: undefined, selectionColumnDef: selectionColumnDef,
|
|
3974
|
+
: undefined, selectionColumnDef: selectionColumnDef, suppressCellFocus: params.suppressCellFocus, suppressClickEdit: true, suppressColumnVirtualisation: suppressColumnVirtualization, suppressStartEditOnTab: true }) })] }));
|
|
3472
3975
|
};
|
|
3473
3976
|
const quickFilterParser = (filterStr) => {
|
|
3474
3977
|
// filter is exact matches exactly groups separated by commas
|
|
@@ -3709,33 +4212,6 @@ const GridFilterButtons = ({ className, luiButtonProps, options, }) => {
|
|
|
3709
4212
|
return (jsx("div", { className: clsx(className, 'flex-col-center'), children: jsx(LuiButtonGroup, { children: options.map((option, index) => (jsx(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}`))) }) }));
|
|
3710
4213
|
};
|
|
3711
4214
|
|
|
3712
|
-
function styleInject(css, ref) {
|
|
3713
|
-
if ( ref === void 0 ) ref = {};
|
|
3714
|
-
var insertAt = ref.insertAt;
|
|
3715
|
-
|
|
3716
|
-
if (!css || typeof document === 'undefined') { return; }
|
|
3717
|
-
|
|
3718
|
-
var head = document.head || document.getElementsByTagName('head')[0];
|
|
3719
|
-
var style = document.createElement('style');
|
|
3720
|
-
style.type = 'text/css';
|
|
3721
|
-
|
|
3722
|
-
if (insertAt === 'top') {
|
|
3723
|
-
if (head.firstChild) {
|
|
3724
|
-
head.insertBefore(style, head.firstChild);
|
|
3725
|
-
} else {
|
|
3726
|
-
head.appendChild(style);
|
|
3727
|
-
}
|
|
3728
|
-
} else {
|
|
3729
|
-
head.appendChild(style);
|
|
3730
|
-
}
|
|
3731
|
-
|
|
3732
|
-
if (style.styleSheet) {
|
|
3733
|
-
style.styleSheet.cssText = css;
|
|
3734
|
-
} else {
|
|
3735
|
-
style.appendChild(document.createTextNode(css));
|
|
3736
|
-
}
|
|
3737
|
-
}
|
|
3738
|
-
|
|
3739
4215
|
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}";
|
|
3740
4216
|
styleInject(css_248z$3);
|
|
3741
4217
|
|
|
@@ -4543,14 +5019,14 @@ const TextInputFormatted = (props) => {
|
|
|
4543
5019
|
|
|
4544
5020
|
const bearingValueFormatter = (value) => {
|
|
4545
5021
|
const safeValue = typeof value === 'string' ? parseFloat(value) : value;
|
|
4546
|
-
if (safeValue == null) {
|
|
5022
|
+
if (safeValue == null || Number.isNaN(safeValue)) {
|
|
4547
5023
|
return '–';
|
|
4548
5024
|
}
|
|
4549
5025
|
return convertDDToDMS(safeValue, false);
|
|
4550
5026
|
};
|
|
4551
5027
|
const bearingCorrectionValueFormatter = (value) => {
|
|
4552
5028
|
const safeValue = value;
|
|
4553
|
-
if (safeValue == null) {
|
|
5029
|
+
if (safeValue == null || Number.isNaN(safeValue)) {
|
|
4554
5030
|
return '–';
|
|
4555
5031
|
}
|
|
4556
5032
|
if (typeof safeValue === 'string') {
|
|
@@ -5346,6 +5822,7 @@ const GridPopoutEditMultiSelectGrid = (colDef, props) => GridCell(colDef, {
|
|
|
5346
5822
|
},
|
|
5347
5823
|
});
|
|
5348
5824
|
|
|
5825
|
+
const GridCellBearingValueFormatter = (params) => bearingValueFormatter(params.value) ?? '';
|
|
5349
5826
|
const GridPopoverEditBearingLike = (colDef, props) => GridCell({
|
|
5350
5827
|
valueFormatter: (params) => props.editorParams?.formatValue(params.value) ?? '',
|
|
5351
5828
|
...colDef,
|
|
@@ -5498,6 +5975,7 @@ const GridContextProvider = (props) => {
|
|
|
5498
5975
|
}
|
|
5499
5976
|
return gridApi && !gridApi.isDestroyed() ? hasApiFn(gridApi) : noApiFn();
|
|
5500
5977
|
}, [gridApi]);
|
|
5978
|
+
const getCellValue = useCallback((...props) => gridApi?.getCellValue(...props), [gridApi]);
|
|
5501
5979
|
/**
|
|
5502
5980
|
* Scroll row into view by Id.
|
|
5503
5981
|
*
|
|
@@ -5657,7 +6135,7 @@ const GridContextProvider = (props) => {
|
|
|
5657
6135
|
// It may be that the first cell is the selection cell, this doesn't exist as a colDef
|
|
5658
6136
|
// so instead, I just try and select it. If it doesn't exist selection will stay on the
|
|
5659
6137
|
// previously focused cell
|
|
5660
|
-
gridApi.setFocusedCell(rowIndex,
|
|
6138
|
+
gridApi.setFocusedCell(rowIndex, agGridSelectRowColId);
|
|
5661
6139
|
}
|
|
5662
6140
|
}, 100);
|
|
5663
6141
|
}
|
|
@@ -6096,6 +6574,7 @@ const GridContextProvider = (props) => {
|
|
|
6096
6574
|
getSelectedRowIds,
|
|
6097
6575
|
getFilteredSelectedRowIds,
|
|
6098
6576
|
getFirstRowId,
|
|
6577
|
+
getCellValue,
|
|
6099
6578
|
editingCells,
|
|
6100
6579
|
ensureRowVisible,
|
|
6101
6580
|
ensureSelectedRowIsVisible,
|
|
@@ -6275,5 +6754,5 @@ const useDeferredPromise = () => {
|
|
|
6275
6754
|
};
|
|
6276
6755
|
};
|
|
6277
6756
|
|
|
6278
|
-
export { ActionButton, CancelPromise, ComponentLoadingWrapper, ControlledMenu, Editor, FocusableItem, FormError, GenericCellEditorComponentWrapper, Grid, GridButton, GridCell, GridCellFiller, GridCellFillerColId, GridCellMultiEditor, GridCellMultiSelectClassRules, GridCellRenderer, GridContext, GridContextProvider, GridEditBoolean, GridFilterButtons, GridFilterColumnsMultiSelect, GridFilterColumnsToggle, GridFilterDownloadCsvButton, GridFilterHeaderIconButton, GridFilterQuick, GridFilters, GridFormDropDown, GridFormEditBearing, GridFormMessage, GridFormMultiSelect, GridFormMultiSelectGrid, GridFormPopoverMenu, GridFormSubComponentTextArea, GridFormSubComponentTextInput, GridFormTextArea, GridFormTextInput, GridIcon, GridLoadableCell, GridNoRowsOverlay, GridNoRowsOverlayFr, GridPopoutEditMultiSelect, GridPopoutEditMultiSelectGrid, GridPopoverContext, GridPopoverContextProvider, GridPopoverEditBearing, GridPopoverEditBearingCorrection, GridPopoverEditBearingCorrectionEditorParams, GridPopoverEditBearingEditorParams, GridPopoverEditDropDown, GridPopoverMenu, GridPopoverMessage, GridPopoverTextArea, GridPopoverTextInput, GridRenderPopoutMenuCell, GridSubComponentContext, GridUpdatingContext, GridUpdatingContextProvider, GridWrapper, Menu, MenuButton, MenuDivider, MenuGroup, MenuHeader, MenuHeaderItem, MenuHeaderString, MenuItem, MenuRadioGroup, MenuSeparator, MenuSeparatorString, PopoutMenuSeparator, SubMenu, TextAreaInput, TextInputFormatted, TextInputValidator, bearingCorrectionRangeValidator, bearingCorrectionValueFormatter, bearingNumberParser, bearingRangeValidator, bearingStringValidator, bearingValueFormatter, colStateFlexed, colStateId, colStateNotFlexed, compareNaturalInsensitive, convertDDToDMS, createCheckboxMultiFilterParams, defaultValueFormatter, downloadCsvUseValueFormattersProcessCellCallback, findParentWithClass, fnOrVar, generateFilterGetter, hasParentClass, isFloat, isGridCellFiller, isNotEmpty, primitiveToSelectOption, sanitiseFileName, stringByteLengthIsInvalid, suppressCellKeyboardEvents, textMatch, useDeferredPromise, useGridContext, useGridContextMenu, useGridFilter, useGridPopoverContext, useGridPopoverHook, useMenuState, usePostSortRowsHook, wait, waitForCondition };
|
|
6757
|
+
export { ActionButton, CancelPromise, ComponentLoadingWrapper, ControlledMenu, Editor, FocusableItem, FormError, GenericCellEditorComponentWrapper, Grid, GridButton, GridCell, GridCellBearingValueFormatter, GridCellFiller, GridCellFillerColId, GridCellMultiEditor, GridCellMultiSelectClassRules, GridCellRenderer, GridContext, GridContextProvider, GridEditBoolean, GridFilterButtons, GridFilterColumnsMultiSelect, GridFilterColumnsToggle, GridFilterDownloadCsvButton, GridFilterHeaderIconButton, GridFilterQuick, GridFilters, GridFormDropDown, GridFormEditBearing, GridFormMessage, GridFormMultiSelect, GridFormMultiSelectGrid, GridFormPopoverMenu, GridFormSubComponentTextArea, GridFormSubComponentTextInput, GridFormTextArea, GridFormTextInput, GridIcon, GridLoadableCell, GridNoRowsOverlay, GridNoRowsOverlayFr, GridPopoutEditMultiSelect, GridPopoutEditMultiSelectGrid, GridPopoverContext, GridPopoverContextProvider, GridPopoverEditBearing, GridPopoverEditBearingCorrection, GridPopoverEditBearingCorrectionEditorParams, GridPopoverEditBearingEditorParams, GridPopoverEditDropDown, GridPopoverMenu, GridPopoverMessage, GridPopoverTextArea, GridPopoverTextInput, GridRenderPopoutMenuCell, GridSubComponentContext, GridUpdatingContext, GridUpdatingContextProvider, GridWrapper, Menu, MenuButton, MenuDivider, MenuGroup, MenuHeader, MenuHeaderItem, MenuHeaderString, MenuItem, MenuRadioGroup, MenuSeparator, MenuSeparatorString, PopoutMenuSeparator, SubMenu, TextAreaInput, TextInputFormatted, TextInputValidator, agGridSelectRowColId, bearingCorrectionRangeValidator, bearingCorrectionValueFormatter, bearingNumberParser, bearingRangeValidator, bearingStringValidator, bearingValueFormatter, colStateFlexed, colStateId, colStateNotFlexed, compareNaturalInsensitive, convertDDToDMS, createCheckboxMultiFilterParams, defaultValueFormatter, downloadCsvUseValueFormattersProcessCellCallback, findParentWithClass, fnOrVar, generateFilterGetter, hasParentClass, isFloat, isGridCellFiller, isNotEmpty, primitiveToSelectOption, sanitiseFileName, stringByteLengthIsInvalid, suppressCellKeyboardEvents, textMatch, useDeferredPromise, useGridContext, useGridContextMenu, useGridFilter, useGridPopoverContext, useGridPopoverHook, useMenuState, usePostSortRowsHook, wait, waitForCondition };
|
|
6279
6758
|
//# sourceMappingURL=step-ag-grid.esm.js.map
|