@servicemind.tis/tis-smart-table-viewer 2.3.5 → 2.3.6

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.
@@ -2096,12 +2096,18 @@ class TisSmartTableViewerComponent {
2096
2096
  }
2097
2097
  if (changes['loadDataApiBaseUrl']) {
2098
2098
  if (changes['loadDataApiBaseUrl'].currentValue) {
2099
+ // Clean up existing subscriptions
2099
2100
  if (this.loadingSubscription) {
2100
2101
  this.loadingSubscription.unsubscribe();
2101
2102
  }
2102
2103
  if (this.dataLengthSubscription) {
2103
2104
  this.dataLengthSubscription.unsubscribe();
2104
2105
  }
2106
+ // ✅ FIX: Disconnect previous dataSource to prevent memory leaks
2107
+ if (this.dataSource) {
2108
+ this.dataSource.disconnect({});
2109
+ }
2110
+ // Create new ApiDataSource
2105
2111
  this.dataSource = new ApiDataSource(this.apiService);
2106
2112
  this.loadingSubscription = this.dataSource.loading$.subscribe(loading => {
2107
2113
  if (!loading) {
@@ -2436,6 +2442,10 @@ class TisSmartTableViewerComponent {
2436
2442
  UrlHelper.safeNavigate(this.router, url);
2437
2443
  }
2438
2444
  toggleSelection(status, row) {
2445
+ // ✅ Add null guards to prevent crashes
2446
+ if (!row || !ValidationHelper.hasRowKey(row, this.selectedRowKey)) {
2447
+ return;
2448
+ }
2439
2449
  if (this.onlySingleSelection && status.checked) {
2440
2450
  this.selection.clear();
2441
2451
  }
@@ -2445,16 +2455,29 @@ class TisSmartTableViewerComponent {
2445
2455
  this.checkAllRowsSelected();
2446
2456
  }
2447
2457
  checkAllRowsSelected() {
2458
+ // ✅ Add comprehensive null guards to prevent crashes
2459
+ if (!this.dataSource?.apiSubject?.value || !Array.isArray(this.dataSource.apiSubject.value)) {
2460
+ this.isAllRowsSelected = false;
2461
+ this.allRowsSelectedChange.emit(this.isAllRowsSelected);
2462
+ return;
2463
+ }
2448
2464
  this.isAllRowsSelected = this.selection.selected.length === this.dataSource.apiSubject.value.length;
2449
2465
  this.allRowsSelectedChange.emit(this.isAllRowsSelected);
2450
2466
  }
2451
2467
  toggleAllRows() {
2468
+ // ✅ Add comprehensive null guards
2469
+ if (!this.dataSource?.apiSubject?.value || !Array.isArray(this.dataSource.apiSubject.value)) {
2470
+ return;
2471
+ }
2452
2472
  if (this.isAllRowsSelected) {
2453
2473
  this.selection.clear();
2454
2474
  }
2455
2475
  else {
2456
2476
  this.dataSource.apiSubject.value.forEach(row => {
2457
- this.selection.select(row);
2477
+ // ✅ Validate each row before selecting
2478
+ if (row && ValidationHelper.hasRowKey(row, this.selectedRowKey)) {
2479
+ this.selection.select(row);
2480
+ }
2458
2481
  });
2459
2482
  }
2460
2483
  this.selectedRows = this.selection.selected;
@@ -2465,8 +2488,13 @@ class TisSmartTableViewerComponent {
2465
2488
  $event.stopPropagation();
2466
2489
  }
2467
2490
  isChecked(row) {
2468
- return ValidationHelper.hasRowKey(row, this.selectedRowKey) &&
2469
- this.selectedIds.has(row[this.selectedRowKey]);
2491
+ // Add comprehensive null guards
2492
+ if (!row ||
2493
+ !ValidationHelper.hasRowKey(row, this.selectedRowKey) ||
2494
+ !this.selectedIds) {
2495
+ return false;
2496
+ }
2497
+ return this.selectedIds.has(row[this.selectedRowKey]);
2470
2498
  }
2471
2499
  getQueryParams(url) {
2472
2500
  return QueryParamsHelper.parseQueryParams(url);
@@ -2525,6 +2553,10 @@ class TisSmartTableViewerComponent {
2525
2553
  return this.computedRowBackgrounds.get(rowId) || null;
2526
2554
  }
2527
2555
  drop(event) {
2556
+ // ✅ Add null guards to prevent crashes
2557
+ if (!this.dataSource?.apiSubject?.value || !Array.isArray(this.dataSource.apiSubject.value)) {
2558
+ return;
2559
+ }
2528
2560
  // Ignore if the item was dropped at the same index
2529
2561
  if (event.previousIndex === event.currentIndex) {
2530
2562
  return;
@@ -2548,14 +2580,28 @@ class TisSmartTableViewerComponent {
2548
2580
  UrlHelper.handleSecondaryButtonClick(this.router, config);
2549
2581
  }
2550
2582
  setSelectedRows() {
2583
+ // ✅ Add null guards to prevent crashes
2584
+ if (!this.dataSource?.apiSubject?.value ||
2585
+ !Array.isArray(this.dataSource.apiSubject.value) ||
2586
+ !this.selectedRowIds) {
2587
+ this.selection.clear();
2588
+ this.selectedRows = [];
2589
+ this.selectedRowsChange.emit(this.selectedRows);
2590
+ return;
2591
+ }
2551
2592
  this.selection.clear();
2593
+ // ✅ FIX: Convert array to Set for O(1) lookup instead of O(n) indexOf
2594
+ const selectedIdsSet = new Set(this.selectedRowIds);
2552
2595
  this.dataSource.apiSubject.value.forEach(row => {
2553
- if (this.selectedRowIds.indexOf(row[this.selectedRowKey]) != -1) {
2596
+ if (row &&
2597
+ ValidationHelper.hasRowKey(row, this.selectedRowKey) &&
2598
+ selectedIdsSet.has(row[this.selectedRowKey])) {
2554
2599
  this.selection.select(row);
2555
2600
  }
2556
2601
  });
2557
2602
  this.selectedRows = this.selection.selected;
2558
2603
  this.selectedRowsChange.emit(this.selectedRows);
2604
+ this.checkAllRowsSelected();
2559
2605
  }
2560
2606
  resetSelectedRows() {
2561
2607
  this.isAllRowsSelected = false;