@shival99/z-ui 1.2.23 → 1.2.24

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.
@@ -325,7 +325,7 @@ class ZTableFilterComponent {
325
325
  this.zColumn().setFilterValue(value || undefined);
326
326
  }
327
327
  onDateRangeChange(value) {
328
- if (value && value.start && value.end) {
328
+ if (value && (value.start || value.end)) {
329
329
  this.zColumn().setFilterValue(value);
330
330
  return;
331
331
  }
@@ -1029,15 +1029,20 @@ function columnConfigToColumnDef(config) {
1029
1029
  columnDef.cell = bodyContent;
1030
1030
  }
1031
1031
  columnDef.footer = resolveHeaderOrFooter(getFooterContent(config));
1032
- if (sortConfig?.sortFn) {
1032
+ const isLocalFilterMode = !filterConfig?.mode || filterConfig.mode === 'local';
1033
+ const isLocalSortMode = !sortConfig?.mode || sortConfig.mode === 'local';
1034
+ if (isLocalSortMode && sortConfig?.sortFn) {
1033
1035
  columnDef.sortingFn = sortConfig.sortFn;
1034
1036
  }
1035
- // Only apply local filter functions when filter mode is 'local' (default)
1036
- // When mode is 'server', filtering is handled externally via zOnChange events
1037
- const isLocalFilterMode = !filterConfig?.mode || filterConfig.mode === 'local';
1037
+ if (!isLocalSortMode) {
1038
+ columnDef.sortingFn = () => 0;
1039
+ }
1038
1040
  if (isLocalFilterMode && filterConfig?.filterFn) {
1039
1041
  columnDef.filterFn = filterConfig.filterFn;
1040
1042
  }
1043
+ if (!isLocalFilterMode) {
1044
+ columnDef.filterFn = () => true;
1045
+ }
1041
1046
  if (isLocalFilterMode && !filterConfig?.filterFn && filterConfig?.type) {
1042
1047
  switch (filterConfig.type) {
1043
1048
  case 'select':
@@ -2429,6 +2434,23 @@ class ZTableComponent {
2429
2434
  };
2430
2435
  return columns.some(c => checkFilter(c));
2431
2436
  }, ...(ngDevMode ? [{ debugName: "hasFiltering" }] : []));
2437
+ hasLocalFiltering = computed(() => {
2438
+ const columns = this.zConfig().columns ?? [];
2439
+ const checkLocalFilter = (col) => {
2440
+ const filterConfig = typeof col.filter === 'boolean' ? { enabled: col.filter } : col.filter;
2441
+ if (filterConfig?.enabled) {
2442
+ const filterMode = filterConfig.mode ?? 'local';
2443
+ if (filterMode === 'local') {
2444
+ return true;
2445
+ }
2446
+ }
2447
+ if (col.columns?.length) {
2448
+ return col.columns.some(c => checkLocalFilter(c));
2449
+ }
2450
+ return false;
2451
+ };
2452
+ return columns.some(c => checkLocalFilter(c));
2453
+ }, ...(ngDevMode ? [{ debugName: "hasLocalFiltering" }] : []));
2432
2454
  hasSorting = computed(() => {
2433
2455
  const config = this.zConfig();
2434
2456
  if (config.enableColumnSorting === false) {
@@ -2450,6 +2472,65 @@ class ZTableComponent {
2450
2472
  };
2451
2473
  return columns.some(c => checkSorting(c));
2452
2474
  }, ...(ngDevMode ? [{ debugName: "hasSorting" }] : []));
2475
+ hasLocalSorting = computed(() => {
2476
+ const config = this.zConfig();
2477
+ if (config.enableColumnSorting === false) {
2478
+ return false;
2479
+ }
2480
+ const columns = config.columns ?? [];
2481
+ const checkLocalSorting = (col) => {
2482
+ const sortConfig = typeof col.sort === 'boolean' ? { enabled: col.sort } : col.sort;
2483
+ if (sortConfig?.enabled) {
2484
+ const sortMode = sortConfig.mode ?? 'local';
2485
+ if (sortMode === 'local') {
2486
+ return true;
2487
+ }
2488
+ }
2489
+ if (col.columns?.length) {
2490
+ return col.columns.some(c => checkLocalSorting(c));
2491
+ }
2492
+ return false;
2493
+ };
2494
+ return columns.some(c => checkLocalSorting(c));
2495
+ }, ...(ngDevMode ? [{ debugName: "hasLocalSorting" }] : []));
2496
+ hasServerFiltering = computed(() => {
2497
+ const columns = this.zConfig().columns ?? [];
2498
+ const checkServerFilter = (col) => {
2499
+ const filterConfig = typeof col.filter === 'boolean' ? { enabled: col.filter } : col.filter;
2500
+ if (filterConfig?.enabled) {
2501
+ const filterMode = filterConfig.mode ?? 'local';
2502
+ if (filterMode === 'server') {
2503
+ return true;
2504
+ }
2505
+ }
2506
+ if (col.columns?.length) {
2507
+ return col.columns.some(c => checkServerFilter(c));
2508
+ }
2509
+ return false;
2510
+ };
2511
+ return columns.some(c => checkServerFilter(c));
2512
+ }, ...(ngDevMode ? [{ debugName: "hasServerFiltering" }] : []));
2513
+ hasServerSorting = computed(() => {
2514
+ const config = this.zConfig();
2515
+ if (config.enableColumnSorting === false) {
2516
+ return false;
2517
+ }
2518
+ const columns = config.columns ?? [];
2519
+ const checkServerSorting = (col) => {
2520
+ const sortConfig = typeof col.sort === 'boolean' ? { enabled: col.sort } : col.sort;
2521
+ if (sortConfig?.enabled) {
2522
+ const sortMode = sortConfig.mode ?? 'local';
2523
+ if (sortMode === 'server') {
2524
+ return true;
2525
+ }
2526
+ }
2527
+ if (col.columns?.length) {
2528
+ return col.columns.some(c => checkServerSorting(c));
2529
+ }
2530
+ return false;
2531
+ };
2532
+ return columns.some(c => checkServerSorting(c));
2533
+ }, ...(ngDevMode ? [{ debugName: "hasServerSorting" }] : []));
2453
2534
  searchConfig = computed(() => {
2454
2535
  const { search } = this.zConfig();
2455
2536
  if (!search) {
@@ -2773,19 +2854,23 @@ class ZTableComponent {
2773
2854
  const isServerMode = config.mode === 'server';
2774
2855
  const pageSize = this.pagination().pageSize || 10;
2775
2856
  const pageCount = isServerMode && config.totalRows ? Math.ceil(config.totalRows / pageSize) : undefined;
2857
+ const hasAnyLocalFiltering = this.hasLocalFiltering();
2858
+ const hasAnyLocalSorting = this.hasLocalSorting();
2859
+ const shouldEnableLocalFiltering = !isServerMode || hasAnyLocalFiltering;
2860
+ const shouldEnableLocalSorting = !isServerMode || hasAnyLocalSorting;
2776
2861
  return {
2777
2862
  data: this._data(),
2778
2863
  columns: this._columns(),
2779
2864
  getCoreRowModel: getCoreRowModel(),
2780
2865
  getExpandedRowModel: this.hasExpandColumn() ? getExpandedRowModel() : undefined,
2781
- getFilteredRowModel: !isServerMode && this.hasFiltering() ? getFilteredRowModel() : undefined,
2782
- getSortedRowModel: !isServerMode && this.hasSorting() ? getSortedRowModel() : undefined,
2866
+ getFilteredRowModel: shouldEnableLocalFiltering && this.hasFiltering() ? getFilteredRowModel() : undefined,
2867
+ getSortedRowModel: shouldEnableLocalSorting && this.hasSorting() ? getSortedRowModel() : undefined,
2783
2868
  getPaginationRowModel: !isServerMode && config.enablePagination ? getPaginationRowModel() : undefined,
2784
- getFacetedRowModel: !isServerMode && this.hasFiltering() ? getFacetedRowModel() : undefined,
2785
- getFacetedUniqueValues: !isServerMode && this.hasFiltering() ? getFacetedUniqueValues() : undefined,
2786
- getFacetedMinMaxValues: !isServerMode && this.hasFiltering() ? getFacetedMinMaxValues() : undefined,
2787
- manualFiltering: isServerMode,
2788
- manualSorting: isServerMode,
2869
+ getFacetedRowModel: shouldEnableLocalFiltering && this.hasFiltering() ? getFacetedRowModel() : undefined,
2870
+ getFacetedUniqueValues: shouldEnableLocalFiltering && this.hasFiltering() ? getFacetedUniqueValues() : undefined,
2871
+ getFacetedMinMaxValues: shouldEnableLocalFiltering && this.hasFiltering() ? getFacetedMinMaxValues() : undefined,
2872
+ manualFiltering: isServerMode && !hasAnyLocalFiltering,
2873
+ manualSorting: isServerMode && !hasAnyLocalSorting,
2789
2874
  manualPagination: isServerMode,
2790
2875
  pageCount: pageCount,
2791
2876
  columnResizeMode: 'onChange',
@@ -2839,24 +2924,38 @@ class ZTableComponent {
2839
2924
  this._handleRowSelectionWithParents(newState);
2840
2925
  },
2841
2926
  onColumnFiltersChange: updater => {
2842
- const newState = typeof updater === 'function' ? updater(this.columnFilters()) : updater;
2843
- this._runAsyncStateUpdate(() => {
2844
- this.columnFilters.set(newState);
2845
- if (this.zConfig().mode !== 'server') {
2927
+ const oldState = this.columnFilters();
2928
+ const newState = typeof updater === 'function' ? updater(oldState) : updater;
2929
+ const changedColumnIds = this._getChangedFilterColumnIds(oldState, newState);
2930
+ const hasAnyLocalChange = changedColumnIds.some(id => this._isColumnFilterModeLocal(id));
2931
+ const hasAnyServerChange = changedColumnIds.some(id => !this._isColumnFilterModeLocal(id));
2932
+ const serverModeFilters = this._filterServerModeColumnFilters(newState);
2933
+ this.columnFilters.set(newState);
2934
+ if (hasAnyLocalChange) {
2935
+ this._runAsyncStateUpdate(() => {
2846
2936
  this.pagination.update(p => ({ ...p, pageIndex: 1 }));
2847
- }
2848
- this._emitFilterChangeDebounced(newState, this.globalFilter());
2849
- });
2937
+ }, true);
2938
+ }
2939
+ if (hasAnyServerChange) {
2940
+ this.zChange.emit({
2941
+ type: 'filter',
2942
+ data: { filters: serverModeFilters, search: this.globalFilter() },
2943
+ });
2944
+ }
2850
2945
  },
2851
2946
  onGlobalFilterChange: updater => {
2852
2947
  const newState = typeof updater === 'function' ? updater(this.globalFilter()) : updater;
2948
+ const hasLocalFilter = this.hasLocalFiltering();
2949
+ const serverModeFilters = this._filterServerModeColumnFilters(this.columnFilters());
2853
2950
  this._runAsyncStateUpdate(() => {
2854
2951
  this.globalFilter.set(newState);
2855
- if (this.zConfig().mode !== 'server') {
2952
+ if (hasLocalFilter) {
2856
2953
  this.pagination.update(p => ({ ...p, pageIndex: 1 }));
2857
2954
  }
2858
- this._emitFilterChangeDebounced(this.columnFilters(), newState);
2859
- });
2955
+ if (serverModeFilters.length > 0 || this.hasServerFiltering()) {
2956
+ this._emitFilterChangeDebounced(serverModeFilters, newState);
2957
+ }
2958
+ }, hasLocalFilter);
2860
2959
  },
2861
2960
  onPaginationChange: updater => {
2862
2961
  const newState = typeof updater === 'function' ? updater(this._tanstackPagination()) : updater;
@@ -2868,14 +2967,21 @@ class ZTableComponent {
2868
2967
  });
2869
2968
  },
2870
2969
  onSortingChange: updater => {
2871
- const newState = typeof updater === 'function' ? updater(this.sorting()) : updater;
2872
- this._runAsyncStateUpdate(() => {
2873
- this.sorting.set(newState);
2874
- if (this.zConfig().mode !== 'server') {
2970
+ const oldState = this.sorting();
2971
+ const newState = typeof updater === 'function' ? updater(oldState) : updater;
2972
+ const changedColumnIds = this._getChangedSortColumnIds(oldState, newState);
2973
+ const hasAnyLocalChange = changedColumnIds.some(id => this._isColumnSortModeLocal(id));
2974
+ const hasAnyServerChange = changedColumnIds.some(id => !this._isColumnSortModeLocal(id));
2975
+ const serverModeSorting = this._filterServerModeSorting(newState);
2976
+ this.sorting.set(newState);
2977
+ if (hasAnyLocalChange) {
2978
+ this._runAsyncStateUpdate(() => {
2875
2979
  this.pagination.update(p => ({ ...p, pageIndex: 1 }));
2876
- }
2877
- this.zChange.emit({ type: 'sort', data: { sorting: newState } });
2878
- });
2980
+ }, true);
2981
+ }
2982
+ if (hasAnyServerChange) {
2983
+ this.zChange.emit({ type: 'sort', data: { sorting: serverModeSorting } });
2984
+ }
2879
2985
  },
2880
2986
  onRowPinningChange: updater => {
2881
2987
  const newState = typeof updater === 'function' ? updater(this.rowPinning()) : updater;
@@ -3032,8 +3138,10 @@ class ZTableComponent {
3032
3138
  }
3033
3139
  });
3034
3140
  explicitEffect([this.columnFilters, this.globalFilter, this.pagination, this.sorting], () => {
3035
- this._checkVerticalScroll();
3036
- this._checkHorizontalScroll();
3141
+ queueMicrotask(() => {
3142
+ this._checkVerticalScroll();
3143
+ this._checkHorizontalScroll();
3144
+ });
3037
3145
  });
3038
3146
  explicitEffect([this.zLoading, this.isProcessing], () => {
3039
3147
  const loading = this.zLoading();
@@ -3142,9 +3250,12 @@ class ZTableComponent {
3142
3250
  data: { selection: finalState },
3143
3251
  });
3144
3252
  }
3145
- _runAsyncStateUpdate(updateFn) {
3253
+ _runAsyncStateUpdate(updateFn, forceLocal = false) {
3146
3254
  const isServerMode = this.zConfig().mode === 'server';
3147
- if (isServerMode) {
3255
+ const hasLocalFiltering = this.hasLocalFiltering();
3256
+ const hasLocalSorting = this.hasLocalSorting();
3257
+ const shouldRunAsync = !isServerMode || forceLocal || hasLocalFiltering || hasLocalSorting;
3258
+ if (!shouldRunAsync) {
3148
3259
  updateFn();
3149
3260
  return;
3150
3261
  }
@@ -3155,14 +3266,6 @@ class ZTableComponent {
3155
3266
  }, this.zConfig().debounceTime ?? Z_DEFAULT_DEBOUNCE_TIME);
3156
3267
  }
3157
3268
  _emitFilterChangeDebounced(filters, search) {
3158
- const isServerMode = this.zConfig().mode === 'server';
3159
- if (isServerMode) {
3160
- this.zChange.emit({
3161
- type: 'filter',
3162
- data: { filters, search },
3163
- });
3164
- return;
3165
- }
3166
3269
  if (this._filterEmitDebounceTimeout) {
3167
3270
  clearTimeout(this._filterEmitDebounceTimeout);
3168
3271
  }
@@ -3310,10 +3413,8 @@ class ZTableComponent {
3310
3413
  pagination: this.pagination(),
3311
3414
  },
3312
3415
  });
3313
- queueMicrotask(() => {
3314
- this._checkVerticalScroll();
3315
- this._checkHorizontalScroll();
3316
- });
3416
+ this._checkVerticalScroll();
3417
+ this._checkHorizontalScroll();
3317
3418
  });
3318
3419
  }
3319
3420
  toggleHeaderFooterShadow() {
@@ -3588,6 +3689,64 @@ class ZTableComponent {
3588
3689
  }
3589
3690
  return true;
3590
3691
  }
3692
+ _getChangedFilterColumnIds(oldState, newState) {
3693
+ const changedIds = [];
3694
+ const oldMap = new Map(oldState.map(f => [f.id, f.value]));
3695
+ const newMap = new Map(newState.map(f => [f.id, f.value]));
3696
+ for (const filter of newState) {
3697
+ const oldValue = oldMap.get(filter.id);
3698
+ if (JSON.stringify(oldValue) !== JSON.stringify(filter.value)) {
3699
+ changedIds.push(filter.id);
3700
+ }
3701
+ }
3702
+ for (const filter of oldState) {
3703
+ if (!newMap.has(filter.id)) {
3704
+ changedIds.push(filter.id);
3705
+ }
3706
+ }
3707
+ return [...new Set(changedIds)];
3708
+ }
3709
+ _getChangedSortColumnIds(oldState, newState) {
3710
+ const changedIds = [];
3711
+ const oldMap = new Map(oldState.map(s => [s.id, s.desc]));
3712
+ const newMap = new Map(newState.map(s => [s.id, s.desc]));
3713
+ for (const sort of newState) {
3714
+ const oldDesc = oldMap.get(sort.id);
3715
+ if (oldDesc !== sort.desc) {
3716
+ changedIds.push(sort.id);
3717
+ }
3718
+ }
3719
+ for (const sort of oldState) {
3720
+ if (!newMap.has(sort.id)) {
3721
+ changedIds.push(sort.id);
3722
+ }
3723
+ }
3724
+ return [...new Set(changedIds)];
3725
+ }
3726
+ _isColumnFilterModeLocal(columnId) {
3727
+ const columnConfig = this._findColumnConfig(columnId);
3728
+ if (!columnConfig) {
3729
+ return true;
3730
+ }
3731
+ const filterConfig = typeof columnConfig.filter === 'boolean' ? { enabled: columnConfig.filter } : columnConfig.filter;
3732
+ const filterMode = filterConfig?.mode ?? 'local';
3733
+ return filterMode === 'local';
3734
+ }
3735
+ _isColumnSortModeLocal(columnId) {
3736
+ const columnConfig = this._findColumnConfig(columnId);
3737
+ if (!columnConfig) {
3738
+ return true;
3739
+ }
3740
+ const sortConfig = typeof columnConfig.sort === 'boolean' ? { enabled: columnConfig.sort } : columnConfig.sort;
3741
+ const sortMode = sortConfig?.mode ?? 'local';
3742
+ return sortMode === 'local';
3743
+ }
3744
+ _filterServerModeColumnFilters(filters) {
3745
+ return filters.filter(filter => !this._isColumnFilterModeLocal(filter.id));
3746
+ }
3747
+ _filterServerModeSorting(sorting) {
3748
+ return sorting.filter(sort => !this._isColumnSortModeLocal(sort.id));
3749
+ }
3591
3750
  _findColumnConfig(columnId) {
3592
3751
  const { columns } = this.zConfig();
3593
3752
  if (columns !== this._lastColumnsRef) {