@linzjs/step-ag-grid 14.9.2 → 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.
@@ -53,7 +53,7 @@ export interface GridContextType<RowType extends GridBaseRow> {
53
53
  removeExternalFilter: (filter: GridFilterExternal<RowType>) => void;
54
54
  isExternalFilterPresent: () => boolean;
55
55
  doesExternalFilterPass: (node: RowNode) => boolean;
56
- invisibleColumnIds: string[];
56
+ invisibleColumnIds: string[] | undefined;
57
57
  setInvisibleColumnIds: (colIds: string[]) => void;
58
58
  downloadCsv: (csvExportParams?: CsvExportParams) => void;
59
59
  setOnCellEditingComplete: (callback: (() => void) | undefined) => void;
@@ -5,10 +5,4 @@ export declare const findParentWithClass: (className: string, child: Node) => HT
5
5
  export declare const hasParentClass: (className: string, child: Node) => boolean;
6
6
  export declare const stringByteLengthIsInvalid: (str: string, maxBytes: number) => boolean;
7
7
  export declare const fnOrVar: (fn: any, param: any) => any;
8
- /**
9
- * Trim filename and replaces troublesome characters.
10
- *
11
- * e.g. " LT 1235/543 &%//*$ " => "LT_1235-543_&%-$"
12
- * e.g. " @filename here!!!" => "@filename_here!!!"
13
- */
14
8
  export declare const sanitiseFileName: (filename: string) => string;
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { LuiMiniSpinner, LuiIcon, LuiButton, LuiCheckboxInput, LuiButtonGroup } from '@linzjs/lui';
3
3
  import { AgGridReact } from 'ag-grid-react';
4
- import { negate, isEmpty, xorBy, last, difference, defer as defer$1, omit, sortBy, findIndex, debounce as debounce$1, delay, partition, pick, groupBy, fromPairs, toPairs, isEqual, sumBy, compact, remove, castArray, flatten } from 'lodash-es';
4
+ import { negate, isEmpty, xorBy, last, difference, defer as defer$1, omit, sortBy, findIndex, debounce as debounce$1, compact, delay, partition, pick, groupBy, fromPairs, toPairs, isEqual, sumBy, remove, castArray, flatten } from 'lodash-es';
5
5
  import * as React from 'react';
6
6
  import { createContext, useContext, useRef, useEffect, useCallback, useState, useMemo, forwardRef, useLayoutEffect, memo, useReducer, cloneElement, useImperativeHandle, Fragment as Fragment$1 } from 'react';
7
7
  import ReactDOM, { unstable_batchedUpdates, flushSync, createPortal } from 'react-dom';
@@ -42,7 +42,7 @@ const GridContext = createContext({
42
42
  console.error("no context provider for getColumns");
43
43
  return [];
44
44
  },
45
- invisibleColumnIds: [],
45
+ invisibleColumnIds: undefined,
46
46
  setInvisibleColumnIds: () => {
47
47
  console.error("no context provider for setInvisibleColumnIds");
48
48
  },
@@ -223,146 +223,6 @@ const useIntervalHook = ({ callback, timeoutMs }) => {
223
223
  }, [timeoutMs]);
224
224
  };
225
225
 
226
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
227
-
228
- function getDefaultExportFromCjs (x) {
229
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
230
- }
231
-
232
- function getAugmentedNamespace(n) {
233
- if (n.__esModule) return n;
234
- var f = n.default;
235
- if (typeof f == "function") {
236
- var a = function a () {
237
- if (this instanceof a) {
238
- var args = [null];
239
- args.push.apply(args, arguments);
240
- var Ctor = Function.bind.apply(f, args);
241
- return new Ctor();
242
- }
243
- return f.apply(this, arguments);
244
- };
245
- a.prototype = f.prototype;
246
- } else a = {};
247
- Object.defineProperty(a, '__esModule', {value: true});
248
- Object.keys(n).forEach(function (k) {
249
- var d = Object.getOwnPropertyDescriptor(n, k);
250
- Object.defineProperty(a, k, d.get ? d : {
251
- enumerable: true,
252
- get: function () {
253
- return n[k];
254
- }
255
- });
256
- });
257
- return a;
258
- }
259
-
260
- function isHighSurrogate(codePoint) {
261
- return codePoint >= 0xd800 && codePoint <= 0xdbff;
262
- }
263
-
264
- function isLowSurrogate(codePoint) {
265
- return codePoint >= 0xdc00 && codePoint <= 0xdfff;
266
- }
267
-
268
- // Truncate string by size in bytes
269
- var truncate$2 = function truncate(getLength, string, byteLength) {
270
- if (typeof string !== "string") {
271
- throw new Error("Input must be string");
272
- }
273
-
274
- var charLength = string.length;
275
- var curByteLength = 0;
276
- var codePoint;
277
- var segment;
278
-
279
- for (var i = 0; i < charLength; i += 1) {
280
- codePoint = string.charCodeAt(i);
281
- segment = string[i];
282
-
283
- if (isHighSurrogate(codePoint) && isLowSurrogate(string.charCodeAt(i + 1))) {
284
- i += 1;
285
- segment += string[i];
286
- }
287
-
288
- curByteLength += getLength(segment);
289
-
290
- if (curByteLength === byteLength) {
291
- return string.slice(0, i + 1);
292
- }
293
- else if (curByteLength > byteLength) {
294
- return string.slice(0, i - segment.length + 1);
295
- }
296
- }
297
-
298
- return string;
299
- };
300
-
301
- var truncate$1 = truncate$2;
302
- var getLength = Buffer.byteLength.bind(Buffer);
303
- var truncateUtf8Bytes = truncate$1.bind(null, getLength);
304
-
305
- /*jshint node:true*/
306
-
307
- /**
308
- * Replaces characters in strings that are illegal/unsafe for filenames.
309
- * Unsafe characters are either removed or replaced by a substitute set
310
- * in the optional `options` object.
311
- *
312
- * Illegal Characters on Various Operating Systems
313
- * / ? < > \ : * | "
314
- * https://kb.acronis.com/content/39790
315
- *
316
- * Unicode Control codes
317
- * C0 0x00-0x1f & C1 (0x80-0x9f)
318
- * http://en.wikipedia.org/wiki/C0_and_C1_control_codes
319
- *
320
- * Reserved filenames on Unix-based systems (".", "..")
321
- * Reserved filenames in Windows ("CON", "PRN", "AUX", "NUL", "COM1",
322
- * "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
323
- * "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", and
324
- * "LPT9") case-insesitively and with or without filename extensions.
325
- *
326
- * Capped at 255 characters in length.
327
- * http://unix.stackexchange.com/questions/32795/what-is-the-maximum-allowed-filename-and-folder-size-with-ecryptfs
328
- *
329
- * @param {String} input Original filename
330
- * @param {Object} options {replacement: String | Function }
331
- * @return {String} Sanitized filename
332
- */
333
-
334
- var truncate = truncateUtf8Bytes;
335
-
336
- var illegalRe = /[\/\?<>\\:\*\|"]/g;
337
- var controlRe = /[\x00-\x1f\x80-\x9f]/g;
338
- var reservedRe = /^\.+$/;
339
- var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i;
340
- var windowsTrailingRe = /[\. ]+$/;
341
-
342
- function sanitize(input, replacement) {
343
- if (typeof input !== 'string') {
344
- throw new Error('Input must be string');
345
- }
346
- var sanitized = input
347
- .replace(illegalRe, replacement)
348
- .replace(controlRe, replacement)
349
- .replace(reservedRe, replacement)
350
- .replace(windowsReservedRe, replacement)
351
- .replace(windowsTrailingRe, replacement);
352
- return truncate(sanitized, 255);
353
- }
354
-
355
- var sanitizeFilename = function (input, options) {
356
- var replacement = (options && options.replacement) || '';
357
- var output = sanitize(input, replacement);
358
- if (replacement === '') {
359
- return output;
360
- }
361
- return sanitize(output, '');
362
- };
363
-
364
- var sanitize$1 = /*@__PURE__*/getDefaultExportFromCjs(sanitizeFilename);
365
-
366
226
  const isNotEmpty = negate(isEmpty);
367
227
  const wait$2 = (timeoutMs) => new Promise((resolve) => {
368
228
  setTimeout(resolve, timeoutMs);
@@ -401,13 +261,19 @@ const hasParentClass = function (className, child) {
401
261
  };
402
262
  const stringByteLengthIsInvalid = (str, maxBytes) => new TextEncoder().encode(str).length > maxBytes;
403
263
  const fnOrVar = (fn, param) => (typeof fn === "function" ? fn(param) : fn);
404
- /**
405
- * Trim filename and replaces troublesome characters.
406
- *
407
- * e.g. " LT 1235/543 &%//*$ " => "LT_1235-543_&%-$"
408
- * e.g. " @filename here!!!" => "@filename_here!!!"
409
- */
410
- const sanitiseFileName = (filename) => sanitize$1(filename.trim().replaceAll(/(\/|\\)+/g, "-")).replaceAll(/\s+/g, "_");
264
+ const sanitiseFileName = (filename) => {
265
+ const valid = filename
266
+ .trim()
267
+ .replaceAll(/(\/|\\)+/g, "-")
268
+ .replaceAll(/\s+/g, "_")
269
+ .replaceAll(/[^\w\-āēīōūĀĒĪŌŪ.]/g, "");
270
+ const parts = valid.split(".");
271
+ const fileExt = parts.length > 1 ? parts.pop() : undefined;
272
+ // Arbitrary max filename length of 64 chars + extension
273
+ if (!fileExt)
274
+ return valid.slice().slice(0, 64);
275
+ return valid.slice(0, -fileExt.length - 1).slice(0, 64) + "." + fileExt;
276
+ };
411
277
 
412
278
  const GridNoRowsOverlay = (params) => (jsx("span", { children: isEmpty(params.rowData)
413
279
  ? params.noRowsOverlayText ?? "There are currently no rows"
@@ -652,11 +518,20 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
652
518
  }
653
519
  needsAutoSize.current = false;
654
520
  }, [autoSizeColumns, params, sizeColumns, sizeColumnsToFit]);
521
+ const lastOwnerDocumentRef = useRef();
655
522
  /**
656
523
  * Auto-size windows that had deferred auto-size
657
524
  */
658
525
  useIntervalHook({
659
526
  callback: () => {
527
+ // Check if window has been popped out and needs resize
528
+ const currentDocument = gridDivRef.current?.ownerDocument;
529
+ if (currentDocument !== lastOwnerDocumentRef.current) {
530
+ lastOwnerDocumentRef.current = currentDocument;
531
+ if (currentDocument) {
532
+ needsAutoSize.current = true;
533
+ }
534
+ }
660
535
  if (needsAutoSize.current) {
661
536
  needsAutoSize.current = false;
662
537
  setInitialContentSize();
@@ -935,11 +810,19 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
935
810
  * Once the grid has auto-sized we want to run fit to fit the grid in its container,
936
811
  * but we don't want the non-flex auto-sized columns to "fit" size, so suppressSizeToFit is set to true.
937
812
  */
938
- const columnDefsAdjusted = useMemo(() => columnDefs.map((colDef) => ({
939
- ...colDef,
940
- suppressSizeToFit: (sizeColumns === "auto" || sizeColumns === "auto-skip-headers") && !colDef.flex,
941
- sortable: colDef.sortable && params.defaultColDef?.sortable !== false,
942
- })), [columnDefs, params.defaultColDef?.sortable, sizeColumns]);
813
+ const columnDefsAdjusted = useMemo(() => {
814
+ const adjustColDefOrGroup = (colDef) => "children" in colDef ? adjustGroupColDef(colDef) : adjustColDef(colDef);
815
+ const adjustGroupColDef = (colDef) => ({
816
+ ...colDef,
817
+ children: colDef.children.map((colDef) => adjustColDefOrGroup(colDef)),
818
+ });
819
+ const adjustColDef = (colDef) => ({
820
+ ...colDef,
821
+ suppressSizeToFit: (sizeColumns === "auto" || sizeColumns === "auto-skip-headers") && !colDef.flex,
822
+ sortable: colDef.sortable && params.defaultColDef?.sortable !== false,
823
+ });
824
+ return columnDefs.map((colDef) => adjustColDefOrGroup(colDef));
825
+ }, [columnDefs, params.defaultColDef?.sortable, sizeColumns]);
943
826
  /**
944
827
  * Set of colIds that need auto-sizing.
945
828
  */
@@ -3034,15 +2917,23 @@ const GridFilterColumnsToggle = ({ saveState = true }) => {
3034
2917
  if (saveState) {
3035
2918
  try {
3036
2919
  const stored = window.localStorage.getItem(columnStorageKey);
3037
- const invisibleIds = JSON.parse(stored ?? "[]");
3038
- if (!Array.isArray(invisibleIds)) {
3039
- console.error(`stored invisible ids not an array: ${stored}`);
3040
- }
3041
- else if (!invisibleIds.every((id) => typeof id === "string")) {
3042
- console.error(`stored invisible ids not strings: ${stored}`);
2920
+ if (!stored) {
2921
+ // infer the invisible ids from colDefs
2922
+ setInvisibleColumnIds(compact(getColumns()
2923
+ .filter((col) => col.initialHide)
2924
+ .map((col) => col.colId)));
3043
2925
  }
3044
2926
  else {
3045
- invisibleIds && setInvisibleColumnIds(invisibleIds);
2927
+ const invisibleIds = JSON.parse(stored ?? "[]");
2928
+ if (!Array.isArray(invisibleIds)) {
2929
+ console.error(`stored invisible ids not an array: ${stored}`);
2930
+ }
2931
+ else if (!invisibleIds.every((id) => typeof id === "string")) {
2932
+ console.error(`stored invisible ids not strings: ${stored}`);
2933
+ }
2934
+ else {
2935
+ invisibleIds && setInvisibleColumnIds(invisibleIds);
2936
+ }
3046
2937
  }
3047
2938
  }
3048
2939
  catch (ex) {
@@ -3050,7 +2941,7 @@ const GridFilterColumnsToggle = ({ saveState = true }) => {
3050
2941
  }
3051
2942
  setLoaded(true);
3052
2943
  }
3053
- }, [columnStorageKey, loaded, saveState, setInvisibleColumnIds]);
2944
+ }, [columnStorageKey, getColumns, loaded, saveState, setInvisibleColumnIds]);
3054
2945
  // Save state on column visibility change
3055
2946
  useEffect(() => {
3056
2947
  loaded &&
@@ -3059,7 +2950,7 @@ const GridFilterColumnsToggle = ({ saveState = true }) => {
3059
2950
  window.localStorage.setItem(columnStorageKey, JSON.stringify(invisibleColumnIds));
3060
2951
  }, [columnStorageKey, invisibleColumnIds, loaded, saveState]);
3061
2952
  const toggleColumn = useCallback((colId) => {
3062
- if (!colId)
2953
+ if (!colId || !invisibleColumnIds)
3063
2954
  return;
3064
2955
  setInvisibleColumnIds(invisibleColumnIds.includes(colId)
3065
2956
  ? invisibleColumnIds.filter((id) => id !== colId)
@@ -3082,7 +2973,7 @@ const GridFilterColumnsToggle = ({ saveState = true }) => {
3082
2973
  toggleColumn(col.colId);
3083
2974
  }
3084
2975
  }
3085
- }, children: jsx(LuiCheckboxInput, { isChecked: !invisibleColumnIds.includes(col.colId ?? ""), value: `${col.colId}`, label: col.headerName ?? "", isDisabled: isNonManageableColumn(col), inputProps: {
2976
+ }, children: jsx(LuiCheckboxInput, { isChecked: !!invisibleColumnIds && !invisibleColumnIds.includes(col.colId ?? ""), value: `${col.colId}`, label: col.headerName ?? "", isDisabled: isNonManageableColumn(col), inputProps: {
3086
2977
  onClick: (e) => {
3087
2978
  // Click is handled by MenuItem onClick so keyboard events work
3088
2979
  e.preventDefault();
@@ -3168,6 +3059,40 @@ const GridFilterDownloadCsvButton = (csvExportParams) => {
3168
3059
  } })) : (jsx(GridFilterHeaderIconButton, { icon: "ic_csv_file", title: "Download CSV", onClick: handleDownloadClick, disabled: downloading }));
3169
3060
  };
3170
3061
 
3062
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
3063
+
3064
+ function getDefaultExportFromCjs (x) {
3065
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
3066
+ }
3067
+
3068
+ function getAugmentedNamespace(n) {
3069
+ if (n.__esModule) return n;
3070
+ var f = n.default;
3071
+ if (typeof f == "function") {
3072
+ var a = function a () {
3073
+ if (this instanceof a) {
3074
+ var args = [null];
3075
+ args.push.apply(args, arguments);
3076
+ var Ctor = Function.bind.apply(f, args);
3077
+ return new Ctor();
3078
+ }
3079
+ return f.apply(this, arguments);
3080
+ };
3081
+ a.prototype = f.prototype;
3082
+ } else a = {};
3083
+ Object.defineProperty(a, '__esModule', {value: true});
3084
+ Object.keys(n).forEach(function (k) {
3085
+ var d = Object.getOwnPropertyDescriptor(n, k);
3086
+ Object.defineProperty(a, k, d.get ? d : {
3087
+ enumerable: true,
3088
+ get: function () {
3089
+ return n[k];
3090
+ }
3091
+ });
3092
+ });
3093
+ return a;
3094
+ }
3095
+
3171
3096
  /* global setTimeout, clearTimeout */
3172
3097
 
3173
3098
  var dist$1 = function debounce(fn) {
@@ -4530,7 +4455,7 @@ const GridContextProvider = (props) => {
4530
4455
  const [columnApi, setColumnApi] = useState();
4531
4456
  const [gridReady, setGridReady] = useState(false);
4532
4457
  const [quickFilter, setQuickFilter] = useState("");
4533
- const [invisibleColumnIds, setInvisibleColumnIds] = useState([]);
4458
+ const [invisibleColumnIds, setInvisibleColumnIds] = useState();
4534
4459
  const testId = useRef();
4535
4460
  const idsBeforeUpdate = useRef([]);
4536
4461
  const prePopupFocusedCell = useRef();
@@ -4650,6 +4575,10 @@ const GridContextProvider = (props) => {
4650
4575
  .map((rowId) => gridApi.getRowNode("" + rowId)) //
4651
4576
  .filter((r) => r), () => []);
4652
4577
  }, [gridApiOp]);
4578
+ /**
4579
+ * Get ColDefs, with flattened ColGroupDefs
4580
+ */
4581
+ const getColumns = useCallback(() => columnApi?.getAllColumns()?.map((col) => col.getColDef()) ?? [], [columnApi]);
4653
4582
  /**
4654
4583
  * Internal method for selecting and flashing rows.
4655
4584
  *
@@ -4673,9 +4602,9 @@ const GridContextProvider = (props) => {
4673
4602
  const firstNode = rowsThatNeedSelecting[0];
4674
4603
  if (firstNode) {
4675
4604
  defer$1(() => gridApi.ensureNodeVisible(firstNode));
4676
- const colDefs = gridApi.getColumnDefs();
4677
- if (colDefs?.length) {
4678
- const col = colDefs[0]; // We don't support ColGroupDef
4605
+ const colDefs = getColumns();
4606
+ if (!isEmpty(colDefs)) {
4607
+ const col = colDefs[0];
4679
4608
  const rowIndex = firstNode.rowIndex;
4680
4609
  if (rowIndex != null && col != null) {
4681
4610
  const colId = col.colId;
@@ -4706,7 +4635,7 @@ const GridContextProvider = (props) => {
4706
4635
  }, 250);
4707
4636
  }
4708
4637
  });
4709
- }, [_getNewNodes, _rowIdsToNodes, gridApiOp]);
4638
+ }, [_getNewNodes, _rowIdsToNodes, getColumns, gridApiOp]);
4710
4639
  const selectRowsById = useCallback((rowIds) => _selectRowsWithOptionalFlash(rowIds, true, false), [_selectRowsWithOptionalFlash]);
4711
4640
  const selectRowsByIdWithFlash = useCallback((rowIds) => _selectRowsWithOptionalFlash(rowIds, true, true), [_selectRowsWithOptionalFlash]);
4712
4641
  const flashRows = useCallback((rowIds) => _selectRowsWithOptionalFlash(rowIds, false, true), [_selectRowsWithOptionalFlash]);
@@ -4939,9 +4868,8 @@ const GridContextProvider = (props) => {
4939
4868
  return externalFilters.current.every((filter) => filter(node.data, node));
4940
4869
  };
4941
4870
  const getColDef = useCallback((colId) => (!!colId && gridApi?.getColumnDef(colId)) || undefined, [gridApi]);
4942
- const getColumns = useCallback(() => gridApi?.getColumnDefs() ?? [], [gridApi]);
4943
4871
  useEffect(() => {
4944
- if (columnApi) {
4872
+ if (columnApi && invisibleColumnIds) {
4945
4873
  // show all columns that aren't invisible
4946
4874
  columnApi.setColumnsVisible(compact(getColumns()
4947
4875
  .filter((col) => !col.lockVisible && col.colId && !invisibleColumnIds.includes(col.colId))