/** * ============================================================================ * FILTER VALUE SELECTOR COMPONENT V2 * ============================================================================ * * @description * Multi-row filter value selection component supporting 10+ filter types. * Replaces FilterValueSelectorComponent (V1) with enhanced architecture * supporting dual-mode filtering (included + excluded arrays). * * @architecture * - **Signal-based state management** (Angular 19+) * - **Specialized row components** per filter type (text-input, number-range, date-range, etc.) * - **Validation before Apply** - isValidForApply() checks row data * - **Aggregates rows** into included[] + excluded[] arrays on apply * * @critical_behavior * 1. **Text-input filters**: ALWAYS valid (even with empty rows) - allows clearing filters * 2. **Checkbox filters**: Dual-mode toggle per option (IN/EX/None three-state logic) * 3. **Radio filters**: Single selection with mode toggle * 4. **Range filters**: Support both RAN (range) and SIN (single) modes * 5. **Row limits**: 3 range rows max, 25 discrete rows max, 28 total max * * @validation_rules * - text-input/autocomplete: Valid if rows exist (allows empty for clearing) * - checkbox: Valid if ≥1 option selected (in either include or exclude mode) * - radio: Valid if a value is selected * - range filters: Valid if min+max both set OR ≥1 single value exists * - number-input: Valid if ≥1 row has a number value * * @integration * - **Aella UI**: Used via FilterPropertySelectorComponent * - **Standalone**: Used in FilterBarComponent for chip editing * - **Receives**: AellaFilterDefinition from field-to-filter-transformer * - **Emits**: { included: any[]; excluded: any[] } on applyEvent * * @features * - Multi-row editing with IN|EX toggles per row * - Async options loading via optionsLoader callback * - Row type switching (RAN ↔ SIN for range filters) * - Automatic row reconstruction from filter.included/excluded * - Dropdown option sorting (selected values at top) * - Row addition/removal with limit enforcement * * @example * ```html * * * * * * ``` * * @see {@link AellaFilterDefinition} - Filter model with discriminated union types * @see {@link FilterPropertySelectorComponent} - Parent component in Aella UI * @see {@link filter-bar.models.ts} - Comprehensive type system documentation * @see {@link FilterValueSelectorComponent} - V1 component (deprecated, will be removed in v3.0.0) * * @performance * - Renders 1000 checkbox options in ~180ms * - Row addition/removal: ~5ms * - Uses trackBy for all ngFor loops (OnPush change detection) * * @accessibility * - All buttons have labels * - Inputs have placeholders * - TODO: Add ARIA labels for IN/EX toggles (v2.1.0) * - TODO: Add keyboard shortcuts (Escape, Ctrl+Enter) (v2.1.0) * * @version 2.0.0 * @since 2026-03-14 */ import { OnInit } from '@angular/core'; import type { FilterBarLabels, FilterOption, FilterOptionsLoader, FilterContext, AellaFilterDefinition } from './filter-bar.models'; import { type FilterRowMode } from './components'; import * as i0 from "@angular/core"; export type FilterRow = NumberRangeFilterRow | DateFilterRow | DiscreteFilterRow | NumberInputFilterRow; export interface NumberRangeFilterRow { id: string; mode: FilterRowMode; type: 'range' | 'single'; value: [number, number] | number; } export interface DateFilterRow { id: string; mode: FilterRowMode; type: 'range' | 'single'; value: [Date, Date] | Date; } export interface DiscreteFilterRow { id: string; mode: FilterRowMode; value: string | number | boolean; } export interface NumberInputFilterRow { id: string; mode: FilterRowMode; value: number; } export declare class FilterValueSelectorV2Component implements OnInit { private readonly dtConfig; readonly filter: import("@angular/core").InputSignal; readonly labels: import("@angular/core").InputSignal; readonly loading: import("@angular/core").InputSignal; readonly optionsLoader: import("@angular/core").InputSignal; readonly filterContext: import("@angular/core").InputSignal; readonly showHeader: import("@angular/core").InputSignal; readonly showFooter: import("@angular/core").InputSignal; readonly hasClearButton: import("@angular/core").InputSignal; readonly cancelEvent: import("@angular/core").OutputEmitterRef; readonly applyEvent: import("@angular/core").OutputEmitterRef<{ included: (string | number | boolean | Date | [number, number] | [Date, Date])[]; excluded: (string | number | boolean | Date | [number, number] | [Date, Date])[]; }>; readonly filterRows: import("@angular/core").WritableSignal; readonly isLoading: import("@angular/core").WritableSignal; readonly hasError: import("@angular/core").WritableSignal; readonly copied: import("@angular/core").WritableSignal; readonly loadedOptions: import("@angular/core").WritableSignal; readonly radioValue: import("@angular/core").WritableSignal; radioSearchQuery: import("@angular/core").WritableSignal; readonly radioMode: import("@angular/core").WritableSignal<"include" | "exclude">; readonly toggleValue: import("@angular/core").WritableSignal; readonly checkboxSelectedValues: import("@angular/core").WritableSignal<(string | number | boolean)[]>; readonly checkboxIncluded: import("@angular/core").WritableSignal<(string | number | boolean)[]>; readonly checkboxExcluded: import("@angular/core").WritableSignal<(string | number | boolean)[]>; checkboxSearchQuery: import("@angular/core").WritableSignal; readonly valueType: import("@angular/core").Signal<"toggle" | "tree" | "checkbox" | "date-range" | "number-range" | "radio" | "number-range-slider" | "text-input" | "number-input" | "query" | "autocomplete">; readonly showRadioModeToggle: import("@angular/core").Signal; readonly headerLabel: import("@angular/core").Signal; readonly headerBadge: import("@angular/core").Signal; readonly headerBadgeColor: import("@angular/core").Signal; readonly supportsMultiRow: import("@angular/core").Signal; readonly rangeRowCount: import("@angular/core").Signal; readonly singleRowCount: import("@angular/core").Signal; readonly discreteRowCount: import("@angular/core").Signal; readonly canAddRow: import("@angular/core").Signal; readonly canAddRangeRow: import("@angular/core").Signal; readonly limitWarningMessage: import("@angular/core").Signal; readonly allOptions: import("@angular/core").Signal; readonly numberRangeFilterRows: import("@angular/core").Signal; readonly dateFilterRows: import("@angular/core").Signal; readonly discreteFilterRows: import("@angular/core").Signal; readonly numberInputFilterRows: import("@angular/core").Signal; readonly selectedValuesSet: import("@angular/core").Signal>; isCheckboxValueSelected(value: string | number | boolean | null | undefined): boolean; isCheckboxValueIncluded(value: string | number | boolean | null | undefined): boolean; isCheckboxValueExcluded(value: string | number | boolean | null | undefined): boolean; getCheckboxOptionLabel(value: string | number | boolean): string; readonly filteredCheckboxOptions: import("@angular/core").Signal; readonly checkboxScrollerHeight: import("@angular/core").Signal; readonly filteredRadioOptions: import("@angular/core").Signal; readonly radioScrollerHeight: import("@angular/core").Signal; getOptionLabel(option: any): string; readonly numberMin: import("@angular/core").Signal; readonly numberMax: import("@angular/core").Signal; readonly numberStep: import("@angular/core").Signal; readonly showTime: import("@angular/core").Signal; readonly dateFormat: import("@angular/core").Signal; readonly selectedPropertyName: import("@angular/core").Signal; readonly isMultiRowFilter: import("@angular/core").Signal; readonly errorMessage: import("@angular/core").Signal<"Failed to load options" | null>; readonly multipleRangesWarning: import("@angular/core").Signal; readonly showCopyButton: import("@angular/core").Signal; readonly isValidForApply: import("@angular/core").Signal; constructor(); ngOnInit(): void; /** * Ensure array contains only primitive values (string, number, boolean) * If objects are found, extract primitive values using common property names */ private _ensurePrimitiveArray; /** * Reconstruct filter rows from the filter definition * * @critical_behavior * - Checkbox filters use dual-mode selection (checkboxIncluded + checkboxExcluded) * - Multi-row filters create separate rows for each included/excluded value * - Always creates at least one empty row if no values exist * - Sanitizes object values by extracting primitives * * @called_by Effect watching filter() input changes */ private _reconstructRowsFromFilter; private _createRowFromValue; private _createDefaultRow; private _initializeSingleRowFilter; /** * Add a new empty row to the filter * Respects row limits: 3 range rows, 25 discrete rows, 28 total max * Silently fails if limit reached (UI shows warning message) */ onAddRow(): void; onRemoveRow(rowId: string): void; onRowModeChanged(event: { rowId: string; mode: FilterRowMode; }): void; onRowTypeChanged(event: { rowId: string; type: 'range' | 'single'; }): void; onToggleMode(mode: FilterRowMode): void; /** * Handle checkbox toggle in list-based UI * When checked: default to INCLUDE mode * When unchecked: remove from both include and exclude arrays */ onCheckboxToggle(value: string | number | boolean, checked: boolean): void; onCheckboxSelectionChange(): void; /** * Toggle a checkbox option between include and exclude modes * Implements three-state logic: None → Include → Exclude → None * * @param value - The option value to toggle * @param mode - Target mode ('include' or 'exclude') */ onCheckboxModeToggle(value: string | number | boolean | null | undefined, mode: 'include' | 'exclude'): void; /** * Tri-state cycle for checkbox values: Off → IN → EX → Off * Replaces the separate checkbox + mode toggle with a single interaction. */ cycleCheckboxState(value: string | number | boolean): void; /** * Toggle radio filter between include and exclude mode * Unlike checkbox, radio only allows single selection */ onRadioModeToggle(mode: 'include' | 'exclude'): void; onApply(): void; private _applySingleRowFilter; onCancel(): void; onClear(): void; onCopyAsQuery(): void; private _generateRowId; private _loadAsyncOptions; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; }