@linzjs/step-ag-grid 14.9.3 → 14.9.4

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@linzjs/step-ag-grid",
3
3
  "repository": "github:linz/step-ag-grid.git",
4
4
  "license": "MIT",
5
- "version": "14.9.3",
5
+ "version": "14.9.4",
6
6
  "keywords": [
7
7
  "aggrid",
8
8
  "ag-grid",
@@ -1,4 +1,4 @@
1
- import { CellClickedEvent, ColDef, ColumnResizedEvent, ModelUpdatedEvent } from "ag-grid-community";
1
+ import { CellClickedEvent, ColDef, ColGroupDef, ColumnResizedEvent, ModelUpdatedEvent } from "ag-grid-community";
2
2
  import { CellClassParams, EditableCallback, EditableCallbackParams } from "ag-grid-community/dist/lib/entities/colDef";
3
3
  import { GridOptions } from "ag-grid-community/dist/lib/entities/gridOptions";
4
4
  import { CellEvent, GridReadyEvent, SelectionChangedEvent } from "ag-grid-community/dist/lib/events";
@@ -153,11 +153,21 @@ export const Grid = ({
153
153
  needsAutoSize.current = false;
154
154
  }, [autoSizeColumns, params, sizeColumns, sizeColumnsToFit]);
155
155
 
156
+ const lastOwnerDocumentRef = useRef<Document>();
157
+
156
158
  /**
157
159
  * Auto-size windows that had deferred auto-size
158
160
  */
159
161
  useIntervalHook({
160
162
  callback: () => {
163
+ // Check if window has been popped out and needs resize
164
+ const currentDocument = gridDivRef.current?.ownerDocument;
165
+ if (currentDocument !== lastOwnerDocumentRef.current) {
166
+ lastOwnerDocumentRef.current = currentDocument;
167
+ if (currentDocument) {
168
+ needsAutoSize.current = true;
169
+ }
170
+ }
161
171
  if (needsAutoSize.current) {
162
172
  needsAutoSize.current = false;
163
173
  setInitialContentSize();
@@ -277,7 +287,7 @@ export const Grid = ({
277
287
  /**
278
288
  * Add selectable column to colDefs. Adjust column defs to block fit for auto sized columns.
279
289
  */
280
- const columnDefs = useMemo((): ColDef[] => {
290
+ const columnDefs = useMemo((): (ColDef | ColGroupDef)[] => {
281
291
  const adjustColDefs = params.columnDefs.map((colDef) => {
282
292
  const colDefEditable = colDef.editable;
283
293
  const editable = combineEditables(params.readOnly !== true, params.defaultColDef?.editable, colDefEditable);
@@ -471,15 +481,23 @@ export const Grid = ({
471
481
  * Once the grid has auto-sized we want to run fit to fit the grid in its container,
472
482
  * but we don't want the non-flex auto-sized columns to "fit" size, so suppressSizeToFit is set to true.
473
483
  */
474
- const columnDefsAdjusted = useMemo(
475
- () =>
476
- columnDefs.map((colDef) => ({
477
- ...colDef,
478
- suppressSizeToFit: (sizeColumns === "auto" || sizeColumns === "auto-skip-headers") && !colDef.flex,
479
- sortable: colDef.sortable && params.defaultColDef?.sortable !== false,
480
- })),
481
- [columnDefs, params.defaultColDef?.sortable, sizeColumns],
482
- );
484
+ const columnDefsAdjusted = useMemo(() => {
485
+ const adjustColDefOrGroup = (colDef: ColDef | ColGroupDef) =>
486
+ "children" in colDef ? adjustGroupColDef(colDef) : adjustColDef(colDef);
487
+
488
+ const adjustGroupColDef = (colDef: ColGroupDef): ColGroupDef => ({
489
+ ...colDef,
490
+ children: colDef.children.map((colDef) => adjustColDefOrGroup(colDef)),
491
+ });
492
+
493
+ const adjustColDef = (colDef: ColDef): ColDef => ({
494
+ ...colDef,
495
+ suppressSizeToFit: (sizeColumns === "auto" || sizeColumns === "auto-skip-headers") && !colDef.flex,
496
+ sortable: colDef.sortable && params.defaultColDef?.sortable !== false,
497
+ });
498
+
499
+ return columnDefs.map((colDef) => adjustColDefOrGroup(colDef));
500
+ }, [columnDefs, params.defaultColDef?.sortable, sizeColumns]);
483
501
 
484
502
  /**
485
503
  * Set of colIds that need auto-sizing.
@@ -1,4 +1,4 @@
1
- import { isEmpty } from "lodash-es";
1
+ import { compact, isEmpty } from "lodash-es";
2
2
  import { useCallback, useContext, useEffect, useMemo, useState } from "react";
3
3
 
4
4
  import { LuiCheckboxInput, LuiIcon } from "@linzjs/lui";
@@ -35,20 +35,31 @@ export const GridFilterColumnsToggle = ({ saveState = true }: GridFilterColumnsT
35
35
  if (saveState) {
36
36
  try {
37
37
  const stored = window.localStorage.getItem(columnStorageKey);
38
- const invisibleIds = JSON.parse(stored ?? "[]");
39
- if (!Array.isArray(invisibleIds)) {
40
- console.error(`stored invisible ids not an array: ${stored}`);
41
- } else if (!invisibleIds.every((id) => typeof id === "string")) {
42
- console.error(`stored invisible ids not strings: ${stored}`);
38
+ if (!stored) {
39
+ // infer the invisible ids from colDefs
40
+ setInvisibleColumnIds(
41
+ compact(
42
+ getColumns()
43
+ .filter((col) => col.initialHide)
44
+ .map((col) => col.colId),
45
+ ),
46
+ );
43
47
  } else {
44
- invisibleIds && setInvisibleColumnIds(invisibleIds);
48
+ const invisibleIds = JSON.parse(stored ?? "[]");
49
+ if (!Array.isArray(invisibleIds)) {
50
+ console.error(`stored invisible ids not an array: ${stored}`);
51
+ } else if (!invisibleIds.every((id) => typeof id === "string")) {
52
+ console.error(`stored invisible ids not strings: ${stored}`);
53
+ } else {
54
+ invisibleIds && setInvisibleColumnIds(invisibleIds);
55
+ }
45
56
  }
46
57
  } catch (ex) {
47
58
  console.error(ex);
48
59
  }
49
60
  setLoaded(true);
50
61
  }
51
- }, [columnStorageKey, loaded, saveState, setInvisibleColumnIds]);
62
+ }, [columnStorageKey, getColumns, loaded, saveState, setInvisibleColumnIds]);
52
63
 
53
64
  // Save state on column visibility change
54
65
  useEffect(() => {
@@ -60,7 +71,7 @@ export const GridFilterColumnsToggle = ({ saveState = true }: GridFilterColumnsT
60
71
 
61
72
  const toggleColumn = useCallback(
62
73
  (colId?: string) => {
63
- if (!colId) return;
74
+ if (!colId || !invisibleColumnIds) return;
64
75
  setInvisibleColumnIds(
65
76
  invisibleColumnIds.includes(colId)
66
77
  ? invisibleColumnIds.filter((id) => id !== colId)
@@ -104,7 +115,7 @@ export const GridFilterColumnsToggle = ({ saveState = true }: GridFilterColumnsT
104
115
  }}
105
116
  >
106
117
  <LuiCheckboxInput
107
- isChecked={!invisibleColumnIds.includes(col.colId ?? "")}
118
+ isChecked={!!invisibleColumnIds && !invisibleColumnIds.includes(col.colId ?? "")}
108
119
  value={`${col.colId}`}
109
120
  label={col.headerName ?? ""}
110
121
  isDisabled={isNonManageableColumn(col)}
@@ -55,7 +55,7 @@ export interface GridContextType<RowType extends GridBaseRow> {
55
55
  removeExternalFilter: (filter: GridFilterExternal<RowType>) => void;
56
56
  isExternalFilterPresent: () => boolean;
57
57
  doesExternalFilterPass: (node: RowNode) => boolean;
58
- invisibleColumnIds: string[];
58
+ invisibleColumnIds: string[] | undefined;
59
59
  setInvisibleColumnIds: (colIds: string[]) => void;
60
60
  downloadCsv: (csvExportParams?: CsvExportParams) => void;
61
61
  setOnCellEditingComplete: (callback: (() => void) | undefined) => void;
@@ -71,7 +71,7 @@ export const GridContext = createContext<GridContextType<any>>({
71
71
  console.error("no context provider for getColumns");
72
72
  return [];
73
73
  },
74
- invisibleColumnIds: [],
74
+ invisibleColumnIds: undefined,
75
75
  setInvisibleColumnIds: () => {
76
76
  console.error("no context provider for setInvisibleColumnIds");
77
77
  },
@@ -26,7 +26,7 @@ export const GridContextProvider = <RowType extends GridBaseRow>(props: GridCont
26
26
  const [columnApi, setColumnApi] = useState<ColumnApi>();
27
27
  const [gridReady, setGridReady] = useState(false);
28
28
  const [quickFilter, setQuickFilter] = useState("");
29
- const [invisibleColumnIds, setInvisibleColumnIds] = useState<string[]>([]);
29
+ const [invisibleColumnIds, setInvisibleColumnIds] = useState<string[]>();
30
30
  const testId = useRef<string | undefined>();
31
31
  const idsBeforeUpdate = useRef<number[]>([]);
32
32
  const prePopupFocusedCell = useRef<CellPosition>();
@@ -178,6 +178,14 @@ export const GridContextProvider = <RowType extends GridBaseRow>(props: GridCont
178
178
  [gridApiOp],
179
179
  );
180
180
 
181
+ /**
182
+ * Get ColDefs, with flattened ColGroupDefs
183
+ */
184
+ const getColumns: () => ColDefT<RowType>[] = useCallback(
185
+ () => columnApi?.getAllColumns()?.map((col) => col.getColDef()) ?? [],
186
+ [columnApi],
187
+ );
188
+
181
189
  /**
182
190
  * Internal method for selecting and flashing rows.
183
191
  *
@@ -211,9 +219,9 @@ export const GridContextProvider = <RowType extends GridBaseRow>(props: GridCont
211
219
  const firstNode = rowsThatNeedSelecting[0];
212
220
  if (firstNode) {
213
221
  defer(() => gridApi.ensureNodeVisible(firstNode));
214
- const colDefs = gridApi.getColumnDefs();
215
- if (colDefs?.length) {
216
- const col = colDefs[0] as ColDef; // We don't support ColGroupDef
222
+ const colDefs = getColumns();
223
+ if (!isEmpty(colDefs)) {
224
+ const col = colDefs[0];
217
225
  const rowIndex = firstNode.rowIndex;
218
226
  if (rowIndex != null && col != null) {
219
227
  const colId = col.colId;
@@ -244,7 +252,7 @@ export const GridContextProvider = <RowType extends GridBaseRow>(props: GridCont
244
252
  }
245
253
  });
246
254
  },
247
- [_getNewNodes, _rowIdsToNodes, gridApiOp],
255
+ [_getNewNodes, _rowIdsToNodes, getColumns, gridApiOp],
248
256
  );
249
257
 
250
258
  const selectRowsById = useCallback(
@@ -585,10 +593,8 @@ export const GridContextProvider = <RowType extends GridBaseRow>(props: GridCont
585
593
  [gridApi],
586
594
  );
587
595
 
588
- const getColumns: () => ColDefT<RowType>[] = useCallback(() => gridApi?.getColumnDefs() ?? [], [gridApi]);
589
-
590
596
  useEffect(() => {
591
- if (columnApi) {
597
+ if (columnApi && invisibleColumnIds) {
592
598
  // show all columns that aren't invisible
593
599
  columnApi.setColumnsVisible(
594
600
  compact(
@@ -55,6 +55,7 @@ interface ITestRow {
55
55
  id: number;
56
56
  position: string;
57
57
  age: number;
58
+ height: number;
58
59
  desc: string;
59
60
  dd: string;
60
61
  }
@@ -76,14 +77,25 @@ const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) =>
76
77
  info: (props) => props.value === "Developer" && "Developers are awesome",
77
78
  },
78
79
  }),
79
- GridCell({
80
- field: "age",
81
- headerName: "Age",
82
- }),
80
+ {
81
+ headerName: "Metrics",
82
+ marryChildren: true,
83
+ children: [
84
+ GridCell({
85
+ field: "age",
86
+ headerName: "Age",
87
+ }),
88
+ GridCell({
89
+ field: "height",
90
+ headerName: "Height",
91
+ }),
92
+ ],
93
+ },
83
94
  GridCell({
84
95
  field: "desc",
85
96
  headerName: "Description",
86
97
  flex: 1,
98
+ initialHide: true,
87
99
  }),
88
100
  GridPopoverMessage(
89
101
  {
@@ -187,9 +199,9 @@ const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) =>
187
199
  );
188
200
 
189
201
  const [rowData] = useState([
190
- { id: 1000, position: "Tester", age: 30, desc: "Tests application", dd: "1" },
191
- { id: 1001, position: "Developer", age: 12, desc: "Develops application", dd: "2" },
192
- { id: 1002, position: "Manager", age: 65, desc: "Manages", dd: "3" },
202
+ { id: 1000, position: "Tester", age: 30, height: `6'4"`, desc: "Tests application", dd: "1" },
203
+ { id: 1001, position: "Developer", age: 12, height: `5'3"`, desc: "Develops application", dd: "2" },
204
+ { id: 1002, position: "Manager", age: 65, height: `5'9"`, desc: "Manages", dd: "3" },
193
205
  ]);
194
206
 
195
207
  return (