@ascentgl/ads-ui 21.58.0 → 21.60.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.
@@ -7272,11 +7272,11 @@ class AdsColumnSortFilterMenuComponent {
7272
7272
  return text.length > this.MAX_LABEL_LENGTH;
7273
7273
  }
7274
7274
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AdsColumnSortFilterMenuComponent, deps: [{ token: i1.AdsIconRegistry }], target: i0.ɵɵFactoryTarget.Component }); }
7275
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: AdsColumnSortFilterMenuComponent, isStandalone: false, selector: "ads-column-sort-filter-menu", inputs: { config: "config", currentSortDirection: "currentSortDirection", selectedFilterValues: "selectedFilterValues" }, outputs: { sortChanged: "sortChanged", filterChanged: "filterChanged", hideColumn: "hideColumn" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"column-sort-filter-menu\"\n (click)=\"$event.stopPropagation()\"\n [class.full-height]=\"hasFilterOptions && hasSortOptions\"\n>\n <!-- Sort Options -->\n @if (hasSortOptions) {\n <div class=\"sort-section\">\n @for (sortOption of sortOptions; track sortOption.direction) {\n <div\n class=\"sort-option\"\n [class.active]=\"isSortActive(sortOption.direction)\"\n (click)=\"onSortOptionClick(sortOption.direction)\"\n >\n <ads-icon\n [name]=\"sortOption.direction === 'asc' ? 'sort_down_to_up' : 'sort_up_to_down'\"\n [theme]=\"isSortActive(sortOption.direction) ? 'secondary' : 'iconPrimary'\"\n size=\"xxs_16\"\n class=\"sort-icon\"\n />\n <span class=\"sort-label\">{{ sortOption.label }}</span>\n @if (isSortActive(sortOption.direction)) {\n <ads-icon\n name=\"check_circle_filled\"\n theme=\"secondary\"\n size=\"xxs_16\"\n />\n }\n </div>\n }\n </div>\n }\n\n @if (hasFilterOptions && hasSortOptions) {\n <ads-divider />\n }\n\n <!-- Filter Section -->\n @if (hasFilterOptions) {\n <div class=\"filter-section\">\n <ads-search-input\n [control]=\"searchControl\"\n placeholder=\"Filter Search\"\n [showFooter]=\"false\"\n />\n\n @if (noResultsFound()) {\n <p class=\"no-results\">\n Can't find \"{{ searchValue() }}.\" Try searching something else.\n </p>\n } @else {\n <div class=\"filter-options\">\n <!-- Select All - only show when not searching -->\n @if (!searchValue()) {\n <ads-checkbox\n [control]=\"selectAllControl\"\n label=\"Select All\"\n [showFooter]=\"false\"\n />\n }\n\n <!-- Filter Options List -->\n @for (option of filteredOptions(); track option.value) {\n <div class=\"filter-option-wrapper\" [matTooltip]=\"option.label\" [matTooltipDisabled]=\"!isTextTruncated(option.label)\">\n <ads-checkbox\n [control]=\"option.control\"\n [label]=\"option.label\"\n [showFooter]=\"false\"\n />\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Hide Column -->\n <div class=\"hide-column-section\" (click)=\"onHideColumnClick()\">\n <ads-icon name=\"visibility_eye_none\" theme=\"iconPrimary\" stroke=\"iconPrimary\" size=\"xxs_16\" />\n <span>Hide Column</span>\n </div>\n</div>\n\n", styles: [".column-sort-filter-menu{width:234px;max-height:358px;background-color:var(--color-white);display:flex;flex-direction:column}.column-sort-filter-menu.full-height{height:358px}.column-sort-filter-menu .sort-section{padding:0;flex-shrink:0}.column-sort-filter-menu .sort-section .sort-option{display:flex;align-items:center;gap:8px;padding:12px;cursor:pointer;transition:background-color .2s ease}.column-sort-filter-menu .sort-section .sort-option .sort-label{font-size:16px;line-height:21px;color:var(--color-dark)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active){background-color:var(--color-secondary-hover)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active) .sort-label{color:var(--color-white)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active) .sort-icon ::ng-deep svg{fill:var(--color-white)!important}.column-sort-filter-menu .sort-section .sort-option.active{background-color:var(--color-secondary-10)}.column-sort-filter-menu .filter-section{padding:0 12px;flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}.column-sort-filter-menu .filter-section ads-search-input{display:block;padding:12px 0;flex-shrink:0}.column-sort-filter-menu .filter-section .no-results{color:var(--color-error);font-size:12px;line-height:16px;padding:12px 0;font-weight:600;margin:0}.column-sort-filter-menu .filter-section .filter-options{flex:1;overflow-y:auto;overflow-x:hidden;min-height:0}.column-sort-filter-menu .filter-section .filter-options .filter-option-wrapper ads-checkbox{display:block}.column-sort-filter-menu .filter-section .filter-options .filter-option-wrapper ads-checkbox ::ng-deep .checkbox-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:160px}.column-sort-filter-menu .hide-column-section{display:flex;align-items:center;gap:8px;padding:12px;cursor:pointer;transition:background-color .2s ease;flex-shrink:0;border-top:1px solid var(--color-light)}.column-sort-filter-menu .hide-column-section:hover{background-color:var(--color-secondary-hover)}.column-sort-filter-menu .hide-column-section:hover span{color:var(--color-white)}.column-sort-filter-menu .hide-column-section:hover ads-icon ::ng-deep svg{fill:var(--color-white)!important;stroke:var(--color-white)!important}.column-sort-filter-menu .hide-column-section:active{background-color:var(--color-secondary-pressed)}.column-sort-filter-menu .hide-column-section:active span{color:var(--color-white)}.column-sort-filter-menu .hide-column-section:active ads-icon ::ng-deep svg{fill:var(--color-white)!important;stroke:var(--color-white)!important}.column-sort-filter-menu .hide-column-section span{font-size:16px;line-height:21px;color:var(--color-dark)}\n"], dependencies: [{ kind: "component", type: i1.AdsIconComponent, selector: "ads-icon", inputs: ["size", "name", "color", "theme", "stroke"] }, { kind: "component", type: AdsSearchInputComponent, selector: "ads-search-input", inputs: ["searchCallback", "isIconClickable", "searchEmptyValue", "loading"] }, { kind: "component", type: AdsCheckboxComponent, selector: "ads-checkbox", inputs: ["indeterminate", "width", "tooltip", "tooltipHref", "size"] }, { kind: "component", type: DividerComponent, selector: "ads-divider", inputs: ["margin", "color"] }, { kind: "directive", type: i13.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
7275
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: AdsColumnSortFilterMenuComponent, isStandalone: false, selector: "ads-column-sort-filter-menu", inputs: { config: "config", currentSortDirection: "currentSortDirection", selectedFilterValues: "selectedFilterValues" }, outputs: { sortChanged: "sortChanged", filterChanged: "filterChanged", hideColumn: "hideColumn" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"column-sort-filter-menu\"\n (click)=\"$event.stopPropagation()\"\n [class.full-height]=\"hasFilterOptions && hasSortOptions\"\n>\n <!-- Sort Options -->\n @if (hasSortOptions) {\n <div class=\"sort-section\">\n @for (sortOption of sortOptions; track sortOption.direction) {\n <div\n class=\"sort-option\"\n [class.active]=\"isSortActive(sortOption.direction)\"\n (click)=\"onSortOptionClick(sortOption.direction)\"\n >\n <ads-icon\n [name]=\"sortOption.direction === 'asc' ? 'sort_down_to_up' : 'sort_up_to_down'\"\n [theme]=\"isSortActive(sortOption.direction) ? 'secondary' : 'iconPrimary'\"\n size=\"xxs_16\"\n class=\"sort-icon\"\n />\n <span class=\"sort-label\">{{ sortOption.label }}</span>\n @if (isSortActive(sortOption.direction)) {\n <ads-icon\n name=\"check_circle_filled\"\n theme=\"secondary\"\n size=\"xxs_16\"\n />\n }\n </div>\n }\n </div>\n }\n\n @if (hasFilterOptions && hasSortOptions) {\n <ads-divider />\n }\n\n <!-- Filter Section -->\n @if (hasFilterOptions) {\n <div class=\"filter-section\">\n <ads-search-input\n [control]=\"searchControl\"\n placeholder=\"Filter Search\"\n [showFooter]=\"false\"\n />\n\n @if (noResultsFound()) {\n <p class=\"no-results\">\n Can't find \"{{ searchValue() }}.\" Try searching something else.\n </p>\n } @else {\n <div class=\"filter-options\">\n <!-- Select All - only show when not searching -->\n @if (!searchValue()) {\n <ads-checkbox\n [control]=\"selectAllControl\"\n label=\"Select All\"\n [showFooter]=\"false\"\n />\n }\n\n <!-- Filter Options List -->\n @for (option of filteredOptions(); track option.value) {\n <div class=\"filter-option-wrapper\" [matTooltip]=\"option.label\" [matTooltipDisabled]=\"!isTextTruncated(option.label)\">\n <ads-checkbox\n [control]=\"option.control\"\n [label]=\"option.label\"\n [showFooter]=\"false\"\n />\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Hide Column -->\n <div class=\"hide-column-section\" (click)=\"onHideColumnClick()\">\n <ads-icon name=\"visibility_eye_none\" theme=\"iconPrimary\" stroke=\"iconPrimary\" size=\"xxs_16\" />\n <span>Hide Column</span>\n </div>\n</div>\n\n", styles: [".column-sort-filter-menu{width:234px;max-height:358px;background-color:var(--color-white);display:flex;flex-direction:column}.column-sort-filter-menu.full-height{height:358px}.column-sort-filter-menu .sort-section{padding:0;flex-shrink:0}.column-sort-filter-menu .sort-section .sort-option{display:flex;align-items:center;gap:8px;padding:12px;cursor:pointer;transition:background-color .2s ease}.column-sort-filter-menu .sort-section .sort-option .sort-label{font-size:16px;line-height:21px;color:var(--color-dark)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active){background-color:var(--color-secondary-hover)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active) .sort-label{color:var(--color-white)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active) .sort-icon ::ng-deep svg{fill:var(--color-white)!important}.column-sort-filter-menu .sort-section .sort-option.active{background-color:var(--color-secondary-10)}.column-sort-filter-menu .filter-section{padding:0 12px;flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}.column-sort-filter-menu .filter-section ads-search-input{display:block;padding:12px 0;flex-shrink:0}.column-sort-filter-menu .filter-section .no-results{color:var(--color-error);font-size:12px;line-height:16px;padding:12px 0;font-weight:600;margin:0}.column-sort-filter-menu .filter-section .filter-options{flex:1;overflow-y:auto;overflow-x:hidden;min-height:0}.column-sort-filter-menu .filter-section .filter-options .filter-option-wrapper ads-checkbox{display:block}.column-sort-filter-menu .filter-section .filter-options .filter-option-wrapper ads-checkbox ::ng-deep .checkbox-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:160px}.column-sort-filter-menu .hide-column-section{display:flex;align-items:center;gap:8px;padding:12px;cursor:pointer;transition:background-color .2s ease;flex-shrink:0;border-top:1px solid var(--color-light)}.column-sort-filter-menu .hide-column-section:hover{background-color:var(--color-secondary-hover)}.column-sort-filter-menu .hide-column-section:hover span{color:var(--color-white)}.column-sort-filter-menu .hide-column-section:hover ads-icon ::ng-deep svg{fill:var(--color-white)!important;stroke:var(--color-white)!important}.column-sort-filter-menu .hide-column-section:active{background-color:var(--color-secondary-pressed)}.column-sort-filter-menu .hide-column-section:active span{color:var(--color-white)}.column-sort-filter-menu .hide-column-section:active ads-icon ::ng-deep svg{fill:var(--color-white)!important;stroke:var(--color-white)!important}.column-sort-filter-menu .hide-column-section span{font-size:16px;line-height:21px;color:var(--color-dark)}\n"], dependencies: [{ kind: "component", type: i1.AdsIconComponent, selector: "ads-icon", inputs: ["size", "name", "color", "theme", "stroke"] }, { kind: "component", type: AdsSearchInputComponent, selector: "ads-search-input", inputs: ["searchCallback", "isIconClickable", "searchEmptyValue", "loading"] }, { kind: "component", type: AdsCheckboxComponent, selector: "ads-checkbox", inputs: ["indeterminate", "width", "tooltip", "tooltipHref", "size"] }, { kind: "component", type: DividerComponent, selector: "ads-divider", inputs: ["margin", "color"] }, { kind: "directive", type: i13.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7276
7276
  }
7277
7277
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AdsColumnSortFilterMenuComponent, decorators: [{
7278
7278
  type: Component,
7279
- args: [{ selector: 'ads-column-sort-filter-menu', standalone: false, template: "<div\n class=\"column-sort-filter-menu\"\n (click)=\"$event.stopPropagation()\"\n [class.full-height]=\"hasFilterOptions && hasSortOptions\"\n>\n <!-- Sort Options -->\n @if (hasSortOptions) {\n <div class=\"sort-section\">\n @for (sortOption of sortOptions; track sortOption.direction) {\n <div\n class=\"sort-option\"\n [class.active]=\"isSortActive(sortOption.direction)\"\n (click)=\"onSortOptionClick(sortOption.direction)\"\n >\n <ads-icon\n [name]=\"sortOption.direction === 'asc' ? 'sort_down_to_up' : 'sort_up_to_down'\"\n [theme]=\"isSortActive(sortOption.direction) ? 'secondary' : 'iconPrimary'\"\n size=\"xxs_16\"\n class=\"sort-icon\"\n />\n <span class=\"sort-label\">{{ sortOption.label }}</span>\n @if (isSortActive(sortOption.direction)) {\n <ads-icon\n name=\"check_circle_filled\"\n theme=\"secondary\"\n size=\"xxs_16\"\n />\n }\n </div>\n }\n </div>\n }\n\n @if (hasFilterOptions && hasSortOptions) {\n <ads-divider />\n }\n\n <!-- Filter Section -->\n @if (hasFilterOptions) {\n <div class=\"filter-section\">\n <ads-search-input\n [control]=\"searchControl\"\n placeholder=\"Filter Search\"\n [showFooter]=\"false\"\n />\n\n @if (noResultsFound()) {\n <p class=\"no-results\">\n Can't find \"{{ searchValue() }}.\" Try searching something else.\n </p>\n } @else {\n <div class=\"filter-options\">\n <!-- Select All - only show when not searching -->\n @if (!searchValue()) {\n <ads-checkbox\n [control]=\"selectAllControl\"\n label=\"Select All\"\n [showFooter]=\"false\"\n />\n }\n\n <!-- Filter Options List -->\n @for (option of filteredOptions(); track option.value) {\n <div class=\"filter-option-wrapper\" [matTooltip]=\"option.label\" [matTooltipDisabled]=\"!isTextTruncated(option.label)\">\n <ads-checkbox\n [control]=\"option.control\"\n [label]=\"option.label\"\n [showFooter]=\"false\"\n />\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Hide Column -->\n <div class=\"hide-column-section\" (click)=\"onHideColumnClick()\">\n <ads-icon name=\"visibility_eye_none\" theme=\"iconPrimary\" stroke=\"iconPrimary\" size=\"xxs_16\" />\n <span>Hide Column</span>\n </div>\n</div>\n\n", styles: [".column-sort-filter-menu{width:234px;max-height:358px;background-color:var(--color-white);display:flex;flex-direction:column}.column-sort-filter-menu.full-height{height:358px}.column-sort-filter-menu .sort-section{padding:0;flex-shrink:0}.column-sort-filter-menu .sort-section .sort-option{display:flex;align-items:center;gap:8px;padding:12px;cursor:pointer;transition:background-color .2s ease}.column-sort-filter-menu .sort-section .sort-option .sort-label{font-size:16px;line-height:21px;color:var(--color-dark)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active){background-color:var(--color-secondary-hover)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active) .sort-label{color:var(--color-white)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active) .sort-icon ::ng-deep svg{fill:var(--color-white)!important}.column-sort-filter-menu .sort-section .sort-option.active{background-color:var(--color-secondary-10)}.column-sort-filter-menu .filter-section{padding:0 12px;flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}.column-sort-filter-menu .filter-section ads-search-input{display:block;padding:12px 0;flex-shrink:0}.column-sort-filter-menu .filter-section .no-results{color:var(--color-error);font-size:12px;line-height:16px;padding:12px 0;font-weight:600;margin:0}.column-sort-filter-menu .filter-section .filter-options{flex:1;overflow-y:auto;overflow-x:hidden;min-height:0}.column-sort-filter-menu .filter-section .filter-options .filter-option-wrapper ads-checkbox{display:block}.column-sort-filter-menu .filter-section .filter-options .filter-option-wrapper ads-checkbox ::ng-deep .checkbox-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:160px}.column-sort-filter-menu .hide-column-section{display:flex;align-items:center;gap:8px;padding:12px;cursor:pointer;transition:background-color .2s ease;flex-shrink:0;border-top:1px solid var(--color-light)}.column-sort-filter-menu .hide-column-section:hover{background-color:var(--color-secondary-hover)}.column-sort-filter-menu .hide-column-section:hover span{color:var(--color-white)}.column-sort-filter-menu .hide-column-section:hover ads-icon ::ng-deep svg{fill:var(--color-white)!important;stroke:var(--color-white)!important}.column-sort-filter-menu .hide-column-section:active{background-color:var(--color-secondary-pressed)}.column-sort-filter-menu .hide-column-section:active span{color:var(--color-white)}.column-sort-filter-menu .hide-column-section:active ads-icon ::ng-deep svg{fill:var(--color-white)!important;stroke:var(--color-white)!important}.column-sort-filter-menu .hide-column-section span{font-size:16px;line-height:21px;color:var(--color-dark)}\n"] }]
7279
+ args: [{ selector: 'ads-column-sort-filter-menu', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"column-sort-filter-menu\"\n (click)=\"$event.stopPropagation()\"\n [class.full-height]=\"hasFilterOptions && hasSortOptions\"\n>\n <!-- Sort Options -->\n @if (hasSortOptions) {\n <div class=\"sort-section\">\n @for (sortOption of sortOptions; track sortOption.direction) {\n <div\n class=\"sort-option\"\n [class.active]=\"isSortActive(sortOption.direction)\"\n (click)=\"onSortOptionClick(sortOption.direction)\"\n >\n <ads-icon\n [name]=\"sortOption.direction === 'asc' ? 'sort_down_to_up' : 'sort_up_to_down'\"\n [theme]=\"isSortActive(sortOption.direction) ? 'secondary' : 'iconPrimary'\"\n size=\"xxs_16\"\n class=\"sort-icon\"\n />\n <span class=\"sort-label\">{{ sortOption.label }}</span>\n @if (isSortActive(sortOption.direction)) {\n <ads-icon\n name=\"check_circle_filled\"\n theme=\"secondary\"\n size=\"xxs_16\"\n />\n }\n </div>\n }\n </div>\n }\n\n @if (hasFilterOptions && hasSortOptions) {\n <ads-divider />\n }\n\n <!-- Filter Section -->\n @if (hasFilterOptions) {\n <div class=\"filter-section\">\n <ads-search-input\n [control]=\"searchControl\"\n placeholder=\"Filter Search\"\n [showFooter]=\"false\"\n />\n\n @if (noResultsFound()) {\n <p class=\"no-results\">\n Can't find \"{{ searchValue() }}.\" Try searching something else.\n </p>\n } @else {\n <div class=\"filter-options\">\n <!-- Select All - only show when not searching -->\n @if (!searchValue()) {\n <ads-checkbox\n [control]=\"selectAllControl\"\n label=\"Select All\"\n [showFooter]=\"false\"\n />\n }\n\n <!-- Filter Options List -->\n @for (option of filteredOptions(); track option.value) {\n <div class=\"filter-option-wrapper\" [matTooltip]=\"option.label\" [matTooltipDisabled]=\"!isTextTruncated(option.label)\">\n <ads-checkbox\n [control]=\"option.control\"\n [label]=\"option.label\"\n [showFooter]=\"false\"\n />\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Hide Column -->\n <div class=\"hide-column-section\" (click)=\"onHideColumnClick()\">\n <ads-icon name=\"visibility_eye_none\" theme=\"iconPrimary\" stroke=\"iconPrimary\" size=\"xxs_16\" />\n <span>Hide Column</span>\n </div>\n</div>\n\n", styles: [".column-sort-filter-menu{width:234px;max-height:358px;background-color:var(--color-white);display:flex;flex-direction:column}.column-sort-filter-menu.full-height{height:358px}.column-sort-filter-menu .sort-section{padding:0;flex-shrink:0}.column-sort-filter-menu .sort-section .sort-option{display:flex;align-items:center;gap:8px;padding:12px;cursor:pointer;transition:background-color .2s ease}.column-sort-filter-menu .sort-section .sort-option .sort-label{font-size:16px;line-height:21px;color:var(--color-dark)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active){background-color:var(--color-secondary-hover)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active) .sort-label{color:var(--color-white)}.column-sort-filter-menu .sort-section .sort-option:hover:not(.active) .sort-icon ::ng-deep svg{fill:var(--color-white)!important}.column-sort-filter-menu .sort-section .sort-option.active{background-color:var(--color-secondary-10)}.column-sort-filter-menu .filter-section{padding:0 12px;flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}.column-sort-filter-menu .filter-section ads-search-input{display:block;padding:12px 0;flex-shrink:0}.column-sort-filter-menu .filter-section .no-results{color:var(--color-error);font-size:12px;line-height:16px;padding:12px 0;font-weight:600;margin:0}.column-sort-filter-menu .filter-section .filter-options{flex:1;overflow-y:auto;overflow-x:hidden;min-height:0}.column-sort-filter-menu .filter-section .filter-options .filter-option-wrapper ads-checkbox{display:block}.column-sort-filter-menu .filter-section .filter-options .filter-option-wrapper ads-checkbox ::ng-deep .checkbox-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:160px}.column-sort-filter-menu .hide-column-section{display:flex;align-items:center;gap:8px;padding:12px;cursor:pointer;transition:background-color .2s ease;flex-shrink:0;border-top:1px solid var(--color-light)}.column-sort-filter-menu .hide-column-section:hover{background-color:var(--color-secondary-hover)}.column-sort-filter-menu .hide-column-section:hover span{color:var(--color-white)}.column-sort-filter-menu .hide-column-section:hover ads-icon ::ng-deep svg{fill:var(--color-white)!important;stroke:var(--color-white)!important}.column-sort-filter-menu .hide-column-section:active{background-color:var(--color-secondary-pressed)}.column-sort-filter-menu .hide-column-section:active span{color:var(--color-white)}.column-sort-filter-menu .hide-column-section:active ads-icon ::ng-deep svg{fill:var(--color-white)!important;stroke:var(--color-white)!important}.column-sort-filter-menu .hide-column-section span{font-size:16px;line-height:21px;color:var(--color-dark)}\n"] }]
7280
7280
  }], ctorParameters: () => [{ type: i1.AdsIconRegistry }], propDecorators: { config: [{
7281
7281
  type: Input
7282
7282
  }], currentSortDirection: [{
@@ -7509,11 +7509,19 @@ class AdsTableComponent {
7509
7509
  adsCustomHeader: AdsCustomHeaderComponent,
7510
7510
  };
7511
7511
  /** @ignore */
7512
- this.filteredColumns = [];
7512
+ this.filteredColumns = signal([], ...(ngDevMode ? [{ debugName: "filteredColumns" }] : []));
7513
7513
  /** @ignore - Flag indicating headers need refresh when menu closes (for dynamic filter options) */
7514
7514
  this.pendingHeaderRefresh = false;
7515
7515
  /** @ignore */
7516
7516
  this.columnVisibilityMenuOpen = false;
7517
+ /** @ignore - Cache for filtered column values to avoid recalculating on every access */
7518
+ this.filteredColumnValuesCache = new Map();
7519
+ /** @ignore - Cache version to invalidate cache when filters change */
7520
+ this.filterCacheVersion = 0;
7521
+ /** @ignore - Cache for unique column values (all values, not filtered) */
7522
+ this.uniqueColumnValuesCache = new Map();
7523
+ /** @ignore - Data version to invalidate unique values cache when rowData changes */
7524
+ this.dataVersion = 0;
7517
7525
  /** @ignore */
7518
7526
  this.isExternalFilterPresent = () => {
7519
7527
  // Check if any custom column filter is active
@@ -7526,8 +7534,11 @@ class AdsTableComponent {
7526
7534
  const explicitConfig = this.columnSortFilterConfigs.find(c => c.field === field);
7527
7535
  if (explicitConfig) {
7528
7536
  // For columns with explicit config, check if not all options are selected
7529
- const config = this.getBaseColumnSortFilterConfig(field);
7530
- if (config?.filterOptions && values.length < config.filterOptions.length) {
7537
+ // Use the original filterOptions from config if provided, otherwise get unique values
7538
+ const baseFilterOptions = explicitConfig.filterOptions && explicitConfig.filterOptions.length > 0
7539
+ ? explicitConfig.filterOptions
7540
+ : this.getUniqueColumnValues(field);
7541
+ if (baseFilterOptions.length > 0 && values.length < baseFilterOptions.length) {
7531
7542
  return true;
7532
7543
  }
7533
7544
  }
@@ -7551,8 +7562,11 @@ class AdsTableComponent {
7551
7562
  const explicitConfig = this.columnSortFilterConfigs.find(c => c.field === field);
7552
7563
  if (explicitConfig) {
7553
7564
  // For columns with explicit config, check if all options are selected
7554
- const config = this.getBaseColumnSortFilterConfig(field);
7555
- if (config?.filterOptions && selectedValues.length === config.filterOptions.length) {
7565
+ // Use the original filterOptions from config if provided, otherwise get unique values
7566
+ const baseFilterOptions = explicitConfig.filterOptions && explicitConfig.filterOptions.length > 0
7567
+ ? explicitConfig.filterOptions
7568
+ : this.getUniqueColumnValues(field);
7569
+ if (baseFilterOptions.length > 0 && selectedValues.length === baseFilterOptions.length) {
7556
7570
  // All values selected = no filter, skip this column
7557
7571
  continue;
7558
7572
  }
@@ -7665,6 +7679,8 @@ class AdsTableComponent {
7665
7679
  if (changes['rowData'] && this.enableCustomSortFilter) {
7666
7680
  const newData = changes['rowData'].currentValue;
7667
7681
  const oldData = changes['rowData'].previousValue;
7682
+ // Invalidate all caches when rowData changes
7683
+ this.invalidateDataCache();
7668
7684
  // Refresh headers if we went from empty/null to having data
7669
7685
  if ((!oldData || oldData.length === 0) && newData && newData.length > 0) {
7670
7686
  Promise.resolve().then(() => {
@@ -7811,16 +7827,17 @@ class AdsTableComponent {
7811
7827
  }
7812
7828
  /** @ignore */
7813
7829
  get filterButtonLabel() {
7814
- if (this.filteredColumns.length === 0) {
7830
+ const filtered = this.filteredColumns();
7831
+ if (filtered.length === 0) {
7815
7832
  return 'Filter';
7816
7833
  }
7817
- else if (this.filteredColumns.length === 1) {
7818
- const column = this.getActiveColumnDefs().find((col) => col.field === this.filteredColumns[0]);
7819
- const columnName = column?.headerName || column?.field || this.filteredColumns[0];
7834
+ else if (filtered.length === 1) {
7835
+ const column = this.getActiveColumnDefs().find((col) => col.field === filtered[0]);
7836
+ const columnName = column?.headerName || column?.field || filtered[0];
7820
7837
  return `Filtered by ${columnName}`;
7821
7838
  }
7822
7839
  else {
7823
- const columnNames = this.filteredColumns.map((fieldName) => {
7840
+ const columnNames = filtered.map((fieldName) => {
7824
7841
  const column = this.getActiveColumnDefs().find((col) => col.field === fieldName);
7825
7842
  return column?.headerName || column?.field || fieldName;
7826
7843
  });
@@ -7833,7 +7850,7 @@ class AdsTableComponent {
7833
7850
  }
7834
7851
  /** @ignore */
7835
7852
  get isFilteredTable() {
7836
- return this.filteredColumns.length > 0;
7853
+ return this.filteredColumns().length > 0;
7837
7854
  }
7838
7855
  /** @ignore */
7839
7856
  updateFilteringState() {
@@ -7845,29 +7862,30 @@ class AdsTableComponent {
7845
7862
  }
7846
7863
  // Check custom column filter states
7847
7864
  for (const [field, values] of this.columnFilterStates()) {
7848
- // Use base config to get all possible options (not filtered ones)
7849
- const config = this.getBaseColumnSortFilterConfig(field);
7850
- if (config?.filterOptions) {
7865
+ // Check if this column has explicit config in columnSortFilterConfigs
7866
+ const explicitConfig = this.columnSortFilterConfigs.find(c => c.field === field);
7867
+ if (explicitConfig) {
7868
+ // Use the original filterOptions from config if provided, otherwise get unique values
7869
+ const baseFilterOptions = explicitConfig.filterOptions && explicitConfig.filterOptions.length > 0
7870
+ ? explicitConfig.filterOptions
7871
+ : this.getUniqueColumnValues(field);
7851
7872
  // Column is filtered if:
7852
7873
  // - No options are selected (empty array = all unchecked)
7853
7874
  // - Some but not all options are selected
7854
- // - filterOptions is empty but we have stored values (data not loaded yet)
7855
- const hasFilterOptions = config.filterOptions.length > 0;
7856
7875
  const isFiltered = values.length === 0 ||
7857
- (hasFilterOptions && values.length < config.filterOptions.length) ||
7858
- (!hasFilterOptions && values.length > 0);
7876
+ (baseFilterOptions.length > 0 && values.length < baseFilterOptions.length);
7859
7877
  if (isFiltered && !filteredColumnsList.includes(field)) {
7860
7878
  filteredColumnsList.push(field);
7861
7879
  }
7862
7880
  }
7863
7881
  else if (values.length > 0) {
7864
- // If no config but we have filter values, consider it filtered
7882
+ // For columns without explicit config, any stored filter state means filter is active
7865
7883
  if (!filteredColumnsList.includes(field)) {
7866
7884
  filteredColumnsList.push(field);
7867
7885
  }
7868
7886
  }
7869
7887
  }
7870
- this.filteredColumns = filteredColumnsList;
7888
+ this.filteredColumns.set(filteredColumnsList);
7871
7889
  }
7872
7890
  /** @ignore */
7873
7891
  onSortChanged() {
@@ -7903,6 +7921,8 @@ class AdsTableComponent {
7903
7921
  }
7904
7922
  }
7905
7923
  this.columnFilterStates.set(newStates);
7924
+ // Invalidate the filter cache since filters changed
7925
+ this.invalidateFilterCache();
7906
7926
  // Trigger external filter update
7907
7927
  this.gridApi.onFilterChanged();
7908
7928
  this.updateFilteringState();
@@ -7926,11 +7946,17 @@ class AdsTableComponent {
7926
7946
  }
7927
7947
  }
7928
7948
  // ============ Custom Sort/Filter Menu Methods ============
7929
- /** @ignore - Extract unique values from a column in rowData */
7949
+ /** @ignore - Extract unique values from a column in rowData (with caching) */
7930
7950
  getUniqueColumnValues(field) {
7931
7951
  if (!this.rowData || this.rowData.length === 0) {
7932
7952
  return [];
7933
7953
  }
7954
+ // Check cache first
7955
+ const cacheKey = `${field}_v${this.dataVersion}`;
7956
+ const cached = this.uniqueColumnValuesCache.get(cacheKey);
7957
+ if (cached) {
7958
+ return cached;
7959
+ }
7934
7960
  const uniqueValues = new Set();
7935
7961
  this.rowData.forEach(row => {
7936
7962
  const value = row[field];
@@ -7938,22 +7964,34 @@ class AdsTableComponent {
7938
7964
  uniqueValues.add(String(value));
7939
7965
  }
7940
7966
  });
7941
- return Array.from(uniqueValues).sort();
7967
+ const result = Array.from(uniqueValues).sort();
7968
+ // Cache the result
7969
+ this.uniqueColumnValuesCache.set(cacheKey, result);
7970
+ return result;
7942
7971
  }
7943
7972
  /**
7944
7973
  * @ignore - Extract unique values for a column, considering filters from OTHER columns only.
7945
7974
  * This enables cross-filtering: when you filter Status="Delayed", the Destination filter
7946
7975
  * shows all destinations that have at least one "Delayed" row, and vice versa.
7976
+ * Uses caching to avoid expensive recalculations on every access.
7947
7977
  */
7948
7978
  getFilteredColumnValues(field) {
7949
7979
  if (!this.rowData || this.rowData.length === 0) {
7950
7980
  return [];
7951
7981
  }
7982
+ // Check cache first
7983
+ const cacheKey = `${field}_v${this.filterCacheVersion}`;
7984
+ const cached = this.filteredColumnValuesCache.get(cacheKey);
7985
+ if (cached) {
7986
+ return cached;
7987
+ }
7952
7988
  // Check if any filter is active (excluding the current field)
7953
7989
  const hasOtherActiveFilters = this.hasActiveFiltersExcluding(field);
7954
7990
  // If no other filters are active, return all unique values
7955
7991
  if (!hasOtherActiveFilters) {
7956
- return this.getUniqueColumnValues(field);
7992
+ const values = this.getUniqueColumnValues(field);
7993
+ this.filteredColumnValuesCache.set(cacheKey, values);
7994
+ return values;
7957
7995
  }
7958
7996
  const uniqueValues = new Set();
7959
7997
  // Iterate through all rows and check if they pass filters from OTHER columns
@@ -7966,10 +8004,28 @@ class AdsTableComponent {
7966
8004
  }
7967
8005
  });
7968
8006
  // If no values found, fall back to all values
8007
+ let result;
7969
8008
  if (uniqueValues.size === 0) {
7970
- return this.getUniqueColumnValues(field);
8009
+ result = this.getUniqueColumnValues(field);
7971
8010
  }
7972
- return Array.from(uniqueValues).sort();
8011
+ else {
8012
+ result = Array.from(uniqueValues).sort();
8013
+ }
8014
+ // Cache the result
8015
+ this.filteredColumnValuesCache.set(cacheKey, result);
8016
+ return result;
8017
+ }
8018
+ /** @ignore - Invalidate the filtered column values cache */
8019
+ invalidateFilterCache() {
8020
+ this.filterCacheVersion++;
8021
+ this.filteredColumnValuesCache.clear();
8022
+ }
8023
+ /** @ignore - Invalidate the unique column values cache (when rowData changes) */
8024
+ invalidateDataCache() {
8025
+ this.dataVersion++;
8026
+ this.uniqueColumnValuesCache.clear();
8027
+ // Also invalidate filter cache since it depends on data
8028
+ this.invalidateFilterCache();
7973
8029
  }
7974
8030
  /** @ignore - Check if there are any active filters excluding the specified field */
7975
8031
  hasActiveFiltersExcluding(excludeField) {
@@ -8133,8 +8189,24 @@ class AdsTableComponent {
8133
8189
  /** @ignore */
8134
8190
  onColumnFilterChanged(event) {
8135
8191
  const newStates = new Map(this.columnFilterStates());
8136
- newStates.set(event.field, event.values);
8192
+ // Get the base filter options for this field to check if all are selected
8193
+ const explicitConfig = this.columnSortFilterConfigs.find(c => c.field === event.field);
8194
+ const baseFilterOptions = explicitConfig?.filterOptions && explicitConfig.filterOptions.length > 0
8195
+ ? explicitConfig.filterOptions
8196
+ : this.getUniqueColumnValues(event.field);
8197
+ // If all options are selected, remove from filter states (no filter active)
8198
+ // Otherwise, store the selected values
8199
+ if (baseFilterOptions.length > 0 && event.values.length === baseFilterOptions.length) {
8200
+ // All items checked = no filter active, remove from storage
8201
+ newStates.delete(event.field);
8202
+ }
8203
+ else {
8204
+ // Some items unchecked or all unchecked = filter is active, store the values
8205
+ newStates.set(event.field, event.values);
8206
+ }
8137
8207
  this.columnFilterStates.set(newStates);
8208
+ // Invalidate the filter cache since filters changed
8209
+ this.invalidateFilterCache();
8138
8210
  // Apply external filter to grid immediately
8139
8211
  if (this.gridApi) {
8140
8212
  this.gridApi.onFilterChanged();
@@ -8259,11 +8331,7 @@ class AdsTableComponent {
8259
8331
  params.api.sizeColumnsToFit();
8260
8332
  // Re-evaluate filtering state now that data is available
8261
8333
  // This ensures filter button shows correct state when filters were applied before data loaded
8262
- // Use setTimeout to avoid ExpressionChangedAfterItHasBeenCheckedError
8263
- setTimeout(() => {
8264
- this.updateFilteringState();
8265
- this.cdr.detectChanges();
8266
- });
8334
+ this.updateFilteringState();
8267
8335
  }
8268
8336
  /** @ignore */
8269
8337
  getAgGridIcons() {