@linzjs/step-ag-grid 29.12.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 +37 -67
- package/dist/src/components/GridCell.d.ts +2 -19
- package/dist/src/components/GridCellFiller.d.ts +1 -1
- package/dist/src/components/GridCellMultiEditor.d.ts +1 -2
- package/dist/src/components/GridPopoverHook.d.ts +1 -1
- package/dist/src/components/GridRangeSelectContextMenu.d.ts +10 -0
- package/dist/src/components/gridFilter/GridFilterButtons.d.ts +1 -1
- package/dist/src/components/gridFilter/useGridFilter.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormDropDown.d.ts +2 -2
- package/dist/src/components/gridForm/GridFormEditBearing.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormMessage.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormMultiSelectGrid.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormPopoverMenu.d.ts +3 -2
- package/dist/src/components/gridForm/GridFormSubComponentTextArea.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormSubComponentTextInput.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormTextArea.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormTextInput.d.ts +1 -1
- package/dist/src/components/gridHook/useGridContextMenu.d.ts +13 -8
- 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/GridButton.d.ts +1 -2
- package/dist/src/components/gridPopoverEdit/GridEditBoolean.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoutEditMultiSelect.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoutEditMultiSelectGrid.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverEditBearing.d.ts +4 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverEditDropDown.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverMenu.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverMessage.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverTextArea.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverTextInput.d.ts +2 -2
- package/dist/src/components/gridRender/GridRenderGenericCell.d.ts +1 -2
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/components/types.d.ts +27 -0
- package/dist/src/contexts/GridContext.d.ts +13 -12
- package/dist/src/contexts/GridPopoverContext.d.ts +1 -1
- 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/textValidator.d.ts +1 -1
- package/dist/src/utils/util.d.ts +1 -0
- package/dist/step-ag-grid.cjs +650 -242
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +651 -245
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +4 -2
- package/src/components/Grid.tsx +312 -221
- package/src/components/GridCell.tsx +1 -25
- package/src/components/GridCellFiller.tsx +1 -1
- package/src/components/GridCellMultiEditor.tsx +2 -2
- package/src/components/GridPopoverHook.tsx +1 -1
- package/src/components/GridRangeSelectContextMenu.tsx +73 -0
- package/src/components/gridFilter/GridFilterButtons.tsx +1 -1
- package/src/components/gridFilter/useGridFilter.ts +1 -1
- package/src/components/gridForm/GridFormDropDown.tsx +2 -4
- package/src/components/gridForm/GridFormEditBearing.tsx +1 -1
- package/src/components/gridForm/GridFormMessage.tsx +1 -1
- package/src/components/gridForm/GridFormMultiSelect.tsx +1 -1
- package/src/components/gridForm/GridFormMultiSelectGrid.tsx +1 -1
- package/src/components/gridForm/GridFormPopoverMenu.tsx +3 -2
- package/src/components/gridForm/GridFormSubComponentTextArea.tsx +1 -1
- package/src/components/gridForm/GridFormSubComponentTextInput.tsx +1 -1
- package/src/components/gridForm/GridFormTextArea.tsx +1 -1
- package/src/components/gridForm/GridFormTextInput.tsx +1 -1
- package/src/components/gridHook/useGridContextMenu.tsx +23 -10
- 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/GridButton.tsx +2 -2
- package/src/components/gridPopoverEdit/GridEditBoolean.tsx +2 -2
- package/src/components/gridPopoverEdit/GridPopoutEditMultiSelect.ts +2 -2
- package/src/components/gridPopoverEdit/GridPopoutEditMultiSelectGrid.ts +2 -2
- package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +5 -2
- package/src/components/gridPopoverEdit/GridPopoverEditDropDown.ts +2 -2
- package/src/components/gridPopoverEdit/GridPopoverMenu.tsx +2 -2
- package/src/components/gridPopoverEdit/GridPopoverMessage.ts +2 -2
- package/src/components/gridPopoverEdit/GridPopoverTextArea.ts +2 -2
- package/src/components/gridPopoverEdit/GridPopoverTextInput.ts +2 -2
- package/src/components/gridRender/GridRenderGenericCell.tsx +1 -2
- package/src/components/index.ts +1 -0
- package/src/components/types.ts +34 -0
- package/src/contexts/GridContext.tsx +57 -148
- package/src/contexts/GridContextProvider.tsx +16 -13
- package/src/contexts/GridPopoverContext.tsx +1 -1
- package/src/contexts/GridPopoverContextProvider.tsx +1 -1
- package/src/lui/timeoutHook.tsx +0 -19
- package/src/lui/tsUtils.ts +8 -0
- package/src/react-menu3/components/MenuButton.tsx +2 -2
- package/src/react-menu3/hooks/useItemState.ts +1 -1
- package/src/stories/grid/GridCopy.stories.tsx +175 -0
- package/src/stories/grid/GridPopoverEditBearing.stories.tsx +4 -4
- package/src/stories/grid/GridPopoverEditDropDown.stories.tsx +3 -3
- package/src/stories/grid/GridReadOnly.stories.tsx +4 -3
- 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/textValidator.test.ts +1 -1
- package/src/utils/textValidator.ts +1 -1
- 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);
|
|
@@ -428,147 +431,54 @@ function useInterval(callback, delay) {
|
|
|
428
431
|
}, [delay]);
|
|
429
432
|
}
|
|
430
433
|
|
|
434
|
+
const NoContext = () => {
|
|
435
|
+
console.error('Missing GridContextProvider');
|
|
436
|
+
return null;
|
|
437
|
+
};
|
|
431
438
|
const GridContext = React.createContext({
|
|
432
439
|
gridReady: false,
|
|
433
440
|
gridRenderState: () => null,
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
getColumns: () => {
|
|
439
|
-
console.error('no context provider for getColumns');
|
|
440
|
-
return [];
|
|
441
|
-
},
|
|
442
|
-
getColumnIds: () => {
|
|
443
|
-
console.error('no context provider for getColumnIds');
|
|
444
|
-
return [];
|
|
445
|
-
},
|
|
441
|
+
getCellValue: NoContext,
|
|
442
|
+
getColDef: NoContext,
|
|
443
|
+
getColumns: NoContext,
|
|
444
|
+
getColumnIds: NoContext,
|
|
446
445
|
invisibleColumnIds: undefined,
|
|
447
|
-
setInvisibleColumnIds:
|
|
448
|
-
|
|
449
|
-
},
|
|
450
|
-
prePopupOps: () => {
|
|
451
|
-
console.error('no context provider for prePopupOps');
|
|
452
|
-
},
|
|
446
|
+
setInvisibleColumnIds: NoContext,
|
|
447
|
+
prePopupOps: NoContext,
|
|
453
448
|
externallySelectedItemsAreInSync: false,
|
|
454
|
-
setApis:
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
selectRowsWithFlashDiff: async () => {
|
|
488
|
-
console.error('no context provider for selectRowsWithFlashDiff');
|
|
489
|
-
},
|
|
490
|
-
flashRows: () => {
|
|
491
|
-
console.error('no context provider for flashRows');
|
|
492
|
-
},
|
|
493
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
494
|
-
flashRowsDiff: async () => {
|
|
495
|
-
console.error('no context provider for flashRows');
|
|
496
|
-
},
|
|
497
|
-
// eslint-disable-next-line @typescript-eslint/require-await,@typescript-eslint/no-misused-promises
|
|
498
|
-
focusByRowById: async () => {
|
|
499
|
-
console.error('no context provider for focusByRowById');
|
|
500
|
-
},
|
|
501
|
-
ensureRowVisible: () => {
|
|
502
|
-
console.error('no context provider for ensureRowVisible');
|
|
503
|
-
return true;
|
|
504
|
-
},
|
|
505
|
-
ensureSelectedRowIsVisible: () => {
|
|
506
|
-
console.error('no context provider for ensureSelectedRowIsVisible');
|
|
507
|
-
},
|
|
508
|
-
getFirstRowId: () => {
|
|
509
|
-
console.error('no context provider for getFirstRowId');
|
|
510
|
-
return -1;
|
|
511
|
-
},
|
|
512
|
-
autoSizeColumns: async () => {
|
|
513
|
-
console.error('no context provider for autoSizeColumns');
|
|
514
|
-
return Promise.resolve(null);
|
|
515
|
-
},
|
|
516
|
-
sizeColumnsToFit: () => {
|
|
517
|
-
console.error('no context provider for autoSizeAllColumns');
|
|
518
|
-
return null;
|
|
519
|
-
},
|
|
520
|
-
editingCells: () => {
|
|
521
|
-
console.error('no context provider for editingCells');
|
|
522
|
-
return false;
|
|
523
|
-
},
|
|
524
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
525
|
-
startCellEditing: async () => {
|
|
526
|
-
console.error('no context provider for startCellEditing');
|
|
527
|
-
},
|
|
528
|
-
resetFocusedCellAfterCellEditing: () => {
|
|
529
|
-
console.error('no context provider for resetFocusedCellAfterCellEditing');
|
|
530
|
-
},
|
|
531
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
532
|
-
updatingCells: async () => {
|
|
533
|
-
console.error('no context provider for modifyUpdating');
|
|
534
|
-
return false;
|
|
535
|
-
},
|
|
536
|
-
redrawRows: () => {
|
|
537
|
-
console.error('no context provider for redrawRows');
|
|
538
|
-
},
|
|
539
|
-
setExternallySelectedItemsAreInSync: () => {
|
|
540
|
-
console.error('no context provider for setExternallySelectedItemsAreInSync');
|
|
541
|
-
},
|
|
542
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
543
|
-
waitForExternallySelectedItemsToBeInSync: async () => {
|
|
544
|
-
console.error('no context provider for waitForExternallySelectedItemsToBeInSync');
|
|
545
|
-
},
|
|
546
|
-
addExternalFilter: () => {
|
|
547
|
-
console.error('no context provider for addExternalFilter');
|
|
548
|
-
},
|
|
549
|
-
removeExternalFilter: () => {
|
|
550
|
-
console.error('no context provider for removeExternalFilter');
|
|
551
|
-
},
|
|
552
|
-
isExternalFilterPresent: () => {
|
|
553
|
-
console.error('no context provider for isExternalFilterPresent');
|
|
554
|
-
return false;
|
|
555
|
-
},
|
|
556
|
-
doesExternalFilterPass: () => {
|
|
557
|
-
console.error('no context provider for doesExternalFilterPass');
|
|
558
|
-
return true;
|
|
559
|
-
},
|
|
560
|
-
downloadCsv: () => {
|
|
561
|
-
console.error('no context provider for downloadCsv');
|
|
562
|
-
},
|
|
563
|
-
onBulkEditingComplete: () => {
|
|
564
|
-
console.error('no context provider for onBulkEditingComplete');
|
|
565
|
-
},
|
|
566
|
-
setOnBulkEditingComplete: () => {
|
|
567
|
-
console.error('no context provider for setOnBulkEditingComplete');
|
|
568
|
-
},
|
|
569
|
-
showNoRowsOverlay: () => {
|
|
570
|
-
console.error('no context provider for showLoadingOverlay');
|
|
571
|
-
},
|
|
449
|
+
setApis: NoContext,
|
|
450
|
+
setQuickFilter: NoContext,
|
|
451
|
+
selectRowsById: NoContext,
|
|
452
|
+
getSelectedRows: NoContext,
|
|
453
|
+
getFilteredSelectedRows: NoContext,
|
|
454
|
+
getSelectedRowIds: NoContext,
|
|
455
|
+
getFilteredSelectedRowIds: NoContext,
|
|
456
|
+
selectRowsDiff: NoContext,
|
|
457
|
+
selectRowsByIdWithFlash: NoContext,
|
|
458
|
+
selectRowsWithFlashDiff: NoContext,
|
|
459
|
+
flashRows: NoContext,
|
|
460
|
+
flashRowsDiff: NoContext,
|
|
461
|
+
focusByRowById: NoContext,
|
|
462
|
+
ensureRowVisible: NoContext,
|
|
463
|
+
ensureSelectedRowIsVisible: NoContext,
|
|
464
|
+
getFirstRowId: NoContext,
|
|
465
|
+
autoSizeColumns: NoContext,
|
|
466
|
+
sizeColumnsToFit: NoContext,
|
|
467
|
+
editingCells: NoContext,
|
|
468
|
+
startCellEditing: NoContext,
|
|
469
|
+
resetFocusedCellAfterCellEditing: NoContext,
|
|
470
|
+
updatingCells: NoContext,
|
|
471
|
+
redrawRows: NoContext,
|
|
472
|
+
setExternallySelectedItemsAreInSync: NoContext,
|
|
473
|
+
waitForExternallySelectedItemsToBeInSync: NoContext,
|
|
474
|
+
addExternalFilter: NoContext,
|
|
475
|
+
removeExternalFilter: NoContext,
|
|
476
|
+
isExternalFilterPresent: NoContext,
|
|
477
|
+
doesExternalFilterPass: NoContext,
|
|
478
|
+
downloadCsv: NoContext,
|
|
479
|
+
onBulkEditingComplete: NoContext,
|
|
480
|
+
setOnBulkEditingComplete: NoContext,
|
|
481
|
+
showNoRowsOverlay: NoContext,
|
|
572
482
|
});
|
|
573
483
|
const useGridContext = () => React.useContext(GridContext);
|
|
574
484
|
|
|
@@ -850,6 +760,36 @@ const GridHeaderSelect = ({ api }) => {
|
|
|
850
760
|
} }) }));
|
|
851
761
|
};
|
|
852
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
|
+
|
|
853
793
|
const EventHandlersContext = React.createContext({
|
|
854
794
|
handleClick: () => { },
|
|
855
795
|
});
|
|
@@ -2684,7 +2624,7 @@ const SubMenuFr = ({ 'aria-label': ariaLabel, className, disabled, direction, la
|
|
|
2684
2624
|
};
|
|
2685
2625
|
const SubMenu = withHovering('SubMenu', SubMenuFr);
|
|
2686
2626
|
|
|
2687
|
-
const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, }) => {
|
|
2627
|
+
const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, context, }) => {
|
|
2688
2628
|
const { redrawRows, prePopupOps, resetFocusedCellAfterCellEditing, getSelectedRows } = React.useContext(GridContext);
|
|
2689
2629
|
const [isOpen, setOpen] = React.useState(false);
|
|
2690
2630
|
const [anchorPoint, setAnchorPoint] = React.useState({ x: 0, y: 0 });
|
|
@@ -2692,6 +2632,7 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
|
|
|
2692
2632
|
const clickedColDefRef = React.useRef(null);
|
|
2693
2633
|
const selectedRowsRef = React.useRef([]);
|
|
2694
2634
|
const clickedRowRef = React.useRef(null);
|
|
2635
|
+
const eventRef = React.useRef(undefined);
|
|
2695
2636
|
const openMenu = React.useCallback((e) => {
|
|
2696
2637
|
if (!e)
|
|
2697
2638
|
return;
|
|
@@ -2711,16 +2652,424 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
|
|
|
2711
2652
|
clickedColDefRef.current = event.colDef;
|
|
2712
2653
|
selectedRowsRef.current = getSelectedRows();
|
|
2713
2654
|
clickedRowRef.current = event.data;
|
|
2655
|
+
eventRef.current = event;
|
|
2714
2656
|
// This is actually a pointer event
|
|
2715
2657
|
openMenu(event.event);
|
|
2716
2658
|
}, [contextMenuSelectRow, getSelectedRows, openMenu]);
|
|
2717
2659
|
return {
|
|
2718
2660
|
openMenu,
|
|
2719
2661
|
cellContextMenu,
|
|
2720
|
-
|
|
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,
|
|
2721
2686
|
};
|
|
2722
2687
|
};
|
|
2723
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,
|
|
2913
|
+
};
|
|
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
|
+
};
|
|
3072
|
+
|
|
2724
3073
|
const GridLoadingOverlayComponentFr = (props, externalRef) => (jsxRuntime.jsx("div", { ref: externalRef, style: {
|
|
2725
3074
|
left: 0,
|
|
2726
3075
|
top: 0,
|
|
@@ -2902,8 +3251,26 @@ agGridCommunity.ModuleRegistry.registerModules([agGridCommunity.AllCommunityModu
|
|
|
2902
3251
|
/**
|
|
2903
3252
|
* Wrapper for AgGrid to add commonly used functionality.
|
|
2904
3253
|
*/
|
|
2905
|
-
const Grid = ({
|
|
2906
|
-
|
|
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 = true, 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();
|
|
2907
3274
|
// CellEditingStop event happens too much for one edit
|
|
2908
3275
|
const startedEditRef = React.useRef(false);
|
|
2909
3276
|
const startCellEditing = React.useCallback((props) => {
|
|
@@ -2912,7 +3279,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
2912
3279
|
}, [propStartCellEditing]);
|
|
2913
3280
|
const { updatedDep, anyUpdating, updatingCols } = React.useContext(GridUpdatingContext);
|
|
2914
3281
|
const gridDivRef = React.useRef(null);
|
|
2915
|
-
const lastSelectedIds = React.useRef(
|
|
3282
|
+
const lastSelectedIds = React.useRef();
|
|
2916
3283
|
const [staleGrid, setStaleGrid] = React.useState(false);
|
|
2917
3284
|
const [autoSized, setAutoSized] = React.useState(false);
|
|
2918
3285
|
const postSortRows = usePostSortRowsHook({ setStaleGrid });
|
|
@@ -3038,12 +3405,13 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3038
3405
|
*/
|
|
3039
3406
|
const hasSelectedFirstItem = React.useRef(false);
|
|
3040
3407
|
React.useEffect(() => {
|
|
3041
|
-
if (!gridReady || hasSelectedFirstItem.current || !rowData || !externallySelectedItemsAreInSync)
|
|
3408
|
+
if (!gridReady || hasSelectedFirstItem.current || !rowData || !externallySelectedItemsAreInSync) {
|
|
3042
3409
|
return;
|
|
3410
|
+
}
|
|
3043
3411
|
hasSelectedFirstItem.current = true;
|
|
3044
|
-
if (isNotEmpty(rowData) && lodashEs.isEmpty(
|
|
3412
|
+
if (isNotEmpty(rowData) && lodashEs.isEmpty(externalSelectedItems) && lodashEs.isEmpty(externalSelectedIds)) {
|
|
3045
3413
|
const firstRowId = getFirstRowId();
|
|
3046
|
-
if (
|
|
3414
|
+
if (autoSelectFirstRow && selectable) {
|
|
3047
3415
|
selectRowsById([firstRowId]);
|
|
3048
3416
|
}
|
|
3049
3417
|
else {
|
|
@@ -3054,31 +3422,52 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3054
3422
|
externallySelectedItemsAreInSync,
|
|
3055
3423
|
focusByRowById,
|
|
3056
3424
|
gridReady,
|
|
3057
|
-
|
|
3058
|
-
|
|
3425
|
+
externalSelectedItems,
|
|
3426
|
+
autoSelectFirstRow,
|
|
3059
3427
|
rowData,
|
|
3060
3428
|
selectRowsById,
|
|
3061
3429
|
getFirstRowId,
|
|
3430
|
+
selectable,
|
|
3431
|
+
externalSelectedIds,
|
|
3062
3432
|
]);
|
|
3063
3433
|
/**
|
|
3064
3434
|
* Ensure external selected items list is in sync with panel.
|
|
3065
3435
|
*/
|
|
3066
3436
|
const synchroniseExternalStateToGridSelection = React.useCallback(({ api }) => {
|
|
3067
|
-
if (
|
|
3068
|
-
|
|
3069
|
-
|
|
3437
|
+
if (externalSelectedIds && setExternalSelectedIds) {
|
|
3438
|
+
const selectedRowsIds = api.getSelectedRows().map((row) => row.id);
|
|
3439
|
+
// We don't want to update selected Items if it hasn't changed to prevent excess renders
|
|
3440
|
+
if (externalSelectedIds.length !== selectedRowsIds.length ||
|
|
3441
|
+
isNotEmpty(lodashEs.xorBy(selectedRowsIds, externalSelectedIds))) {
|
|
3442
|
+
setExternallySelectedItemsAreInSync(false);
|
|
3443
|
+
setExternalSelectedIds([...selectedRowsIds]);
|
|
3444
|
+
}
|
|
3445
|
+
else {
|
|
3446
|
+
setExternallySelectedItemsAreInSync(true);
|
|
3447
|
+
}
|
|
3070
3448
|
}
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3449
|
+
else if (externalSelectedItems && setExternalSelectedItems) {
|
|
3450
|
+
const selectedRows = api.getSelectedRows();
|
|
3451
|
+
// We don't want to update selected Items if it hasn't changed to prevent excess renders
|
|
3452
|
+
if (externalSelectedItems.length !== selectedRows.length ||
|
|
3453
|
+
isNotEmpty(lodashEs.xorBy(selectedRows, externalSelectedItems, (row) => row.id))) {
|
|
3454
|
+
setExternallySelectedItemsAreInSync(false);
|
|
3455
|
+
setExternalSelectedItems([...selectedRows]);
|
|
3456
|
+
}
|
|
3457
|
+
else {
|
|
3458
|
+
setExternallySelectedItemsAreInSync(true);
|
|
3459
|
+
}
|
|
3077
3460
|
}
|
|
3078
3461
|
else {
|
|
3079
3462
|
setExternallySelectedItemsAreInSync(true);
|
|
3080
3463
|
}
|
|
3081
|
-
}, [
|
|
3464
|
+
}, [
|
|
3465
|
+
externalSelectedIds,
|
|
3466
|
+
externalSelectedItems,
|
|
3467
|
+
setExternalSelectedIds,
|
|
3468
|
+
setExternalSelectedItems,
|
|
3469
|
+
setExternallySelectedItemsAreInSync,
|
|
3470
|
+
]);
|
|
3082
3471
|
/**
|
|
3083
3472
|
* Synchronise externally selected items to grid.
|
|
3084
3473
|
* If new ids are selected scroll them into view.
|
|
@@ -3086,19 +3475,26 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3086
3475
|
const synchroniseExternallySelectedItemsToGrid = React.useCallback(() => {
|
|
3087
3476
|
if (!gridReady)
|
|
3088
3477
|
return;
|
|
3089
|
-
if (!
|
|
3478
|
+
if (!externalSelectedItems && !externalSelectedIds) {
|
|
3090
3479
|
setExternallySelectedItemsAreInSync(true);
|
|
3091
3480
|
return;
|
|
3092
3481
|
}
|
|
3093
|
-
const selectedIds =
|
|
3094
|
-
const lastNewId = lodashEs.last(lodashEs.difference(selectedIds, lastSelectedIds.current));
|
|
3482
|
+
const selectedIds = externalSelectedIds ?? externalSelectedItems?.map((row) => row.id);
|
|
3483
|
+
const lastNewId = lodashEs.last(lodashEs.difference(selectedIds, lastSelectedIds.current ?? []));
|
|
3095
3484
|
if (lastNewId != null) {
|
|
3096
3485
|
ensureRowVisible(lastNewId);
|
|
3097
3486
|
}
|
|
3098
3487
|
lastSelectedIds.current = selectedIds;
|
|
3099
3488
|
selectRowsById(selectedIds);
|
|
3100
3489
|
setExternallySelectedItemsAreInSync(true);
|
|
3101
|
-
}, [
|
|
3490
|
+
}, [
|
|
3491
|
+
gridReady,
|
|
3492
|
+
externalSelectedItems,
|
|
3493
|
+
externalSelectedIds,
|
|
3494
|
+
selectRowsById,
|
|
3495
|
+
setExternallySelectedItemsAreInSync,
|
|
3496
|
+
ensureRowVisible,
|
|
3497
|
+
]);
|
|
3102
3498
|
/**
|
|
3103
3499
|
* Combine grid and cell editable into one function
|
|
3104
3500
|
*/
|
|
@@ -3140,7 +3536,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3140
3536
|
const columnDefs = React.useMemo(() => {
|
|
3141
3537
|
return params.columnDefs.map(mapColDef);
|
|
3142
3538
|
}, [params.columnDefs, mapColDef]);
|
|
3143
|
-
const hasExternallySelectedItems = !!
|
|
3539
|
+
const hasExternallySelectedItems = !!setExternalSelectedItems || !!setExternalSelectedIds;
|
|
3144
3540
|
/**
|
|
3145
3541
|
* When grid is ready set the apis to the grid context and sync selected items to grid.
|
|
3146
3542
|
*/
|
|
@@ -3196,15 +3592,6 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3196
3592
|
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3197
3593
|
}
|
|
3198
3594
|
}, [startCellEditing]);
|
|
3199
|
-
/**
|
|
3200
|
-
* Handle single click edits
|
|
3201
|
-
*/
|
|
3202
|
-
const onCellClicked = React.useCallback((event) => {
|
|
3203
|
-
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3204
|
-
if ((editable && event.colDef.singleClickEdit) ?? singleClickEdit) {
|
|
3205
|
-
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3206
|
-
}
|
|
3207
|
-
}, [singleClickEdit, startCellEditing]);
|
|
3208
3595
|
const onCellEditingStopped = React.useCallback((event) => {
|
|
3209
3596
|
if (!startedEditRef.current) {
|
|
3210
3597
|
return;
|
|
@@ -3253,6 +3640,78 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3253
3640
|
prePopupOps();
|
|
3254
3641
|
}
|
|
3255
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]);
|
|
3256
3715
|
/**
|
|
3257
3716
|
* Once the grid has auto-sized we want to run fit to fit the grid in its container,
|
|
3258
3717
|
* but we don't want the non-flex auto-sized columns to "fit" size, so suppressSizeToFit is set to true.
|
|
@@ -3270,7 +3729,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3270
3729
|
let comparator = colDef.comparator;
|
|
3271
3730
|
if (sortable && !comparator) {
|
|
3272
3731
|
comparator = (value1, value2, node1, node2) => {
|
|
3273
|
-
let r
|
|
3732
|
+
let r;
|
|
3274
3733
|
if (typeof valueFormatter === 'function') {
|
|
3275
3734
|
r = compareNaturalInsensitive(valueFormatter({
|
|
3276
3735
|
data: node1.data,
|
|
@@ -3360,37 +3819,6 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3360
3819
|
}
|
|
3361
3820
|
prevLoading.current = newLoading;
|
|
3362
3821
|
}, [params.loading, rowData, showNoRowsOverlay]);
|
|
3363
|
-
/**
|
|
3364
|
-
* Set of column I'd's that are prevented from auto-sizing as they are user set
|
|
3365
|
-
*/
|
|
3366
|
-
const userSizedColIds = React.useRef(new Map());
|
|
3367
|
-
/**
|
|
3368
|
-
* Lock/unlock column width on user edit/reset.
|
|
3369
|
-
*/
|
|
3370
|
-
const onColumnResized = React.useCallback((e) => {
|
|
3371
|
-
const colId = e.column?.getColId();
|
|
3372
|
-
if (colId == null) {
|
|
3373
|
-
return;
|
|
3374
|
-
}
|
|
3375
|
-
const width = e.column?.getActualWidth();
|
|
3376
|
-
if (width == null) {
|
|
3377
|
-
return;
|
|
3378
|
-
}
|
|
3379
|
-
switch (e.source) {
|
|
3380
|
-
case 'uiColumnResized':
|
|
3381
|
-
userSizedColIds.current.set(colId, width);
|
|
3382
|
-
/*const colDef = e.column?.getColDef();
|
|
3383
|
-
if (!colDef?.flex) {
|
|
3384
|
-
onGridResize(e);
|
|
3385
|
-
}*/
|
|
3386
|
-
break;
|
|
3387
|
-
case 'autosizeColumns':
|
|
3388
|
-
userSizedColIds.current.delete(colId);
|
|
3389
|
-
//onGridResize(e);
|
|
3390
|
-
break;
|
|
3391
|
-
}
|
|
3392
|
-
}, []);
|
|
3393
|
-
const gridContextMenu = useGridContextMenu({ contextMenu: params.contextMenu, contextMenuSelectRow });
|
|
3394
3822
|
const startDragYRef = React.useRef(null);
|
|
3395
3823
|
const clearHighlightRowClasses = React.useCallback(() => {
|
|
3396
3824
|
document.querySelectorAll(`.ag-row-highlight-above`)?.forEach((el) => {
|
|
@@ -3467,11 +3895,14 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3467
3895
|
}
|
|
3468
3896
|
}, [params, clearHighlightRowClasses]);
|
|
3469
3897
|
React.useEffect(() => {
|
|
3470
|
-
if (
|
|
3471
|
-
console.warn('<Grid/> has setExternalSelectedItems parameter, but is missing selectable parameter,' +
|
|
3898
|
+
if ((setExternalSelectedItems || setExternalSelectedIds) && selectable == null) {
|
|
3899
|
+
console.warn('<Grid/> has setExternalSelectedItems/setExternalSelectedIds parameter, but is missing selectable parameter,' +
|
|
3472
3900
|
'this will cause weird delays in editing.\nIf you need to hide selection column use hideSelectColumn=true');
|
|
3473
3901
|
}
|
|
3474
|
-
},
|
|
3902
|
+
},
|
|
3903
|
+
// Only needs to run on startup
|
|
3904
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3905
|
+
[selectable]);
|
|
3475
3906
|
// This is setting a ref in the GridContext so won't be triggering an update loop
|
|
3476
3907
|
setOnBulkEditingComplete(params.onBulkEditingComplete);
|
|
3477
3908
|
const getRowId = React.useCallback((params) => `${params.data.id}`, []);
|
|
@@ -3515,25 +3946,24 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3515
3946
|
}
|
|
3516
3947
|
return false;
|
|
3517
3948
|
},
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
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,
|
|
3521
3952
|
};
|
|
3522
3953
|
}, [
|
|
3523
|
-
params.enableClickSelection,
|
|
3524
|
-
params.enableSelectionWithoutKeys,
|
|
3525
3954
|
params.hideSelectColumn,
|
|
3526
3955
|
params.onRowDragEnd,
|
|
3527
3956
|
rowSelection,
|
|
3528
3957
|
selectColumnPinned,
|
|
3529
3958
|
selectable,
|
|
3959
|
+
params.enableClickSelection,
|
|
3530
3960
|
]);
|
|
3531
3961
|
const onGridSizeChanged = React.useCallback((event) => {
|
|
3532
3962
|
if (sizeColumns === 'fit' || (['auto', 'auto-skip-headers'].includes(sizeColumns) && hasSetContentSize.current)) {
|
|
3533
3963
|
event.api.sizeColumnsToFit();
|
|
3534
3964
|
}
|
|
3535
3965
|
}, [sizeColumns]);
|
|
3536
|
-
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
|
|
3537
3967
|
? {
|
|
3538
3968
|
enableSelectionWithoutKeys: params.enableSelectionWithoutKeys ?? false,
|
|
3539
3969
|
enableClickSelection: params.enableClickSelection ?? false,
|
|
@@ -3543,7 +3973,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3543
3973
|
headerCheckbox: false,
|
|
3544
3974
|
}),
|
|
3545
3975
|
}
|
|
3546
|
-
: undefined, selectionColumnDef: selectionColumnDef,
|
|
3976
|
+
: undefined, selectionColumnDef: selectionColumnDef, suppressCellFocus: params.suppressCellFocus, suppressClickEdit: true, suppressColumnVirtualisation: suppressColumnVirtualization, suppressStartEditOnTab: true }) })] }));
|
|
3547
3977
|
};
|
|
3548
3978
|
const quickFilterParser = (filterStr) => {
|
|
3549
3979
|
// filter is exact matches exactly groups separated by commas
|
|
@@ -3784,33 +4214,6 @@ const GridFilterButtons = ({ className, luiButtonProps, options, }) => {
|
|
|
3784
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}`))) }) }));
|
|
3785
4215
|
};
|
|
3786
4216
|
|
|
3787
|
-
function styleInject(css, ref) {
|
|
3788
|
-
if ( ref === void 0 ) ref = {};
|
|
3789
|
-
var insertAt = ref.insertAt;
|
|
3790
|
-
|
|
3791
|
-
if (!css || typeof document === 'undefined') { return; }
|
|
3792
|
-
|
|
3793
|
-
var head = document.head || document.getElementsByTagName('head')[0];
|
|
3794
|
-
var style = document.createElement('style');
|
|
3795
|
-
style.type = 'text/css';
|
|
3796
|
-
|
|
3797
|
-
if (insertAt === 'top') {
|
|
3798
|
-
if (head.firstChild) {
|
|
3799
|
-
head.insertBefore(style, head.firstChild);
|
|
3800
|
-
} else {
|
|
3801
|
-
head.appendChild(style);
|
|
3802
|
-
}
|
|
3803
|
-
} else {
|
|
3804
|
-
head.appendChild(style);
|
|
3805
|
-
}
|
|
3806
|
-
|
|
3807
|
-
if (style.styleSheet) {
|
|
3808
|
-
style.styleSheet.cssText = css;
|
|
3809
|
-
} else {
|
|
3810
|
-
style.appendChild(document.createTextNode(css));
|
|
3811
|
-
}
|
|
3812
|
-
}
|
|
3813
|
-
|
|
3814
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}";
|
|
3815
4218
|
styleInject(css_248z$3);
|
|
3816
4219
|
|
|
@@ -4618,14 +5021,14 @@ const TextInputFormatted = (props) => {
|
|
|
4618
5021
|
|
|
4619
5022
|
const bearingValueFormatter = (value) => {
|
|
4620
5023
|
const safeValue = typeof value === 'string' ? parseFloat(value) : value;
|
|
4621
|
-
if (safeValue == null) {
|
|
5024
|
+
if (safeValue == null || Number.isNaN(safeValue)) {
|
|
4622
5025
|
return '–';
|
|
4623
5026
|
}
|
|
4624
5027
|
return convertDDToDMS(safeValue, false);
|
|
4625
5028
|
};
|
|
4626
5029
|
const bearingCorrectionValueFormatter = (value) => {
|
|
4627
5030
|
const safeValue = value;
|
|
4628
|
-
if (safeValue == null) {
|
|
5031
|
+
if (safeValue == null || Number.isNaN(safeValue)) {
|
|
4629
5032
|
return '–';
|
|
4630
5033
|
}
|
|
4631
5034
|
if (typeof safeValue === 'string') {
|
|
@@ -5421,6 +5824,7 @@ const GridPopoutEditMultiSelectGrid = (colDef, props) => GridCell(colDef, {
|
|
|
5421
5824
|
},
|
|
5422
5825
|
});
|
|
5423
5826
|
|
|
5827
|
+
const GridCellBearingValueFormatter = (params) => bearingValueFormatter(params.value) ?? '';
|
|
5424
5828
|
const GridPopoverEditBearingLike = (colDef, props) => GridCell({
|
|
5425
5829
|
valueFormatter: (params) => props.editorParams?.formatValue(params.value) ?? '',
|
|
5426
5830
|
...colDef,
|
|
@@ -5573,6 +5977,7 @@ const GridContextProvider = (props) => {
|
|
|
5573
5977
|
}
|
|
5574
5978
|
return gridApi && !gridApi.isDestroyed() ? hasApiFn(gridApi) : noApiFn();
|
|
5575
5979
|
}, [gridApi]);
|
|
5980
|
+
const getCellValue = React.useCallback((...props) => gridApi?.getCellValue(...props), [gridApi]);
|
|
5576
5981
|
/**
|
|
5577
5982
|
* Scroll row into view by Id.
|
|
5578
5983
|
*
|
|
@@ -5732,7 +6137,7 @@ const GridContextProvider = (props) => {
|
|
|
5732
6137
|
// It may be that the first cell is the selection cell, this doesn't exist as a colDef
|
|
5733
6138
|
// so instead, I just try and select it. If it doesn't exist selection will stay on the
|
|
5734
6139
|
// previously focused cell
|
|
5735
|
-
gridApi.setFocusedCell(rowIndex,
|
|
6140
|
+
gridApi.setFocusedCell(rowIndex, agGridSelectRowColId);
|
|
5736
6141
|
}
|
|
5737
6142
|
}, 100);
|
|
5738
6143
|
}
|
|
@@ -6171,6 +6576,7 @@ const GridContextProvider = (props) => {
|
|
|
6171
6576
|
getSelectedRowIds,
|
|
6172
6577
|
getFilteredSelectedRowIds,
|
|
6173
6578
|
getFirstRowId,
|
|
6579
|
+
getCellValue,
|
|
6174
6580
|
editingCells,
|
|
6175
6581
|
ensureRowVisible,
|
|
6176
6582
|
ensureSelectedRowIsVisible,
|
|
@@ -6361,6 +6767,7 @@ exports.GenericCellEditorComponentWrapper = GenericCellEditorComponentWrapper;
|
|
|
6361
6767
|
exports.Grid = Grid;
|
|
6362
6768
|
exports.GridButton = GridButton;
|
|
6363
6769
|
exports.GridCell = GridCell;
|
|
6770
|
+
exports.GridCellBearingValueFormatter = GridCellBearingValueFormatter;
|
|
6364
6771
|
exports.GridCellFiller = GridCellFiller;
|
|
6365
6772
|
exports.GridCellFillerColId = GridCellFillerColId;
|
|
6366
6773
|
exports.GridCellMultiEditor = GridCellMultiEditor;
|
|
@@ -6424,6 +6831,7 @@ exports.SubMenu = SubMenu;
|
|
|
6424
6831
|
exports.TextAreaInput = TextAreaInput;
|
|
6425
6832
|
exports.TextInputFormatted = TextInputFormatted;
|
|
6426
6833
|
exports.TextInputValidator = TextInputValidator;
|
|
6834
|
+
exports.agGridSelectRowColId = agGridSelectRowColId;
|
|
6427
6835
|
exports.bearingCorrectionRangeValidator = bearingCorrectionRangeValidator;
|
|
6428
6836
|
exports.bearingCorrectionValueFormatter = bearingCorrectionValueFormatter;
|
|
6429
6837
|
exports.bearingNumberParser = bearingNumberParser;
|