@linzjs/step-ag-grid 7.10.2 → 7.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -41,6 +41,8 @@ Storybook demo deployed at: https://linz.github.io/step-ag-grid/
41
41
 
42
42
  ## Usage
43
43
 
44
+ Check `src\stories` for more usage examples
45
+
44
46
  ```tsx
45
47
  import "@linzjs/lui/dist/scss/base.scss";
46
48
  import "@linzjs/lui/dist/fonts";
@@ -133,4 +135,49 @@ const GridDemo = () => {
133
135
  };
134
136
  ```
135
137
 
136
- Check `src\stories` for more usage examples
138
+ ## Writing tests
139
+
140
+ The following testing calls can be imported from step-ag-grid:
141
+
142
+ - findRow
143
+ - queryRow
144
+ - selectRow
145
+ - deselectRow
146
+ - findCell
147
+ - selectCell
148
+ - editCell
149
+ - findOpenMenu
150
+ - queryMenuOption
151
+ - findMenuOption
152
+ - clickMenuOption
153
+ - openAndClickMenuOption
154
+ - getMultiSelectOptions
155
+ - findMultiSelectOption
156
+ - clickMultiSelectOption
157
+ - typeOtherInput
158
+ - typeOtherTextArea
159
+ - closeMenu
160
+ - findActionButton
161
+ - clickActionButton
162
+
163
+ ```tsx
164
+ import { render, screen } from "@testing-library/react";
165
+ import { waitFor } from "@testing-library/react";
166
+ import { findRow, GridUpdatingContextProvider, openAndClickMenuOption } from "@linzjs/step-ag-grid";
167
+
168
+ const TestComponent = (): JSX.Element => {
169
+ return (
170
+ <GridUpdatingContextProvider>
171
+ <MyGrid />
172
+ </GridUpdatingContextProvider>
173
+ );
174
+ };
175
+
176
+ test("click Delete menu option removes row from the table", async () => {
177
+ await render(<TestComponent />);
178
+ await screen.findByText("My component header");
179
+ expect((await findRow(12345)).getAttribute("row-index")).toBe("1");
180
+ await openAndClickMenuOption(12345, "actions", "Delete");
181
+ await waitFor(async () => expect((await queryRow(12345)).not.toBeDefined());
182
+ });
183
+ ```
package/dist/index.js CHANGED
@@ -1975,10 +1975,7 @@ var MenuRadioGroupFr = function (_a, externalRef) {
1975
1975
  var MenuRadioGroup = React.forwardRef(MenuRadioGroupFr);
1976
1976
 
1977
1977
  var GridContext = React.createContext({
1978
- gridReady: function () {
1979
- console.error("no context provider for gridReady");
1980
- return false;
1981
- },
1978
+ gridReady: false,
1982
1979
  setGridApi: function () {
1983
1980
  console.error("no context provider for setGridApi");
1984
1981
  },
@@ -2045,7 +2042,16 @@ var GridContext = React.createContext({
2045
2042
  }); },
2046
2043
  redrawRows: function () {
2047
2044
  console.error("no context provider for redrawRows");
2048
- }
2045
+ },
2046
+ setExternallySelectedItemsAreInSync: function () {
2047
+ console.error("no context provider for setExternallySelectedItemsAreInSync");
2048
+ },
2049
+ waitForExternallySelectedItemsToBeInSync: function () { return __awaiter(void 0, void 0, void 0, function () {
2050
+ return __generator(this, function (_a) {
2051
+ console.error("no context provider for waitForExternallySelectedItemsToBeInSync");
2052
+ return [2 /*return*/];
2053
+ });
2054
+ }); }
2049
2055
  });
2050
2056
 
2051
2057
  var GridUpdatingContext = React.createContext({
@@ -2069,19 +2075,13 @@ var GridUpdatingContext = React.createContext({
2069
2075
  */
2070
2076
  var GridContextProvider = function (props) {
2071
2077
  var modifyUpdating = React.useContext(GridUpdatingContext).modifyUpdating;
2072
- var gridApiRef = React.useRef();
2078
+ var _a = React.useState(), gridApi = _a[0], _setGridApi = _a[1];
2079
+ var _b = React.useState(false), gridReady = _b[0], setGridReady = _b[1];
2073
2080
  var idsBeforeUpdate = React.useRef([]);
2074
- /**
2075
- * Has Grid api has been set?
2076
- * Some ops in components may occur before onGridReady has been called,
2077
- * and thus will need to check grid is ready before calling.
2078
- */
2079
- var gridReady = function () { return gridApiRef.current != null; };
2080
- /**
2081
- * Set current ref to grid api.
2082
- */
2083
- var setGridApi = function (_gridApi) {
2084
- gridApiRef.current = _gridApi;
2081
+ var externallySelectedItemsAreInSync = React.useRef(false);
2082
+ var setGridApi = function (gridApi) {
2083
+ _setGridApi(gridApi);
2084
+ setGridReady(!!gridApi);
2085
2085
  };
2086
2086
  /**
2087
2087
  * Wraps things that require gridApi in common handling, for when gridApi not present.
@@ -2093,7 +2093,6 @@ var GridContextProvider = function (props) {
2093
2093
  if (!noApiFn) {
2094
2094
  noApiFn = (function () { });
2095
2095
  }
2096
- var gridApi = gridApiRef.current;
2097
2096
  return gridApi ? hasApiFn(gridApi) : noApiFn();
2098
2097
  };
2099
2098
  /**
@@ -2151,7 +2150,7 @@ var GridContextProvider = function (props) {
2151
2150
  * @param retryCount Table updates may not be present when this is called, so retry is needed.
2152
2151
  */
2153
2152
  var _selectRowsWithOptionalFlash = function (rowIds, select, flash, retryCount) {
2154
- if (retryCount === void 0) { retryCount = 5; }
2153
+ if (retryCount === void 0) { retryCount = 15; }
2155
2154
  return gridApiOp(function (gridApi) {
2156
2155
  var _a;
2157
2156
  var rowNodes = rowIds ? _rowIdsToNodes(rowIds) : _getNewNodes();
@@ -2343,6 +2342,29 @@ var GridContextProvider = function (props) {
2343
2342
  gridApi.tabToPreviousCell();
2344
2343
  });
2345
2344
  };
2345
+ var setExternallySelectedItemsAreInSync = function (inSync) {
2346
+ externallySelectedItemsAreInSync.current = inSync;
2347
+ };
2348
+ var waitForExternallySelectedItemsToBeInSync = function () { return __awaiter(void 0, void 0, void 0, function () {
2349
+ var i;
2350
+ return __generator(this, function (_a) {
2351
+ switch (_a.label) {
2352
+ case 0:
2353
+ i = 0;
2354
+ _a.label = 1;
2355
+ case 1:
2356
+ if (!(i < 5000 / 200 && !externallySelectedItemsAreInSync.current)) return [3 /*break*/, 4];
2357
+ return [4 /*yield*/, wait$2(200)];
2358
+ case 2:
2359
+ _a.sent();
2360
+ _a.label = 3;
2361
+ case 3:
2362
+ i++;
2363
+ return [3 /*break*/, 1];
2364
+ case 4: return [2 /*return*/];
2365
+ }
2366
+ });
2367
+ }); };
2346
2368
  return (jsxRuntime.jsx(GridContext.Provider, __assign({ value: {
2347
2369
  gridReady: gridReady,
2348
2370
  setGridApi: setGridApi,
@@ -2361,7 +2383,9 @@ var GridContextProvider = function (props) {
2361
2383
  sizeColumnsToFit: sizeColumnsToFit,
2362
2384
  stopEditing: stopEditing,
2363
2385
  updatingCells: updatingCells,
2364
- redrawRows: redrawRows
2386
+ redrawRows: redrawRows,
2387
+ setExternallySelectedItemsAreInSync: setExternallySelectedItemsAreInSync,
2388
+ waitForExternallySelectedItemsToBeInSync: waitForExternallySelectedItemsToBeInSync
2365
2389
  } }, { children: props.children })));
2366
2390
  };
2367
2391
 
@@ -2691,12 +2715,29 @@ var GridHeaderSelect = function (_a) {
2691
2715
  */
2692
2716
  var Grid = function (params) {
2693
2717
  var _a, _b, _c;
2694
- var _d = React.useContext(GridContext), gridReady = _d.gridReady, setGridApi = _d.setGridApi, setQuickFilter = _d.setQuickFilter, ensureRowVisible = _d.ensureRowVisible, selectRowsById = _d.selectRowsById, ensureSelectedRowIsVisible = _d.ensureSelectedRowIsVisible, sizeColumnsToFit = _d.sizeColumnsToFit;
2718
+ var _d = React.useContext(GridContext), gridReady = _d.gridReady, setGridApi = _d.setGridApi, setQuickFilter = _d.setQuickFilter, ensureRowVisible = _d.ensureRowVisible, selectRowsById = _d.selectRowsById, ensureSelectedRowIsVisible = _d.ensureSelectedRowIsVisible, sizeColumnsToFit = _d.sizeColumnsToFit, setExternallySelectedItemsAreInSync = _d.setExternallySelectedItemsAreInSync;
2695
2719
  var checkUpdating = React.useContext(GridUpdatingContext).checkUpdating;
2696
2720
  var _e = React.useState(""), internalQuickFilter = _e[0], setInternalQuickFilter = _e[1];
2697
2721
  var lastSelectedIds = React.useRef([]);
2698
2722
  var _f = React.useState(false), staleGrid = _f[0], setStaleGrid = _f[1];
2699
2723
  var postSortRows = usePostSortRowsHook({ setStaleGrid: setStaleGrid });
2724
+ /**
2725
+ * On data load select the first row of the grid if required.
2726
+ */
2727
+ var hasSelectedFirstItem = React.useRef(false);
2728
+ React.useEffect(function () {
2729
+ if (!gridReady || !params.autoSelectFirstRow || hasSelectedFirstItem.current || !params.rowData)
2730
+ return;
2731
+ hasSelectedFirstItem.current = true;
2732
+ if (isNotEmpty(params.rowData)) {
2733
+ if (params.setExternalSelectedItems) {
2734
+ params.setExternalSelectedItems([params.rowData[0]]);
2735
+ }
2736
+ else {
2737
+ selectRowsById([params.rowData[0].id]);
2738
+ }
2739
+ }
2740
+ }, [gridReady, params, params.autoSelectFirstRow, params.rowData, selectRowsById]);
2700
2741
  /**
2701
2742
  * AgGrid checkbox select does not pass clicks within cell but not on the checkbox to checkbox.
2702
2743
  * This passes the event to the checkbox when you click anywhere in the cell.
@@ -2713,36 +2754,45 @@ var Grid = function (params) {
2713
2754
  */
2714
2755
  var synchroniseExternalStateToGridSelection = React.useCallback(function (_a) {
2715
2756
  var api = _a.api;
2716
- if (!params.externalSelectedItems || !params.setExternalSelectedItems)
2757
+ if (!params.externalSelectedItems || !params.setExternalSelectedItems) {
2758
+ setExternallySelectedItemsAreInSync(true);
2717
2759
  return;
2760
+ }
2718
2761
  var selectedRows = api.getSelectedRows();
2719
2762
  // We don't want to update selected Items if it hasn't changed to prevent excess renders
2720
2763
  if (params.externalSelectedItems.length != selectedRows.length ||
2721
2764
  isNotEmpty(lodashEs.xorBy(selectedRows, params.externalSelectedItems, function (row) { return row.id; }))) {
2765
+ setExternallySelectedItemsAreInSync(false);
2722
2766
  params.setExternalSelectedItems(__spreadArray([], selectedRows, true));
2723
2767
  }
2724
- }, [params]);
2768
+ else {
2769
+ setExternallySelectedItemsAreInSync(true);
2770
+ }
2771
+ }, [params, setExternallySelectedItemsAreInSync]);
2725
2772
  /**
2726
2773
  * Synchronise externally selected items to grid.
2727
2774
  * If new ids are selected scroll them into view.
2728
2775
  */
2729
2776
  var synchroniseExternallySelectedItemsToGrid = React.useCallback(function () {
2730
- if (!gridReady())
2777
+ if (!gridReady)
2731
2778
  return;
2732
- if (!params.externalSelectedItems)
2779
+ if (!params.externalSelectedItems) {
2780
+ setExternallySelectedItemsAreInSync(true);
2733
2781
  return;
2782
+ }
2734
2783
  var selectedIds = params.externalSelectedItems.map(function (row) { return row.id; });
2735
2784
  var lastNewId = lodashEs.last(lodashEs.difference(selectedIds, lastSelectedIds.current));
2736
2785
  if (lastNewId != null)
2737
2786
  ensureRowVisible(lastNewId);
2738
2787
  lastSelectedIds.current = selectedIds;
2739
2788
  selectRowsById(selectedIds);
2740
- }, [params.externalSelectedItems, ensureRowVisible, gridReady, selectRowsById]);
2789
+ setExternallySelectedItemsAreInSync(true);
2790
+ }, [gridReady, params.externalSelectedItems, ensureRowVisible, selectRowsById, setExternallySelectedItemsAreInSync]);
2741
2791
  /**
2742
2792
  * Synchronise quick filter to grid
2743
2793
  */
2744
2794
  var updateQuickFilter = React.useCallback(function () {
2745
- if (!gridReady())
2795
+ if (!gridReady)
2746
2796
  return;
2747
2797
  if (params.quickFilter) {
2748
2798
  setQuickFilter(internalQuickFilter);
@@ -2856,7 +2906,7 @@ var Grid = function (params) {
2856
2906
  sizeColumnsToFit();
2857
2907
  }
2858
2908
  }, [columnDefs === null || columnDefs === void 0 ? void 0 : columnDefs.length, sizeColumnsToFit]);
2859
- return (jsxRuntime.jsxs("div", __assign({ "data-testid": params["data-testid"], className: clsx("Grid-container", "ag-theme-alpine", staleGrid && "Grid-sortIsStale") }, { children: [params.quickFilter && (jsxRuntime.jsx("div", __assign({ className: "Grid-quickFilter" }, { children: jsxRuntime.jsx("input", { "aria-label": "Search", className: "lui-margin-top-xxs lui-margin-bottom-xxs Grid-quickFilterBox", type: "text", placeholder: (_a = params.quickFilterPlaceholder) !== null && _a !== void 0 ? _a : "Search...", value: internalQuickFilter, onChange: function (event) {
2909
+ return (jsxRuntime.jsxs("div", __assign({ "data-testid": params["data-testid"], className: clsx("Grid-container", "ag-theme-alpine", staleGrid && "Grid-sortIsStale", gridReady && params.rowData && "Grid-ready") }, { children: [params.quickFilter && (jsxRuntime.jsx("div", __assign({ className: "Grid-quickFilter" }, { children: jsxRuntime.jsx("input", { "aria-label": "Search", className: "lui-margin-top-xxs lui-margin-bottom-xxs Grid-quickFilterBox", type: "text", placeholder: (_a = params.quickFilterPlaceholder) !== null && _a !== void 0 ? _a : "Search...", value: internalQuickFilter, onChange: function (event) {
2860
2910
  setInternalQuickFilter(event.target.value);
2861
2911
  } }) }))), jsxRuntime.jsx(agGridReact.AgGridReact, { animateRows: params.animateRows, rowClassRules: params.rowClassRules, defaultColDef: params.defaultColDef, getRowId: function (params) { return "".concat(params.data.id); }, suppressRowClickSelection: true, rowSelection: (_b = params.rowSelection) !== null && _b !== void 0 ? _b : "multiple", suppressBrowserResizeObserver: true, colResizeDefault: "shift", onFirstDataRendered: sizeColumnsToFit, onGridSizeChanged: sizeColumnsToFit, suppressClickEdit: true, onCellKeyPress: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStarted: refreshSelectedRows, onCellEditingStopped: onCellEditingStopped, domLayout: params.domLayout, columnDefs: columnDefs, rowData: params.rowData, noRowsOverlayComponent: noRowsOverlayComponent, onGridReady: onGridReady, onSortChanged: ensureSelectedRowIsVisible, postSortRows: (_c = params.postSortRows) !== null && _c !== void 0 ? _c : postSortRows, onSelectionChanged: synchroniseExternalStateToGridSelection })] })));
2862
2912
  };
@@ -24451,17 +24501,36 @@ var _selectRow = function (select, rowId, within) { return __awaiter(void 0, voi
24451
24501
  return __generator(this, function (_a) {
24452
24502
  switch (_a.label) {
24453
24503
  case 0: return [4 /*yield*/, act(function () { return __awaiter(void 0, void 0, void 0, function () {
24454
- var row, isSelected;
24504
+ var row, isSelected, cell;
24455
24505
  return __generator(this, function (_a) {
24456
24506
  switch (_a.label) {
24457
24507
  case 0: return [4 /*yield*/, findRow(rowId, within)];
24458
24508
  case 1:
24459
24509
  row = _a.sent();
24460
- isSelected = !row.className.includes("ag-row-selected");
24461
- if (select === "toggle" || (select === "select" && !isSelected) || (select === "deselect" && isSelected)) {
24462
- userEvent.click(row);
24463
- }
24464
- return [2 /*return*/];
24510
+ isSelected = row.className.includes("ag-row-selected");
24511
+ if (!(select === "toggle" || (select === "select" && !isSelected) || (select === "deselect" && isSelected))) return [3 /*break*/, 4];
24512
+ return [4 /*yield*/, findCell(rowId, "selection", within)];
24513
+ case 2:
24514
+ cell = _a.sent();
24515
+ userEvent.click(cell);
24516
+ return [4 /*yield*/, waitForWrapper(function () { return __awaiter(void 0, void 0, void 0, function () {
24517
+ var row, nowSelected;
24518
+ return __generator(this, function (_a) {
24519
+ switch (_a.label) {
24520
+ case 0: return [4 /*yield*/, findRow(rowId, within)];
24521
+ case 1:
24522
+ row = _a.sent();
24523
+ nowSelected = row.className.includes("ag-row-selected");
24524
+ if (nowSelected == isSelected)
24525
+ throw "Row ".concat(rowId, " won't select");
24526
+ return [2 /*return*/];
24527
+ }
24528
+ });
24529
+ }); })];
24530
+ case 3:
24531
+ _a.sent();
24532
+ _a.label = 4;
24533
+ case 4: return [2 /*return*/];
24465
24534
  }
24466
24535
  });
24467
24536
  }); })];
@@ -24532,22 +24601,25 @@ var selectCell = function (rowId, colId, within) { return __awaiter(void 0, void
24532
24601
  var editCell = function (rowId, colId, within) { return __awaiter(void 0, void 0, void 0, function () {
24533
24602
  return __generator(this, function (_a) {
24534
24603
  switch (_a.label) {
24535
- case 0: return [4 /*yield*/, act(function () { return __awaiter(void 0, void 0, void 0, function () {
24536
- var cell;
24537
- return __generator(this, function (_a) {
24538
- switch (_a.label) {
24539
- case 0: return [4 /*yield*/, findCell(rowId, colId, within)];
24540
- case 1:
24541
- cell = _a.sent();
24542
- userEvent.dblClick(cell);
24543
- return [2 /*return*/];
24544
- }
24545
- });
24546
- }); })];
24604
+ case 0: return [4 /*yield*/, selectRow(rowId, within)];
24547
24605
  case 1:
24548
24606
  _a.sent();
24549
- return [4 /*yield*/, findOpenMenu()];
24607
+ return [4 /*yield*/, act(function () { return __awaiter(void 0, void 0, void 0, function () {
24608
+ var cell;
24609
+ return __generator(this, function (_a) {
24610
+ switch (_a.label) {
24611
+ case 0: return [4 /*yield*/, findCell(rowId, colId, within)];
24612
+ case 1:
24613
+ cell = _a.sent();
24614
+ userEvent.dblClick(cell);
24615
+ return [2 /*return*/];
24616
+ }
24617
+ });
24618
+ }); })];
24550
24619
  case 2:
24620
+ _a.sent();
24621
+ return [4 /*yield*/, waitForWrapper(findOpenMenu)];
24622
+ case 3:
24551
24623
  _a.sent();
24552
24624
  return [2 /*return*/];
24553
24625
  }
@@ -24588,27 +24660,25 @@ var findMenuOption = function (menuOptionText) { return __awaiter(void 0, void 0
24588
24660
  return [2 /*return*/, menuOption];
24589
24661
  }
24590
24662
  });
24591
- }); }, { timeout: 10000 })];
24663
+ }); }, { timeout: 5000 })];
24592
24664
  case 1: return [2 /*return*/, _a.sent()];
24593
24665
  }
24594
24666
  });
24595
24667
  }); };
24596
24668
  var clickMenuOption = function (menuOptionText) { return __awaiter(void 0, void 0, void 0, function () {
24669
+ var menuOption;
24597
24670
  return __generator(this, function (_a) {
24598
24671
  switch (_a.label) {
24599
- case 0: return [4 /*yield*/, act(function () { return __awaiter(void 0, void 0, void 0, function () {
24600
- var menuOption;
24601
- return __generator(this, function (_a) {
24602
- switch (_a.label) {
24603
- case 0: return [4 /*yield*/, findMenuOption(menuOptionText)];
24604
- case 1:
24605
- menuOption = _a.sent();
24606
- menuOption && userEvent.click(menuOption);
24607
- return [2 /*return*/];
24608
- }
24609
- });
24610
- }); })];
24672
+ case 0: return [4 /*yield*/, findMenuOption(menuOptionText)];
24611
24673
  case 1:
24674
+ menuOption = _a.sent();
24675
+ return [4 /*yield*/, act(function () { return __awaiter(void 0, void 0, void 0, function () {
24676
+ return __generator(this, function (_a) {
24677
+ userEvent.click(menuOption);
24678
+ return [2 /*return*/];
24679
+ });
24680
+ }); })];
24681
+ case 2:
24612
24682
  _a.sent();
24613
24683
  return [2 /*return*/];
24614
24684
  }
@@ -24619,12 +24689,9 @@ var openAndClickMenuOption = function (rowId, colId, menuOptionText, within) { r
24619
24689
  switch (_a.label) {
24620
24690
  case 0: return [4 /*yield*/, editCell(rowId, colId, within)];
24621
24691
  case 1:
24622
- _a.sent();
24623
- return [4 /*yield*/, wait$2(100)];
24624
- case 2:
24625
24692
  _a.sent();
24626
24693
  return [4 /*yield*/, clickMenuOption(menuOptionText)];
24627
- case 3:
24694
+ case 2:
24628
24695
  _a.sent();
24629
24696
  return [2 /*return*/];
24630
24697
  }