@rivet-health/design-system 40.27.2 → 40.28.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.
Files changed (23) hide show
  1. package/esm2020/lib/table/simple-table/simple-table.component.mjs +3 -2
  2. package/esm2020/lib/table/table/state-helpers/column-helpers.mjs +255 -0
  3. package/esm2020/lib/table/table/state-helpers/display-helpers.mjs +48 -0
  4. package/esm2020/lib/table/table/state-helpers/order-helpers.mjs +143 -0
  5. package/esm2020/lib/table/table/state-helpers/pagination-helpers.mjs +174 -0
  6. package/esm2020/lib/table/table/state-helpers/result-helpers.mjs +77 -0
  7. package/esm2020/lib/table/table/state-helpers/search-helpers.mjs +28 -0
  8. package/esm2020/lib/table/table/state-helpers/selection-helpers.mjs +180 -0
  9. package/esm2020/lib/table/table/state.mjs +73 -631
  10. package/esm2020/lib/table/table/table-header-resize-handle/table-header-resize-handle.component.mjs +4 -4
  11. package/fesm2015/rivet-health-design-system.mjs +821 -513
  12. package/fesm2015/rivet-health-design-system.mjs.map +1 -1
  13. package/fesm2020/rivet-health-design-system.mjs +962 -633
  14. package/fesm2020/rivet-health-design-system.mjs.map +1 -1
  15. package/lib/table/table/state-helpers/column-helpers.d.ts +14 -0
  16. package/lib/table/table/state-helpers/display-helpers.d.ts +5 -0
  17. package/lib/table/table/state-helpers/order-helpers.d.ts +12 -0
  18. package/lib/table/table/state-helpers/pagination-helpers.d.ts +13 -0
  19. package/lib/table/table/state-helpers/result-helpers.d.ts +11 -0
  20. package/lib/table/table/state-helpers/search-helpers.d.ts +5 -0
  21. package/lib/table/table/state-helpers/selection-helpers.d.ts +13 -0
  22. package/lib/table/table/state.d.ts +48 -1
  23. package/package.json +1 -1
@@ -5,7 +5,7 @@ import { DOCUMENT, DatePipe as DatePipe$1, DecimalPipe, CurrencyPipe, PercentPip
5
5
  import { BehaviorSubject, Subject, merge, scan, startWith, connectable, map, ReplaySubject, distinctUntilChanged, skip, filter, combineLatest, shareReplay, skipUntil, mergeScan, from, share, fromEvent, tap, switchMap, takeUntil, concatWith, of } from 'rxjs';
6
6
  import { timeYears, timeYear, timeMonths, timeMonth, timeDays, timeDay, timeSunday, timeWeek, utcYear, utcMonth, utcWeek, utcDay } from 'd3-time';
7
7
  import { timeFormat, utcFormat } from 'd3-time-format';
8
- import { defaultsDeep, sortBy, isNumber, flattenDeep, debounce, isEqual, uniqueId, cloneDeep, orderBy, range, toInteger, difference, union, sumBy, sum, uniq } from 'lodash';
8
+ import { defaultsDeep, sortBy, isNumber, flattenDeep, debounce, isEqual, uniqueId, cloneDeep, difference, toInteger, orderBy, range, union, sumBy, sum, uniq } from 'lodash';
9
9
  import Fuse from 'fuse.js';
10
10
  import { query, style, animate, trigger, transition, group } from '@angular/animations';
11
11
  import { map as map$1, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs/operators';
@@ -8263,6 +8263,900 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
8263
8263
  args: ['class.selected']
8264
8264
  }] } });
8265
8265
 
8266
+ var TableColumnHelpers;
8267
+ (function (TableColumnHelpers) {
8268
+ function getColumnAlignment(dataType, isFirst) {
8269
+ if (isFirst)
8270
+ return 'left';
8271
+ switch (dataType) {
8272
+ case 'date':
8273
+ case 'longText':
8274
+ return 'left';
8275
+ case 'advanced':
8276
+ case 'icon':
8277
+ case 'shortText':
8278
+ return 'center';
8279
+ case 'currency':
8280
+ case 'number':
8281
+ return 'right';
8282
+ }
8283
+ }
8284
+ TableColumnHelpers.getColumnAlignment = getColumnAlignment;
8285
+ function getAllColumns(state, supportedColumns, columnNameMap) {
8286
+ // If the table offers more columns than the user has configuration settings
8287
+ // for (or if the user has no configuration settings yet), we'll append them
8288
+ // to the end (unless they should be pinned by default, in which case we'll
8289
+ // append them after the other pinned columns). This ensures that new columns
8290
+ // we add to existing tables over time (1) get displayed even though they
8291
+ // don't appear in the user's configuration settings yet, and (2) don't
8292
+ // interrupt their existing setup.
8293
+ const columnNamesWithoutUserSettings = difference([...supportedColumns.keys()], state.display.columnSettings.map(({ key }) => key));
8294
+ // Throw out settings for columns no longer offered by the table.
8295
+ const columnsWithUserSettings = state.display.columnSettings.filter(({ key }) => supportedColumns.has(key));
8296
+ const columnsWithoutUserSettings = [
8297
+ ...columnNamesWithoutUserSettings,
8298
+ ].map((key) => ({
8299
+ key,
8300
+ enabled: true,
8301
+ preferredWidth: 'auto',
8302
+ pinned: !!supportedColumns.get(key)?.defaultPinned,
8303
+ }));
8304
+ return orderIntentionally([...columnsWithUserSettings, ...columnsWithoutUserSettings], columnNameMap);
8305
+ }
8306
+ TableColumnHelpers.getAllColumns = getAllColumns;
8307
+ function orderIntentionally(columns, columnNameMap) {
8308
+ return [
8309
+ ...columns.filter(v => v.pinned),
8310
+ ...columns.filter(v => v.enabled && !v.pinned),
8311
+ ...columns
8312
+ .filter(v => !v.enabled && !v.pinned)
8313
+ .sort((a, b) => {
8314
+ const aName = columnNameMap.get(a.key) ?? a.key;
8315
+ const bName = columnNameMap.get(b.key) ?? b.key;
8316
+ return aName.localeCompare(bName);
8317
+ }),
8318
+ ];
8319
+ }
8320
+ function getAlignment(metadata, index, allowSelection) {
8321
+ return getColumnAlignment(metadata.dataType, index === 0 && !allowSelection);
8322
+ }
8323
+ function resolveColumns(state, supportedColumns, columnNameMap, allowSelection) {
8324
+ const allColumns = getAllColumns(state, supportedColumns, columnNameMap);
8325
+ return allColumns
8326
+ .filter(({ enabled }) => enabled)
8327
+ .reduce((fullColumns, settings, i) => {
8328
+ const metadata = supportedColumns.get(settings.key);
8329
+ const resolvedWidth = settings.preferredWidth === 'auto'
8330
+ ? metadata.minWidth
8331
+ : Math.max(metadata.minWidth, settings.preferredWidth);
8332
+ const previousColumn = fullColumns[i - 1];
8333
+ return [
8334
+ ...fullColumns,
8335
+ {
8336
+ ...settings,
8337
+ ...metadata,
8338
+ width: resolvedWidth,
8339
+ left: settings.pinned
8340
+ ? previousColumn
8341
+ ? (previousColumn.left || 0) + previousColumn.width
8342
+ : !!allowSelection
8343
+ ? 40
8344
+ : 0
8345
+ : null,
8346
+ alignment: getAlignment(metadata, i, !!allowSelection),
8347
+ },
8348
+ ];
8349
+ }, []);
8350
+ }
8351
+ TableColumnHelpers.resolveColumns = resolveColumns;
8352
+ function changeColumnPin(state, columns, columnNameMap, column, pinned) {
8353
+ const allColumns = getAllColumns(state, columns, columnNameMap);
8354
+ if (pinned) {
8355
+ const target = allColumns.find(c => c.key === column);
8356
+ const wasEnabled = !!target?.enabled;
8357
+ if (!wasEnabled) {
8358
+ const enabledCount = allColumns.filter(col => col.enabled).length;
8359
+ if (enabledCount >= RivTable.ColumnsMaxShown) {
8360
+ return state; // refuse the pin since it would exceed the max
8361
+ }
8362
+ }
8363
+ }
8364
+ return {
8365
+ ...state,
8366
+ display: {
8367
+ ...state.display,
8368
+ columnSettings: orderIntentionally(allColumns.map(c => ({
8369
+ ...c,
8370
+ pinned: c.key === column ? pinned : c.pinned,
8371
+ // Check/enable if being pinned
8372
+ enabled: c.key === column && pinned ? true : c.enabled,
8373
+ })), columnNameMap),
8374
+ },
8375
+ };
8376
+ }
8377
+ TableColumnHelpers.changeColumnPin = changeColumnPin;
8378
+ function changeColumnsFreezeState(state, columns, columnNameMap, index, freeze) {
8379
+ const allColumns = getAllColumns(state, columns, columnNameMap);
8380
+ return {
8381
+ ...state,
8382
+ display: {
8383
+ ...state.display,
8384
+ columnSettings: allColumns.map((c, i) => {
8385
+ return { ...c, pinned: freeze && i <= index };
8386
+ }),
8387
+ },
8388
+ };
8389
+ }
8390
+ TableColumnHelpers.changeColumnsFreezeState = changeColumnsFreezeState;
8391
+ function moveColumnTo(state, columns, columnNameMap, column, position) {
8392
+ const allColumns = getAllColumns(state, columns, columnNameMap);
8393
+ const previousIndex = allColumns.findIndex(c => c.key === column);
8394
+ const lastIndex = position == 'end' ? allColumns.findIndex(c => !c.enabled) : 0;
8395
+ const newIndex = position == 'start'
8396
+ ? 0
8397
+ : lastIndex == -1
8398
+ ? allColumns.length - 1
8399
+ : lastIndex;
8400
+ if (!allColumns[previousIndex].enabled &&
8401
+ allColumns.filter(col => col.enabled).length >= RivTable.ColumnsMaxShown)
8402
+ return state;
8403
+ const movedState = changeColumnOrder(state, columns, columnNameMap, previousIndex, newIndex);
8404
+ //Make sure the column is enabled
8405
+ return changeColumnEnabled(movedState, columns, columnNameMap, column, true);
8406
+ }
8407
+ TableColumnHelpers.moveColumnTo = moveColumnTo;
8408
+ function changeColumnOrder(state, columns, columnNameMap, previousIndex, newIndex) {
8409
+ const allColumns = getAllColumns(state, columns, columnNameMap);
8410
+ // First, put the columns in the desired order.
8411
+ const item = allColumns[previousIndex];
8412
+ const withoutItem = allColumns.filter((_, i) => i !== previousIndex);
8413
+ const reordered = [
8414
+ ...withoutItem.slice(0, newIndex),
8415
+ item,
8416
+ ...withoutItem.slice(newIndex),
8417
+ ];
8418
+ // Then, we may need to fix the pins (all pinned columns appear at the
8419
+ // beginning of the columns array) since the user is allowed to drag
8420
+ // and drop columns to and from the pinned area. If the user drags a
8421
+ // column across that threshold, update its pinned status.
8422
+ const updated = reordered.map((settings, i, arr) => {
8423
+ if (newIndex === i) {
8424
+ return {
8425
+ ...settings,
8426
+ pinned: settings.pinned
8427
+ ? arr[i - 1]?.pinned ?? true
8428
+ : arr[i + 1]?.pinned ?? false,
8429
+ enabled: settings.enabled
8430
+ ? arr[i - 1]?.enabled ?? true
8431
+ : arr[i + 1]?.enabled ?? false,
8432
+ };
8433
+ }
8434
+ else
8435
+ return settings;
8436
+ });
8437
+ const wasDisabled = !item.enabled;
8438
+ const becameEnabled = updated[newIndex].enabled;
8439
+ if (wasDisabled && becameEnabled) {
8440
+ const enabledCount = allColumns.filter(c => c.enabled).length;
8441
+ if (enabledCount >= RivTable.ColumnsMaxShown) {
8442
+ // Refuse the move; keep state as-is
8443
+ return state;
8444
+ }
8445
+ }
8446
+ return {
8447
+ ...state,
8448
+ display: {
8449
+ ...state.display,
8450
+ columnSettings: orderIntentionally(updated, columnNameMap),
8451
+ },
8452
+ };
8453
+ }
8454
+ TableColumnHelpers.changeColumnOrder = changeColumnOrder;
8455
+ function changeColumnEnabled(state, columns, columnNameMap, column, enabled) {
8456
+ const allColumns = getAllColumns(state, columns, columnNameMap);
8457
+ if (enabled &&
8458
+ allColumns.filter(col => col.enabled).length >= RivTable.ColumnsMaxShown) {
8459
+ return state;
8460
+ }
8461
+ return {
8462
+ ...state,
8463
+ display: {
8464
+ ...state.display,
8465
+ columnSettings: orderIntentionally(allColumns.map(c => ({
8466
+ ...c,
8467
+ enabled: c.key === column ? enabled : c.enabled,
8468
+ // Unpin if being unchecked
8469
+ pinned: c.key === column && !enabled ? false : c.pinned,
8470
+ })), columnNameMap),
8471
+ },
8472
+ };
8473
+ }
8474
+ TableColumnHelpers.changeColumnEnabled = changeColumnEnabled;
8475
+ function enableAllColumns(state, columns, columnNameMap, enabled) {
8476
+ const allColumns = getAllColumns(state, columns, columnNameMap);
8477
+ if (enabled && allColumns.length > RivTable.ColumnsMaxShown)
8478
+ return state;
8479
+ return {
8480
+ ...state,
8481
+ display: {
8482
+ ...state.display,
8483
+ columnSettings: orderIntentionally(allColumns.map(c => ({
8484
+ ...c,
8485
+ enabled: enabled,
8486
+ // Unpin if being unchecked
8487
+ pinned: !enabled ? false : c.pinned,
8488
+ })), columnNameMap),
8489
+ },
8490
+ };
8491
+ }
8492
+ TableColumnHelpers.enableAllColumns = enableAllColumns;
8493
+ function changeColumnWidth(state, columns, columnNameMap, column, preferredWidth) {
8494
+ const allColumns = getAllColumns(state, columns, columnNameMap);
8495
+ return {
8496
+ ...state,
8497
+ display: {
8498
+ ...state.display,
8499
+ columnSettings: allColumns.map(c => ({
8500
+ ...c,
8501
+ preferredWidth: c.key === column ? preferredWidth : c.preferredWidth,
8502
+ })),
8503
+ },
8504
+ };
8505
+ }
8506
+ TableColumnHelpers.changeColumnWidth = changeColumnWidth;
8507
+ function resetToDefaultColumns(state, columns, columnNameMap, defaultColumnState) {
8508
+ return {
8509
+ ...state,
8510
+ display: {
8511
+ ...state.display,
8512
+ columnSettings: orderIntentionally(defaultColumnState, columnNameMap),
8513
+ },
8514
+ };
8515
+ }
8516
+ TableColumnHelpers.resetToDefaultColumns = resetToDefaultColumns;
8517
+ })(TableColumnHelpers || (TableColumnHelpers = {}));
8518
+
8519
+ var TableResultHelpers;
8520
+ (function (TableResultHelpers) {
8521
+ function isRegularResult(result) {
8522
+ if ('currentPageData' in result) {
8523
+ return true;
8524
+ }
8525
+ return false;
8526
+ }
8527
+ TableResultHelpers.isRegularResult = isRegularResult;
8528
+ function isGroupResult(result) {
8529
+ if ('totalGroupCount' in result) {
8530
+ return true;
8531
+ }
8532
+ return false;
8533
+ }
8534
+ TableResultHelpers.isGroupResult = isGroupResult;
8535
+ function isNestedResult(result) {
8536
+ if ('currentPageNestedRows' in result) {
8537
+ return true;
8538
+ }
8539
+ return false;
8540
+ }
8541
+ TableResultHelpers.isNestedResult = isNestedResult;
8542
+ function isNestedWithHeaderResult(result) {
8543
+ if ('currentPageNestedHeaders' in result) {
8544
+ return true;
8545
+ }
8546
+ return false;
8547
+ }
8548
+ TableResultHelpers.isNestedWithHeaderResult = isNestedWithHeaderResult;
8549
+ function getAllRowsFromResult(result) {
8550
+ if (isGroupResult(result)) {
8551
+ return result.groupResults.flatMap(groups => groups.currentPageData);
8552
+ }
8553
+ else if (isNestedResult(result)) {
8554
+ return getAllRowsFromNestedRows(result.currentPageNestedRows);
8555
+ }
8556
+ else if (isNestedWithHeaderResult(result)) {
8557
+ return getAllRowsFromNestedHeaders(result.currentPageNestedHeaders);
8558
+ }
8559
+ else {
8560
+ return result.currentPageData;
8561
+ }
8562
+ }
8563
+ TableResultHelpers.getAllRowsFromResult = getAllRowsFromResult;
8564
+ function getAllRowsFromNestedRows(nestedRows) {
8565
+ const allRows = [];
8566
+ function recursiveGetNestedRows(currentNestedRow) {
8567
+ allRows.push(currentNestedRow.data);
8568
+ const subRows = currentNestedRow.subRows ?? [];
8569
+ for (const subRow of subRows) {
8570
+ recursiveGetNestedRows(subRow);
8571
+ }
8572
+ }
8573
+ for (const nestedRow of nestedRows) {
8574
+ recursiveGetNestedRows(nestedRow);
8575
+ }
8576
+ return allRows;
8577
+ }
8578
+ TableResultHelpers.getAllRowsFromNestedRows = getAllRowsFromNestedRows;
8579
+ function getAllRowsFromNestedHeaders(nestedHeaders) {
8580
+ const allRows = [];
8581
+ for (const outerNestedHeaderRow of nestedHeaders) {
8582
+ const rowsInHeader = getAllRowsFromNestedRows(outerNestedHeaderRow.subRows);
8583
+ for (const rowInHeader of rowsInHeader) {
8584
+ allRows.push(rowInHeader);
8585
+ }
8586
+ }
8587
+ return allRows;
8588
+ }
8589
+ TableResultHelpers.getAllRowsFromNestedHeaders = getAllRowsFromNestedHeaders;
8590
+ function getCsvFilename(pluralEntityName, options) {
8591
+ return ((options?.csvFileBasename?.slice(0, 200) ?? pluralEntityName) + '.csv');
8592
+ }
8593
+ TableResultHelpers.getCsvFilename = getCsvFilename;
8594
+ })(TableResultHelpers || (TableResultHelpers = {}));
8595
+
8596
+ var TableSearchHelpers;
8597
+ (function (TableSearchHelpers) {
8598
+ function getSearchColumnsSelectedState(state, expectedValue) {
8599
+ switch (expectedValue) {
8600
+ case 'all':
8601
+ return Array.from(state.query.searchColumns.values()).every(value => value);
8602
+ case 'none':
8603
+ return Array.from(state.query.searchColumns.values()).every(value => !value);
8604
+ }
8605
+ }
8606
+ TableSearchHelpers.getSearchColumnsSelectedState = getSearchColumnsSelectedState;
8607
+ function toggleAllSearchColumns(state) {
8608
+ const noneSelected = getSearchColumnsSelectedState(state, 'none');
8609
+ const payload = new Map(Array.from(state.query.searchColumns.keys()).map(key => [
8610
+ key,
8611
+ noneSelected,
8612
+ ]));
8613
+ return {
8614
+ ...state,
8615
+ query: {
8616
+ ...state.query,
8617
+ searchColumns: payload,
8618
+ },
8619
+ };
8620
+ }
8621
+ TableSearchHelpers.toggleAllSearchColumns = toggleAllSearchColumns;
8622
+ })(TableSearchHelpers || (TableSearchHelpers = {}));
8623
+
8624
+ var TableDisplayHelpers;
8625
+ (function (TableDisplayHelpers) {
8626
+ function getZeroStateMessage(state, entity) {
8627
+ if ((TableResultHelpers.isGroupResult(state.result) &&
8628
+ state.result.totalGroupCount > 0) ||
8629
+ (!TableResultHelpers.isGroupResult(state.result) &&
8630
+ state.result.totalMatchingRowCount > 0))
8631
+ return null;
8632
+ const allSearchColumnsSelected = TableSearchHelpers.getSearchColumnsSelectedState(state, 'all');
8633
+ if (state.query.search && allSearchColumnsSelected)
8634
+ return `No ${entity} match your current search keyword.`;
8635
+ if (state.query.search && !allSearchColumnsSelected)
8636
+ return `No ${entity} match your current search keyword in the selected search columns.`;
8637
+ if (state.query.filters)
8638
+ return `No ${entity} match your current filters.`;
8639
+ return `No ${entity}.`;
8640
+ }
8641
+ TableDisplayHelpers.getZeroStateMessage = getZeroStateMessage;
8642
+ function memoizedCellRowSpan(s, fullColumns, options) {
8643
+ const getRowSpanForCell = options?.getRowSpanForCell;
8644
+ const result = s.result;
8645
+ // If the dataset exceeds the current page size, skip span calculations.
8646
+ if (s.result.totalMatchingRowCount > s.query.pagination.pageSize)
8647
+ return null;
8648
+ // If the user hasn't provided the row span configuration, default to no spanning
8649
+ if (!getRowSpanForCell)
8650
+ return null;
8651
+ // Row spanning is not supported on grouped tables.
8652
+ if (TableResultHelpers.isGroupResult(result))
8653
+ return null;
8654
+ // Memoize the user's configuration for the current page.
8655
+ return new Map(fullColumns.map(column => [
8656
+ column.key,
8657
+ result.currentPageData.map((_, i) => {
8658
+ const raw = getRowSpanForCell(i, column.key);
8659
+ if (raw === 0)
8660
+ return 0;
8661
+ else
8662
+ return Math.max(1, toInteger(raw));
8663
+ }),
8664
+ ]));
8665
+ }
8666
+ TableDisplayHelpers.memoizedCellRowSpan = memoizedCellRowSpan;
8667
+ })(TableDisplayHelpers || (TableDisplayHelpers = {}));
8668
+
8669
+ var TableOrderHelpers;
8670
+ (function (TableOrderHelpers) {
8671
+ function orderEmptyLast(rows, key, direction) {
8672
+ return orderBy(rows, [row => row[key] == null, key], ['asc', direction]);
8673
+ }
8674
+ TableOrderHelpers.orderEmptyLast = orderEmptyLast;
8675
+ function orderNestedRowsEmptyLast(rows, key, direction) {
8676
+ return orderBy(rows, [row => row.data[key] == null, row => row.data[key]], ['asc', direction]);
8677
+ }
8678
+ TableOrderHelpers.orderNestedRowsEmptyLast = orderNestedRowsEmptyLast;
8679
+ function orderNestedRowsBySearchMatch(rows, idToSearchIndexMap) {
8680
+ return orderBy(rows, [row => idToSearchIndexMap.get(row.data.id)], ['asc']);
8681
+ }
8682
+ TableOrderHelpers.orderNestedRowsBySearchMatch = orderNestedRowsBySearchMatch;
8683
+ function toggleColumnOrder(state, column) {
8684
+ if (state.query.order?.column === column) {
8685
+ return {
8686
+ ...state,
8687
+ query: {
8688
+ ...state.query,
8689
+ order: state.query.order.direction === 'asc'
8690
+ ? {
8691
+ column,
8692
+ direction: 'desc',
8693
+ }
8694
+ : null,
8695
+ },
8696
+ };
8697
+ }
8698
+ return {
8699
+ ...state,
8700
+ query: {
8701
+ ...state.query,
8702
+ order: {
8703
+ column,
8704
+ direction: 'asc',
8705
+ },
8706
+ },
8707
+ };
8708
+ }
8709
+ TableOrderHelpers.toggleColumnOrder = toggleColumnOrder;
8710
+ /*
8711
+ We only sort the lowest level rows if rows are nested.
8712
+
8713
+ In other words, we sort within each nested group, but do
8714
+ NOT sort in relation to the other groups.
8715
+ */
8716
+ function sortLowLevelNestedRows(allRows, sortKey, direction) {
8717
+ function recursiveSortRows(nestedRows) {
8718
+ const hasDeeperNesting = nestedRows.some(row => row.subRows && row.subRows.length > 0);
8719
+ if (!hasDeeperNesting) {
8720
+ const sortedRows = orderNestedRowsEmptyLast(nestedRows, sortKey, direction);
8721
+ return sortedRows;
8722
+ }
8723
+ else {
8724
+ // If there is a deeper nesting, keep recursing
8725
+ const sortedRows = [];
8726
+ for (const currentNestedRow of nestedRows) {
8727
+ if (currentNestedRow.subRows && currentNestedRow.subRows.length > 0) {
8728
+ const sortedSubRows = recursiveSortRows(currentNestedRow.subRows);
8729
+ sortedRows.push({
8730
+ ...currentNestedRow,
8731
+ subRows: sortedSubRows,
8732
+ });
8733
+ }
8734
+ else {
8735
+ sortedRows.push(currentNestedRow);
8736
+ }
8737
+ }
8738
+ return sortedRows;
8739
+ }
8740
+ }
8741
+ return recursiveSortRows(allRows);
8742
+ }
8743
+ TableOrderHelpers.sortLowLevelNestedRows = sortLowLevelNestedRows;
8744
+ // Sort the data inside the headers, not the headers themselves
8745
+ function sortLowLevelNestedRowsWithHeaders(allHeaders, sortKey, direction) {
8746
+ const sortedHeaderRows = [];
8747
+ for (const headerRow of allHeaders) {
8748
+ const sortedSubRows = sortLowLevelNestedRows(headerRow.subRows, sortKey, direction);
8749
+ sortedHeaderRows.push({
8750
+ ...headerRow,
8751
+ subRows: sortedSubRows,
8752
+ });
8753
+ }
8754
+ return sortedHeaderRows;
8755
+ }
8756
+ TableOrderHelpers.sortLowLevelNestedRowsWithHeaders = sortLowLevelNestedRowsWithHeaders;
8757
+ // Create map to help us sort on Fuse relevance order
8758
+ function createIdToSearchIndexMap(rowsMatchingSearch) {
8759
+ const idToSearchIndexMap = new Map();
8760
+ for (let i = 0; i < rowsMatchingSearch.length; i++) {
8761
+ const rowMatchingIndex = rowsMatchingSearch[i];
8762
+ idToSearchIndexMap.set(rowMatchingIndex.id, i);
8763
+ }
8764
+ return idToSearchIndexMap;
8765
+ }
8766
+ TableOrderHelpers.createIdToSearchIndexMap = createIdToSearchIndexMap;
8767
+ // Sort based on how well the rows match a search
8768
+ function sortNestedRowsBasedOnSearchMatches(allRows, idToSearchIndexMap) {
8769
+ function recursiveSortRowsBySearchMatch(nestedRows) {
8770
+ const hasDeeperNesting = nestedRows.some(row => row.subRows && row.subRows.length > 0);
8771
+ if (!hasDeeperNesting) {
8772
+ const sortedRows = orderNestedRowsBySearchMatch(nestedRows, idToSearchIndexMap);
8773
+ return sortedRows;
8774
+ }
8775
+ else {
8776
+ // If there is a deeper nesting, keep recursing
8777
+ const sortedRows = [];
8778
+ for (const currentNestedRow of nestedRows) {
8779
+ if (currentNestedRow.subRows && currentNestedRow.subRows.length > 0) {
8780
+ const sortedSubRows = recursiveSortRowsBySearchMatch(currentNestedRow.subRows);
8781
+ sortedRows.push({
8782
+ ...currentNestedRow,
8783
+ subRows: sortedSubRows,
8784
+ });
8785
+ }
8786
+ else {
8787
+ sortedRows.push(currentNestedRow);
8788
+ }
8789
+ }
8790
+ return sortedRows;
8791
+ }
8792
+ }
8793
+ return recursiveSortRowsBySearchMatch(allRows);
8794
+ }
8795
+ TableOrderHelpers.sortNestedRowsBasedOnSearchMatches = sortNestedRowsBasedOnSearchMatches;
8796
+ // Sort based on how well the rows match a search
8797
+ function sortNestedRowsWithHeadersBasedOnSearchMatches(allHeaders, idToSearchIndexMap) {
8798
+ const sortedHeaderRows = [];
8799
+ for (const headerRow of allHeaders) {
8800
+ const sortedSubRows = sortNestedRowsBasedOnSearchMatches(headerRow.subRows, idToSearchIndexMap);
8801
+ sortedHeaderRows.push({
8802
+ ...headerRow,
8803
+ subRows: sortedSubRows,
8804
+ });
8805
+ }
8806
+ return sortedHeaderRows;
8807
+ }
8808
+ TableOrderHelpers.sortNestedRowsWithHeadersBasedOnSearchMatches = sortNestedRowsWithHeadersBasedOnSearchMatches;
8809
+ })(TableOrderHelpers || (TableOrderHelpers = {}));
8810
+
8811
+ var TablePaginationHelpers;
8812
+ (function (TablePaginationHelpers) {
8813
+ function getPageCount(state) {
8814
+ if (TableResultHelpers.isGroupResult(state.result)) {
8815
+ return Math.max(Math.ceil(state.result.totalGroupCount / state.query.grouping.groupsPerPage), 1);
8816
+ }
8817
+ return Math.max(Math.ceil(state.result.totalMatchingRowCount / state.query.pagination.pageSize), 1);
8818
+ }
8819
+ TablePaginationHelpers.getPageCount = getPageCount;
8820
+ function getPreviousPage(state) {
8821
+ return state.query.pagination.page === 0
8822
+ ? null
8823
+ : state.query.pagination.page - 1;
8824
+ }
8825
+ TablePaginationHelpers.getPreviousPage = getPreviousPage;
8826
+ function getPages(state) {
8827
+ const padding = 4;
8828
+ const min = 0;
8829
+ const max = getPageCount(state) - 1;
8830
+ const desiredStart = state.query.pagination.page - padding;
8831
+ const clampedStart = Math.max(min, desiredStart);
8832
+ const desiredEnd = state.query.pagination.page + padding;
8833
+ const clampedEnd = Math.min(max, desiredEnd);
8834
+ const start = Math.max(min, clampedStart - (desiredEnd - clampedEnd));
8835
+ const end = Math.min(max, clampedEnd + (clampedStart - desiredStart));
8836
+ return range(start, end + 1);
8837
+ }
8838
+ TablePaginationHelpers.getPages = getPages;
8839
+ function getNextPage(state) {
8840
+ const max = getPageCount(state) - 1;
8841
+ const next = state.query.pagination.page + 1;
8842
+ return next <= max ? next : null;
8843
+ }
8844
+ TablePaginationHelpers.getNextPage = getNextPage;
8845
+ // We don't want to show the pagination controls when they are unnecessary.
8846
+ function getShowPaginationControls(state) {
8847
+ if (state.query.pagination.page > 0) {
8848
+ return true;
8849
+ }
8850
+ if (TableResultHelpers.isGroupResult(state.result)) {
8851
+ return state.result.totalGroupCount > state.query.grouping.groupsPerPage;
8852
+ }
8853
+ return (state.result.totalMatchingRowCount > Math.min(...[...RivTable.pageSizes]));
8854
+ }
8855
+ TablePaginationHelpers.getShowPaginationControls = getShowPaginationControls;
8856
+ function getPageRowStart(state) {
8857
+ return state.query.pagination.page * state.query.pagination.pageSize + 1;
8858
+ }
8859
+ TablePaginationHelpers.getPageRowStart = getPageRowStart;
8860
+ function getPageRowEnd(state) {
8861
+ return Math.min((state.query.pagination.page + 1) * state.query.pagination.pageSize, state.result.totalMatchingRowCount);
8862
+ }
8863
+ TablePaginationHelpers.getPageRowEnd = getPageRowEnd;
8864
+ function isPageOutOfBounds(state, result) {
8865
+ if (TableResultHelpers.isGroupResult(result)) {
8866
+ const minGroupValToShowOnCurrentPage = state.query.pagination.page * state.query.grouping.groupsPerPage + 1;
8867
+ if (result.totalGroupCount < minGroupValToShowOnCurrentPage) {
8868
+ return true;
8869
+ }
8870
+ }
8871
+ else {
8872
+ const minRowToShowOnCurrentPage = state.query.pagination.page * state.query.pagination.pageSize + 1;
8873
+ if (result.totalMatchingRowCount < minRowToShowOnCurrentPage) {
8874
+ return true;
8875
+ }
8876
+ }
8877
+ return false;
8878
+ }
8879
+ TablePaginationHelpers.isPageOutOfBounds = isPageOutOfBounds;
8880
+ // Paginate based on bottom level rows, splitting as necessary to fit within the page
8881
+ function paginateNestedRows(allNestedRows, pageNumber, pageSize) {
8882
+ const startIdx = pageSize * pageNumber;
8883
+ const endIdx = startIdx + pageSize;
8884
+ let bottomLevelRowCount = 0;
8885
+ function recursivePaginateRows(currentNestedRow) {
8886
+ // If there are no subrows, stop recursing
8887
+ if (!currentNestedRow.subRows) {
8888
+ bottomLevelRowCount++;
8889
+ // Since we add 1 first, the bounds should be (startIdx, endIdx]
8890
+ if (bottomLevelRowCount > startIdx && bottomLevelRowCount <= endIdx) {
8891
+ return currentNestedRow;
8892
+ }
8893
+ return null;
8894
+ }
8895
+ else {
8896
+ const subRowsToKeep = [];
8897
+ for (const subRow of currentNestedRow.subRows) {
8898
+ const countedRow = recursivePaginateRows(subRow);
8899
+ if (countedRow != null) {
8900
+ subRowsToKeep.push(countedRow);
8901
+ }
8902
+ }
8903
+ if (subRowsToKeep.length == 0) {
8904
+ return null;
8905
+ }
8906
+ else {
8907
+ // Keep any top level row that has at least one subrow
8908
+ return {
8909
+ ...currentNestedRow,
8910
+ subRows: subRowsToKeep,
8911
+ };
8912
+ }
8913
+ }
8914
+ }
8915
+ const paginatedRows = [];
8916
+ for (const nestedRow of allNestedRows) {
8917
+ const recursedRow = recursivePaginateRows(nestedRow);
8918
+ if (recursedRow != null) {
8919
+ paginatedRows.push(recursedRow);
8920
+ }
8921
+ }
8922
+ return paginatedRows;
8923
+ }
8924
+ TablePaginationHelpers.paginateNestedRows = paginateNestedRows;
8925
+ // Paginate based on bottom level rows, splitting as necessary to fit within the page
8926
+ function paginateNestedHeaderRows(allHeaders, pageNumber, pageSize) {
8927
+ const startIdx = pageSize * pageNumber;
8928
+ const endIdx = startIdx + pageSize;
8929
+ let bottomLevelRowCount = 0;
8930
+ function recursivePaginateRows(currentNestedRow) {
8931
+ // If there are no subrows, stop recursing
8932
+ if (!currentNestedRow.subRows) {
8933
+ bottomLevelRowCount++;
8934
+ // Since we add 1 first, the bounds should be (startIdx, endIdx]
8935
+ if (bottomLevelRowCount > startIdx && bottomLevelRowCount <= endIdx) {
8936
+ return currentNestedRow;
8937
+ }
8938
+ return null;
8939
+ }
8940
+ else {
8941
+ const subRowsToKeep = [];
8942
+ for (const subRow of currentNestedRow.subRows) {
8943
+ const countedRow = recursivePaginateRows(subRow);
8944
+ if (countedRow != null) {
8945
+ subRowsToKeep.push(countedRow);
8946
+ }
8947
+ }
8948
+ if (subRowsToKeep.length == 0) {
8949
+ return null;
8950
+ }
8951
+ else {
8952
+ // Keep any top level row that has at least one subrow
8953
+ return {
8954
+ ...currentNestedRow,
8955
+ subRows: subRowsToKeep,
8956
+ };
8957
+ }
8958
+ }
8959
+ }
8960
+ const paginatedHeaders = [];
8961
+ for (const headerRow of allHeaders) {
8962
+ const paginatedSubRows = [];
8963
+ for (const subRow of headerRow.subRows) {
8964
+ const recursedSubRow = recursivePaginateRows(subRow);
8965
+ if (recursedSubRow != null) {
8966
+ paginatedSubRows.push(recursedSubRow);
8967
+ }
8968
+ }
8969
+ if (paginatedSubRows.length > 0) {
8970
+ // Keep any header that has at least one subrow in the current page
8971
+ paginatedHeaders.push({
8972
+ ...headerRow,
8973
+ subRows: paginatedSubRows,
8974
+ });
8975
+ }
8976
+ }
8977
+ return paginatedHeaders;
8978
+ }
8979
+ TablePaginationHelpers.paginateNestedHeaderRows = paginateNestedHeaderRows;
8980
+ })(TablePaginationHelpers || (TablePaginationHelpers = {}));
8981
+
8982
+ var TableSelectionHelpers;
8983
+ (function (TableSelectionHelpers) {
8984
+ function isRowSelected(state, id) {
8985
+ switch (state.selection.mode) {
8986
+ case 'include':
8987
+ return state.selection.included.has(id);
8988
+ case 'exclude':
8989
+ return !state.selection.excluded.has(id);
8990
+ }
8991
+ }
8992
+ TableSelectionHelpers.isRowSelected = isRowSelected;
8993
+ function isGroupSelected(state, group) {
8994
+ switch (state.selection.mode) {
8995
+ case 'include': {
8996
+ let allFound = true;
8997
+ let anyFound = false;
8998
+ for (const row of group.currentPageData) {
8999
+ if (!state.selection.included.has(row.id)) {
9000
+ allFound = false;
9001
+ }
9002
+ else {
9003
+ anyFound = true;
9004
+ }
9005
+ }
9006
+ return allFound ? true : anyFound ? 'indeterminate' : false;
9007
+ }
9008
+ case 'exclude': {
9009
+ let allFound = true;
9010
+ let anyFound = false;
9011
+ for (const row of group.currentPageData) {
9012
+ if (state.selection.excluded.has(row.id)) {
9013
+ allFound = false;
9014
+ }
9015
+ else {
9016
+ anyFound = true;
9017
+ }
9018
+ }
9019
+ return allFound ? true : anyFound ? 'indeterminate' : false;
9020
+ }
9021
+ }
9022
+ }
9023
+ TableSelectionHelpers.isGroupSelected = isGroupSelected;
9024
+ function isAllSelected(state) {
9025
+ // If there are no rows, "all selected" should be false
9026
+ if (state.result.totalMatchingRowCount === 0) {
9027
+ return false;
9028
+ }
9029
+ if ((state.selection.mode === 'exclude' &&
9030
+ state.selection.excluded.size === 0) ||
9031
+ (state.selection.mode === 'include' &&
9032
+ state.selection.included.size === state.result.totalMatchingRowCount))
9033
+ return true;
9034
+ if ((state.selection.mode === 'exclude' &&
9035
+ state.selection.excluded.size === state.result.totalMatchingRowCount) ||
9036
+ (state.selection.mode === 'include' &&
9037
+ state.selection.included.size === 0))
9038
+ return false;
9039
+ return 'indeterminate';
9040
+ }
9041
+ TableSelectionHelpers.isAllSelected = isAllSelected;
9042
+ function isCurrentPageSelected(state) {
9043
+ const selectedStates = TableResultHelpers.getAllRowsFromResult(state.result).map(({ id }) => isRowSelected(state, id));
9044
+ if (selectedStates.length > 0) {
9045
+ if (selectedStates.every(v => v))
9046
+ return true;
9047
+ if (selectedStates.some(v => v))
9048
+ return 'indeterminate';
9049
+ }
9050
+ return false;
9051
+ }
9052
+ TableSelectionHelpers.isCurrentPageSelected = isCurrentPageSelected;
9053
+ function selectedCount(state) {
9054
+ switch (state.selection.mode) {
9055
+ case 'include':
9056
+ return state.selection.included.size;
9057
+ case 'exclude':
9058
+ return (state.result.totalMatchingRowCount - state.selection.excluded.size);
9059
+ }
9060
+ }
9061
+ TableSelectionHelpers.selectedCount = selectedCount;
9062
+ function setRowSelected(state, id, selected, contiguous) {
9063
+ if (selected) {
9064
+ const newSelection = new Set([id]);
9065
+ if (contiguous && state.selection.mostRecentlySelected) {
9066
+ const startIdx = TableResultHelpers.getAllRowsFromResult(state.result).findIndex(row => row.id === state.selection.mostRecentlySelected);
9067
+ const endIdx = TableResultHelpers.getAllRowsFromResult(state.result).findIndex(row => row.id === id);
9068
+ if (typeof startIdx === 'number' && typeof endIdx === 'number') {
9069
+ for (let i = Math.min(startIdx, endIdx); i <= Math.max(startIdx, endIdx); i++) {
9070
+ newSelection.add(TableResultHelpers.getAllRowsFromResult(state.result)[i].id);
9071
+ }
9072
+ }
9073
+ }
9074
+ return {
9075
+ ...state,
9076
+ selection: {
9077
+ mostRecentlySelected: id,
9078
+ ...(state.selection.mode === 'include'
9079
+ ? {
9080
+ mode: 'include',
9081
+ included: new Set(union([...state.selection.included], [...newSelection])),
9082
+ }
9083
+ : {
9084
+ mode: 'exclude',
9085
+ excluded: new Set(difference([...state.selection.excluded], [...newSelection])),
9086
+ }),
9087
+ },
9088
+ };
9089
+ }
9090
+ else {
9091
+ return {
9092
+ ...state,
9093
+ selection: {
9094
+ mostRecentlySelected: null,
9095
+ ...(state.selection.mode === 'include'
9096
+ ? {
9097
+ mode: 'include',
9098
+ included: new Set(difference([...state.selection.included], [id])),
9099
+ }
9100
+ : {
9101
+ mode: 'exclude',
9102
+ excluded: new Set(union([...state.selection.excluded], [id])),
9103
+ }),
9104
+ },
9105
+ };
9106
+ }
9107
+ }
9108
+ TableSelectionHelpers.setRowSelected = setRowSelected;
9109
+ function toggleGroupSelected(state, group) {
9110
+ const isGroupFullySelected = isGroupSelected(state, { ...group, currentPageData: group.rows }) ===
9111
+ true;
9112
+ return group.rows.reduce((accumulatedState, row) => {
9113
+ return setRowSelected(accumulatedState, row.id, !isGroupFullySelected, false);
9114
+ }, state);
9115
+ }
9116
+ TableSelectionHelpers.toggleGroupSelected = toggleGroupSelected;
9117
+ function togglePageSelected(state) {
9118
+ const isPageFullySelected = TableResultHelpers.getAllRowsFromResult(state.result).every(({ id }) => isRowSelected(state, id));
9119
+ return TableResultHelpers.getAllRowsFromResult(state.result).reduce((accumulatedState, row) => {
9120
+ return setRowSelected(accumulatedState, row.id, !isPageFullySelected, false);
9121
+ }, state);
9122
+ }
9123
+ TableSelectionHelpers.togglePageSelected = togglePageSelected;
9124
+ function toggleAllSelected(state) {
9125
+ if (isAllSelected(state) === true) {
9126
+ return {
9127
+ ...state,
9128
+ selection: {
9129
+ mostRecentlySelected: null,
9130
+ mode: 'include',
9131
+ included: new Set(),
9132
+ },
9133
+ };
9134
+ }
9135
+ else {
9136
+ return {
9137
+ ...state,
9138
+ selection: {
9139
+ mostRecentlySelected: null,
9140
+ mode: 'exclude',
9141
+ excluded: new Set(),
9142
+ },
9143
+ };
9144
+ }
9145
+ }
9146
+ TableSelectionHelpers.toggleAllSelected = toggleAllSelected;
9147
+ function clearSelection(state) {
9148
+ return {
9149
+ ...state,
9150
+ selection: {
9151
+ mostRecentlySelected: null,
9152
+ mode: 'include',
9153
+ included: new Set(),
9154
+ },
9155
+ };
9156
+ }
9157
+ TableSelectionHelpers.clearSelection = clearSelection;
9158
+ })(TableSelectionHelpers || (TableSelectionHelpers = {}));
9159
+
8266
9160
  var RivTable;
8267
9161
  (function (RivTable) {
8268
9162
  RivTable.pageSizes = [25, 50, 100, 250];
@@ -8334,8 +9228,8 @@ var RivTable;
8334
9228
  const csvExportAllowed = !(options?.getRowSpanForCell || options?.customSummaryRow);
8335
9229
  // Augment state with derived state, and subscribe.
8336
9230
  const state = connectable(coreState.pipe(map(({ state: s }) => {
8337
- const resolvedColumns = resolveColumns(s, columns, columnNameMap, !!options?.allowSelection);
8338
- if (isGroupResult(s.result)) {
9231
+ const resolvedColumns = TableColumnHelpers.resolveColumns(s, columns, columnNameMap, !!options?.allowSelection);
9232
+ if (TableResultHelpers.isGroupResult(s.result)) {
8339
9233
  if (options?.getRowSpanForCell) {
8340
9234
  // eslint-disable-next-line no-console
8341
9235
  console.warn('Heads up! Custom row spans are not supported for grouped tables.');
@@ -8350,9 +9244,9 @@ var RivTable;
8350
9244
  rowLink: options?.rowLink
8351
9245
  ? options.rowLink(row, group.groupData)
8352
9246
  : null,
8353
- selected: isRowSelected(s, row.id),
9247
+ selected: TableSelectionHelpers.isRowSelected(s, row.id),
8354
9248
  })),
8355
- selected: isGroupSelected(s, group),
9249
+ selected: TableSelectionHelpers.isGroupSelected(s, group),
8356
9250
  totalMatchingRowCount: group.totalMatchingRowCount,
8357
9251
  groupData: group.groupData,
8358
9252
  }));
@@ -8369,9 +9263,9 @@ var RivTable;
8369
9263
  pageSize: s.result.totalMatchingRowCount,
8370
9264
  },
8371
9265
  }, { type: 'load' });
8372
- if (!isGroupResult(dataSet))
9266
+ if (!TableResultHelpers.isGroupResult(dataSet))
8373
9267
  throw new Error('Returned non-grouped CSV data for grouped table');
8374
- const fullColumns = resolveColumns(s, columns, columnNameMap, !!options.allowSelection);
9268
+ const fullColumns = TableColumnHelpers.resolveColumns(s, columns, columnNameMap, !!options.allowSelection);
8375
9269
  const data = [];
8376
9270
  data.push(fullColumns.map(({ key }) => columnNameMap.get(key) ?? key));
8377
9271
  if (groupCellFormatter) {
@@ -8382,7 +9276,8 @@ var RivTable;
8382
9276
  group: groups.groupData,
8383
9277
  })))) {
8384
9278
  const record = rowItem.row;
8385
- if (mode === 'selection' && !isRowSelected(s, record.id))
9279
+ if (mode === 'selection' &&
9280
+ !TableSelectionHelpers.isRowSelected(s, record.id))
8386
9281
  continue;
8387
9282
  const row = [];
8388
9283
  for (const column of fullColumns) {
@@ -8401,23 +9296,23 @@ var RivTable;
8401
9296
  ...s.query,
8402
9297
  pagination: {
8403
9298
  ...s.query.pagination,
8404
- previous: getPreviousPage(s),
8405
- pages: getPages(s),
8406
- next: getNextPage(s),
8407
- pageCount: getPageCount(s),
8408
- showControls: getShowPaginationControls(s),
8409
- pageRowStart: getPageRowStart(s),
8410
- pageRowEnd: getPageRowEnd(s),
9299
+ previous: TablePaginationHelpers.getPreviousPage(s),
9300
+ pages: TablePaginationHelpers.getPages(s),
9301
+ next: TablePaginationHelpers.getNextPage(s),
9302
+ pageCount: TablePaginationHelpers.getPageCount(s),
9303
+ showControls: TablePaginationHelpers.getShowPaginationControls(s),
9304
+ pageRowStart: TablePaginationHelpers.getPageRowStart(s),
9305
+ pageRowEnd: TablePaginationHelpers.getPageRowEnd(s),
8411
9306
  },
8412
- noSearchColumnsSelected: getSearchColumnsSelectedState(s, 'none'),
9307
+ noSearchColumnsSelected: TableSearchHelpers.getSearchColumnsSelectedState(s, 'none'),
8413
9308
  },
8414
9309
  display: {
8415
9310
  ...s.display,
8416
9311
  columns: resolvedColumns,
8417
- allColumns: getAllColumns(s, columns, columnNameMap),
9312
+ allColumns: TableColumnHelpers.getAllColumns(s, columns, columnNameMap),
8418
9313
  columnNameMap: columnNameMap,
8419
9314
  searchableColumnMap: searchableColumnMap,
8420
- zeroStateMessage: getZeroStateMessage(s, pluralEntityName),
9315
+ zeroStateMessage: TableDisplayHelpers.getZeroStateMessage(s, pluralEntityName),
8421
9316
  columnsAreFreezable: !!options?.columnsAreFreezable,
8422
9317
  columnsAreHideable: !!options?.columnsAreHideable,
8423
9318
  columnsAreReorderable: options?.columnsAreReorderable ?? true,
@@ -8432,9 +9327,9 @@ var RivTable;
8432
9327
  selection: {
8433
9328
  ...s.selection,
8434
9329
  allowSelection: options?.allowSelection ?? false,
8435
- isAllSelected: isAllSelected(s),
8436
- isCurrentPageSelected: isCurrentPageSelected(s),
8437
- selectedCount: selectedCount(s),
9330
+ isAllSelected: TableSelectionHelpers.isAllSelected(s),
9331
+ isCurrentPageSelected: TableSelectionHelpers.isCurrentPageSelected(s),
9332
+ selectedCount: TableSelectionHelpers.selectedCount(s),
8438
9333
  },
8439
9334
  result: {
8440
9335
  ...s.result,
@@ -8442,7 +9337,7 @@ var RivTable;
8442
9337
  rowGroups,
8443
9338
  rows: rowGroups.flatMap(group => group.rows),
8444
9339
  csvData,
8445
- csvFilename: getCsvFilename(pluralEntityName, options),
9340
+ csvFilename: TableResultHelpers.getCsvFilename(pluralEntityName, options),
8446
9341
  },
8447
9342
  };
8448
9343
  }
@@ -8450,9 +9345,9 @@ var RivTable;
8450
9345
  const rows = s.result.currentPageData.map(row => ({
8451
9346
  ...row,
8452
9347
  rowLink: options?.rowLink ? options.rowLink(row) : null,
8453
- selected: isRowSelected(s, row.id),
9348
+ selected: TableSelectionHelpers.isRowSelected(s, row.id),
8454
9349
  }));
8455
- const cellRowSpanCache = memoizedCellRowSpan(s, resolvedColumns, options);
9350
+ const cellRowSpanCache = TableDisplayHelpers.memoizedCellRowSpan(s, resolvedColumns, options);
8456
9351
  const cellRowSpan = (rowIndex, column) => cellRowSpanCache?.get(column)?.[rowIndex] ?? 1;
8457
9352
  const hasAnyRowSpans = cellRowSpanCache
8458
9353
  ? [...cellRowSpanCache.values()].some(spans => spans.some(span => span > 1))
@@ -8473,13 +9368,14 @@ var RivTable;
8473
9368
  pageSize: s.result.totalMatchingRowCount,
8474
9369
  },
8475
9370
  }, { type: 'load' });
8476
- if (isGroupResult(dataSet))
9371
+ if (TableResultHelpers.isGroupResult(dataSet))
8477
9372
  throw new Error('Returned grouped CSV data for non-grouped table');
8478
- const fullColumns = resolveColumns(s, columns, columnNameMap, !!options.allowSelection);
9373
+ const fullColumns = TableColumnHelpers.resolveColumns(s, columns, columnNameMap, !!options.allowSelection);
8479
9374
  const data = [];
8480
9375
  data.push(fullColumns.map(({ key }) => columnNameMap.get(key) ?? key));
8481
9376
  for (const record of dataSet.currentPageData) {
8482
- if (mode === 'selection' && !isRowSelected(s, record.id))
9377
+ if (mode === 'selection' &&
9378
+ !TableSelectionHelpers.isRowSelected(s, record.id))
8483
9379
  continue;
8484
9380
  const row = [];
8485
9381
  for (const column of fullColumns) {
@@ -8496,23 +9392,23 @@ var RivTable;
8496
9392
  order: hasAnyRowSpans ? null : s.query.order,
8497
9393
  pagination: {
8498
9394
  ...s.query.pagination,
8499
- previous: getPreviousPage(s),
8500
- pages: getPages(s),
8501
- next: getNextPage(s),
8502
- pageCount: getPageCount(s),
8503
- showControls: getShowPaginationControls(s),
8504
- pageRowStart: getPageRowStart(s),
8505
- pageRowEnd: getPageRowEnd(s),
9395
+ previous: TablePaginationHelpers.getPreviousPage(s),
9396
+ pages: TablePaginationHelpers.getPages(s),
9397
+ next: TablePaginationHelpers.getNextPage(s),
9398
+ pageCount: TablePaginationHelpers.getPageCount(s),
9399
+ showControls: TablePaginationHelpers.getShowPaginationControls(s),
9400
+ pageRowStart: TablePaginationHelpers.getPageRowStart(s),
9401
+ pageRowEnd: TablePaginationHelpers.getPageRowEnd(s),
8506
9402
  },
8507
- noSearchColumnsSelected: getSearchColumnsSelectedState(s, 'none'),
9403
+ noSearchColumnsSelected: TableSearchHelpers.getSearchColumnsSelectedState(s, 'none'),
8508
9404
  },
8509
9405
  display: {
8510
9406
  ...s.display,
8511
9407
  columns: resolvedColumns.map(column => hasAnyRowSpans ? { ...column, orderable: false } : column),
8512
- allColumns: getAllColumns(s, columns, columnNameMap),
9408
+ allColumns: TableColumnHelpers.getAllColumns(s, columns, columnNameMap),
8513
9409
  columnNameMap: columnNameMap,
8514
9410
  searchableColumnMap: searchableColumnMap,
8515
- zeroStateMessage: getZeroStateMessage(s, pluralEntityName),
9411
+ zeroStateMessage: TableDisplayHelpers.getZeroStateMessage(s, pluralEntityName),
8516
9412
  columnsAreFreezable: !!options?.columnsAreFreezable,
8517
9413
  columnsAreHideable: !!options?.columnsAreHideable,
8518
9414
  columnsAreReorderable: options?.columnsAreReorderable ?? true,
@@ -8534,9 +9430,9 @@ var RivTable;
8534
9430
  selection: {
8535
9431
  ...s.selection,
8536
9432
  allowSelection: options?.allowSelection ?? false,
8537
- isAllSelected: isAllSelected(s),
8538
- isCurrentPageSelected: isCurrentPageSelected(s),
8539
- selectedCount: selectedCount(s),
9433
+ isAllSelected: TableSelectionHelpers.isAllSelected(s),
9434
+ isCurrentPageSelected: TableSelectionHelpers.isCurrentPageSelected(s),
9435
+ selectedCount: TableSelectionHelpers.selectedCount(s),
8540
9436
  },
8541
9437
  result: {
8542
9438
  ...s.result,
@@ -8548,7 +9444,7 @@ var RivTable;
8548
9444
  totalMatchingRowCount: rows.length,
8549
9445
  groupData: { key: '' },
8550
9446
  },
8551
- csvFilename: getCsvFilename(pluralEntityName, options),
9447
+ csvFilename: TableResultHelpers.getCsvFilename(pluralEntityName, options),
8552
9448
  csvData,
8553
9449
  },
8554
9450
  };
@@ -8568,9 +9464,6 @@ var RivTable;
8568
9464
  return { actions, state, effects };
8569
9465
  }
8570
9466
  RivTable.createManager = createManager;
8571
- function orderEmptyLast(rows, key, direction) {
8572
- return orderBy(rows, [row => row[key] == null, key], ['asc', direction]);
8573
- }
8574
9467
  function createInMemoryManager(fetchDataset, columns, pluralEntityName, options) {
8575
9468
  let data;
8576
9469
  let fuse;
@@ -8630,14 +9523,14 @@ var RivTable;
8630
9523
  const matches = fuse.search(query.search).map(result => result.item);
8631
9524
  ordered =
8632
9525
  hasExplicitSort && query.order
8633
- ? orderEmptyLast(matches, orderColumn, query.order.direction)
9526
+ ? TableOrderHelpers.orderEmptyLast(matches, orderColumn, query.order.direction)
8634
9527
  : matches;
8635
9528
  }
8636
9529
  else if (hasExplicitSort && query.order) {
8637
- ordered = orderEmptyLast(data, orderColumn, query.order.direction);
9530
+ ordered = TableOrderHelpers.orderEmptyLast(data, orderColumn, query.order.direction);
8638
9531
  }
8639
9532
  else if (query.order == null && defaultSortSpec) {
8640
- ordered = orderEmptyLast(data, defaultSortSpec.key, defaultSortSpec.direction);
9533
+ ordered = TableOrderHelpers.orderEmptyLast(data, defaultSortSpec.key, defaultSortSpec.direction);
8641
9534
  }
8642
9535
  else {
8643
9536
  ordered = data;
@@ -8687,26 +9580,6 @@ var RivTable;
8687
9580
  return createManager(source, columnMetadata, pluralEntityName, options);
8688
9581
  }
8689
9582
  RivTable.createInMemoryManager = createInMemoryManager;
8690
- ///////////////
8691
- // Utilities //
8692
- ///////////////
8693
- function getColumnAlignment(dataType, isFirst) {
8694
- if (isFirst)
8695
- return 'left';
8696
- switch (dataType) {
8697
- case 'date':
8698
- case 'longText':
8699
- return 'left';
8700
- case 'advanced':
8701
- case 'icon':
8702
- case 'shortText':
8703
- return 'center';
8704
- case 'currency':
8705
- case 'number':
8706
- return 'right';
8707
- }
8708
- }
8709
- RivTable.getColumnAlignment = getColumnAlignment;
8710
9583
  })(RivTable || (RivTable = {}));
8711
9584
  /**
8712
9585
  * This function keeps the state object references as stable as possible, which
@@ -8744,384 +9617,6 @@ function stableState(target, source) {
8744
9617
  }
8745
9618
  return target;
8746
9619
  }
8747
- function getPageCount(state) {
8748
- if (isGroupResult(state.result)) {
8749
- return Math.max(Math.ceil(state.result.totalGroupCount / state.query.grouping.groupsPerPage), 1);
8750
- }
8751
- return Math.max(Math.ceil(state.result.totalMatchingRowCount / state.query.pagination.pageSize), 1);
8752
- }
8753
- function getPreviousPage(state) {
8754
- return state.query.pagination.page === 0
8755
- ? null
8756
- : state.query.pagination.page - 1;
8757
- }
8758
- function getPages(state) {
8759
- const padding = 4;
8760
- const min = 0;
8761
- const max = getPageCount(state) - 1;
8762
- const desiredStart = state.query.pagination.page - padding;
8763
- const clampedStart = Math.max(min, desiredStart);
8764
- const desiredEnd = state.query.pagination.page + padding;
8765
- const clampedEnd = Math.min(max, desiredEnd);
8766
- const start = Math.max(min, clampedStart - (desiredEnd - clampedEnd));
8767
- const end = Math.min(max, clampedEnd + (clampedStart - desiredStart));
8768
- return range(start, end + 1);
8769
- }
8770
- function getNextPage(state) {
8771
- const max = getPageCount(state) - 1;
8772
- const next = state.query.pagination.page + 1;
8773
- return next <= max ? next : null;
8774
- }
8775
- // We don't want to show the pagination controls when they are unnecessary.
8776
- function getShowPaginationControls(state) {
8777
- if (state.query.pagination.page > 0) {
8778
- return true;
8779
- }
8780
- if (isGroupResult(state.result)) {
8781
- return state.result.totalGroupCount > state.query.grouping.groupsPerPage;
8782
- }
8783
- return (state.result.totalMatchingRowCount > Math.min(...[...RivTable.pageSizes]));
8784
- }
8785
- function getPageRowStart(state) {
8786
- return state.query.pagination.page * state.query.pagination.pageSize + 1;
8787
- }
8788
- function getPageRowEnd(state) {
8789
- return Math.min((state.query.pagination.page + 1) * state.query.pagination.pageSize, state.result.totalMatchingRowCount);
8790
- }
8791
- function getCsvFilename(pluralEntityName, options) {
8792
- return (options?.csvFileBasename?.slice(0, 200) ?? pluralEntityName) + '.csv';
8793
- }
8794
- function memoizedCellRowSpan(s, fullColumns, options) {
8795
- const getRowSpanForCell = options?.getRowSpanForCell;
8796
- const result = s.result;
8797
- // If the dataset exceeds the current page size, skip span calculations.
8798
- if (s.result.totalMatchingRowCount > s.query.pagination.pageSize)
8799
- return null;
8800
- // If the user hasn't provided the row span configuration, default to no spanning
8801
- if (!getRowSpanForCell)
8802
- return null;
8803
- // Row spanning is not supported on grouped tables.
8804
- if (isGroupResult(result))
8805
- return null;
8806
- // Memoize the user's configuration for the current page.
8807
- return new Map(fullColumns.map(column => [
8808
- column.key,
8809
- result.currentPageData.map((_, i) => {
8810
- const raw = getRowSpanForCell(i, column.key);
8811
- if (raw === 0)
8812
- return 0;
8813
- else
8814
- return Math.max(1, toInteger(raw));
8815
- }),
8816
- ]));
8817
- }
8818
- function getAllColumns(state, supportedColumns, columnNameMap) {
8819
- // If the table offers more columns than the user has configuration settings
8820
- // for (or if the user has no configuration settings yet), we'll append them
8821
- // to the end (unless they should be pinned by default, in which case we'll
8822
- // append them after the other pinned columns). This ensures that new columns
8823
- // we add to existing tables over time (1) get displayed even though they
8824
- // don't appear in the user's configuration settings yet, and (2) don't
8825
- // interrupt their existing setup.
8826
- const columnNamesWithoutUserSettings = difference([...supportedColumns.keys()], state.display.columnSettings.map(({ key }) => key));
8827
- // Throw out settings for columns no longer offered by the table.
8828
- const columnsWithUserSettings = state.display.columnSettings.filter(({ key }) => supportedColumns.has(key));
8829
- const columnsWithoutUserSettings = [
8830
- ...columnNamesWithoutUserSettings,
8831
- ].map((key) => ({
8832
- key,
8833
- enabled: true,
8834
- preferredWidth: 'auto',
8835
- pinned: !!supportedColumns.get(key)?.defaultPinned,
8836
- }));
8837
- return orderIntentionally([...columnsWithUserSettings, ...columnsWithoutUserSettings], columnNameMap);
8838
- }
8839
- function orderIntentionally(columns, columnNameMap) {
8840
- return [
8841
- ...columns.filter(v => v.pinned),
8842
- ...columns.filter(v => v.enabled && !v.pinned),
8843
- ...columns
8844
- .filter(v => !v.enabled && !v.pinned)
8845
- .sort((a, b) => {
8846
- const aName = columnNameMap.get(a.key) ?? a.key;
8847
- const bName = columnNameMap.get(b.key) ?? b.key;
8848
- return aName.localeCompare(bName);
8849
- }),
8850
- ];
8851
- }
8852
- function getAlignment(metadata, index, allowSelection) {
8853
- return RivTable.getColumnAlignment(metadata.dataType, index === 0 && !allowSelection);
8854
- }
8855
- function resolveColumns(state, supportedColumns, columnNameMap, allowSelection) {
8856
- const allColumns = getAllColumns(state, supportedColumns, columnNameMap);
8857
- return allColumns
8858
- .filter(({ enabled }) => enabled)
8859
- .reduce((fullColumns, settings, i) => {
8860
- const metadata = supportedColumns.get(settings.key);
8861
- const resolvedWidth = settings.preferredWidth === 'auto'
8862
- ? metadata.minWidth
8863
- : Math.max(metadata.minWidth, settings.preferredWidth);
8864
- const previousColumn = fullColumns[i - 1];
8865
- return [
8866
- ...fullColumns,
8867
- {
8868
- ...settings,
8869
- ...metadata,
8870
- width: resolvedWidth,
8871
- left: settings.pinned
8872
- ? previousColumn
8873
- ? (previousColumn.left || 0) + previousColumn.width
8874
- : !!allowSelection
8875
- ? 40
8876
- : 0
8877
- : null,
8878
- alignment: getAlignment(metadata, i, !!allowSelection),
8879
- },
8880
- ];
8881
- }, []);
8882
- }
8883
- function getZeroStateMessage(state, entity) {
8884
- if ((isGroupResult(state.result) && state.result.totalGroupCount > 0) ||
8885
- (!isGroupResult(state.result) && state.result.totalMatchingRowCount > 0))
8886
- return null;
8887
- const allSearchColumnsSelected = getSearchColumnsSelectedState(state, 'all');
8888
- if (state.query.search && allSearchColumnsSelected)
8889
- return `No ${entity} match your current search keyword.`;
8890
- if (state.query.search && !allSearchColumnsSelected)
8891
- return `No ${entity} match your current search keyword in the selected search columns.`;
8892
- if (state.query.filters)
8893
- return `No ${entity} match your current filters.`;
8894
- return `No ${entity}.`;
8895
- }
8896
- function changeColumnPin(state, columns, columnNameMap, column, pinned) {
8897
- const allColumns = getAllColumns(state, columns, columnNameMap);
8898
- if (pinned) {
8899
- const target = allColumns.find(c => c.key === column);
8900
- const wasEnabled = !!target?.enabled;
8901
- if (!wasEnabled) {
8902
- const enabledCount = allColumns.filter(col => col.enabled).length;
8903
- if (enabledCount >= RivTable.ColumnsMaxShown) {
8904
- return state; // refuse the pin since it would exceed the max
8905
- }
8906
- }
8907
- }
8908
- return {
8909
- ...state,
8910
- display: {
8911
- ...state.display,
8912
- columnSettings: orderIntentionally(allColumns.map(c => ({
8913
- ...c,
8914
- pinned: c.key === column ? pinned : c.pinned,
8915
- // Check/enable if being pinned
8916
- enabled: c.key === column && pinned ? true : c.enabled,
8917
- })), columnNameMap),
8918
- },
8919
- };
8920
- }
8921
- function changeColumnsFreezeState(state, columns, columnNameMap, index, freeze) {
8922
- const allColumns = getAllColumns(state, columns, columnNameMap);
8923
- return {
8924
- ...state,
8925
- display: {
8926
- ...state.display,
8927
- columnSettings: allColumns.map((c, i) => {
8928
- return { ...c, pinned: freeze && i <= index };
8929
- }),
8930
- },
8931
- };
8932
- }
8933
- function moveColumnTo(state, columns, columnNameMap, column, position) {
8934
- const allColumns = getAllColumns(state, columns, columnNameMap);
8935
- const previousIndex = allColumns.findIndex(c => c.key === column);
8936
- const lastIndex = position == 'end' ? allColumns.findIndex(c => !c.enabled) : 0;
8937
- const newIndex = position == 'start'
8938
- ? 0
8939
- : lastIndex == -1
8940
- ? allColumns.length - 1
8941
- : lastIndex;
8942
- if (!allColumns[previousIndex].enabled &&
8943
- allColumns.filter(col => col.enabled).length >= RivTable.ColumnsMaxShown)
8944
- return state;
8945
- const movedState = changeColumnOrder(state, columns, columnNameMap, previousIndex, newIndex);
8946
- //Make sure the column is enabled
8947
- return changeColumnEnabled(movedState, columns, columnNameMap, column, true);
8948
- }
8949
- function changeColumnOrder(state, columns, columnNameMap, previousIndex, newIndex) {
8950
- const allColumns = getAllColumns(state, columns, columnNameMap);
8951
- // First, put the columns in the desired order.
8952
- const item = allColumns[previousIndex];
8953
- const withoutItem = allColumns.filter((_, i) => i !== previousIndex);
8954
- const reordered = [
8955
- ...withoutItem.slice(0, newIndex),
8956
- item,
8957
- ...withoutItem.slice(newIndex),
8958
- ];
8959
- // Then, we may need to fix the pins (all pinned columns appear at the
8960
- // beginning of the columns array) since the user is allowed to drag
8961
- // and drop columns to and from the pinned area. If the user drags a
8962
- // column across that threshold, update its pinned status.
8963
- const updated = reordered.map((settings, i, arr) => {
8964
- if (newIndex === i) {
8965
- return {
8966
- ...settings,
8967
- pinned: settings.pinned
8968
- ? arr[i - 1]?.pinned ?? true
8969
- : arr[i + 1]?.pinned ?? false,
8970
- enabled: settings.enabled
8971
- ? arr[i - 1]?.enabled ?? true
8972
- : arr[i + 1]?.enabled ?? false,
8973
- };
8974
- }
8975
- else
8976
- return settings;
8977
- });
8978
- const wasDisabled = !item.enabled;
8979
- const becameEnabled = updated[newIndex].enabled;
8980
- if (wasDisabled && becameEnabled) {
8981
- const enabledCount = allColumns.filter(c => c.enabled).length;
8982
- if (enabledCount >= RivTable.ColumnsMaxShown) {
8983
- // Refuse the move; keep state as-is
8984
- return state;
8985
- }
8986
- }
8987
- return {
8988
- ...state,
8989
- display: {
8990
- ...state.display,
8991
- columnSettings: orderIntentionally(updated, columnNameMap),
8992
- },
8993
- };
8994
- }
8995
- function changeColumnEnabled(state, columns, columnNameMap, column, enabled) {
8996
- const allColumns = getAllColumns(state, columns, columnNameMap);
8997
- if (enabled &&
8998
- allColumns.filter(col => col.enabled).length >= RivTable.ColumnsMaxShown) {
8999
- return state;
9000
- }
9001
- return {
9002
- ...state,
9003
- display: {
9004
- ...state.display,
9005
- columnSettings: orderIntentionally(allColumns.map(c => ({
9006
- ...c,
9007
- enabled: c.key === column ? enabled : c.enabled,
9008
- // Unpin if being unchecked
9009
- pinned: c.key === column && !enabled ? false : c.pinned,
9010
- })), columnNameMap),
9011
- },
9012
- };
9013
- }
9014
- function enableAllColumns(state, columns, columnNameMap, enabled) {
9015
- const allColumns = getAllColumns(state, columns, columnNameMap);
9016
- if (enabled && allColumns.length > RivTable.ColumnsMaxShown)
9017
- return state;
9018
- return {
9019
- ...state,
9020
- display: {
9021
- ...state.display,
9022
- columnSettings: orderIntentionally(allColumns.map(c => ({
9023
- ...c,
9024
- enabled: enabled,
9025
- // Unpin if being unchecked
9026
- pinned: !enabled ? false : c.pinned,
9027
- })), columnNameMap),
9028
- },
9029
- };
9030
- }
9031
- function changeColumnWidth(state, columns, columnNameMap, column, preferredWidth) {
9032
- const allColumns = getAllColumns(state, columns, columnNameMap);
9033
- return {
9034
- ...state,
9035
- display: {
9036
- ...state.display,
9037
- columnSettings: allColumns.map(c => ({
9038
- ...c,
9039
- preferredWidth: c.key === column ? preferredWidth : c.preferredWidth,
9040
- })),
9041
- },
9042
- };
9043
- }
9044
- function resetToDefaultColumns(state, columns, columnNameMap, defaultColumnState) {
9045
- return {
9046
- ...state,
9047
- display: {
9048
- ...state.display,
9049
- columnSettings: orderIntentionally(defaultColumnState, columnNameMap),
9050
- },
9051
- };
9052
- }
9053
- function isRowSelected(state, id) {
9054
- switch (state.selection.mode) {
9055
- case 'include':
9056
- return state.selection.included.has(id);
9057
- case 'exclude':
9058
- return !state.selection.excluded.has(id);
9059
- }
9060
- }
9061
- function isGroupSelected(state, group) {
9062
- switch (state.selection.mode) {
9063
- case 'include': {
9064
- let allFound = true;
9065
- let anyFound = false;
9066
- for (const row of group.currentPageData) {
9067
- if (!state.selection.included.has(row.id)) {
9068
- allFound = false;
9069
- }
9070
- else {
9071
- anyFound = true;
9072
- }
9073
- }
9074
- return allFound ? true : anyFound ? 'indeterminate' : false;
9075
- }
9076
- case 'exclude': {
9077
- let allFound = true;
9078
- let anyFound = false;
9079
- for (const row of group.currentPageData) {
9080
- if (state.selection.excluded.has(row.id)) {
9081
- allFound = false;
9082
- }
9083
- else {
9084
- anyFound = true;
9085
- }
9086
- }
9087
- return allFound ? true : anyFound ? 'indeterminate' : false;
9088
- }
9089
- }
9090
- }
9091
- function isAllSelected(state) {
9092
- // If there are no rows, "all selected" should be false
9093
- if (state.result.totalMatchingRowCount === 0) {
9094
- return false;
9095
- }
9096
- if ((state.selection.mode === 'exclude' &&
9097
- state.selection.excluded.size === 0) ||
9098
- (state.selection.mode === 'include' &&
9099
- state.selection.included.size === state.result.totalMatchingRowCount))
9100
- return true;
9101
- if ((state.selection.mode === 'exclude' &&
9102
- state.selection.excluded.size === state.result.totalMatchingRowCount) ||
9103
- (state.selection.mode === 'include' && state.selection.included.size === 0))
9104
- return false;
9105
- return 'indeterminate';
9106
- }
9107
- function isCurrentPageSelected(state) {
9108
- const selectedStates = getAllRowsFromResult(state.result).map(({ id }) => isRowSelected(state, id));
9109
- if (selectedStates.length > 0) {
9110
- if (selectedStates.every(v => v))
9111
- return true;
9112
- if (selectedStates.some(v => v))
9113
- return 'indeterminate';
9114
- }
9115
- return false;
9116
- }
9117
- function selectedCount(state) {
9118
- switch (state.selection.mode) {
9119
- case 'include':
9120
- return state.selection.included.size;
9121
- case 'exclude':
9122
- return state.result.totalMatchingRowCount - state.selection.excluded.size;
9123
- }
9124
- }
9125
9620
  async function* refreshResultWith(state, source, mostRecentAction) {
9126
9621
  yield {
9127
9622
  state: {
@@ -9135,7 +9630,7 @@ async function* refreshResultWith(state, source, mostRecentAction) {
9135
9630
  };
9136
9631
  try {
9137
9632
  const result = await source(state.query, mostRecentAction);
9138
- if (isPageOutOfBounds(state, result)) {
9633
+ if (TablePaginationHelpers.isPageOutOfBounds(state, result)) {
9139
9634
  state.query.pagination.page = 0;
9140
9635
  }
9141
9636
  yield {
@@ -9165,144 +9660,6 @@ async function* refreshResultWith(state, source, mostRecentAction) {
9165
9660
  };
9166
9661
  }
9167
9662
  }
9168
- function setRowSelected(state, id, selected, contiguous) {
9169
- if (selected) {
9170
- const newSelection = new Set([id]);
9171
- if (contiguous && state.selection.mostRecentlySelected) {
9172
- const startIdx = getAllRowsFromResult(state.result).findIndex(row => row.id === state.selection.mostRecentlySelected);
9173
- const endIdx = getAllRowsFromResult(state.result).findIndex(row => row.id === id);
9174
- if (typeof startIdx === 'number' && typeof endIdx === 'number') {
9175
- for (let i = Math.min(startIdx, endIdx); i <= Math.max(startIdx, endIdx); i++) {
9176
- newSelection.add(getAllRowsFromResult(state.result)[i].id);
9177
- }
9178
- }
9179
- }
9180
- return {
9181
- ...state,
9182
- selection: {
9183
- mostRecentlySelected: id,
9184
- ...(state.selection.mode === 'include'
9185
- ? {
9186
- mode: 'include',
9187
- included: new Set(union([...state.selection.included], [...newSelection])),
9188
- }
9189
- : {
9190
- mode: 'exclude',
9191
- excluded: new Set(difference([...state.selection.excluded], [...newSelection])),
9192
- }),
9193
- },
9194
- };
9195
- }
9196
- else {
9197
- return {
9198
- ...state,
9199
- selection: {
9200
- mostRecentlySelected: null,
9201
- ...(state.selection.mode === 'include'
9202
- ? {
9203
- mode: 'include',
9204
- included: new Set(difference([...state.selection.included], [id])),
9205
- }
9206
- : {
9207
- mode: 'exclude',
9208
- excluded: new Set(union([...state.selection.excluded], [id])),
9209
- }),
9210
- },
9211
- };
9212
- }
9213
- }
9214
- function toggleGroupSelected(state, group) {
9215
- const isGroupFullySelected = isGroupSelected(state, { ...group, currentPageData: group.rows }) === true;
9216
- return group.rows.reduce((accumulatedState, row) => {
9217
- return setRowSelected(accumulatedState, row.id, !isGroupFullySelected, false);
9218
- }, state);
9219
- }
9220
- function togglePageSelected(state) {
9221
- const isPageFullySelected = getAllRowsFromResult(state.result).every(({ id }) => isRowSelected(state, id));
9222
- return getAllRowsFromResult(state.result).reduce((accumulatedState, row) => {
9223
- return setRowSelected(accumulatedState, row.id, !isPageFullySelected, false);
9224
- }, state);
9225
- }
9226
- function toggleAllSelected(state) {
9227
- if (isAllSelected(state) === true) {
9228
- return {
9229
- ...state,
9230
- selection: {
9231
- mostRecentlySelected: null,
9232
- mode: 'include',
9233
- included: new Set(),
9234
- },
9235
- };
9236
- }
9237
- else {
9238
- return {
9239
- ...state,
9240
- selection: {
9241
- mostRecentlySelected: null,
9242
- mode: 'exclude',
9243
- excluded: new Set(),
9244
- },
9245
- };
9246
- }
9247
- }
9248
- function clearSelection(state) {
9249
- return {
9250
- ...state,
9251
- selection: {
9252
- mostRecentlySelected: null,
9253
- mode: 'include',
9254
- included: new Set(),
9255
- },
9256
- };
9257
- }
9258
- function toggleColumnOrder(state, column) {
9259
- if (state.query.order?.column === column) {
9260
- return {
9261
- ...state,
9262
- query: {
9263
- ...state.query,
9264
- order: state.query.order.direction === 'asc'
9265
- ? {
9266
- column,
9267
- direction: 'desc',
9268
- }
9269
- : null,
9270
- },
9271
- };
9272
- }
9273
- return {
9274
- ...state,
9275
- query: {
9276
- ...state.query,
9277
- order: {
9278
- column,
9279
- direction: 'asc',
9280
- },
9281
- },
9282
- };
9283
- }
9284
- function getSearchColumnsSelectedState(state, expectedValue) {
9285
- switch (expectedValue) {
9286
- case 'all':
9287
- return Array.from(state.query.searchColumns.values()).every(value => value);
9288
- case 'none':
9289
- return Array.from(state.query.searchColumns.values()).every(value => !value);
9290
- }
9291
- }
9292
- function toggleAllSearchColumns(state) {
9293
- const noneSelected = getSearchColumnsSelectedState(state, 'none');
9294
- const payload = new Map(Array.from(state.query.searchColumns.keys()).map(key => [
9295
- key,
9296
- noneSelected,
9297
- ]));
9298
- return {
9299
- ...state,
9300
- query: {
9301
- ...state.query,
9302
- searchColumns: payload,
9303
- },
9304
- };
9305
- }
9306
9663
  async function* reduce(state, action, columns, source, columnNameMap, defaultColumnState) {
9307
9664
  switch (action.type) {
9308
9665
  case 'load':
@@ -9323,7 +9680,7 @@ async function* reduce(state, action, columns, source, columnNameMap, defaultCol
9323
9680
  }, source, action);
9324
9681
  break;
9325
9682
  case 'orderColumnToggle':
9326
- yield* refreshResultWith(toggleColumnOrder(state, action.column), source, action);
9683
+ yield* refreshResultWith(TableOrderHelpers.toggleColumnOrder(state, action.column), source, action);
9327
9684
  break;
9328
9685
  case 'searchChange':
9329
9686
  yield* refreshResultWith({
@@ -9389,7 +9746,7 @@ async function* reduce(state, action, columns, source, columnNameMap, defaultCol
9389
9746
  ...state.query,
9390
9747
  pagination: {
9391
9748
  ...state.query.pagination,
9392
- page: getPreviousPage(state) ?? 0,
9749
+ page: TablePaginationHelpers.getPreviousPage(state) ?? 0,
9393
9750
  },
9394
9751
  },
9395
9752
  }, source, action);
@@ -9401,7 +9758,8 @@ async function* reduce(state, action, columns, source, columnNameMap, defaultCol
9401
9758
  ...state.query,
9402
9759
  pagination: {
9403
9760
  ...state.query.pagination,
9404
- page: getNextPage(state) ?? getPageCount(state) - 1,
9761
+ page: TablePaginationHelpers.getNextPage(state) ??
9762
+ TablePaginationHelpers.getPageCount(state) - 1,
9405
9763
  },
9406
9764
  },
9407
9765
  }, source, action);
@@ -9468,49 +9826,49 @@ async function* reduce(state, action, columns, source, columnNameMap, defaultCol
9468
9826
  break;
9469
9827
  case 'columnPinChange':
9470
9828
  yield {
9471
- state: changeColumnPin(state, columns, columnNameMap, action.column, action.pinned),
9829
+ state: TableColumnHelpers.changeColumnPin(state, columns, columnNameMap, action.column, action.pinned),
9472
9830
  effect: 'saveColumnPreferences',
9473
9831
  };
9474
9832
  break;
9475
9833
  case 'columnsFreezeUpToChange':
9476
9834
  yield {
9477
- state: changeColumnsFreezeState(state, columns, columnNameMap, action.index, action.freeze),
9835
+ state: TableColumnHelpers.changeColumnsFreezeState(state, columns, columnNameMap, action.index, action.freeze),
9478
9836
  effect: 'saveColumnPreferences',
9479
9837
  };
9480
9838
  break;
9481
9839
  case 'columnOrderChange':
9482
9840
  yield {
9483
- state: changeColumnOrder(state, columns, columnNameMap, action.previousIndex, action.newIndex),
9841
+ state: TableColumnHelpers.changeColumnOrder(state, columns, columnNameMap, action.previousIndex, action.newIndex),
9484
9842
  effect: 'saveColumnPreferences',
9485
9843
  };
9486
9844
  break;
9487
9845
  case 'columnMoveToChange':
9488
9846
  yield {
9489
- state: moveColumnTo(state, columns, columnNameMap, action.column, action.position),
9847
+ state: TableColumnHelpers.moveColumnTo(state, columns, columnNameMap, action.column, action.position),
9490
9848
  effect: 'saveColumnPreferences',
9491
9849
  };
9492
9850
  break;
9493
9851
  case 'columnEnabledChange':
9494
9852
  yield {
9495
- state: changeColumnEnabled(state, columns, columnNameMap, action.column, action.enabled),
9853
+ state: TableColumnHelpers.changeColumnEnabled(state, columns, columnNameMap, action.column, action.enabled),
9496
9854
  effect: 'saveColumnPreferences',
9497
9855
  };
9498
9856
  break;
9499
9857
  case 'enableAllColumnsChange':
9500
9858
  yield {
9501
- state: enableAllColumns(state, columns, columnNameMap, action.enabled),
9859
+ state: TableColumnHelpers.enableAllColumns(state, columns, columnNameMap, action.enabled),
9502
9860
  effect: 'saveColumnPreferences',
9503
9861
  };
9504
9862
  break;
9505
9863
  case 'columnWidthChange':
9506
9864
  yield {
9507
- state: changeColumnWidth(state, columns, columnNameMap, action.column, action.preferredWidth),
9865
+ state: TableColumnHelpers.changeColumnWidth(state, columns, columnNameMap, action.column, action.preferredWidth),
9508
9866
  effect: 'saveColumnPreferences',
9509
9867
  };
9510
9868
  break;
9511
9869
  case 'resetToDefaultColumns':
9512
9870
  yield {
9513
- state: resetToDefaultColumns(state, columns, columnNameMap, defaultColumnState),
9871
+ state: TableColumnHelpers.resetToDefaultColumns(state, columns, columnNameMap, defaultColumnState),
9514
9872
  effect: 'saveColumnPreferences',
9515
9873
  };
9516
9874
  break;
@@ -9525,31 +9883,31 @@ async function* reduce(state, action, columns, source, columnNameMap, defaultCol
9525
9883
  break;
9526
9884
  case 'rowSelectedChange':
9527
9885
  yield {
9528
- state: setRowSelected(state, action.id, action.selected, action.contiguous),
9886
+ state: TableSelectionHelpers.setRowSelected(state, action.id, action.selected, action.contiguous),
9529
9887
  effect: null,
9530
9888
  };
9531
9889
  break;
9532
9890
  case 'pageSelectedChange':
9533
9891
  yield {
9534
- state: togglePageSelected(state),
9892
+ state: TableSelectionHelpers.togglePageSelected(state),
9535
9893
  effect: null,
9536
9894
  };
9537
9895
  break;
9538
9896
  case 'allSelectedChange':
9539
9897
  yield {
9540
- state: toggleAllSelected(state),
9898
+ state: TableSelectionHelpers.toggleAllSelected(state),
9541
9899
  effect: null,
9542
9900
  };
9543
9901
  break;
9544
9902
  case 'selectionClear':
9545
9903
  yield {
9546
- state: clearSelection(state),
9904
+ state: TableSelectionHelpers.clearSelection(state),
9547
9905
  effect: null,
9548
9906
  };
9549
9907
  break;
9550
9908
  case 'groupSelectionChange':
9551
9909
  yield {
9552
- state: toggleGroupSelected(state, action.payload),
9910
+ state: TableSelectionHelpers.toggleGroupSelected(state, action.payload),
9553
9911
  effect: null,
9554
9912
  };
9555
9913
  break;
@@ -9590,39 +9948,10 @@ async function* reduce(state, action, columns, source, columnNameMap, defaultCol
9590
9948
  }, source, action);
9591
9949
  break;
9592
9950
  case 'toggleAllSearchColumns':
9593
- yield* refreshResultWith(toggleAllSearchColumns(state), source, action);
9951
+ yield* refreshResultWith(TableSearchHelpers.toggleAllSearchColumns(state), source, action);
9594
9952
  break;
9595
9953
  }
9596
9954
  }
9597
- function isGroupResult(result) {
9598
- if ('totalGroupCount' in result) {
9599
- return true;
9600
- }
9601
- return false;
9602
- }
9603
- function getAllRowsFromResult(result) {
9604
- if (isGroupResult(result)) {
9605
- return result.groupResults.flatMap(groups => groups.currentPageData);
9606
- }
9607
- else {
9608
- return result.currentPageData;
9609
- }
9610
- }
9611
- function isPageOutOfBounds(state, result) {
9612
- if (isGroupResult(result)) {
9613
- const minGroupValToShowOnCurrentPage = state.query.pagination.page * state.query.grouping.groupsPerPage + 1;
9614
- if (result.totalGroupCount < minGroupValToShowOnCurrentPage) {
9615
- return true;
9616
- }
9617
- }
9618
- else {
9619
- const minRowToShowOnCurrentPage = state.query.pagination.page * state.query.pagination.pageSize + 1;
9620
- if (result.totalMatchingRowCount < minRowToShowOnCurrentPage) {
9621
- return true;
9622
- }
9623
- }
9624
- return false;
9625
- }
9626
9955
 
9627
9956
  function createCellCoordinateCalculator(cells, totalColumns) {
9628
9957
  // Pre-calculate coordinates for all cells
@@ -9700,7 +10029,7 @@ class SimpleTableComponent {
9700
10029
  const allowedTypes = RivTable.ColumnDataTypes.join(', ');
9701
10030
  throw new Error(`Each header cell must define an appropriate dataType, one of ${allowedTypes}`);
9702
10031
  }
9703
- const newAlignment = RivTable.getColumnAlignment(dataType, i === 0);
10032
+ const newAlignment = TableColumnHelpers.getColumnAlignment(dataType, i === 0);
9704
10033
  const newLeftPinOffset = runningWidthTotal;
9705
10034
  runningWidthTotal += headerCell.width;
9706
10035
  const changed = headerCell.alignment != newAlignment ||
@@ -10140,10 +10469,10 @@ class TableHeaderResizeHandleComponent {
10140
10469
  }
10141
10470
  }
10142
10471
  TableHeaderResizeHandleComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TableHeaderResizeHandleComponent, deps: [{ token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component });
10143
- TableHeaderResizeHandleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TableHeaderResizeHandleComponent, selector: "riv-table-header-resize-handle", outputs: { dragResize: "dragResize" }, ngImport: i0, template: "", styles: [":host{position:absolute;top:0;right:calc(var(--border-width) * -1);bottom:0;padding-left:var(--size-small);background-color:var(--brand);background-clip:content-box;box-sizing:content-box;width:var(--border-width);opacity:0;transition:opacity var(--medium-transition);cursor:ew-resize}:host:hover{opacity:1}\n"] });
10472
+ TableHeaderResizeHandleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TableHeaderResizeHandleComponent, selector: "riv-table-header-resize-handle", outputs: { dragResize: "dragResize" }, ngImport: i0, template: "", styles: [":host{position:absolute;top:0;right:calc(var(--border-width) * -1);bottom:0;padding-left:var(--size-small);background-color:var(--brand);background-clip:content-box;box-sizing:content-box;width:var(--border-width);opacity:0;transition:opacity var(--medium-transition);cursor:ew-resize}:host:hover{opacity:1}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10144
10473
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TableHeaderResizeHandleComponent, decorators: [{
10145
10474
  type: Component,
10146
- args: [{ selector: 'riv-table-header-resize-handle', template: "", styles: [":host{position:absolute;top:0;right:calc(var(--border-width) * -1);bottom:0;padding-left:var(--size-small);background-color:var(--brand);background-clip:content-box;box-sizing:content-box;width:var(--border-width);opacity:0;transition:opacity var(--medium-transition);cursor:ew-resize}:host:hover{opacity:1}\n"] }]
10475
+ args: [{ selector: 'riv-table-header-resize-handle', changeDetection: ChangeDetectionStrategy.OnPush, template: "", styles: [":host{position:absolute;top:0;right:calc(var(--border-width) * -1);bottom:0;padding-left:var(--size-small);background-color:var(--brand);background-clip:content-box;box-sizing:content-box;width:var(--border-width);opacity:0;transition:opacity var(--medium-transition);cursor:ew-resize}:host:hover{opacity:1}\n"] }]
10147
10476
  }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: Document, decorators: [{
10148
10477
  type: Inject,
10149
10478
  args: [DOCUMENT]