@praxisui/table 3.0.0-beta.2 → 3.0.0-beta.4

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.
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { EventEmitter, Output, Input, Optional, Component, ChangeDetectionStrategy, Injectable, LOCALE_ID, Inject, inject, DestroyRef, Directive, ElementRef, ChangeDetectorRef, ViewChild, InjectionToken, HostListener, booleanAttribute, HostBinding, ContentChild, ENVIRONMENT_INITIALIZER } from '@angular/core';
3
- import * as i1$2 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
3
+ import * as i2$1 from '@angular/common';
4
+ import { CommonModule, DatePipe, DecimalPipe, CurrencyPipe, PercentPipe, UpperCasePipe, LowerCasePipe, TitleCasePipe } from '@angular/common';
5
5
  import * as i8$1 from '@angular/material/table';
6
6
  import { MatTableDataSource, MatTableModule, MatTable } from '@angular/material/table';
7
7
  import { HttpContext } from '@angular/common/http';
@@ -19,7 +19,7 @@ import * as i6$1 from '@angular/material/slide-toggle';
19
19
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
20
20
  import * as i10 from '@angular/material/tooltip';
21
21
  import { MatTooltipModule } from '@angular/material/tooltip';
22
- import * as i2$1 from '@angular/material/snack-bar';
22
+ import * as i2$2 from '@angular/material/snack-bar';
23
23
  import { MatSnackBarModule, MatSnackBar } from '@angular/material/snack-bar';
24
24
  import * as i9 from '@angular/material/checkbox';
25
25
  import { MatCheckboxModule } from '@angular/material/checkbox';
@@ -59,7 +59,7 @@ import { MatExpansionModule } from '@angular/material/expansion';
59
59
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
60
60
  import * as i15 from '@angular/material/chips';
61
61
  import { MatChipsModule } from '@angular/material/chips';
62
- import * as i1$3 from '@angular/material/dialog';
62
+ import * as i1$2 from '@angular/material/dialog';
63
63
  import { MatDialogModule } from '@angular/material/dialog';
64
64
  import { distinctUntilChanged, debounceTime as debounceTime$1, take, map, startWith, takeUntil as takeUntil$1 } from 'rxjs/operators';
65
65
  import * as i15$3 from '@angular/material/datepicker';
@@ -4446,7 +4446,7 @@ class VisualFormulaBuilderComponent {
4446
4446
  </div>
4447
4447
  </mat-expansion-panel>
4448
4448
  </div>
4449
- `, isInline: true, styles: [":host{--vfb-primary: var(--md-sys-color-primary);--vfb-primary-container: var(--md-sys-color-primary-container);--vfb-on-primary-container: var(--md-sys-color-on-primary-container);--vfb-surface-container-low: var(--md-sys-color-surface-container-low);--vfb-surface-container: var(--md-sys-color-surface-container);--vfb-outline: var(--md-sys-color-outline);--vfb-on-surface-variant: var(--md-sys-color-on-surface-variant);--vfb-error: var(--md-sys-color-error);--vfb-error-container: var(--md-sys-color-error-container);--vfb-on-error-container: var(--md-sys-color-on-error-container)}.visual-formula-builder{display:flex;flex-direction:column;gap:16px}.formula-type-card,.parameters-card,.expression-preview-card{background-color:var(--vfb-surface-container-low)}.compact-header{padding-bottom:8px;align-items:center}.compact-header .mat-mdc-card-title{font-size:1.1rem;margin:0;line-height:1.2}.compact-header .mat-mdc-card-subtitle{font-size:.875rem;margin:0}.compact-header .mat-mdc-card-avatar{align-self:center}.formula-icon,.params-icon,.preview-icon{background-color:var(--vfb-primary-container);color:var(--vfb-on-primary-container);border-radius:50%;width:36px;height:36px;font-size:20px;display:inline-flex;align-items:center;justify-content:center}.formula-type-select{width:100%}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.formula-option{display:flex;align-items:center;gap:12px;padding:8px 0}.option-icon{color:var(--vfb-primary);font-size:20px;opacity:.95}.option-content{display:flex;flex-direction:column}.option-label{font-weight:500;font-size:.9rem}.option-description{font-size:.8rem;color:var(--vfb-on-surface-variant)}.parameters-form{display:flex;flex-direction:column;gap:16px}.parameter-field{display:flex;flex-direction:column}.full-width{width:100%}.field-option{display:flex;align-items:center;gap:8px}.field-type-icon{font-size:16px;color:var(--vfb-outline)}.field-info{display:flex;flex-direction:column}.field-label{font-weight:500;font-size:.9rem}.field-name{font-size:.8rem;color:var(--vfb-on-surface-variant);font-family:monospace}.checkbox-field{padding:8px 0}.checkbox-hint{font-size:.75rem;color:var(--vfb-on-surface-variant);margin-top:4px;margin-left:32px}.expression-textarea{font-family:Monaco,Menlo,Ubuntu Mono,Consolas,monospace!important;font-size:13px!important;line-height:1.4!important}.test-panel{margin-top:8px}.test-content{padding:16px 0}.test-actions{display:flex;gap:12px;margin-bottom:16px}.sample-data-section{margin:16px 0}.sample-data{background-color:var(--vfb-surface-container);padding:12px;border-radius:4px;font-size:12px;overflow-x:auto}.test-result{margin:16px 0}.success-result,.error-result{display:flex;align-items:center;gap:8px;padding:12px;border-radius:4px}.success-result{background-color:var(--vfb-primary-container);color:var(--vfb-on-primary-container)}.error-result{background-color:var(--vfb-error-container);color:var(--vfb-on-error-container)}.result-icon.success{color:var(--vfb-primary)}.result-icon.error{color:var(--vfb-error)}.result-value{font-weight:500;font-family:monospace}.validation-errors{margin:16px 0}.error-chip{background-color:var(--vfb-error-container);color:var(--vfb-on-error-container)}.value-input-container{display:flex;flex-direction:column;gap:12px}.value-input-selector{display:flex;align-items:center;margin-bottom:8px}.input-mode-toggle{font-size:.875rem}.input-mode-toggle .mat-button-toggle{height:36px;display:flex;align-items:center;gap:6px}.literal-input-container{width:100%}@media(max-width:768px){.test-actions{flex-direction:column}.sample-data{font-size:10px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i10$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i10$1.MatCardAvatar, selector: "[mat-card-avatar], [matCardAvatar]" }, { kind: "directive", type: i10$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i10$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i10$1.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i10$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i15.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i15.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i15.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i10$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i15$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i15$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4449
+ `, isInline: true, styles: [":host{--vfb-primary: var(--md-sys-color-primary);--vfb-primary-container: var(--md-sys-color-primary-container);--vfb-on-primary-container: var(--md-sys-color-on-primary-container);--vfb-surface-container-low: var(--md-sys-color-surface-container-low);--vfb-surface-container: var(--md-sys-color-surface-container);--vfb-outline: var(--md-sys-color-outline);--vfb-on-surface-variant: var(--md-sys-color-on-surface-variant);--vfb-error: var(--md-sys-color-error);--vfb-error-container: var(--md-sys-color-error-container);--vfb-on-error-container: var(--md-sys-color-on-error-container)}.visual-formula-builder{display:flex;flex-direction:column;gap:16px}.formula-type-card,.parameters-card,.expression-preview-card{background-color:var(--vfb-surface-container-low)}.compact-header{padding-bottom:8px;align-items:center}.compact-header .mat-mdc-card-title{font-size:1.1rem;margin:0;line-height:1.2}.compact-header .mat-mdc-card-subtitle{font-size:.875rem;margin:0}.compact-header .mat-mdc-card-avatar{align-self:center}.formula-icon,.params-icon,.preview-icon{background-color:var(--vfb-primary-container);color:var(--vfb-on-primary-container);border-radius:50%;width:36px;height:36px;font-size:20px;display:inline-flex;align-items:center;justify-content:center}.formula-type-select{width:100%}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.formula-option{display:flex;align-items:center;gap:12px;padding:8px 0}.option-icon{color:var(--vfb-primary);font-size:20px;opacity:.95}.option-content{display:flex;flex-direction:column}.option-label{font-weight:500;font-size:.9rem}.option-description{font-size:.8rem;color:var(--vfb-on-surface-variant)}.parameters-form{display:flex;flex-direction:column;gap:16px}.parameter-field{display:flex;flex-direction:column}.full-width{width:100%}.field-option{display:flex;align-items:center;gap:8px}.field-type-icon{font-size:16px;color:var(--vfb-outline)}.field-info{display:flex;flex-direction:column}.field-label{font-weight:500;font-size:.9rem}.field-name{font-size:.8rem;color:var(--vfb-on-surface-variant);font-family:monospace}.checkbox-field{padding:8px 0}.checkbox-hint{font-size:.75rem;color:var(--vfb-on-surface-variant);margin-top:4px;margin-left:32px}.expression-textarea{font-family:Monaco,Menlo,Ubuntu Mono,Consolas,monospace!important;font-size:13px!important;line-height:1.4!important}.test-panel{margin-top:8px}.test-content{padding:16px 0}.test-actions{display:flex;gap:12px;margin-bottom:16px}.sample-data-section{margin:16px 0}.sample-data{background-color:var(--vfb-surface-container);padding:12px;border-radius:4px;font-size:12px;overflow-x:auto}.test-result{margin:16px 0}.success-result,.error-result{display:flex;align-items:center;gap:8px;padding:12px;border-radius:4px}.success-result{background-color:var(--vfb-primary-container);color:var(--vfb-on-primary-container)}.error-result{background-color:var(--vfb-error-container);color:var(--vfb-on-error-container)}.result-icon.success{color:var(--vfb-primary)}.result-icon.error{color:var(--vfb-error)}.result-value{font-weight:500;font-family:monospace}.validation-errors{margin:16px 0}.error-chip{background-color:var(--vfb-error-container);color:var(--vfb-on-error-container)}.value-input-container{display:flex;flex-direction:column;gap:12px}.value-input-selector{display:flex;align-items:center;margin-bottom:8px}.input-mode-toggle{font-size:.875rem}.input-mode-toggle .mat-button-toggle{height:36px;display:flex;align-items:center;gap:6px}.literal-input-container{width:100%}@media(max-width:768px){.test-actions{flex-direction:column}.sample-data{font-size:10px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i10$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i10$1.MatCardAvatar, selector: "[mat-card-avatar], [matCardAvatar]" }, { kind: "directive", type: i10$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i10$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i10$1.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i10$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i15.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i15.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i15.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i10$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i15$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i15$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4450
4450
  }
4451
4451
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: VisualFormulaBuilderComponent, decorators: [{
4452
4452
  type: Component,
@@ -5767,7 +5767,7 @@ class ValueMappingEditorComponent {
5767
5767
  this.importError = '';
5768
5768
  this.cdr.markForCheck();
5769
5769
  }
5770
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ValueMappingEditorComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$3.MatDialog }, { token: i2$1.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component });
5770
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ValueMappingEditorComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$2.MatDialog }, { token: i2$2.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component });
5771
5771
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: ValueMappingEditorComponent, isStandalone: true, selector: "value-mapping-editor", inputs: { currentMapping: "currentMapping", keyInputType: "keyInputType", labelKey: "labelKey", labelValue: "labelValue" }, outputs: { mappingChange: "mappingChange" }, usesOnChanges: true, ngImport: i0, template: `
5772
5772
  <div class="value-mapping-editor">
5773
5773
  <!-- Header with Import/Export Actions -->
@@ -6124,7 +6124,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
6124
6124
  }
6125
6125
  </div>
6126
6126
  `, styles: [":host{--vme-primary: var(--md-sys-color-primary);--vme-surface: var(--md-sys-color-surface);--vme-surface-container: var(--md-sys-color-surface-container);--vme-on-surface: var(--md-sys-color-on-surface);--vme-on-surface-variant: var(--md-sys-color-on-surface-variant);--vme-outline-variant: var(--md-sys-color-outline-variant);--vme-error: var(--md-sys-color-error);--vme-error-container: var(--md-sys-color-error-container);--vme-on-error-container: var(--md-sys-color-on-error-container)}.value-mapping-editor{display:flex;flex-direction:column;gap:16px}.mapping-toolbar{display:flex;justify-content:space-between;align-items:center;padding:12px 0;border-bottom:1px solid var(--vme-outline-variant)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.toolbar-title{display:flex;align-items:center;gap:8px}.title-icon{color:var(--vme-primary)}.toolbar-title h4{margin:0;font-size:1rem;font-weight:500}.mapping-count{color:var(--vme-on-surface-variant);font-size:.875rem}.toolbar-actions{display:flex;gap:8px}.toolbar-actions .mat-mdc-outlined-button.mdc-button--disabled{color:var(--vme-on-surface-variant);border-color:var(--vme-outline-variant);background:var(--vme-surface-container)}.toolbar-actions .mat-mdc-outlined-button.mdc-button--disabled .mat-icon{color:var(--vme-on-surface-variant)}.mappings-container{min-height:200px;border:1px solid var(--vme-outline-variant);border-radius:8px;overflow:hidden;background:var(--vme-surface)}.mappings-table{width:100%}.mappings-table .mat-mdc-header-row{background:var(--vme-surface-container)}.mappings-table .mat-mdc-header-cell{color:var(--vme-on-surface);font-weight:600;border-bottom-color:var(--vme-outline-variant)}.key-cell,.value-cell{padding:8px 12px}.key-input,.value-input{width:100%}.key-input .mat-mdc-form-field-infix,.value-input .mat-mdc-form-field-infix{min-height:40px}.boolean-key-container{display:flex;align-items:center;min-height:40px}.error-input{border-color:var(--vme-error)!important}.actions-header{width:80px;text-align:center}.actions-cell{text-align:center;padding:8px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 24px;text-align:center;color:var(--vme-on-surface-variant)}.empty-icon{font-size:48px;width:48px;height:48px;margin-bottom:16px;opacity:.5}.empty-state h4{margin:0 0 8px;font-weight:500}.empty-state p{margin:0;font-size:.875rem}.add-mapping-section{display:flex;justify-content:center;padding:16px 0}.add-mapping-button{display:flex;align-items:center;gap:8px}.import-panel{margin-top:16px}.import-content{padding:16px 0}.json-input{width:100%;margin-bottom:16px}.json-textarea{font-family:Monaco,Menlo,Ubuntu Mono,Consolas,monospace!important;font-size:13px!important;line-height:1.4!important}.import-actions{display:flex;gap:8px;justify-content:flex-end}.import-error{display:flex;align-items:center;gap:8px;margin-top:16px;padding:12px;background-color:var(--vme-error-container);color:var(--vme-on-error-container);border-radius:4px;font-size:.875rem}@media(max-width:768px){.mapping-toolbar{flex-direction:column;gap:12px;align-items:stretch}.toolbar-actions{justify-content:center}.mappings-table,.key-input,.value-input{font-size:.875rem}}\n"] }]
6127
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$3.MatDialog }, { type: i2$1.MatSnackBar }], propDecorators: { currentMapping: [{
6127
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$2.MatDialog }, { type: i2$2.MatSnackBar }], propDecorators: { currentMapping: [{
6128
6128
  type: Input
6129
6129
  }], keyInputType: [{
6130
6130
  type: Input
@@ -6397,6 +6397,9 @@ const BOOLEAN_PRESETS = [
6397
6397
  ];
6398
6398
 
6399
6399
  class DataFormattingService {
6400
+ locale;
6401
+ groupSeparator;
6402
+ decimalSeparator;
6400
6403
  datePipe;
6401
6404
  decimalPipe;
6402
6405
  currencyPipe;
@@ -6404,18 +6407,15 @@ class DataFormattingService {
6404
6407
  upperCasePipe;
6405
6408
  lowerCasePipe;
6406
6409
  titleCasePipe;
6407
- locale;
6408
- groupSeparator;
6409
- decimalSeparator;
6410
- constructor(datePipe, decimalPipe, currencyPipe, percentPipe, upperCasePipe, lowerCasePipe, titleCasePipe, locale) {
6411
- this.datePipe = datePipe;
6412
- this.decimalPipe = decimalPipe;
6413
- this.currencyPipe = currencyPipe;
6414
- this.percentPipe = percentPipe;
6415
- this.upperCasePipe = upperCasePipe;
6416
- this.lowerCasePipe = lowerCasePipe;
6417
- this.titleCasePipe = titleCasePipe;
6410
+ constructor(locale) {
6418
6411
  this.locale = locale;
6412
+ this.datePipe = new DatePipe(this.locale);
6413
+ this.decimalPipe = new DecimalPipe(this.locale);
6414
+ this.currencyPipe = new CurrencyPipe(this.locale);
6415
+ this.percentPipe = new PercentPipe(this.locale);
6416
+ this.upperCasePipe = new UpperCasePipe();
6417
+ this.lowerCasePipe = new LowerCasePipe();
6418
+ this.titleCasePipe = new TitleCasePipe();
6419
6419
  const parts = new Intl.NumberFormat(this.locale).formatToParts(12345.6);
6420
6420
  this.groupSeparator = parts.find((p) => p.type === 'group')?.value || ',';
6421
6421
  this.decimalSeparator =
@@ -6678,7 +6678,7 @@ class DataFormattingService {
6678
6678
  const fmt = formatString.trim();
6679
6679
  return !!(fmt && columnType !== 'custom');
6680
6680
  }
6681
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DataFormattingService, deps: [{ token: i1$2.DatePipe }, { token: i1$2.DecimalPipe }, { token: i1$2.CurrencyPipe }, { token: i1$2.PercentPipe }, { token: i1$2.UpperCasePipe }, { token: i1$2.LowerCasePipe }, { token: i1$2.TitleCasePipe }, { token: LOCALE_ID }], target: i0.ɵɵFactoryTarget.Injectable });
6681
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DataFormattingService, deps: [{ token: LOCALE_ID }], target: i0.ɵɵFactoryTarget.Injectable });
6682
6682
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DataFormattingService, providedIn: 'root' });
6683
6683
  }
6684
6684
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DataFormattingService, decorators: [{
@@ -6686,7 +6686,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
6686
6686
  args: [{
6687
6687
  providedIn: 'root',
6688
6688
  }]
6689
- }], ctorParameters: () => [{ type: i1$2.DatePipe }, { type: i1$2.DecimalPipe }, { type: i1$2.CurrencyPipe }, { type: i1$2.PercentPipe }, { type: i1$2.UpperCasePipe }, { type: i1$2.LowerCasePipe }, { type: i1$2.TitleCasePipe }, { type: undefined, decorators: [{
6689
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
6690
6690
  type: Inject,
6691
6691
  args: [LOCALE_ID]
6692
6692
  }] }] });
@@ -7438,7 +7438,7 @@ class DataFormatterComponent {
7438
7438
  </div>
7439
7439
  </div> }
7440
7440
  </div>
7441
- `, isInline: true, styles: [".data-formatter{display:flex;flex-direction:column;gap:16px}.formatter-header{display:flex;align-items:center;gap:12px;padding:16px 0;border-bottom:1px solid var(--md-sys-color-outline-variant)}.header-icon{font-size:24px;width:24px;height:24px;color:var(--md-sys-color-primary)}.header-content h4{margin:0 0 4px;font-size:1.1rem;font-weight:500;color:var(--md-sys-color-on-surface)}.header-description{margin:0;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.format-section{display:flex;flex-direction:column;gap:16px}.format-row{display:flex;gap:16px;align-items:center;flex-wrap:wrap}.full-width{width:100%}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.decimal-select,.currency-select{min-width:200px;flex:1}.truncate-length{flex:1;min-width:120px}.truncate-suffix{flex:1;min-width:100px}.boolean-value{flex:1;min-width:150px}.format-checkbox{margin-right:16px}.preset-option{display:flex;justify-content:space-between;align-items:center;width:100%;padding:4px 0}.preset-content{display:flex;flex-direction:column;flex:1}.preset-label{font-weight:500;font-size:.9rem}.preset-description{font-size:.8rem;color:var(--md-sys-color-on-surface-variant)}.preset-example{font-family:monospace;font-size:.8rem;color:var(--md-sys-color-primary);background-color:var(--md-sys-color-primary-container);padding:2px 6px;border-radius:4px;margin-left:8px}.truncate-options{margin-left:24px;padding-left:16px;border-left:2px solid var(--md-sys-color-outline-variant)}.custom-boolean{margin-top:8px}.preview-section{margin-top:16px}.preview-content{display:flex;align-items:center;gap:12px;padding:16px;background-color:var(--md-sys-color-surface-container);border-radius:8px;margin-top:16px}.preview-icon{color:var(--md-sys-color-secondary)}.preview-text{display:flex;flex-direction:column;gap:4px}.preview-label{font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.preview-value{font-family:monospace;font-size:1rem;font-weight:500;color:var(--md-sys-color-on-surface);background-color:var(--md-sys-color-surface-container-high);padding:8px 12px;border-radius:4px;border:1px solid var(--md-sys-color-outline-variant)}@media(max-width:768px){.format-row{flex-direction:column;align-items:stretch}.decimal-select,.currency-select,.truncate-length,.truncate-suffix,.boolean-value{min-width:unset;width:100%}.format-checkbox{margin-right:0;margin-bottom:8px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i10$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7441
+ `, isInline: true, styles: [".data-formatter{display:flex;flex-direction:column;gap:16px}.formatter-header{display:flex;align-items:center;gap:12px;padding:16px 0;border-bottom:1px solid var(--md-sys-color-outline-variant)}.header-icon{font-size:24px;width:24px;height:24px;color:var(--md-sys-color-primary)}.header-content h4{margin:0 0 4px;font-size:1.1rem;font-weight:500;color:var(--md-sys-color-on-surface)}.header-description{margin:0;font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.format-section{display:flex;flex-direction:column;gap:16px}.format-row{display:flex;gap:16px;align-items:center;flex-wrap:wrap}.full-width{width:100%}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.decimal-select,.currency-select{min-width:200px;flex:1}.truncate-length{flex:1;min-width:120px}.truncate-suffix{flex:1;min-width:100px}.boolean-value{flex:1;min-width:150px}.format-checkbox{margin-right:16px}.preset-option{display:flex;justify-content:space-between;align-items:center;width:100%;padding:4px 0}.preset-content{display:flex;flex-direction:column;flex:1}.preset-label{font-weight:500;font-size:.9rem}.preset-description{font-size:.8rem;color:var(--md-sys-color-on-surface-variant)}.preset-example{font-family:monospace;font-size:.8rem;color:var(--md-sys-color-primary);background-color:var(--md-sys-color-primary-container);padding:2px 6px;border-radius:4px;margin-left:8px}.truncate-options{margin-left:24px;padding-left:16px;border-left:2px solid var(--md-sys-color-outline-variant)}.custom-boolean{margin-top:8px}.preview-section{margin-top:16px}.preview-content{display:flex;align-items:center;gap:12px;padding:16px;background-color:var(--md-sys-color-surface-container);border-radius:8px;margin-top:16px}.preview-icon{color:var(--md-sys-color-secondary)}.preview-text{display:flex;flex-direction:column;gap:4px}.preview-label{font-size:.875rem;color:var(--md-sys-color-on-surface-variant)}.preview-value{font-family:monospace;font-size:1rem;font-weight:500;color:var(--md-sys-color-on-surface);background-color:var(--md-sys-color-surface-container-high);padding:8px 12px;border-radius:4px;border:1px solid var(--md-sys-color-outline-variant)}@media(max-width:768px){.format-row{flex-direction:column;align-items:stretch}.decimal-select,.currency-select,.truncate-length,.truncate-suffix,.boolean-value{min-width:unset;width:100%}.format-checkbox{margin-right:0;margin-bottom:8px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i10$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7442
7442
  }
7443
7443
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DataFormatterComponent, decorators: [{
7444
7444
  type: Component,
@@ -7866,7 +7866,7 @@ class TableRatingCellComponent {
7866
7866
  </svg>
7867
7867
  </span>
7868
7868
  </span>
7869
- `, isInline: true, styles: [":host{--pfx-table-rating-size: 20px;--pfx-table-rating-fill: var(--md-sys-color-tertiary, var(--md-sys-color-primary, currentColor));--pfx-table-rating-outline: var(--md-sys-color-outline-variant, var(--md-sys-color-on-surface-variant, currentColor));display:inline-flex;align-items:center;gap:2px;line-height:0;vertical-align:middle}:host(.pfx-table-rating--size-sm){--pfx-table-rating-size: 16px}:host(.pfx-table-rating--size-lg){--pfx-table-rating-size: 28px}.pfx-table-rating__item{display:inline-flex;width:var(--pfx-table-rating-size);height:var(--pfx-table-rating-size);position:relative}.pfx-table-rating__svg{width:100%;height:100%;display:block}.pfx-table-rating__svg--outline{overflow:visible}.pfx-table-rating__fill-clip{position:absolute;inset:0 auto 0 0;height:100%;overflow:hidden}.pfx-table-rating__outline{stroke:var(--pfx-table-rating-outline);stroke-width:1.8}.pfx-table-rating__fill{fill:var(--pfx-table-rating-fill)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
7869
+ `, isInline: true, styles: [":host{--pfx-table-rating-size: 20px;--pfx-table-rating-fill: var(--md-sys-color-tertiary, var(--md-sys-color-primary, currentColor));--pfx-table-rating-outline: var(--md-sys-color-outline-variant, var(--md-sys-color-on-surface-variant, currentColor));display:inline-flex;align-items:center;gap:2px;line-height:0;vertical-align:middle}:host(.pfx-table-rating--size-sm){--pfx-table-rating-size: 16px}:host(.pfx-table-rating--size-lg){--pfx-table-rating-size: 28px}.pfx-table-rating__item{display:inline-flex;width:var(--pfx-table-rating-size);height:var(--pfx-table-rating-size);position:relative}.pfx-table-rating__svg{width:100%;height:100%;display:block}.pfx-table-rating__svg--outline{overflow:visible}.pfx-table-rating__fill-clip{position:absolute;inset:0 auto 0 0;height:100%;overflow:hidden}.pfx-table-rating__outline{stroke:var(--pfx-table-rating-outline);stroke-width:1.8}.pfx-table-rating__fill{fill:var(--pfx-table-rating-fill)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
7870
7870
  }
7871
7871
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TableRatingCellComponent, decorators: [{
7872
7872
  type: Component,
@@ -11781,7 +11781,7 @@ class ColumnsConfigEditorComponent {
11781
11781
  </div>
11782
11782
  </div>
11783
11783
  </div>
11784
- `, isInline: true, styles: [".columns-config-editor{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;gap:16px}.educational-card{background:var(--md-sys-color-surface-container-low);border-left:4px solid var(--md-sys-color-primary);margin-bottom:12px}.inline-icon{font-size:18px;width:18px;height:18px;color:var(--md-sys-color-primary)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.global-config-accordion{margin-bottom:16px}.global-config-panel{background:var(--md-sys-color-surface-container);border-left:4px solid var(--md-sys-color-secondary)}.config-panel-content{padding:16px 20px 20px}.config-layout{display:flex;flex-wrap:wrap;gap:24px;align-items:flex-start}.config-group{display:flex;flex-direction:column;min-width:0}.config-group:not(.features-group){flex:0 0 auto}.features-group{flex:1 1 300px;min-width:300px}.control-section{display:flex;flex-direction:column;gap:8px}.control-label{font-size:.875rem;font-weight:500;color:var(--md-sys-color-on-surface);margin:0}.control-status{font-weight:400;color:var(--md-sys-color-on-surface-variant);font-size:.75rem;margin-left:4px}.visibility-toggle-group,.alignment-toggle-group{display:flex}.visibility-toggle-group .mat-button-toggle{min-width:90px;height:40px}.alignment-toggle-group .mat-button-toggle{min-width:56px;width:auto;height:40px;padding:0 8px}.features-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-top:4px}.feature-checkbox{justify-self:start}.master-detail-layout{display:flex;flex:1;gap:16px;min-height:0}.master-panel{flex:0 0 350px;display:flex;flex-direction:column;background:var(--md-sys-color-surface-container-low);border-radius:8px;overflow:hidden}.list-header{display:flex;justify-content:space-between;align-items:center;padding:16px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant)}.list-header h3{margin:0;font-size:1.1rem;font-weight:500}.add-column-fab{transform:scale(.7)}.columns-list-container{flex:1;overflow-y:auto}.columns-list{padding:0}.column-item{border-bottom:1px solid var(--md-sys-color-outline-variant);cursor:pointer;transition:background-color .2s}.column-item:hover{background:var(--md-sys-color-surface-container)}.column-item.selected{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.column-item-content{display:flex;justify-content:space-between;align-items:center;width:100%;padding:12px 16px}.column-main-info{flex:1;display:flex;flex-direction:column;gap:4px}.column-header{display:flex;align-items:center;gap:8px;width:100%}.drag-handle{cursor:grab;color:var(--md-sys-color-on-surface-variant);font-size:18px;flex-shrink:0}.column-text-info{flex:1;display:flex;flex-direction:column;gap:2px;min-width:0}.column-title{font-weight:600;font-size:.9rem;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.column-field{font-size:.75rem;color:var(--md-sys-color-on-surface-variant);font-family:monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.column-indicators{display:flex;align-items:center;gap:6px;flex-shrink:0}.column-type-icon,.mapping-indicator-icon,.renderer-indicator-icon{font-size:16px;color:var(--md-sys-color-on-surface-variant)}.visibility-checkbox{transform:scale(.9)}.remove-button{opacity:.7;transition:opacity .2s}.remove-button:hover{opacity:1}.detail-panel{flex:1;display:flex;flex-direction:column;background:var(--md-sys-color-surface-container-low);border-radius:8px;overflow:hidden}.no-selection-message{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1;text-align:center;padding:48px;color:var(--md-sys-color-on-surface-variant)}.no-selection-message mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:16px}.editor-header{padding:16px 24px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant)}.editor-title{margin:0;font-size:1.1rem;font-weight:500;color:var(--md-sys-color-on-surface)}.column-form{flex:1;padding:24px;overflow:visible}.form-row{display:flex;gap:16px;margin-bottom:24px;align-items:flex-start}.field-input,.header-input,.width-input,.data-type-input{flex:1}.header-input{flex:2}.alignment-group,.sticky-group{display:flex;flex-direction:column;gap:8px}.control-label{font-size:.875rem;font-weight:500;color:var(--md-sys-color-on-surface)}.renderer-grid,.renderer-config{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}.renderer-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:8px}.renderer-errors{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border:1px solid var(--md-sys-color-error);padding:8px 12px;border-radius:6px;font-size:.85rem}.renderer-preview{margin-top:8px;padding:8px 12px;background:var(--md-sys-color-surface-container-low);border:1px solid var(--md-sys-color-outline-variant);border-radius:6px}.renderer-preview-list{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.renderer-preview-list .pfx-compose{display:inline-flex;gap:6px;align-items:center}.pfx-badge{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;border-radius:10px;font-size:12px;line-height:1}.pfx-badge-icon{font-size:14px;width:14px;height:14px}.pfx-badge--outlined{border:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface);background:transparent}.pfx-badge--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-badge--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-badge--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-badge--soft-primary{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.pfx-badge--soft-accent{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container)}.pfx-badge--soft-warn{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.pfx-cell-image{display:inline-block;border-radius:4px;object-fit:cover}.pfx-link{color:var(--md-sys-color-primary);text-decoration:underline;cursor:pointer}.pfx-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:10px;font-size:12px;border:1px solid transparent}.pfx-chip--outlined{border-color:var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}.pfx-chip--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-chip--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-chip--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-chip--soft-primary{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.pfx-chip--soft-accent{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container)}.pfx-chip--soft-warn{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.pfx-progress{position:relative;width:120px;height:8px;background:var(--md-sys-color-surface-container-highest);border-radius:4px;overflow:hidden}.pfx-progress-bar{height:100%;background:var(--md-sys-color-primary)}.pfx-avatar{display:inline-flex;align-items:center;justify-content:center;background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface);border-radius:4px;overflow:hidden;font-weight:600;width:32px;height:32px}.pfx-avatar.shape-rounded{border-radius:8px}.pfx-avatar.shape-circle{border-radius:999px}.pfx-avatar--initials{text-transform:uppercase;font-size:12px}@media(max-width:768px){.master-detail-layout{flex-direction:column}.master-panel{flex:0 0 auto;max-height:300px}.form-row{flex-direction:column;gap:12px}.config-layout{flex-direction:column;gap:20px}.features-group{min-width:auto}.features-grid{grid-template-columns:1fr;gap:8px}.visibility-toggle-group .mat-button-toggle{min-width:80px;font-size:.875rem}}@media(max-width:480px){.visibility-toggle-group .mat-button-toggle{min-width:70px;font-size:.8rem}.alignment-toggle-group .mat-button-toggle{min-width:48px;padding:0 6px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1$2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1$2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i10$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i10$1.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i15$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i15$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i11.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i11.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "component", type: i10$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i8.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i15$2.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i12.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: VisualFormulaBuilderComponent, selector: "visual-formula-builder", inputs: ["availableDataSchema", "currentFormula"], outputs: ["formulaChange", "generatedExpressionChange"] }, { kind: "component", type: ValueMappingEditorComponent, selector: "value-mapping-editor", inputs: ["currentMapping", "keyInputType", "labelKey", "labelValue"], outputs: ["mappingChange"] }, { kind: "component", type: DataFormatterComponent, selector: "data-formatter", inputs: ["columnType", "currentFormat"], outputs: ["formatChange"] }, { kind: "component", type: TableRatingCellComponent, selector: "praxis-table-rating", inputs: ["itemsCount", "value", "size", "ratingColor", "outlineColor", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11784
+ `, isInline: true, styles: [".columns-config-editor{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;gap:16px}.educational-card{background:var(--md-sys-color-surface-container-low);border-left:4px solid var(--md-sys-color-primary);margin-bottom:12px}.inline-icon{font-size:18px;width:18px;height:18px;color:var(--md-sys-color-primary)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.global-config-accordion{margin-bottom:16px}.global-config-panel{background:var(--md-sys-color-surface-container);border-left:4px solid var(--md-sys-color-secondary)}.config-panel-content{padding:16px 20px 20px}.config-layout{display:flex;flex-wrap:wrap;gap:24px;align-items:flex-start}.config-group{display:flex;flex-direction:column;min-width:0}.config-group:not(.features-group){flex:0 0 auto}.features-group{flex:1 1 300px;min-width:300px}.control-section{display:flex;flex-direction:column;gap:8px}.control-label{font-size:.875rem;font-weight:500;color:var(--md-sys-color-on-surface);margin:0}.control-status{font-weight:400;color:var(--md-sys-color-on-surface-variant);font-size:.75rem;margin-left:4px}.visibility-toggle-group,.alignment-toggle-group{display:flex}.visibility-toggle-group .mat-button-toggle{min-width:90px;height:40px}.alignment-toggle-group .mat-button-toggle{min-width:56px;width:auto;height:40px;padding:0 8px}.features-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-top:4px}.feature-checkbox{justify-self:start}.master-detail-layout{display:flex;flex:1;gap:16px;min-height:0}.master-panel{flex:0 0 350px;display:flex;flex-direction:column;background:var(--md-sys-color-surface-container-low);border-radius:8px;overflow:hidden}.list-header{display:flex;justify-content:space-between;align-items:center;padding:16px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant)}.list-header h3{margin:0;font-size:1.1rem;font-weight:500}.add-column-fab{transform:scale(.7)}.columns-list-container{flex:1;overflow-y:auto}.columns-list{padding:0}.column-item{border-bottom:1px solid var(--md-sys-color-outline-variant);cursor:pointer;transition:background-color .2s}.column-item:hover{background:var(--md-sys-color-surface-container)}.column-item.selected{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.column-item-content{display:flex;justify-content:space-between;align-items:center;width:100%;padding:12px 16px}.column-main-info{flex:1;display:flex;flex-direction:column;gap:4px}.column-header{display:flex;align-items:center;gap:8px;width:100%}.drag-handle{cursor:grab;color:var(--md-sys-color-on-surface-variant);font-size:18px;flex-shrink:0}.column-text-info{flex:1;display:flex;flex-direction:column;gap:2px;min-width:0}.column-title{font-weight:600;font-size:.9rem;color:var(--md-sys-color-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.column-field{font-size:.75rem;color:var(--md-sys-color-on-surface-variant);font-family:monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.column-indicators{display:flex;align-items:center;gap:6px;flex-shrink:0}.column-type-icon,.mapping-indicator-icon,.renderer-indicator-icon{font-size:16px;color:var(--md-sys-color-on-surface-variant)}.visibility-checkbox{transform:scale(.9)}.remove-button{opacity:.7;transition:opacity .2s}.remove-button:hover{opacity:1}.detail-panel{flex:1;display:flex;flex-direction:column;background:var(--md-sys-color-surface-container-low);border-radius:8px;overflow:hidden}.no-selection-message{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1;text-align:center;padding:48px;color:var(--md-sys-color-on-surface-variant)}.no-selection-message mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:16px}.editor-header{padding:16px 24px;background:var(--md-sys-color-surface-container);border-bottom:1px solid var(--md-sys-color-outline-variant)}.editor-title{margin:0;font-size:1.1rem;font-weight:500;color:var(--md-sys-color-on-surface)}.column-form{flex:1;padding:24px;overflow:visible}.form-row{display:flex;gap:16px;margin-bottom:24px;align-items:flex-start}.field-input,.header-input,.width-input,.data-type-input{flex:1}.header-input{flex:2}.alignment-group,.sticky-group{display:flex;flex-direction:column;gap:8px}.control-label{font-size:.875rem;font-weight:500;color:var(--md-sys-color-on-surface)}.renderer-grid,.renderer-config{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}.renderer-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:8px}.renderer-errors{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border:1px solid var(--md-sys-color-error);padding:8px 12px;border-radius:6px;font-size:.85rem}.renderer-preview{margin-top:8px;padding:8px 12px;background:var(--md-sys-color-surface-container-low);border:1px solid var(--md-sys-color-outline-variant);border-radius:6px}.renderer-preview-list{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.renderer-preview-list .pfx-compose{display:inline-flex;gap:6px;align-items:center}.pfx-badge{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;border-radius:10px;font-size:12px;line-height:1}.pfx-badge-icon{font-size:14px;width:14px;height:14px}.pfx-badge--outlined{border:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface);background:transparent}.pfx-badge--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-badge--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-badge--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-badge--soft-primary{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.pfx-badge--soft-accent{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container)}.pfx-badge--soft-warn{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.pfx-cell-image{display:inline-block;border-radius:4px;object-fit:cover}.pfx-link{color:var(--md-sys-color-primary);text-decoration:underline;cursor:pointer}.pfx-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:10px;font-size:12px;border:1px solid transparent}.pfx-chip--outlined{border-color:var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}.pfx-chip--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-chip--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-chip--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-chip--soft-primary{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.pfx-chip--soft-accent{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container)}.pfx-chip--soft-warn{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.pfx-progress{position:relative;width:120px;height:8px;background:var(--md-sys-color-surface-container-highest);border-radius:4px;overflow:hidden}.pfx-progress-bar{height:100%;background:var(--md-sys-color-primary)}.pfx-avatar{display:inline-flex;align-items:center;justify-content:center;background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface);border-radius:4px;overflow:hidden;font-weight:600;width:32px;height:32px}.pfx-avatar.shape-rounded{border-radius:8px}.pfx-avatar.shape-circle{border-radius:999px}.pfx-avatar--initials{text-transform:uppercase;font-size:12px}@media(max-width:768px){.master-detail-layout{flex-direction:column}.master-panel{flex:0 0 auto;max-height:300px}.form-row{flex-direction:column;gap:12px}.config-layout{flex-direction:column;gap:20px}.features-group{min-width:auto}.features-grid{grid-template-columns:1fr;gap:8px}.visibility-toggle-group .mat-button-toggle{min-width:80px;font-size:.875rem}}@media(max-width:480px){.visibility-toggle-group .mat-button-toggle{min-width:70px;font-size:.8rem}.alignment-toggle-group .mat-button-toggle{min-width:48px;padding:0 6px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i10$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i10$1.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i15$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i15$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i11.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i11.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "component", type: i10$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i8.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i15$2.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i12.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: VisualFormulaBuilderComponent, selector: "visual-formula-builder", inputs: ["availableDataSchema", "currentFormula"], outputs: ["formulaChange", "generatedExpressionChange"] }, { kind: "component", type: ValueMappingEditorComponent, selector: "value-mapping-editor", inputs: ["currentMapping", "keyInputType", "labelKey", "labelValue"], outputs: ["mappingChange"] }, { kind: "component", type: DataFormatterComponent, selector: "data-formatter", inputs: ["columnType", "currentFormat"], outputs: ["formatChange"] }, { kind: "component", type: TableRatingCellComponent, selector: "praxis-table-rating", inputs: ["itemsCount", "value", "size", "ratingColor", "outlineColor", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11785
11785
  }
11786
11786
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ColumnsConfigEditorComponent, decorators: [{
11787
11787
  type: Component,
@@ -15192,7 +15192,7 @@ class BehaviorConfigEditorComponent {
15192
15192
  </mat-expansion-panel> }
15193
15193
  </form>
15194
15194
  </div>
15195
- `, isInline: true, styles: [".behavior-config-container{width:100%;padding:8px}.config-section{padding:16px}.mode-constraint-note{margin:0 0 12px;padding:10px 12px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.35}.schema-only-note-inline{margin-top:-8px;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.schema-only-note-inline a{color:var(--md-sys-color-primary);text-decoration:underline;margin-left:6px}.config-fields{display:flex;flex-direction:column;gap:16px;margin-top:16px}.toggle-field{display:flex;align-items:center;gap:8px}.section-icon{margin-right:8px;color:var(--md-sys-color-primary)}.info-icon{font-size:18px;width:18px;height:18px;color:var(--md-sys-color-on-surface-variant);cursor:help}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}mat-form-field{width:100%}mat-expansion-panel{margin-bottom:8px;border-radius:8px;overflow:hidden}mat-expansion-panel-header{min-height:56px}mat-panel-description{color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i10$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }] });
15195
+ `, isInline: true, styles: [".behavior-config-container{width:100%;padding:8px}.config-section{padding:16px}.mode-constraint-note{margin:0 0 12px;padding:10px 12px;border-radius:8px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);font-size:12px;line-height:1.35}.schema-only-note-inline{margin-top:-8px;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.schema-only-note-inline a{color:var(--md-sys-color-primary);text-decoration:underline;margin-left:6px}.config-fields{display:flex;flex-direction:column;gap:16px;margin-top:16px}.toggle-field{display:flex;align-items:center;gap:8px}.section-icon{margin-right:8px;color:var(--md-sys-color-primary)}.info-icon{font-size:18px;width:18px;height:18px;color:var(--md-sys-color-on-surface-variant);cursor:help}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}mat-form-field{width:100%}mat-expansion-panel{margin-bottom:8px;border-radius:8px;overflow:hidden}mat-expansion-panel-header{min-height:56px}mat-panel-description{color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i10$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }] });
15196
15196
  }
15197
15197
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: BehaviorConfigEditorComponent, decorators: [{
15198
15198
  type: Component,
@@ -18989,7 +18989,7 @@ class ToolbarActionsEditorComponent {
18989
18989
  </mat-expansion-panel> }
18990
18990
  </form>
18991
18991
  </div>
18992
- `, isInline: true, styles: [":host{--tae-primary: var(--md-sys-color-primary);--tae-surface: var(--md-sys-color-surface);--tae-surface-low: var(--md-sys-color-surface-container-low);--tae-surface-variant: var(--md-sys-color-surface-variant);--tae-outline-variant: var(--md-sys-color-outline-variant);--tae-on-surface: var(--md-sys-color-on-surface);--tae-on-surface-variant: var(--md-sys-color-on-surface-variant)}.toolbar-actions-container{width:100%;padding:8px}.config-section{padding:16px}.section-hint{color:var(--tae-on-surface-variant);font-size:12px;margin-bottom:12px}.config-fields{display:flex;flex-direction:column;gap:16px;margin-top:16px}.nested-fields{display:flex;flex-direction:column;gap:12px;margin-left:24px;margin-top:12px;padding:16px;background-color:var(--tae-surface-variant);border-radius:8px}.action-section-title{width:100%;margin:12px 0 4px;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--tae-on-surface-variant)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.action-global-fields .mat-mdc-form-field-icon-suffix{align-self:center}.toggle-field{display:flex;align-items:center;gap:8px}.section-icon{margin-right:8px;color:var(--tae-primary)}.subsection{margin-top:24px;padding:16px;border:1px solid var(--tae-outline-variant);border-radius:8px}.subsection h4{margin:0 0 16px;color:var(--tae-on-surface);font-weight:500}.actions-header{margin:16px 0;display:flex;justify-content:flex-start}.actions-list{display:flex;flex-direction:column;gap:8px;min-height:60px}.action-item{border:1px solid var(--tae-outline-variant);border-radius:8px;background-color:var(--tae-surface);overflow:hidden}.action-header{display:flex;align-items:center;padding:12px 16px;background-color:var(--tae-surface-low);cursor:move}.drag-handle{margin-right:8px;color:var(--tae-on-surface-variant);cursor:grab}.drag-handle:active{cursor:grabbing}.action-label{flex:1;margin-left:8px;font-weight:500}.action-controls{display:flex;gap:4px}.action-details{padding:16px;border-top:1px solid var(--tae-outline-variant);background-color:var(--tae-surface)}.action-form{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px}.action-global-fields{grid-column:1 / -1;padding:12px 14px;border:1px dashed var(--tae-outline-variant);border-radius:10px;background:var(--md-sys-color-surface-container)}.action-global-title{font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--tae-on-surface-variant);margin-bottom:10px}.action-global-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px 16px}mat-form-field{width:100%}mat-expansion-panel{margin-bottom:8px;border-radius:8px;overflow:hidden}mat-expansion-panel-header{min-height:56px}mat-panel-description{color:var(--tae-on-surface-variant)}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:var(--md-sys-elevation-level3)}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.actions-list.cdk-drop-list-dragging .action-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i5$1.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i17.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i17.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i17.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i12.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
18992
+ `, isInline: true, styles: [":host{--tae-primary: var(--md-sys-color-primary);--tae-surface: var(--md-sys-color-surface);--tae-surface-low: var(--md-sys-color-surface-container-low);--tae-surface-variant: var(--md-sys-color-surface-variant);--tae-outline-variant: var(--md-sys-color-outline-variant);--tae-on-surface: var(--md-sys-color-on-surface);--tae-on-surface-variant: var(--md-sys-color-on-surface-variant)}.toolbar-actions-container{width:100%;padding:8px}.config-section{padding:16px}.section-hint{color:var(--tae-on-surface-variant);font-size:12px;margin-bottom:12px}.config-fields{display:flex;flex-direction:column;gap:16px;margin-top:16px}.nested-fields{display:flex;flex-direction:column;gap:12px;margin-left:24px;margin-top:12px;padding:16px;background-color:var(--tae-surface-variant);border-radius:8px}.action-section-title{width:100%;margin:12px 0 4px;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--tae-on-surface-variant)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.action-global-fields .mat-mdc-form-field-icon-suffix{align-self:center}.toggle-field{display:flex;align-items:center;gap:8px}.section-icon{margin-right:8px;color:var(--tae-primary)}.subsection{margin-top:24px;padding:16px;border:1px solid var(--tae-outline-variant);border-radius:8px}.subsection h4{margin:0 0 16px;color:var(--tae-on-surface);font-weight:500}.actions-header{margin:16px 0;display:flex;justify-content:flex-start}.actions-list{display:flex;flex-direction:column;gap:8px;min-height:60px}.action-item{border:1px solid var(--tae-outline-variant);border-radius:8px;background-color:var(--tae-surface);overflow:hidden}.action-header{display:flex;align-items:center;padding:12px 16px;background-color:var(--tae-surface-low);cursor:move}.drag-handle{margin-right:8px;color:var(--tae-on-surface-variant);cursor:grab}.drag-handle:active{cursor:grabbing}.action-label{flex:1;margin-left:8px;font-weight:500}.action-controls{display:flex;gap:4px}.action-details{padding:16px;border-top:1px solid var(--tae-outline-variant);background-color:var(--tae-surface)}.action-form{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px}.action-global-fields{grid-column:1 / -1;padding:12px 14px;border:1px dashed var(--tae-outline-variant);border-radius:10px;background:var(--md-sys-color-surface-container)}.action-global-title{font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--tae-on-surface-variant);margin-bottom:10px}.action-global-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px 16px}mat-form-field{width:100%}mat-expansion-panel{margin-bottom:8px;border-radius:8px;overflow:hidden}mat-expansion-panel-header{min-height:56px}mat-panel-description{color:var(--tae-on-surface-variant)}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:var(--md-sys-elevation-level3)}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.actions-list.cdk-drop-list-dragging .action-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i5$1.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i17.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i17.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i17.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i12.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
18993
18993
  }
18994
18994
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ToolbarActionsEditorComponent, decorators: [{
18995
18995
  type: Component,
@@ -24006,7 +24006,7 @@ class FilterSettingsComponent {
24006
24006
  // In a real implementation, this would trigger schema reload in PraxisFilter
24007
24007
  }
24008
24008
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: FilterSettingsComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
24009
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: FilterSettingsComponent, isStandalone: true, selector: "filter-settings", inputs: { metadata: "metadata", metadataSource: "metadataSource", metadataLoading: "metadataLoading", metadataErrorMsg: "metadataErrorMsg", settings: "settings", configKey: "configKey" }, outputs: { settingsChange: "settingsChange" }, usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-tab-group (selectedTabChange)=\"onTabChange($event)\">\n <mat-tab label=\"Sempre Vis\u00EDveis\">\n <div class=\"always-visible-tab-flow\">\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Campos sempre vis\u00EDveis</mat-label>\n <mat-select\n formControlName=\"alwaysVisibleFields\"\n multiple\n >\n <mat-option\n [value]=\"meta.name\"\n *ngFor=\"let meta of filteredAlwaysVisibleMetadata(); trackBy: trackFieldMetadataByName\"\n >\n {{ meta.label || meta.name }}\n </mat-option>\n </mat-select>\n <mat-hint *ngIf=\"metadataLoading && metadataSource === 'filter-dto'\">\n Carregando campos do DTO de filtro...\n </mat-hint>\n <mat-error *ngIf=\"metadataErrorMsg\">{{ metadataErrorMsg }}</mat-error>\n <mat-hint\n *ngIf=\"!metadataLoading && !metadataErrorMsg && !metadata.length && metadataSource === 'filter-dto'\"\n >\n Nenhum campo do DTO de filtro dispon\u00EDvel para este recurso.\n </mat-hint>\n <mat-hint\n *ngIf=\"!metadataLoading && !metadataErrorMsg && metadata.length && !hasAlwaysVisibleMetadataResults() && alwaysVisibleFieldSearchText\"\n >\n Nenhum campo encontrado para \"{{ alwaysVisibleFieldSearchText }}\".\n </mat-hint>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Escolha os campos que aparecem sempre na barra de filtros.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Buscar campo</mat-label>\n <input\n matInput\n [ngModel]=\"alwaysVisibleFieldSearchText\"\n (ngModelChange)=\"onAlwaysVisibleFieldSearchChange($event)\"\n [ngModelOptions]=\"{standalone: true}\"\n placeholder=\"Filtrar por nome ou label\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n *ngIf=\"alwaysVisibleFieldSearchText\"\n (click)=\"clearAlwaysVisibleFieldSearch()\"\n aria-label=\"Limpar busca de campo\"\n >\n <mat-icon [praxisIcon]=\"'close'\"></mat-icon>\n </button>\n </mat-form-field>\n <p class=\"field-hint\">\n {{ alwaysVisibleSelectionCount() }} campo(s) selecionado(s).\n </p>\n <div class=\"always-visible-context\">\n <div class=\"always-visible-summary\" role=\"status\" aria-live=\"polite\">\n <div class=\"always-visible-summary-item\">\n <span class=\"summary-value\">{{ alwaysVisibleSelectionCount() }}</span>\n <span class=\"summary-label\">campos fixos</span>\n </div>\n <div class=\"always-visible-summary-item\">\n <span class=\"summary-value\">{{ activeAlwaysVisibleOverrideCount() }}</span>\n <span class=\"summary-label\">overrides ativos</span>\n </div>\n </div>\n <nav\n class=\"always-visible-quick-nav\"\n aria-label=\"Navega\u00E7\u00E3o r\u00E1pida da se\u00E7\u00E3o Sempre Vis\u00EDveis\"\n >\n <button\n mat-stroked-button\n type=\"button\"\n [class.quick-nav-active]=\"isAlwaysVisibleSectionActive('always-visible-order')\"\n [attr.aria-current]=\"isAlwaysVisibleSectionActive('always-visible-order') ? 'location' : null\"\n aria-controls=\"always-visible-order\"\n (click)=\"scrollToAlwaysVisibleSection('always-visible-order')\"\n >\n Ordem\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n [class.quick-nav-active]=\"isAlwaysVisibleSectionActive('always-visible-metadata')\"\n [attr.aria-current]=\"isAlwaysVisibleSectionActive('always-visible-metadata') ? 'location' : null\"\n aria-controls=\"always-visible-metadata\"\n (click)=\"scrollToAlwaysVisibleSection('always-visible-metadata')\"\n >\n Metadados\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n [class.quick-nav-active]=\"isAlwaysVisibleSectionActive('always-visible-json')\"\n [attr.aria-current]=\"isAlwaysVisibleSectionActive('always-visible-json') ? 'location' : null\"\n aria-controls=\"always-visible-json\"\n (click)=\"scrollToAlwaysVisibleSection('always-visible-json')\"\n >\n JSON\n </button>\n </nav>\n </div>\n\n <div\n id=\"always-visible-order\"\n class=\"options options-compact-flow always-visible-section-anchor\"\n [class.section-active]=\"isAlwaysVisibleSectionActive('always-visible-order')\"\n [style.--section-enter-delay]=\"sectionEnterDelay('always-visible-order')\"\n tabindex=\"-1\"\n (focusin)=\"onAlwaysVisibleSectionFocus('always-visible-order')\"\n >\n <div class=\"options-header\">\n <h4 class=\"section-title\">Ordem dos campos</h4>\n <p class=\"section-help\">\n Reordene no formato mais pr\u00F3ximo da toolbar real: faixa de a\u00E7\u00F5es, barra inline e grid.\n </p>\n </div>\n <div class=\"order-layout-toolbar\">\n <mat-button-toggle-group\n class=\"order-viewport-toggle-group\"\n [value]=\"orderPreviewViewport\"\n (change)=\"onAlwaysVisibleViewportChange($event.value)\"\n aria-label=\"Largura simulada da toolbar\"\n >\n <mat-button-toggle\n *ngFor=\"let viewport of alwaysVisibleViewports\"\n [value]=\"viewport\"\n [attr.aria-label]=\"alwaysVisibleViewportHint(viewport)\"\n >\n {{ alwaysVisibleViewportLabel(viewport) }}\n </mat-button-toggle>\n </mat-button-toggle-group>\n <span class=\"order-viewport-caption\">\n {{ alwaysVisibleViewportWidth() }}px\n </span>\n </div>\n <p class=\"section-help\">\n Ajuste o viewport para simular a quebra real das linhas na toolbar.\n </p>\n <div class=\"order-layout-viewport\">\n <div\n class=\"order-layout-frame\"\n [attr.data-viewport]=\"orderPreviewViewport\"\n [style.maxWidth.px]=\"alwaysVisibleViewportWidth()\"\n >\n <div class=\"order-layout-composer\" cdkDropListGroup>\n <section\n class=\"order-lane\"\n *ngFor=\"let lane of alwaysVisibleLayoutLanes\"\n [attr.data-lane]=\"lane\"\n >\n <ng-container *ngIf=\"alwaysVisibleLaneItems(lane) as laneItems\">\n <header class=\"order-lane-header\">\n <div class=\"order-lane-title-block\">\n <h5 class=\"order-lane-title\">{{ alwaysVisibleLaneLabel(lane) }}</h5>\n <p class=\"order-lane-help\">{{ alwaysVisibleLaneHint(lane) }}</p>\n </div>\n <span class=\"order-lane-count\">{{ laneItems.length }}</span>\n </header>\n <div\n cdkDropList\n class=\"order-lane-canvas\"\n [id]=\"alwaysVisibleLaneDropListId(lane)\"\n [class.is-empty]=\"!laneItems.length\"\n [cdkDropListData]=\"laneItems\"\n [cdkDropListEnterPredicate]=\"allowAlwaysVisibleLaneEnter\"\n cdkDropListOrientation=\"horizontal\"\n [attr.aria-label]=\"'Faixa ' + alwaysVisibleLaneLabel(lane)\"\n (cdkDropListDropped)=\"dropAlwaysVisibleLane(lane, $event)\"\n >\n <button\n type=\"button\"\n class=\"order-pill\"\n *ngFor=\"let item of laneItems; let i = index; trackBy: trackAlwaysVisibleLayoutItemByName\"\n cdkDrag\n [cdkDragData]=\"item\"\n [attr.aria-label]=\"alwaysVisibleLayoutItemAriaLabel(item, lane, i, laneItems.length)\"\n (keydown)=\"onAlwaysVisibleLaneItemKeydown($event, lane, item.name)\"\n >\n <mat-icon [praxisIcon]=\"'drag_indicator'\" cdkDragHandle></mat-icon>\n <span class=\"order-pill-label\">{{ item.label }}</span>\n <span class=\"order-pill-badges\">\n <span class=\"order-pill-chip\">{{ item.controlTypeLabel }}</span>\n <span class=\"order-pill-chip order-pill-chip-width\">{{ item.widthHint }}</span>\n <span class=\"order-pill-chip order-pill-chip-override\" *ngIf=\"item.hasOverride\">\n Override\n </span>\n </span>\n </button>\n <p class=\"order-lane-empty\" *ngIf=\"!laneItems.length\">\n {{ alwaysVisibleLaneEmptyHint(lane) }}\n </p>\n </div>\n </ng-container>\n </section>\n </div>\n </div>\n </div>\n <p class=\"field-hint\">\n Acessibilidade: use Alt/Ctrl + setas para reordenar dentro de cada faixa. O drag & drop n\u00E3o mistura faixas.\n </p>\n <p class=\"section-help\" *ngIf=\"!form.controls.alwaysVisibleFields.value?.length\">\n Nenhum campo selecionado. Use o seletor acima para adicionar.\n </p>\n </div>\n\n <mat-divider class=\"section-divider\" role=\"presentation\"></mat-divider>\n\n <div\n id=\"always-visible-metadata\"\n class=\"options options-compact-flow always-visible-section-anchor\"\n [class.section-active]=\"isAlwaysVisibleSectionActive('always-visible-metadata')\"\n [style.--section-enter-delay]=\"sectionEnterDelay('always-visible-metadata')\"\n tabindex=\"-1\"\n (focusin)=\"onAlwaysVisibleSectionFocus('always-visible-metadata')\"\n >\n <div class=\"options-header\">\n <h4 class=\"section-title\">Editor visual de metadados</h4>\n <p class=\"section-help\">\n Edite os principais ajustes dos campos sempre vis\u00EDveis no fluxo visual. Para propriedades avan\u00E7adas, use o JSON abaixo.\n </p>\n </div>\n <p class=\"section-help\" *ngIf=\"!form.controls.alwaysVisibleFields.value?.length\">\n Selecione campos em \u201CCampos sempre vis\u00EDveis\u201D para habilitar a edi\u00E7\u00E3o visual.\n </p>\n <div class=\"metadata-card-grid\" *ngIf=\"form.controls.alwaysVisibleFields.value?.length\">\n <article class=\"metadata-card\" *ngFor=\"let name of form.controls.alwaysVisibleFields.value\">\n <header class=\"metadata-card-header\">\n <div class=\"metadata-card-title\">\n <strong>{{ getFieldLabel(name) }}</strong>\n <span>{{ name }}</span>\n </div>\n <div class=\"metadata-card-badges\">\n <span class=\"metadata-chip\">{{ getAlwaysVisibleControlTypeLabel(name) }}</span>\n <span class=\"metadata-chip metadata-chip-override\" *ngIf=\"hasAlwaysVisibleOverride(name)\">\n Override ativo\n </span>\n </div>\n </header>\n <p class=\"metadata-card-summary\">{{ getAlwaysVisibleOverridePreview(name) }}</p>\n <div class=\"metadata-card-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"openAlwaysVisibleMetadataEditor(name)\">\n <mat-icon [praxisIcon]=\"'tune'\"></mat-icon>\n Editar campo\n </button>\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"clearAlwaysVisibleOverride(name)\"\n [disabled]=\"!hasAlwaysVisibleOverride(name)\"\n >\n Limpar override\n </button>\n </div>\n </article>\n </div>\n </div>\n\n <mat-divider class=\"section-divider\" role=\"presentation\"></mat-divider>\n\n <div\n id=\"always-visible-json\"\n class=\"always-visible-section-anchor\"\n [class.section-active]=\"isAlwaysVisibleSectionActive('always-visible-json')\"\n [style.--section-enter-delay]=\"sectionEnterDelay('always-visible-json')\"\n tabindex=\"-1\"\n (focusin)=\"onAlwaysVisibleSectionFocus('always-visible-json')\"\n >\n <mat-expansion-panel\n class=\"options options-compact-flow options-advanced-json\"\n [expanded]=\"!!alwaysVisibleOverridesErrorMsg\"\n >\n <mat-expansion-panel-header>\n <mat-panel-title>Avan\u00E7ado (JSON opcional)</mat-panel-title>\n <mat-panel-description>Para ajustes n\u00E3o expostos no editor visual</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"options-header\">\n <h4 class=\"section-title\">Modo avan\u00E7ado (JSON)</h4>\n <p class=\"section-help\">\n Use JSON para ajustes em lote ou propriedades ainda n\u00E3o expostas no editor visual.\n </p>\n </div>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>alwaysVisibleFieldMetadataOverrides (JSON)</mat-label>\n <textarea\n matInput\n rows=\"8\"\n [(ngModel)]=\"alwaysVisibleOverridesJsonText\"\n [ngModelOptions]=\"{standalone: true}\"\n ></textarea>\n </mat-form-field>\n <div class=\"actions\">\n <button mat-stroked-button type=\"button\" (click)=\"formatAlwaysVisibleOverridesJson()\">Formatar</button>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"applyAlwaysVisibleOverridesJson()\">\n Validar e carregar no editor\n </button>\n </div>\n <p class=\"json-tip\">\n Esta a\u00E7\u00E3o n\u00E3o persiste a configura\u00E7\u00E3o. Para persistir, use \u201CSalvar &amp; Fechar\u201D no rodap\u00E9.\n </p>\n <p class=\"json-tip\">\n Exemplo:\n &#123;\"status\":&#123;\"controlType\":\"inlineSelect\",\"clearButton\":&#123;\"enabled\":true&#125;,\"inlineAutoSize\":&#123;\"minWidth\":140,\"maxWidth\":280&#125;&#125;&#125;\n </p>\n <p *ngIf=\"alwaysVisibleOverridesErrorMsg\" class=\"json-error\" role=\"status\" aria-live=\"polite\">{{ alwaysVisibleOverridesErrorMsg }}</p>\n </mat-expansion-panel>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Layout\">\n <div class=\"options\">\n <div class=\"options-header\">\n <h4 class=\"section-title\">Grid e responsividade</h4>\n <p class=\"section-help\">\n Ajuste largura m\u00EDnima e n\u00FAmero de colunas por breakpoint. Em telas menores que 600px, o layout usa 1 coluna.\n </p>\n </div>\n <div class=\"layout-preview-section\" aria-live=\"polite\">\n <h5 class=\"layout-preview-title\">Pr\u00E9-visualiza\u00E7\u00E3o do grid</h5>\n <p class=\"section-help\">\n Simula\u00E7\u00E3o com {{ layoutPreviewFields.length }} campos e largura m\u00EDnima de {{ layoutMinWidth() }}px por campo.\n </p>\n <div class=\"layout-preview-cards\">\n <article class=\"layout-preview-card\">\n <div class=\"layout-preview-header\">\n <strong>Mobile</strong>\n <span>&lt;600px \u00B7 {{ layoutColsFor('sm') }} coluna</span>\n </div>\n <div class=\"layout-mini-grid\" [style.gridTemplateColumns]=\"'repeat(' + layoutColsFor('sm') + ', minmax(0, 1fr))'\">\n <span *ngFor=\"let field of layoutPreviewFields\">{{ field }}</span>\n </div>\n </article>\n <article class=\"layout-preview-card\">\n <div class=\"layout-preview-header\">\n <strong>Tablet</strong>\n <span>&ge;600px \u00B7 {{ layoutColsFor('md') }} colunas</span>\n </div>\n <div class=\"layout-mini-grid\" [style.gridTemplateColumns]=\"'repeat(' + layoutColsFor('md') + ', minmax(0, 1fr))'\">\n <span *ngFor=\"let field of layoutPreviewFields\">{{ field }}</span>\n </div>\n </article>\n <article class=\"layout-preview-card\">\n <div class=\"layout-preview-header\">\n <strong>Desktop</strong>\n <span>&ge;960px \u00B7 {{ layoutColsFor('lg') }} colunas</span>\n </div>\n <div class=\"layout-mini-grid\" [style.gridTemplateColumns]=\"'repeat(' + layoutColsFor('lg') + ', minmax(0, 1fr))'\">\n <span *ngFor=\"let field of layoutPreviewFields\">{{ field }}</span>\n </div>\n </article>\n </div>\n </div>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Largura m\u00EDnima por campo (px)</mat-label>\n <input\n matInput\n type=\"number\"\n formControlName=\"alwaysMinWidth\"\n min=\"180\"\n max=\"480\"\n step=\"1\"\n inputmode=\"numeric\"\n praxisNumberWheelBlur\n (blur)=\"normalizeLayoutControl('alwaysMinWidth')\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n aria-label=\"Ajuda sobre largura m\u00EDnima por campo\"\n matTooltip=\"Define a largura m\u00EDnima de cada campo no grid. Recomendado entre 200 e 300px.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-hint align=\"start\">Intervalo permitido: 180 a 480px.</mat-hint>\n <mat-hint align=\"end\">Recomendado: 200 a 300px.</mat-hint>\n <mat-error *ngIf=\"layoutControlError('alwaysMinWidth') as error\">{{ error }}</mat-error>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Colunas em tablet (&ge;600px)</mat-label>\n <input\n matInput\n type=\"number\"\n formControlName=\"alwaysColsMd\"\n min=\"1\"\n max=\"3\"\n step=\"1\"\n inputmode=\"numeric\"\n praxisNumberWheelBlur\n (blur)=\"normalizeLayoutControl('alwaysColsMd')\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n aria-label=\"Ajuda sobre colunas em tablet\"\n matTooltip=\"Define quantas colunas aparecem em telas m\u00E9dias (a partir de 600px).\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-hint align=\"start\">Mobile (&lt;600px) usa 1 coluna.</mat-hint>\n <mat-hint align=\"end\">Intervalo: 1 a 3 colunas.</mat-hint>\n <mat-error *ngIf=\"layoutControlError('alwaysColsMd') as error\">{{ error }}</mat-error>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Colunas em desktop (&ge;960px)</mat-label>\n <input\n matInput\n type=\"number\"\n formControlName=\"alwaysColsLg\"\n min=\"1\"\n max=\"4\"\n step=\"1\"\n inputmode=\"numeric\"\n praxisNumberWheelBlur\n (blur)=\"normalizeLayoutControl('alwaysColsLg')\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n aria-label=\"Ajuda sobre colunas em desktop\"\n matTooltip=\"Define quantas colunas aparecem em telas grandes (a partir de 960px).\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-hint align=\"start\">Use mais colunas apenas quando houver espa\u00E7o.</mat-hint>\n <mat-hint align=\"end\">Intervalo: 1 a 4 colunas.</mat-hint>\n <mat-error *ngIf=\"layoutControlError('alwaysColsLg') as error\">{{ error }}</mat-error>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab label=\"Booleanos\">\n <div class=\"options\">\n <p class=\"section-help\" *ngIf=\"!hasBooleanFieldMetadata()\">\n Nenhum campo booleano foi detectado no schema atual. Estas prefer\u00EAncias ser\u00E3o aplicadas quando houver\n campos `toggle`/boolean no filtro.\n </p>\n <div class=\"toggle-preview-section\" *ngIf=\"hasBooleanFieldMetadata()\">\n <h4>Visualiza\u00E7\u00E3o dos Booleanos</h4>\n <p class=\"section-help\">Veja o comportamento dos booleanos inline (com texto ou compacto) e a posi\u00E7\u00E3o na barra.</p>\n <div class=\"preview-container\">\n <div class=\"preview-item\">\n <strong>Grade Principal</strong>\n <div class=\"mock-grid\" [class.with-booleans]=\"!form.controls.placeBooleansInActions.value\">\n <div class=\"mock-field\">Campo 1</div>\n <div class=\"mock-field\">Campo 2</div>\n <div class=\"mock-pill\" *ngIf=\"!form.controls.placeBooleansInActions.value\"\n [class.compact]=\"!form.controls.showToggleLabels.value\">\n <mat-slide-toggle [checked]=\"true\"></mat-slide-toggle>\n <span *ngIf=\"form.controls.showToggleLabels.value\">Ativo</span>\n </div>\n </div>\n </div>\n <div class=\"preview-item\">\n <strong>\u00C1rea de A\u00E7\u00F5es</strong>\n <div class=\"mock-actions\" [class.with-booleans]=\"form.controls.placeBooleansInActions.value\">\n <button mat-icon-button><mat-icon>search</mat-icon></button>\n <button mat-icon-button><mat-icon>tune</mat-icon></button>\n <div class=\"mock-pill\" *ngIf=\"form.controls.placeBooleansInActions.value\"\n [class.compact]=\"!form.controls.showToggleLabels.value\">\n <mat-slide-toggle [checked]=\"true\"></mat-slide-toggle>\n <span *ngIf=\"form.controls.showToggleLabels.value\">Ativo</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <mat-checkbox formControlName=\"placeBooleansInActions\">\n <mat-icon>swap_horiz</mat-icon>\n Posicionar booleanos na \u00E1rea de a\u00E7\u00F5es\n </mat-checkbox>\n <p class=\"field-hint\">Move os booleanos da grade para os bot\u00F5es de a\u00E7\u00E3o, liberando espa\u00E7o horizontal.</p>\n <mat-checkbox formControlName=\"showToggleLabels\">\n <mat-icon>text_fields</mat-icon>\n Mostrar texto nos booleanos inline\n </mat-checkbox>\n <p class=\"field-hint\">Quando desativado, os booleanos ficam em modo compacto (somente controle, sem texto).</p>\n </div>\n </mat-tab>\n <mat-tab label=\"Op\u00E7\u00F5es\">\n <div class=\"options\">\n <div class=\"options-header\">\n <h4 class=\"section-title\">Painel Avan\u00E7ado</h4>\n <p class=\"section-help\">Apar\u00EAncia e comportamento do painel de filtros avan\u00E7ados.</p>\n </div>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Modo de abertura do Avan\u00E7ado</mat-label>\n <mat-select formControlName=\"advancedOpenMode\">\n <mat-option value=\"modal\">Modal (padr\u00E3o)</mat-option>\n <mat-option value=\"drawer\">Drawer (direita)</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Escolha como o painel de filtros avan\u00E7ados ser\u00E1 exibido: centralizado ou lateral.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-checkbox formControlName=\"advancedClearButtonsEnabled\">\n Mostrar bot\u00E3o de limpar nos campos\n </mat-checkbox>\n <p class=\"field-hint\">\n Desative para ocultar o bot\u00E3o de limpar nos campos do painel avan\u00E7ado.\n </p>\n\n <mat-checkbox formControlName=\"useInlineSearchableSelectVariant\">\n Compactar selects com busca/async/autocomplete na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Padr\u00E3o do filtro din\u00E2mico. Desative apenas quando o host precisar preservar o renderer dedicado por compatibilidade, performance ou comportamento legado. O lookup de entidade inline \u00E9 configurado por controlType expl\u00EDcito (`inlineEntityLookup`).\n </p>\n\n <mat-checkbox formControlName=\"useInlineRangeVariant\">\n Compactar range slider na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Usa o componente inline em formato chip + popover para rangeSlider (single e faixa).\n </p>\n\n <mat-checkbox formControlName=\"useInlineDateVariant\">\n Compactar campos de data na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Usa o componente inline dedicado para date/dateInput/datepicker, com largura por conte\u00FAdo e placeholder compacto.\n </p>\n\n <mat-checkbox formControlName=\"useInlineDateRangeVariant\">\n Compactar intervalo de datas na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Padr\u00E3o do filtro din\u00E2mico para dateRange/daterange. Desative apenas para preservar o renderer tradicional em hosts legados.\n </p>\n\n <mat-checkbox formControlName=\"useInlineTimeVariant\">\n Compactar campos de horario na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Padr\u00E3o do filtro din\u00E2mico para time/timePicker, com largura por conteudo e clear rapido. Desative apenas para manter a experi\u00EAncia legada.\n </p>\n\n <mat-checkbox formControlName=\"useInlineTimeRangeVariant\">\n Compactar intervalo de horario na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Padr\u00E3o do filtro din\u00E2mico para timeRange/timerange. Desative apenas para preservar o renderer tradicional em hosts legados.\n </p>\n\n <mat-checkbox formControlName=\"useInlineTreeSelectVariant\">\n Compactar tree select na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Padr\u00E3o do filtro din\u00E2mico para treeSelect na faixa compacta. Desative apenas quando o host depender do renderer dedicado. multiSelectTree mant\u00E9m o componente dedicado.\n </p>\n\n <mat-checkbox formControlName=\"confirmTagDelete\">Confirmar exclus\u00E3o de atalho</mat-checkbox>\n <p class=\"field-hint\">Solicita confirma\u00E7\u00E3o antes de apagar atalhos salvos.</p>\n\n <div class=\"options\">\n <h4>Tema dos Atalhos (Tags)</h4>\n\n <!-- Preview Section -->\n <div class=\"preview-section\" [class.mdc-theme-dark]=\"previewDarkMode\" [class.dark-mode]=\"previewDarkMode\">\n <div class=\"preview-controls\">\n <span class=\"preview-label\">Pr\u00E9-visualiza\u00E7\u00E3o</span>\n <button mat-icon-button (click)=\"previewDarkMode = !previewDarkMode\"\n [matTooltip]=\"previewDarkMode ? 'Mudar para fundo claro' : 'Mudar para fundo escuro'\">\n <mat-icon>{{ previewDarkMode ? 'light_mode' : 'dark_mode' }}</mat-icon>\n </button>\n </div>\n\n <div class=\"preview-chips praxis-filter-tags\"\n [class.outlined]=\"form.controls.tagVariant.value === 'outlined'\">\n <mat-chip-set>\n <!-- Inactive Chip -->\n <mat-chip\n [color]=\"form.controls.tagVariant.value === 'outlined' ? null : (form.controls.tagColor.value === 'basic' ? null : form.controls.tagColor.value)\"\n [highlighted]=\"form.controls.tagVariant.value === 'filled' && form.controls.tagColor.value !== 'basic'\">\n Atalho Inativo\n </mat-chip>\n\n <!-- Active Chip -->\n <mat-chip class=\"active\" [color]=\"form.controls.tagVariant.value === 'outlined' ? null : 'accent'\"\n [highlighted]=\"form.controls.tagVariant.value === 'filled'\">\n <mat-icon matChipAvatar>check</mat-icon>\n Atalho Ativo\n <button matChipTrailingIcon mat-icon-button\n [color]=\"form.controls.tagButtonColor.value === 'basic' ? null : form.controls.tagButtonColor.value\">\n <mat-icon>arrow_drop_down</mat-icon>\n </button>\n </mat-chip>\n </mat-chip-set>\n </div>\n\n <div class=\"contrast-warning\" *ngIf=\"getContrastWarning() as warning\">\n <mat-icon>warning</mat-icon>\n <span>{{ warning }}</span>\n </div>\n </div>\n\n <!-- Reordered Fields -->\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante do atalho</mat-label>\n <mat-select formControlName=\"tagVariant\">\n <mat-option value=\"filled\">Filled (Preenchido)</mat-option>\n <mat-option value=\"outlined\">Outlined (Contorno)</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Define o estilo base do atalho.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor do atalho</mat-label>\n <mat-select formControlName=\"tagColor\">\n <mat-option value=\"primary\">Primary</mat-option>\n <mat-option value=\"accent\">Accent</mat-option>\n <mat-option value=\"warn\">Warn</mat-option>\n <mat-option value=\"basic\">Basic</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Cor de fundo (Filled) ou de contorno (Outlined).\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor do bot\u00E3o do menu do atalho</mat-label>\n <mat-select formControlName=\"tagButtonColor\">\n <mat-option value=\"basic\">Basic</mat-option>\n <mat-option value=\"primary\">Primary</mat-option>\n <mat-option value=\"accent\">Accent</mat-option>\n <mat-option value=\"warn\">Warn</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Cor do bot\u00E3o de dropdown dentro do atalho ativo.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n </div>\n\n <div class=\"options\">\n <h4>Tema dos bot\u00F5es de a\u00E7\u00E3o</h4>\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor dos bot\u00F5es</mat-label>\n <mat-select formControlName=\"actionsButtonColor\">\n <mat-option value=\"basic\">Basic</mat-option>\n <mat-option value=\"primary\">Primary</mat-option>\n <mat-option value=\"accent\">Accent</mat-option>\n <mat-option value=\"warn\">Warn</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante dos bot\u00F5es</mat-label>\n <mat-select formControlName=\"actionsVariant\">\n <mat-option value=\"standard\">Standard</mat-option>\n <mat-option value=\"outlined\">Outlined</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"options\">\n <h4>Predefini\u00E7\u00F5es de tema</h4>\n <div class=\"preset-grid\">\n <button\n type=\"button\"\n class=\"preset-card\"\n *ngFor=\"let p of presets\"\n (click)=\"applyPreset(p.key)\"\n [attr.aria-label]=\"'Aplicar predefini\u00E7\u00E3o: ' + p.label\"\n >\n <div class=\"preset-preview\" [ngClass]=\"p.previewClass\"></div>\n <div class=\"preset-info\">\n <span class=\"preset-name\">{{ p.label }}</span>\n <span class=\"preset-desc\">{{ p.description }}</span>\n </div>\n </button>\n </div>\n <button mat-button color=\"warn\" (click)=\"resetPreferences()\" class=\"restore-btn\">\n Restaurar padr\u00E3o\n </button>\n </div>\n </div>\n </mat-tab>\n @if (configKey) {\n <mat-tab label=\"Atalhos\">\n <div class=\"options\">\n <p class=\"section-help\">Os atalhos s\u00E3o salvos por chave de configura\u00E7\u00E3o e compartilhados entre sess\u00F5es.</p>\n <div class=\"tags-header\">\n <span><strong>Atalhos salvos</strong></span>\n <span class=\"spacer\"></span>\n <button mat-stroked-button color=\"warn\" (click)=\"clearTags()\">Apagar tudo</button>\n </div>\n <div class=\"new-tag\">\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>R\u00F3tulo do novo atalho</mat-label>\n <input matInput [(ngModel)]=\"newTagLabel\" [ngModelOptions]=\"{standalone: true}\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Patch (JSON, opcional)</mat-label>\n <textarea matInput rows=\"3\" [(ngModel)]=\"newTagPatchText\" [ngModelOptions]=\"{standalone: true}\"></textarea>\n </mat-form-field>\n <div>\n <button mat-stroked-button color=\"primary\" (click)=\"addTag()\">Adicionar</button>\n @if (hasCurrentDto()) {\n <button mat-stroked-button (click)=\"addTagFromCurrent()\">Adicionar a partir dos filtros atuais</button>\n }\n </div>\n <div>\n <button mat-stroked-button color=\"primary\" (click)=\"importTags()\">Importar</button>\n <button mat-stroked-button (click)=\"loadTags()\">Recarregar</button>\n <button mat-stroked-button (click)=\"saveTags()\">Salvar</button>\n </div>\n </div>\n </div>\n </mat-tab>\n }\n <mat-tab label=\"JSON\">\n <div class=\"options\">\n <p><strong>Configura\u00E7\u00E3o atual (somente leitura)</strong></p>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Atual</mat-label>\n <textarea matInput rows=\"8\" [value]=\"effectiveJson\" readonly></textarea>\n </mat-form-field>\n\n <p><strong>Editar JSON</strong></p>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>JSON</mat-label>\n <textarea matInput rows=\"12\" [(ngModel)]=\"settingsJsonText\" [ngModelOptions]=\"{standalone: true}\"></textarea>\n </mat-form-field>\n <div class=\"actions\">\n <button mat-stroked-button (click)=\"onJsonReload()\">Recarregar do formul\u00E1rio</button>\n <button mat-stroked-button (click)=\"onJsonFormat()\">Formatar</button>\n <button mat-stroked-button color=\"primary\" (click)=\"onJsonApply()\">Carregar JSON no formul\u00E1rio</button>\n </div>\n <p class=\"json-tip\">\n Dica: esta a\u00E7\u00E3o apenas atualiza o editor local. Para persistir, use os bot\u00F5es Aplicar ou\n Salvar &amp; Fechar no rodap\u00E9 do painel.\n </p>\n <p *ngIf=\"jsonErrorMsg\" class=\"json-error\" role=\"status\" aria-live=\"polite\">{{ jsonErrorMsg }}</p>\n </div>\n </mat-tab>\n <mat-tab label=\"Comportamento\">\n <div class=\"options\">\n <mat-checkbox formControlName=\"allowSaveTags\">Permitir salvar atalhos</mat-checkbox>\n </div>\n </mat-tab>\n <mat-tab label=\"Avan\u00E7ado\">\n <div class=\"options\">\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Debounce de altera\u00E7\u00F5es (ms)</mat-label>\n <input matInput type=\"number\" formControlName=\"changeDebounceMs\" min=\"100\" max=\"1000\" />\n @if (form.controls.changeDebounceMs.invalid) { <mat-error>Valor deve estar entre 100 e 1000</mat-error> }\n </mat-form-field>\n <div class=\"actions\">\n <button mat-stroked-button color=\"warn\" (click)=\"resetPreferences()\">\n <mat-icon [praxisIcon]=\"'restart_alt'\"></mat-icon>\n Redefinir prefer\u00EAncias do filtro\n </button>\n <button mat-stroked-button color=\"accent\" (click)=\"clearPersistedFilters()\">\n <mat-icon [praxisIcon]=\"'clear_all'\"></mat-icon>\n Limpar filtros salvos\n </button>\n <button mat-stroked-button (click)=\"forceSchemaReload()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n For\u00E7ar recarregamento do schema\n </button>\n </div>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>N\u00EDvel de log</mat-label>\n <mat-select formControlName=\"logLevel\">\n <mat-option value=\"none\">Nenhum</mat-option>\n <mat-option value=\"error\">Erro</mat-option>\n <mat-option value=\"warn\">Aviso</mat-option>\n <mat-option value=\"info\">Info</mat-option>\n <mat-option value=\"debug\">Debug</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Persistido no contrato para integra\u00E7\u00E3o host. Sem efeito direto no runtime atual do filtro.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-checkbox formControlName=\"enablePerformanceMetrics\">Habilitar m\u00E9tricas de performance</mat-checkbox>\n <p class=\"field-hint\">Prefer\u00EAncia persistida para integra\u00E7\u00E3o host. Sem efeito direto no runtime atual do filtro.</p>\n </div>\n </mat-tab>\n </mat-tab-group>\n</form>\n", styles: [":host{display:block;min-width:0}.full-width{width:100%}.always-visible-tab-flow{display:flex;flex-direction:column;gap:4px}.always-visible-context{position:sticky;top:0;z-index:2;display:flex;flex-direction:column;gap:6px;padding:8px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 88%,transparent);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.always-visible-summary{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px 10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;background:var(--md-sys-color-surface-container-low)}.always-visible-summary-item{display:flex;align-items:baseline;gap:6px;min-width:0}.summary-value{font-size:1rem;font-weight:700;color:var(--md-sys-color-primary)}.summary-label{font-size:.8rem;color:var(--md-sys-color-on-surface-variant);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.always-visible-quick-nav{display:flex;flex-wrap:wrap;gap:6px}.always-visible-quick-nav button{min-height:30px;font-size:.76rem;padding-inline:10px;transition:border-color .18s ease,background-color .18s ease,color .18s ease}.always-visible-quick-nav button.quick-nav-active{border-color:color-mix(in srgb,var(--md-sys-color-primary) 50%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 34%,var(--md-sys-color-surface-container-low));color:var(--md-sys-color-primary)}.always-visible-section-anchor{scroll-margin-top:140px;opacity:0;transform:translateY(8px);animation:always-visible-section-enter .22s cubic-bezier(.2,0,0,1) forwards;animation-delay:var(--section-enter-delay, 0ms)}.always-visible-section-anchor.section-active,.always-visible-section-anchor.section-active .options-advanced-json{box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 40%,transparent)}.always-visible-section-anchor:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}@keyframes always-visible-section-enter{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.options{display:flex;flex-direction:column;gap:.75rem;padding:12px;width:100%;max-width:100%;min-width:0;box-sizing:border-box;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;background:var(--md-sys-color-surface-container)}.options .options{padding:0;border:0;border-radius:0;background:transparent}.options-compact-flow{gap:8px;padding-top:10px;padding-bottom:10px}.section-divider{margin:2px;border-top-style:dashed;border-top-color:var(--md-sys-color-outline-variant);opacity:.28}.options-advanced-json{display:block;padding:0;overflow:hidden}:host ::ng-deep .options-advanced-json .mat-expansion-panel-header{padding:0 12px;min-height:52px}:host ::ng-deep .options-advanced-json .mat-expansion-panel-body{padding:0 12px 12px}.options-header{display:flex;flex-direction:column;gap:6px}.section-title{margin:0;font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.section-help{margin:0;font-size:.85rem;color:var(--md-sys-color-on-surface);opacity:.84}.field-hint{margin:-4px 0 0;font-size:.8rem;color:var(--md-sys-color-on-surface);opacity:.78}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.order-layout-toolbar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}.order-viewport-toggle-group{max-width:100%}.order-viewport-caption{display:inline-flex;align-items:center;min-height:28px;padding:0 10px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);font-size:.75rem;font-weight:600;color:var(--md-sys-color-on-surface-variant)}.order-layout-viewport{width:100%;display:flex;justify-content:center;padding:10px;border-radius:14px;border:1px solid var(--md-sys-color-outline-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 74%,transparent)}.order-layout-frame{width:100%;transition:max-width .18s ease}.order-layout-frame[data-viewport=tablet] .order-lane-canvas{gap:7px}.order-layout-frame[data-viewport=mobile] .order-lane-canvas{gap:6px;padding:7px}.order-layout-frame[data-viewport=mobile] .order-pill{width:100%;max-width:100%;border-radius:12px}.order-layout-composer{display:flex;flex-direction:column;gap:9px}.order-lane{display:flex;flex-direction:column;gap:6px}.order-lane-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.order-lane-title-block{display:flex;flex-direction:column;gap:2px;min-width:0}.order-lane-title{margin:0;font-size:.85rem;font-weight:600;color:var(--md-sys-color-on-surface)}.order-lane-help{margin:0;font-size:.76rem;color:var(--md-sys-color-on-surface-variant)}.order-lane-count{display:inline-flex;align-items:center;justify-content:center;min-width:24px;height:24px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);font-size:.76rem;font-weight:600;padding:0 8px}.order-lane-canvas{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-height:56px;padding:8px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:12px;background:var(--md-sys-color-surface-container-low)}.order-lane-canvas.cdk-drop-list-dragging{border-color:color-mix(in srgb,var(--md-sys-color-primary) 45%,var(--md-sys-color-outline-variant))}.order-lane[data-lane=actions] .order-lane-canvas{background:color-mix(in srgb,var(--md-sys-color-secondary-container) 28%,var(--md-sys-color-surface-container-low))}.order-lane[data-lane=inline] .order-lane-canvas{background:color-mix(in srgb,var(--md-sys-color-primary-container) 22%,var(--md-sys-color-surface-container-low))}.order-lane[data-lane=grid] .order-lane-canvas{background:color-mix(in srgb,var(--md-sys-color-tertiary-container) 18%,var(--md-sys-color-surface-container-low))}.order-lane-canvas.is-empty{justify-content:flex-start}.order-pill{display:inline-flex;align-items:center;gap:8px;max-width:min(100%,520px);min-height:38px;border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);padding:4px 8px;box-sizing:border-box;cursor:grab;font:inherit;text-align:left}.order-pill:hover{border-color:var(--md-sys-color-outline)}.order-pill:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.order-pill mat-icon{opacity:.75}.order-pill-label{min-width:0;max-width:190px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.86rem;font-weight:500}.order-pill-badges{display:inline-flex;flex-wrap:wrap;align-items:center;gap:4px}.order-pill-chip{display:inline-flex;align-items:center;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface-variant);font-size:.7rem;font-weight:600;padding:1px 7px;white-space:nowrap}.order-pill-chip-width{font-weight:500;opacity:.86}.order-pill-chip-override{border-color:color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary)}.order-lane-empty{margin:0;font-size:.78rem;color:var(--md-sys-color-on-surface-variant)}.order-pill.cdk-drag-preview{box-shadow:var(--md-sys-elevation-level2)}.order-pill.cdk-drag-placeholder{opacity:.45}.layout-preview-section{display:flex;flex-direction:column;gap:10px;padding:12px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;background:var(--md-sys-color-surface-container-low);min-width:0}.layout-preview-title{margin:0;font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.layout-preview-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;min-width:0}.layout-preview-card{display:flex;flex-direction:column;gap:8px;padding:10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container);min-width:0}.layout-preview-header{display:flex;flex-direction:column;gap:2px}.layout-preview-header strong{font-size:.85rem;color:var(--md-sys-color-on-surface)}.layout-preview-header span{font-size:.78rem;color:var(--md-sys-color-on-surface-variant)}.layout-mini-grid{display:grid;gap:6px;min-width:0}.layout-mini-grid span{display:block;min-width:0;padding:6px 8px;border-radius:6px;background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container);font-size:.75rem;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tags-header{display:flex;align-items:center;gap:8px}.spacer{flex:1 1 auto}.new-tag{display:flex;flex-direction:column;gap:8px}.preset-row{display:flex;flex-wrap:wrap;gap:8px}.option-with-preview{display:flex;align-items:center;gap:8px}.preview-card{width:20px;height:20px;background:var(--md-sys-color-surface-container-high);border:1px solid var(--md-sys-color-outline-variant);border-radius:4px}.preview-frosted{width:20px;height:20px;background:var(--md-sys-color-surface-container);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border:1px solid var(--md-sys-color-outline-variant);border-radius:4px}.toggle-preview-section{margin-bottom:1.5rem;padding:1rem;background:var(--md-sys-color-surface-container-low);border-radius:8px;border:1px solid var(--md-sys-color-outline-variant)}.toggle-preview-section h4{margin:0 0 1rem;font-size:1.1rem;color:var(--md-sys-color-on-surface)}.preview-container{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1rem}.preview-item{text-align:center}.preview-item strong{display:block;margin-bottom:.5rem;font-weight:500}.mock-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));align-items:center;gap:8px;padding:8px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline);border-radius:8px;min-height:72px}.mock-grid.with-booleans{grid-template-columns:repeat(3,minmax(0,1fr))}.mock-field{padding:4px 8px;background:var(--md-sys-color-primary-container);border-radius:6px;font-size:.8rem;text-align:center}.mock-actions{display:flex;align-items:center;gap:8px;padding:8px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline);border-radius:8px;min-height:48px}.mock-actions button{width:34px;height:34px}.mock-pill{display:flex;align-items:center;gap:8px;min-height:34px;padding:0 10px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant);font-size:.82rem;justify-self:start}.mock-pill.compact{padding-inline:8px;gap:0}.mock-pill mat-slide-toggle{--mdc-switch-selected-track-color: var(--md-sys-color-primary);--mdc-switch-selected-handle-color: var(--md-sys-color-on-primary);transform:scale(.8);pointer-events:none}.mock-pill span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:500}.preview-section{display:flex;flex-direction:column;gap:16px;padding:16px;background:var(--md-sys-color-surface-container-low);border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;margin-bottom:16px;box-shadow:var(--md-sys-elevation-level1);transition:background-color .3s,color .3s}.preview-section.dark-mode{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface);border-color:var(--md-sys-color-outline-variant)}.preview-section.dark-mode .preview-label{color:var(--md-sys-color-on-surface-variant)}.preview-controls{display:flex;justify-content:space-between;align-items:center}.preview-label{font-weight:500;font-size:.9rem;color:var(--md-sys-color-on-surface-variant)}.preview-chips{display:flex;justify-content:center;padding:16px 0}.praxis-filter-tags.outlined .mat-mdc-chip{background:transparent!important;--mat-chip-outline-width: 1px;--mat-chip-outline-color: var(--md-sys-color-outline-variant);box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)}.praxis-filter-tags.outlined mat-chip.active .mat-mdc-chip,.praxis-filter-tags.outlined .mat-mdc-chip.mat-mdc-chip-highlighted{--mat-chip-outline-color: var(--md-sys-color-primary) !important;box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)!important}.praxis-filter-tags.outlined mat-chip[ng-reflect-color=primary] .mat-mdc-chip{--mat-chip-outline-color: var(--md-sys-color-primary)}.praxis-filter-tags.outlined mat-chip[ng-reflect-color=accent] .mat-mdc-chip{--mat-chip-outline-color: var(--md-sys-color-tertiary)}.praxis-filter-tags.outlined mat-chip[ng-reflect-color=warn] .mat-mdc-chip{--mat-chip-outline-color: var(--md-sys-color-error)}.praxis-filter-tags .mat-mdc-standard-chip .mdc-evolution-chip__text-label{display:flex;align-items:center;gap:4px}.contrast-warning{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-radius:4px;font-size:.85rem}.contrast-warning mat-icon{font-size:20px;width:20px;height:20px}.preset-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:12px;margin-bottom:12px}.preset-card{display:flex;width:100%;flex-direction:column;gap:8px;padding:12px;text-align:left;font:inherit;color:inherit;background:transparent;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;cursor:pointer;transition:all .2s}.preset-card:hover{background:var(--md-sys-color-surface-container-high);border-color:var(--md-sys-color-outline)}.preset-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.preset-preview{height:24px;border-radius:4px;background:var(--md-sys-color-surface-variant)}.preset-preview.preview-minimal{background:transparent;border:1px solid var(--md-sys-color-outline)}.preset-preview.preview-primary{background:var(--md-sys-color-primary-container)}.preset-preview.preview-accent{background:var(--md-sys-color-tertiary-container)}.preset-preview.preview-warn{background:var(--md-sys-color-error-container)}.preset-info{display:flex;flex-direction:column}.preset-name{font-weight:500;font-size:.9rem}.preset-desc{font-size:.75rem;opacity:.7}.restore-btn{align-self:flex-start}.metadata-card-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:10px}.metadata-card{display:flex;flex-direction:column;gap:10px;padding:12px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low)}.metadata-card-header{display:flex;justify-content:space-between;align-items:flex-start;gap:10px}.metadata-card-title{display:flex;flex-direction:column;min-width:0}.metadata-card-title strong{font-size:.92rem;color:var(--md-sys-color-on-surface)}.metadata-card-title span{font-size:.78rem;color:var(--md-sys-color-on-surface-variant);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.metadata-card-badges{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:6px}.metadata-chip{display:inline-flex;align-items:center;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface-variant);font-size:.78rem;font-weight:500;padding:2px 8px;white-space:nowrap}.metadata-chip-override{border-color:color-mix(in srgb,var(--md-sys-color-primary) 40%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 38%,var(--md-sys-color-surface-container))}.metadata-card-summary{margin:0;font-size:.8rem;color:var(--md-sys-color-on-surface-variant)}.metadata-card-actions{display:flex;flex-wrap:wrap;gap:6px}.metadata-card-actions button{display:inline-flex;align-items:center;gap:4px}.metadata-card-actions button:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:1px}:host ::ng-deep .metadata-card-actions button[disabled]{opacity:.62}.json-tip{margin:6px 0 0;font-size:.85rem;color:var(--md-sys-color-on-surface-variant)}.json-error{margin-top:6px;font-size:.85rem;color:var(--md-sys-color-error)}@media(prefers-reduced-motion:reduce){.always-visible-section-anchor{animation:none;opacity:1;transform:none}.always-visible-quick-nav button{transition:none}}@media(max-width:680px){.order-layout-toolbar{flex-direction:column;align-items:stretch}.order-viewport-caption{align-self:flex-start}.order-layout-viewport{padding:8px}.always-visible-context{position:static;-webkit-backdrop-filter:none;backdrop-filter:none}.always-visible-summary{grid-template-columns:1fr}.always-visible-quick-nav{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}.order-pill{width:100%;max-width:100%}.order-pill-label{max-width:none}.order-pill-badges{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i4.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i4.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i10$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i15$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i15$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i12.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i12.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i15.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i15.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i15.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "directive", type: i15.MatChipTrailingIcon, selector: "mat-chip-trailing-icon, [matChipTrailingIcon]" }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "directive", type: PraxisNumberWheelBlurDirective, selector: "input[type=number][praxisNumberWheelBlur]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
24009
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: FilterSettingsComponent, isStandalone: true, selector: "filter-settings", inputs: { metadata: "metadata", metadataSource: "metadataSource", metadataLoading: "metadataLoading", metadataErrorMsg: "metadataErrorMsg", settings: "settings", configKey: "configKey" }, outputs: { settingsChange: "settingsChange" }, usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-tab-group (selectedTabChange)=\"onTabChange($event)\">\n <mat-tab label=\"Sempre Vis\u00EDveis\">\n <div class=\"always-visible-tab-flow\">\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Campos sempre vis\u00EDveis</mat-label>\n <mat-select\n formControlName=\"alwaysVisibleFields\"\n multiple\n >\n <mat-option\n [value]=\"meta.name\"\n *ngFor=\"let meta of filteredAlwaysVisibleMetadata(); trackBy: trackFieldMetadataByName\"\n >\n {{ meta.label || meta.name }}\n </mat-option>\n </mat-select>\n <mat-hint *ngIf=\"metadataLoading && metadataSource === 'filter-dto'\">\n Carregando campos do DTO de filtro...\n </mat-hint>\n <mat-error *ngIf=\"metadataErrorMsg\">{{ metadataErrorMsg }}</mat-error>\n <mat-hint\n *ngIf=\"!metadataLoading && !metadataErrorMsg && !metadata.length && metadataSource === 'filter-dto'\"\n >\n Nenhum campo do DTO de filtro dispon\u00EDvel para este recurso.\n </mat-hint>\n <mat-hint\n *ngIf=\"!metadataLoading && !metadataErrorMsg && metadata.length && !hasAlwaysVisibleMetadataResults() && alwaysVisibleFieldSearchText\"\n >\n Nenhum campo encontrado para \"{{ alwaysVisibleFieldSearchText }}\".\n </mat-hint>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Escolha os campos que aparecem sempre na barra de filtros.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Buscar campo</mat-label>\n <input\n matInput\n [ngModel]=\"alwaysVisibleFieldSearchText\"\n (ngModelChange)=\"onAlwaysVisibleFieldSearchChange($event)\"\n [ngModelOptions]=\"{standalone: true}\"\n placeholder=\"Filtrar por nome ou label\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n *ngIf=\"alwaysVisibleFieldSearchText\"\n (click)=\"clearAlwaysVisibleFieldSearch()\"\n aria-label=\"Limpar busca de campo\"\n >\n <mat-icon [praxisIcon]=\"'close'\"></mat-icon>\n </button>\n </mat-form-field>\n <p class=\"field-hint\">\n {{ alwaysVisibleSelectionCount() }} campo(s) selecionado(s).\n </p>\n <div class=\"always-visible-context\">\n <div class=\"always-visible-summary\" role=\"status\" aria-live=\"polite\">\n <div class=\"always-visible-summary-item\">\n <span class=\"summary-value\">{{ alwaysVisibleSelectionCount() }}</span>\n <span class=\"summary-label\">campos fixos</span>\n </div>\n <div class=\"always-visible-summary-item\">\n <span class=\"summary-value\">{{ activeAlwaysVisibleOverrideCount() }}</span>\n <span class=\"summary-label\">overrides ativos</span>\n </div>\n </div>\n <nav\n class=\"always-visible-quick-nav\"\n aria-label=\"Navega\u00E7\u00E3o r\u00E1pida da se\u00E7\u00E3o Sempre Vis\u00EDveis\"\n >\n <button\n mat-stroked-button\n type=\"button\"\n [class.quick-nav-active]=\"isAlwaysVisibleSectionActive('always-visible-order')\"\n [attr.aria-current]=\"isAlwaysVisibleSectionActive('always-visible-order') ? 'location' : null\"\n aria-controls=\"always-visible-order\"\n (click)=\"scrollToAlwaysVisibleSection('always-visible-order')\"\n >\n Ordem\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n [class.quick-nav-active]=\"isAlwaysVisibleSectionActive('always-visible-metadata')\"\n [attr.aria-current]=\"isAlwaysVisibleSectionActive('always-visible-metadata') ? 'location' : null\"\n aria-controls=\"always-visible-metadata\"\n (click)=\"scrollToAlwaysVisibleSection('always-visible-metadata')\"\n >\n Metadados\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n [class.quick-nav-active]=\"isAlwaysVisibleSectionActive('always-visible-json')\"\n [attr.aria-current]=\"isAlwaysVisibleSectionActive('always-visible-json') ? 'location' : null\"\n aria-controls=\"always-visible-json\"\n (click)=\"scrollToAlwaysVisibleSection('always-visible-json')\"\n >\n JSON\n </button>\n </nav>\n </div>\n\n <div\n id=\"always-visible-order\"\n class=\"options options-compact-flow always-visible-section-anchor\"\n [class.section-active]=\"isAlwaysVisibleSectionActive('always-visible-order')\"\n [style.--section-enter-delay]=\"sectionEnterDelay('always-visible-order')\"\n tabindex=\"-1\"\n (focusin)=\"onAlwaysVisibleSectionFocus('always-visible-order')\"\n >\n <div class=\"options-header\">\n <h4 class=\"section-title\">Ordem dos campos</h4>\n <p class=\"section-help\">\n Reordene no formato mais pr\u00F3ximo da toolbar real: faixa de a\u00E7\u00F5es, barra inline e grid.\n </p>\n </div>\n <div class=\"order-layout-toolbar\">\n <mat-button-toggle-group\n class=\"order-viewport-toggle-group\"\n [value]=\"orderPreviewViewport\"\n (change)=\"onAlwaysVisibleViewportChange($event.value)\"\n aria-label=\"Largura simulada da toolbar\"\n >\n <mat-button-toggle\n *ngFor=\"let viewport of alwaysVisibleViewports\"\n [value]=\"viewport\"\n [attr.aria-label]=\"alwaysVisibleViewportHint(viewport)\"\n >\n {{ alwaysVisibleViewportLabel(viewport) }}\n </mat-button-toggle>\n </mat-button-toggle-group>\n <span class=\"order-viewport-caption\">\n {{ alwaysVisibleViewportWidth() }}px\n </span>\n </div>\n <p class=\"section-help\">\n Ajuste o viewport para simular a quebra real das linhas na toolbar.\n </p>\n <div class=\"order-layout-viewport\">\n <div\n class=\"order-layout-frame\"\n [attr.data-viewport]=\"orderPreviewViewport\"\n [style.maxWidth.px]=\"alwaysVisibleViewportWidth()\"\n >\n <div class=\"order-layout-composer\" cdkDropListGroup>\n <section\n class=\"order-lane\"\n *ngFor=\"let lane of alwaysVisibleLayoutLanes\"\n [attr.data-lane]=\"lane\"\n >\n <ng-container *ngIf=\"alwaysVisibleLaneItems(lane) as laneItems\">\n <header class=\"order-lane-header\">\n <div class=\"order-lane-title-block\">\n <h5 class=\"order-lane-title\">{{ alwaysVisibleLaneLabel(lane) }}</h5>\n <p class=\"order-lane-help\">{{ alwaysVisibleLaneHint(lane) }}</p>\n </div>\n <span class=\"order-lane-count\">{{ laneItems.length }}</span>\n </header>\n <div\n cdkDropList\n class=\"order-lane-canvas\"\n [id]=\"alwaysVisibleLaneDropListId(lane)\"\n [class.is-empty]=\"!laneItems.length\"\n [cdkDropListData]=\"laneItems\"\n [cdkDropListEnterPredicate]=\"allowAlwaysVisibleLaneEnter\"\n cdkDropListOrientation=\"horizontal\"\n [attr.aria-label]=\"'Faixa ' + alwaysVisibleLaneLabel(lane)\"\n (cdkDropListDropped)=\"dropAlwaysVisibleLane(lane, $event)\"\n >\n <button\n type=\"button\"\n class=\"order-pill\"\n *ngFor=\"let item of laneItems; let i = index; trackBy: trackAlwaysVisibleLayoutItemByName\"\n cdkDrag\n [cdkDragData]=\"item\"\n [attr.aria-label]=\"alwaysVisibleLayoutItemAriaLabel(item, lane, i, laneItems.length)\"\n (keydown)=\"onAlwaysVisibleLaneItemKeydown($event, lane, item.name)\"\n >\n <mat-icon [praxisIcon]=\"'drag_indicator'\" cdkDragHandle></mat-icon>\n <span class=\"order-pill-label\">{{ item.label }}</span>\n <span class=\"order-pill-badges\">\n <span class=\"order-pill-chip\">{{ item.controlTypeLabel }}</span>\n <span class=\"order-pill-chip order-pill-chip-width\">{{ item.widthHint }}</span>\n <span class=\"order-pill-chip order-pill-chip-override\" *ngIf=\"item.hasOverride\">\n Override\n </span>\n </span>\n </button>\n <p class=\"order-lane-empty\" *ngIf=\"!laneItems.length\">\n {{ alwaysVisibleLaneEmptyHint(lane) }}\n </p>\n </div>\n </ng-container>\n </section>\n </div>\n </div>\n </div>\n <p class=\"field-hint\">\n Acessibilidade: use Alt/Ctrl + setas para reordenar dentro de cada faixa. O drag & drop n\u00E3o mistura faixas.\n </p>\n <p class=\"section-help\" *ngIf=\"!form.controls.alwaysVisibleFields.value?.length\">\n Nenhum campo selecionado. Use o seletor acima para adicionar.\n </p>\n </div>\n\n <mat-divider class=\"section-divider\" role=\"presentation\"></mat-divider>\n\n <div\n id=\"always-visible-metadata\"\n class=\"options options-compact-flow always-visible-section-anchor\"\n [class.section-active]=\"isAlwaysVisibleSectionActive('always-visible-metadata')\"\n [style.--section-enter-delay]=\"sectionEnterDelay('always-visible-metadata')\"\n tabindex=\"-1\"\n (focusin)=\"onAlwaysVisibleSectionFocus('always-visible-metadata')\"\n >\n <div class=\"options-header\">\n <h4 class=\"section-title\">Editor visual de metadados</h4>\n <p class=\"section-help\">\n Edite os principais ajustes dos campos sempre vis\u00EDveis no fluxo visual. Para propriedades avan\u00E7adas, use o JSON abaixo.\n </p>\n </div>\n <p class=\"section-help\" *ngIf=\"!form.controls.alwaysVisibleFields.value?.length\">\n Selecione campos em \u201CCampos sempre vis\u00EDveis\u201D para habilitar a edi\u00E7\u00E3o visual.\n </p>\n <div class=\"metadata-card-grid\" *ngIf=\"form.controls.alwaysVisibleFields.value?.length\">\n <article class=\"metadata-card\" *ngFor=\"let name of form.controls.alwaysVisibleFields.value\">\n <header class=\"metadata-card-header\">\n <div class=\"metadata-card-title\">\n <strong>{{ getFieldLabel(name) }}</strong>\n <span>{{ name }}</span>\n </div>\n <div class=\"metadata-card-badges\">\n <span class=\"metadata-chip\">{{ getAlwaysVisibleControlTypeLabel(name) }}</span>\n <span class=\"metadata-chip metadata-chip-override\" *ngIf=\"hasAlwaysVisibleOverride(name)\">\n Override ativo\n </span>\n </div>\n </header>\n <p class=\"metadata-card-summary\">{{ getAlwaysVisibleOverridePreview(name) }}</p>\n <div class=\"metadata-card-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"openAlwaysVisibleMetadataEditor(name)\">\n <mat-icon [praxisIcon]=\"'tune'\"></mat-icon>\n Editar campo\n </button>\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"clearAlwaysVisibleOverride(name)\"\n [disabled]=\"!hasAlwaysVisibleOverride(name)\"\n >\n Limpar override\n </button>\n </div>\n </article>\n </div>\n </div>\n\n <mat-divider class=\"section-divider\" role=\"presentation\"></mat-divider>\n\n <div\n id=\"always-visible-json\"\n class=\"always-visible-section-anchor\"\n [class.section-active]=\"isAlwaysVisibleSectionActive('always-visible-json')\"\n [style.--section-enter-delay]=\"sectionEnterDelay('always-visible-json')\"\n tabindex=\"-1\"\n (focusin)=\"onAlwaysVisibleSectionFocus('always-visible-json')\"\n >\n <mat-expansion-panel\n class=\"options options-compact-flow options-advanced-json\"\n [expanded]=\"!!alwaysVisibleOverridesErrorMsg\"\n >\n <mat-expansion-panel-header>\n <mat-panel-title>Avan\u00E7ado (JSON opcional)</mat-panel-title>\n <mat-panel-description>Para ajustes n\u00E3o expostos no editor visual</mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"options-header\">\n <h4 class=\"section-title\">Modo avan\u00E7ado (JSON)</h4>\n <p class=\"section-help\">\n Use JSON para ajustes em lote ou propriedades ainda n\u00E3o expostas no editor visual.\n </p>\n </div>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>alwaysVisibleFieldMetadataOverrides (JSON)</mat-label>\n <textarea\n matInput\n rows=\"8\"\n [(ngModel)]=\"alwaysVisibleOverridesJsonText\"\n [ngModelOptions]=\"{standalone: true}\"\n ></textarea>\n </mat-form-field>\n <div class=\"actions\">\n <button mat-stroked-button type=\"button\" (click)=\"formatAlwaysVisibleOverridesJson()\">Formatar</button>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"applyAlwaysVisibleOverridesJson()\">\n Validar e carregar no editor\n </button>\n </div>\n <p class=\"json-tip\">\n Esta a\u00E7\u00E3o n\u00E3o persiste a configura\u00E7\u00E3o. Para persistir, use \u201CSalvar &amp; Fechar\u201D no rodap\u00E9.\n </p>\n <p class=\"json-tip\">\n Exemplo:\n &#123;\"status\":&#123;\"controlType\":\"inlineSelect\",\"clearButton\":&#123;\"enabled\":true&#125;,\"inlineAutoSize\":&#123;\"minWidth\":140,\"maxWidth\":280&#125;&#125;&#125;\n </p>\n <p *ngIf=\"alwaysVisibleOverridesErrorMsg\" class=\"json-error\" role=\"status\" aria-live=\"polite\">{{ alwaysVisibleOverridesErrorMsg }}</p>\n </mat-expansion-panel>\n </div>\n </div>\n </mat-tab>\n <mat-tab label=\"Layout\">\n <div class=\"options\">\n <div class=\"options-header\">\n <h4 class=\"section-title\">Grid e responsividade</h4>\n <p class=\"section-help\">\n Ajuste largura m\u00EDnima e n\u00FAmero de colunas por breakpoint. Em telas menores que 600px, o layout usa 1 coluna.\n </p>\n </div>\n <div class=\"layout-preview-section\" aria-live=\"polite\">\n <h5 class=\"layout-preview-title\">Pr\u00E9-visualiza\u00E7\u00E3o do grid</h5>\n <p class=\"section-help\">\n Simula\u00E7\u00E3o com {{ layoutPreviewFields.length }} campos e largura m\u00EDnima de {{ layoutMinWidth() }}px por campo.\n </p>\n <div class=\"layout-preview-cards\">\n <article class=\"layout-preview-card\">\n <div class=\"layout-preview-header\">\n <strong>Mobile</strong>\n <span>&lt;600px \u00B7 {{ layoutColsFor('sm') }} coluna</span>\n </div>\n <div class=\"layout-mini-grid\" [style.gridTemplateColumns]=\"'repeat(' + layoutColsFor('sm') + ', minmax(0, 1fr))'\">\n <span *ngFor=\"let field of layoutPreviewFields\">{{ field }}</span>\n </div>\n </article>\n <article class=\"layout-preview-card\">\n <div class=\"layout-preview-header\">\n <strong>Tablet</strong>\n <span>&ge;600px \u00B7 {{ layoutColsFor('md') }} colunas</span>\n </div>\n <div class=\"layout-mini-grid\" [style.gridTemplateColumns]=\"'repeat(' + layoutColsFor('md') + ', minmax(0, 1fr))'\">\n <span *ngFor=\"let field of layoutPreviewFields\">{{ field }}</span>\n </div>\n </article>\n <article class=\"layout-preview-card\">\n <div class=\"layout-preview-header\">\n <strong>Desktop</strong>\n <span>&ge;960px \u00B7 {{ layoutColsFor('lg') }} colunas</span>\n </div>\n <div class=\"layout-mini-grid\" [style.gridTemplateColumns]=\"'repeat(' + layoutColsFor('lg') + ', minmax(0, 1fr))'\">\n <span *ngFor=\"let field of layoutPreviewFields\">{{ field }}</span>\n </div>\n </article>\n </div>\n </div>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Largura m\u00EDnima por campo (px)</mat-label>\n <input\n matInput\n type=\"number\"\n formControlName=\"alwaysMinWidth\"\n min=\"180\"\n max=\"480\"\n step=\"1\"\n inputmode=\"numeric\"\n praxisNumberWheelBlur\n (blur)=\"normalizeLayoutControl('alwaysMinWidth')\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n aria-label=\"Ajuda sobre largura m\u00EDnima por campo\"\n matTooltip=\"Define a largura m\u00EDnima de cada campo no grid. Recomendado entre 200 e 300px.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-hint align=\"start\">Intervalo permitido: 180 a 480px.</mat-hint>\n <mat-hint align=\"end\">Recomendado: 200 a 300px.</mat-hint>\n <mat-error *ngIf=\"layoutControlError('alwaysMinWidth') as error\">{{ error }}</mat-error>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Colunas em tablet (&ge;600px)</mat-label>\n <input\n matInput\n type=\"number\"\n formControlName=\"alwaysColsMd\"\n min=\"1\"\n max=\"3\"\n step=\"1\"\n inputmode=\"numeric\"\n praxisNumberWheelBlur\n (blur)=\"normalizeLayoutControl('alwaysColsMd')\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n aria-label=\"Ajuda sobre colunas em tablet\"\n matTooltip=\"Define quantas colunas aparecem em telas m\u00E9dias (a partir de 600px).\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-hint align=\"start\">Mobile (&lt;600px) usa 1 coluna.</mat-hint>\n <mat-hint align=\"end\">Intervalo: 1 a 3 colunas.</mat-hint>\n <mat-error *ngIf=\"layoutControlError('alwaysColsMd') as error\">{{ error }}</mat-error>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Colunas em desktop (&ge;960px)</mat-label>\n <input\n matInput\n type=\"number\"\n formControlName=\"alwaysColsLg\"\n min=\"1\"\n max=\"4\"\n step=\"1\"\n inputmode=\"numeric\"\n praxisNumberWheelBlur\n (blur)=\"normalizeLayoutControl('alwaysColsLg')\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n aria-label=\"Ajuda sobre colunas em desktop\"\n matTooltip=\"Define quantas colunas aparecem em telas grandes (a partir de 960px).\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n <mat-hint align=\"start\">Use mais colunas apenas quando houver espa\u00E7o.</mat-hint>\n <mat-hint align=\"end\">Intervalo: 1 a 4 colunas.</mat-hint>\n <mat-error *ngIf=\"layoutControlError('alwaysColsLg') as error\">{{ error }}</mat-error>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab label=\"Booleanos\">\n <div class=\"options\">\n <p class=\"section-help\" *ngIf=\"!hasBooleanFieldMetadata()\">\n Nenhum campo booleano foi detectado no schema atual. Estas prefer\u00EAncias ser\u00E3o aplicadas quando houver\n campos `toggle`/boolean no filtro.\n </p>\n <div class=\"toggle-preview-section\" *ngIf=\"hasBooleanFieldMetadata()\">\n <h4>Visualiza\u00E7\u00E3o dos Booleanos</h4>\n <p class=\"section-help\">Veja o comportamento dos booleanos inline (com texto ou compacto) e a posi\u00E7\u00E3o na barra.</p>\n <div class=\"preview-container\">\n <div class=\"preview-item\">\n <strong>Grade Principal</strong>\n <div class=\"mock-grid\" [class.with-booleans]=\"!form.controls.placeBooleansInActions.value\">\n <div class=\"mock-field\">Campo 1</div>\n <div class=\"mock-field\">Campo 2</div>\n <div class=\"mock-pill\" *ngIf=\"!form.controls.placeBooleansInActions.value\"\n [class.compact]=\"!form.controls.showToggleLabels.value\">\n <mat-slide-toggle [checked]=\"true\"></mat-slide-toggle>\n <span *ngIf=\"form.controls.showToggleLabels.value\">Ativo</span>\n </div>\n </div>\n </div>\n <div class=\"preview-item\">\n <strong>\u00C1rea de A\u00E7\u00F5es</strong>\n <div class=\"mock-actions\" [class.with-booleans]=\"form.controls.placeBooleansInActions.value\">\n <button mat-icon-button><mat-icon>search</mat-icon></button>\n <button mat-icon-button><mat-icon>tune</mat-icon></button>\n <div class=\"mock-pill\" *ngIf=\"form.controls.placeBooleansInActions.value\"\n [class.compact]=\"!form.controls.showToggleLabels.value\">\n <mat-slide-toggle [checked]=\"true\"></mat-slide-toggle>\n <span *ngIf=\"form.controls.showToggleLabels.value\">Ativo</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <mat-checkbox formControlName=\"placeBooleansInActions\">\n <mat-icon>swap_horiz</mat-icon>\n Posicionar booleanos na \u00E1rea de a\u00E7\u00F5es\n </mat-checkbox>\n <p class=\"field-hint\">Move os booleanos da grade para os bot\u00F5es de a\u00E7\u00E3o, liberando espa\u00E7o horizontal.</p>\n <mat-checkbox formControlName=\"showToggleLabels\">\n <mat-icon>text_fields</mat-icon>\n Mostrar texto nos booleanos inline\n </mat-checkbox>\n <p class=\"field-hint\">Quando desativado, os booleanos ficam em modo compacto (somente controle, sem texto).</p>\n </div>\n </mat-tab>\n <mat-tab label=\"Op\u00E7\u00F5es\">\n <div class=\"options\">\n <div class=\"options-header\">\n <h4 class=\"section-title\">Painel Avan\u00E7ado</h4>\n <p class=\"section-help\">Apar\u00EAncia e comportamento do painel de filtros avan\u00E7ados.</p>\n </div>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Modo de abertura do Avan\u00E7ado</mat-label>\n <mat-select formControlName=\"advancedOpenMode\">\n <mat-option value=\"modal\">Modal (padr\u00E3o)</mat-option>\n <mat-option value=\"drawer\">Drawer (direita)</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Escolha como o painel de filtros avan\u00E7ados ser\u00E1 exibido: centralizado ou lateral.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-checkbox formControlName=\"advancedClearButtonsEnabled\">\n Mostrar bot\u00E3o de limpar nos campos\n </mat-checkbox>\n <p class=\"field-hint\">\n Desative para ocultar o bot\u00E3o de limpar nos campos do painel avan\u00E7ado.\n </p>\n\n <mat-checkbox formControlName=\"useInlineSearchableSelectVariant\">\n Compactar selects com busca/async/autocomplete na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Padr\u00E3o do filtro din\u00E2mico. Desative apenas quando o host precisar preservar o renderer dedicado por compatibilidade, performance ou comportamento legado. O lookup de entidade inline \u00E9 configurado por controlType expl\u00EDcito (`inlineEntityLookup`).\n </p>\n\n <mat-checkbox formControlName=\"useInlineRangeVariant\">\n Compactar range slider na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Usa o componente inline em formato chip + popover para rangeSlider (single e faixa).\n </p>\n\n <mat-checkbox formControlName=\"useInlineDateVariant\">\n Compactar campos de data na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Usa o componente inline dedicado para date/dateInput/datepicker, com largura por conte\u00FAdo e placeholder compacto.\n </p>\n\n <mat-checkbox formControlName=\"useInlineDateRangeVariant\">\n Compactar intervalo de datas na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Padr\u00E3o do filtro din\u00E2mico para dateRange/daterange. Desative apenas para preservar o renderer tradicional em hosts legados.\n </p>\n\n <mat-checkbox formControlName=\"useInlineTimeVariant\">\n Compactar campos de horario na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Padr\u00E3o do filtro din\u00E2mico para time/timePicker, com largura por conteudo e clear rapido. Desative apenas para manter a experi\u00EAncia legada.\n </p>\n\n <mat-checkbox formControlName=\"useInlineTimeRangeVariant\">\n Compactar intervalo de horario na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Padr\u00E3o do filtro din\u00E2mico para timeRange/timerange. Desative apenas para preservar o renderer tradicional em hosts legados.\n </p>\n\n <mat-checkbox formControlName=\"useInlineTreeSelectVariant\">\n Compactar tree select na barra inline\n </mat-checkbox>\n <p class=\"field-hint\">\n Padr\u00E3o do filtro din\u00E2mico para treeSelect na faixa compacta. Desative apenas quando o host depender do renderer dedicado. multiSelectTree mant\u00E9m o componente dedicado.\n </p>\n\n <mat-checkbox formControlName=\"confirmTagDelete\">Confirmar exclus\u00E3o de atalho</mat-checkbox>\n <p class=\"field-hint\">Solicita confirma\u00E7\u00E3o antes de apagar atalhos salvos.</p>\n\n <div class=\"options\">\n <h4>Tema dos Atalhos (Tags)</h4>\n\n <!-- Preview Section -->\n <div class=\"preview-section\" [class.mdc-theme-dark]=\"previewDarkMode\" [class.dark-mode]=\"previewDarkMode\">\n <div class=\"preview-controls\">\n <span class=\"preview-label\">Pr\u00E9-visualiza\u00E7\u00E3o</span>\n <button mat-icon-button (click)=\"previewDarkMode = !previewDarkMode\"\n [matTooltip]=\"previewDarkMode ? 'Mudar para fundo claro' : 'Mudar para fundo escuro'\">\n <mat-icon>{{ previewDarkMode ? 'light_mode' : 'dark_mode' }}</mat-icon>\n </button>\n </div>\n\n <div class=\"preview-chips praxis-filter-tags\"\n [class.outlined]=\"form.controls.tagVariant.value === 'outlined'\">\n <mat-chip-set>\n <!-- Inactive Chip -->\n <mat-chip\n [color]=\"form.controls.tagVariant.value === 'outlined' ? null : (form.controls.tagColor.value === 'basic' ? null : form.controls.tagColor.value)\"\n [highlighted]=\"form.controls.tagVariant.value === 'filled' && form.controls.tagColor.value !== 'basic'\">\n Atalho Inativo\n </mat-chip>\n\n <!-- Active Chip -->\n <mat-chip class=\"active\" [color]=\"form.controls.tagVariant.value === 'outlined' ? null : 'accent'\"\n [highlighted]=\"form.controls.tagVariant.value === 'filled'\">\n <mat-icon matChipAvatar>check</mat-icon>\n Atalho Ativo\n <button matChipTrailingIcon mat-icon-button\n [color]=\"form.controls.tagButtonColor.value === 'basic' ? null : form.controls.tagButtonColor.value\">\n <mat-icon>arrow_drop_down</mat-icon>\n </button>\n </mat-chip>\n </mat-chip-set>\n </div>\n\n <div class=\"contrast-warning\" *ngIf=\"getContrastWarning() as warning\">\n <mat-icon>warning</mat-icon>\n <span>{{ warning }}</span>\n </div>\n </div>\n\n <!-- Reordered Fields -->\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante do atalho</mat-label>\n <mat-select formControlName=\"tagVariant\">\n <mat-option value=\"filled\">Filled (Preenchido)</mat-option>\n <mat-option value=\"outlined\">Outlined (Contorno)</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Define o estilo base do atalho.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor do atalho</mat-label>\n <mat-select formControlName=\"tagColor\">\n <mat-option value=\"primary\">Primary</mat-option>\n <mat-option value=\"accent\">Accent</mat-option>\n <mat-option value=\"warn\">Warn</mat-option>\n <mat-option value=\"basic\">Basic</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Cor de fundo (Filled) ou de contorno (Outlined).\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor do bot\u00E3o do menu do atalho</mat-label>\n <mat-select formControlName=\"tagButtonColor\">\n <mat-option value=\"basic\">Basic</mat-option>\n <mat-option value=\"primary\">Primary</mat-option>\n <mat-option value=\"accent\">Accent</mat-option>\n <mat-option value=\"warn\">Warn</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Cor do bot\u00E3o de dropdown dentro do atalho ativo.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n </div>\n\n <div class=\"options\">\n <h4>Tema dos bot\u00F5es de a\u00E7\u00E3o</h4>\n <mat-form-field appearance=\"outline\">\n <mat-label>Cor dos bot\u00F5es</mat-label>\n <mat-select formControlName=\"actionsButtonColor\">\n <mat-option value=\"basic\">Basic</mat-option>\n <mat-option value=\"primary\">Primary</mat-option>\n <mat-option value=\"accent\">Accent</mat-option>\n <mat-option value=\"warn\">Warn</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Variante dos bot\u00F5es</mat-label>\n <mat-select formControlName=\"actionsVariant\">\n <mat-option value=\"standard\">Standard</mat-option>\n <mat-option value=\"outlined\">Outlined</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"options\">\n <h4>Predefini\u00E7\u00F5es de tema</h4>\n <div class=\"preset-grid\">\n <button\n type=\"button\"\n class=\"preset-card\"\n *ngFor=\"let p of presets\"\n (click)=\"applyPreset(p.key)\"\n [attr.aria-label]=\"'Aplicar predefini\u00E7\u00E3o: ' + p.label\"\n >\n <div class=\"preset-preview\" [ngClass]=\"p.previewClass\"></div>\n <div class=\"preset-info\">\n <span class=\"preset-name\">{{ p.label }}</span>\n <span class=\"preset-desc\">{{ p.description }}</span>\n </div>\n </button>\n </div>\n <button mat-button color=\"warn\" (click)=\"resetPreferences()\" class=\"restore-btn\">\n Restaurar padr\u00E3o\n </button>\n </div>\n </div>\n </mat-tab>\n @if (configKey) {\n <mat-tab label=\"Atalhos\">\n <div class=\"options\">\n <p class=\"section-help\">Os atalhos s\u00E3o salvos por chave de configura\u00E7\u00E3o e compartilhados entre sess\u00F5es.</p>\n <div class=\"tags-header\">\n <span><strong>Atalhos salvos</strong></span>\n <span class=\"spacer\"></span>\n <button mat-stroked-button color=\"warn\" (click)=\"clearTags()\">Apagar tudo</button>\n </div>\n <div class=\"new-tag\">\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>R\u00F3tulo do novo atalho</mat-label>\n <input matInput [(ngModel)]=\"newTagLabel\" [ngModelOptions]=\"{standalone: true}\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Patch (JSON, opcional)</mat-label>\n <textarea matInput rows=\"3\" [(ngModel)]=\"newTagPatchText\" [ngModelOptions]=\"{standalone: true}\"></textarea>\n </mat-form-field>\n <div>\n <button mat-stroked-button color=\"primary\" (click)=\"addTag()\">Adicionar</button>\n @if (hasCurrentDto()) {\n <button mat-stroked-button (click)=\"addTagFromCurrent()\">Adicionar a partir dos filtros atuais</button>\n }\n </div>\n <div>\n <button mat-stroked-button color=\"primary\" (click)=\"importTags()\">Importar</button>\n <button mat-stroked-button (click)=\"loadTags()\">Recarregar</button>\n <button mat-stroked-button (click)=\"saveTags()\">Salvar</button>\n </div>\n </div>\n </div>\n </mat-tab>\n }\n <mat-tab label=\"JSON\">\n <div class=\"options\">\n <p><strong>Configura\u00E7\u00E3o atual (somente leitura)</strong></p>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Atual</mat-label>\n <textarea matInput rows=\"8\" [value]=\"effectiveJson\" readonly></textarea>\n </mat-form-field>\n\n <p><strong>Editar JSON</strong></p>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>JSON</mat-label>\n <textarea matInput rows=\"12\" [(ngModel)]=\"settingsJsonText\" [ngModelOptions]=\"{standalone: true}\"></textarea>\n </mat-form-field>\n <div class=\"actions\">\n <button mat-stroked-button (click)=\"onJsonReload()\">Recarregar do formul\u00E1rio</button>\n <button mat-stroked-button (click)=\"onJsonFormat()\">Formatar</button>\n <button mat-stroked-button color=\"primary\" (click)=\"onJsonApply()\">Carregar JSON no formul\u00E1rio</button>\n </div>\n <p class=\"json-tip\">\n Dica: esta a\u00E7\u00E3o apenas atualiza o editor local. Para persistir, use os bot\u00F5es Aplicar ou\n Salvar &amp; Fechar no rodap\u00E9 do painel.\n </p>\n <p *ngIf=\"jsonErrorMsg\" class=\"json-error\" role=\"status\" aria-live=\"polite\">{{ jsonErrorMsg }}</p>\n </div>\n </mat-tab>\n <mat-tab label=\"Comportamento\">\n <div class=\"options\">\n <mat-checkbox formControlName=\"allowSaveTags\">Permitir salvar atalhos</mat-checkbox>\n </div>\n </mat-tab>\n <mat-tab label=\"Avan\u00E7ado\">\n <div class=\"options\">\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Debounce de altera\u00E7\u00F5es (ms)</mat-label>\n <input matInput type=\"number\" formControlName=\"changeDebounceMs\" min=\"100\" max=\"1000\" />\n @if (form.controls.changeDebounceMs.invalid) { <mat-error>Valor deve estar entre 100 e 1000</mat-error> }\n </mat-form-field>\n <div class=\"actions\">\n <button mat-stroked-button color=\"warn\" (click)=\"resetPreferences()\">\n <mat-icon [praxisIcon]=\"'restart_alt'\"></mat-icon>\n Redefinir prefer\u00EAncias do filtro\n </button>\n <button mat-stroked-button color=\"accent\" (click)=\"clearPersistedFilters()\">\n <mat-icon [praxisIcon]=\"'clear_all'\"></mat-icon>\n Limpar filtros salvos\n </button>\n <button mat-stroked-button (click)=\"forceSchemaReload()\">\n <mat-icon [praxisIcon]=\"'refresh'\"></mat-icon>\n For\u00E7ar recarregamento do schema\n </button>\n </div>\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>N\u00EDvel de log</mat-label>\n <mat-select formControlName=\"logLevel\">\n <mat-option value=\"none\">Nenhum</mat-option>\n <mat-option value=\"error\">Erro</mat-option>\n <mat-option value=\"warn\">Aviso</mat-option>\n <mat-option value=\"info\">Info</mat-option>\n <mat-option value=\"debug\">Debug</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Persistido no contrato para integra\u00E7\u00E3o host. Sem efeito direto no runtime atual do filtro.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-checkbox formControlName=\"enablePerformanceMetrics\">Habilitar m\u00E9tricas de performance</mat-checkbox>\n <p class=\"field-hint\">Prefer\u00EAncia persistida para integra\u00E7\u00E3o host. Sem efeito direto no runtime atual do filtro.</p>\n </div>\n </mat-tab>\n </mat-tab-group>\n</form>\n", styles: [":host{display:block;min-width:0}.full-width{width:100%}.always-visible-tab-flow{display:flex;flex-direction:column;gap:4px}.always-visible-context{position:sticky;top:0;z-index:2;display:flex;flex-direction:column;gap:6px;padding:8px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 88%,transparent);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.always-visible-summary{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px 10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;background:var(--md-sys-color-surface-container-low)}.always-visible-summary-item{display:flex;align-items:baseline;gap:6px;min-width:0}.summary-value{font-size:1rem;font-weight:700;color:var(--md-sys-color-primary)}.summary-label{font-size:.8rem;color:var(--md-sys-color-on-surface-variant);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.always-visible-quick-nav{display:flex;flex-wrap:wrap;gap:6px}.always-visible-quick-nav button{min-height:30px;font-size:.76rem;padding-inline:10px;transition:border-color .18s ease,background-color .18s ease,color .18s ease}.always-visible-quick-nav button.quick-nav-active{border-color:color-mix(in srgb,var(--md-sys-color-primary) 50%,var(--md-sys-color-outline-variant));background:color-mix(in srgb,var(--md-sys-color-primary-container) 34%,var(--md-sys-color-surface-container-low));color:var(--md-sys-color-primary)}.always-visible-section-anchor{scroll-margin-top:140px;opacity:0;transform:translateY(8px);animation:always-visible-section-enter .22s cubic-bezier(.2,0,0,1) forwards;animation-delay:var(--section-enter-delay, 0ms)}.always-visible-section-anchor.section-active,.always-visible-section-anchor.section-active .options-advanced-json{box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 40%,transparent)}.always-visible-section-anchor:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}@keyframes always-visible-section-enter{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.options{display:flex;flex-direction:column;gap:.75rem;padding:12px;width:100%;max-width:100%;min-width:0;box-sizing:border-box;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;background:var(--md-sys-color-surface-container)}.options .options{padding:0;border:0;border-radius:0;background:transparent}.options-compact-flow{gap:8px;padding-top:10px;padding-bottom:10px}.section-divider{margin:2px;border-top-style:dashed;border-top-color:var(--md-sys-color-outline-variant);opacity:.28}.options-advanced-json{display:block;padding:0;overflow:hidden}:host ::ng-deep .options-advanced-json .mat-expansion-panel-header{padding:0 12px;min-height:52px}:host ::ng-deep .options-advanced-json .mat-expansion-panel-body{padding:0 12px 12px}.options-header{display:flex;flex-direction:column;gap:6px}.section-title{margin:0;font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.section-help{margin:0;font-size:.85rem;color:var(--md-sys-color-on-surface);opacity:.84}.field-hint{margin:-4px 0 0;font-size:.8rem;color:var(--md-sys-color-on-surface);opacity:.78}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}.order-layout-toolbar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}.order-viewport-toggle-group{max-width:100%}.order-viewport-caption{display:inline-flex;align-items:center;min-height:28px;padding:0 10px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);font-size:.75rem;font-weight:600;color:var(--md-sys-color-on-surface-variant)}.order-layout-viewport{width:100%;display:flex;justify-content:center;padding:10px;border-radius:14px;border:1px solid var(--md-sys-color-outline-variant);background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 74%,transparent)}.order-layout-frame{width:100%;transition:max-width .18s ease}.order-layout-frame[data-viewport=tablet] .order-lane-canvas{gap:7px}.order-layout-frame[data-viewport=mobile] .order-lane-canvas{gap:6px;padding:7px}.order-layout-frame[data-viewport=mobile] .order-pill{width:100%;max-width:100%;border-radius:12px}.order-layout-composer{display:flex;flex-direction:column;gap:9px}.order-lane{display:flex;flex-direction:column;gap:6px}.order-lane-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.order-lane-title-block{display:flex;flex-direction:column;gap:2px;min-width:0}.order-lane-title{margin:0;font-size:.85rem;font-weight:600;color:var(--md-sys-color-on-surface)}.order-lane-help{margin:0;font-size:.76rem;color:var(--md-sys-color-on-surface-variant)}.order-lane-count{display:inline-flex;align-items:center;justify-content:center;min-width:24px;height:24px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);font-size:.76rem;font-weight:600;padding:0 8px}.order-lane-canvas{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-height:56px;padding:8px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:12px;background:var(--md-sys-color-surface-container-low)}.order-lane-canvas.cdk-drop-list-dragging{border-color:color-mix(in srgb,var(--md-sys-color-primary) 45%,var(--md-sys-color-outline-variant))}.order-lane[data-lane=actions] .order-lane-canvas{background:color-mix(in srgb,var(--md-sys-color-secondary-container) 28%,var(--md-sys-color-surface-container-low))}.order-lane[data-lane=inline] .order-lane-canvas{background:color-mix(in srgb,var(--md-sys-color-primary-container) 22%,var(--md-sys-color-surface-container-low))}.order-lane[data-lane=grid] .order-lane-canvas{background:color-mix(in srgb,var(--md-sys-color-tertiary-container) 18%,var(--md-sys-color-surface-container-low))}.order-lane-canvas.is-empty{justify-content:flex-start}.order-pill{display:inline-flex;align-items:center;gap:8px;max-width:min(100%,520px);min-height:38px;border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface);padding:4px 8px;box-sizing:border-box;cursor:grab;font:inherit;text-align:left}.order-pill:hover{border-color:var(--md-sys-color-outline)}.order-pill:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.order-pill mat-icon{opacity:.75}.order-pill-label{min-width:0;max-width:190px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.86rem;font-weight:500}.order-pill-badges{display:inline-flex;flex-wrap:wrap;align-items:center;gap:4px}.order-pill-chip{display:inline-flex;align-items:center;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface-variant);font-size:.7rem;font-weight:600;padding:1px 7px;white-space:nowrap}.order-pill-chip-width{font-weight:500;opacity:.86}.order-pill-chip-override{border-color:color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary)}.order-lane-empty{margin:0;font-size:.78rem;color:var(--md-sys-color-on-surface-variant)}.order-pill.cdk-drag-preview{box-shadow:var(--md-sys-elevation-level2)}.order-pill.cdk-drag-placeholder{opacity:.45}.layout-preview-section{display:flex;flex-direction:column;gap:10px;padding:12px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;background:var(--md-sys-color-surface-container-low);min-width:0}.layout-preview-title{margin:0;font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.layout-preview-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;min-width:0}.layout-preview-card{display:flex;flex-direction:column;gap:8px;padding:10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;background:var(--md-sys-color-surface-container);min-width:0}.layout-preview-header{display:flex;flex-direction:column;gap:2px}.layout-preview-header strong{font-size:.85rem;color:var(--md-sys-color-on-surface)}.layout-preview-header span{font-size:.78rem;color:var(--md-sys-color-on-surface-variant)}.layout-mini-grid{display:grid;gap:6px;min-width:0}.layout-mini-grid span{display:block;min-width:0;padding:6px 8px;border-radius:6px;background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container);font-size:.75rem;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tags-header{display:flex;align-items:center;gap:8px}.spacer{flex:1 1 auto}.new-tag{display:flex;flex-direction:column;gap:8px}.preset-row{display:flex;flex-wrap:wrap;gap:8px}.option-with-preview{display:flex;align-items:center;gap:8px}.preview-card{width:20px;height:20px;background:var(--md-sys-color-surface-container-high);border:1px solid var(--md-sys-color-outline-variant);border-radius:4px}.preview-frosted{width:20px;height:20px;background:var(--md-sys-color-surface-container);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border:1px solid var(--md-sys-color-outline-variant);border-radius:4px}.toggle-preview-section{margin-bottom:1.5rem;padding:1rem;background:var(--md-sys-color-surface-container-low);border-radius:8px;border:1px solid var(--md-sys-color-outline-variant)}.toggle-preview-section h4{margin:0 0 1rem;font-size:1.1rem;color:var(--md-sys-color-on-surface)}.preview-container{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1rem}.preview-item{text-align:center}.preview-item strong{display:block;margin-bottom:.5rem;font-weight:500}.mock-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));align-items:center;gap:8px;padding:8px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline);border-radius:8px;min-height:72px}.mock-grid.with-booleans{grid-template-columns:repeat(3,minmax(0,1fr))}.mock-field{padding:4px 8px;background:var(--md-sys-color-primary-container);border-radius:6px;font-size:.8rem;text-align:center}.mock-actions{display:flex;align-items:center;gap:8px;padding:8px;background:var(--md-sys-color-surface);border:1px solid var(--md-sys-color-outline);border-radius:8px;min-height:48px}.mock-actions button{width:34px;height:34px}.mock-pill{display:flex;align-items:center;gap:8px;min-height:34px;padding:0 10px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-high);color:var(--md-sys-color-on-surface-variant);font-size:.82rem;justify-self:start}.mock-pill.compact{padding-inline:8px;gap:0}.mock-pill mat-slide-toggle{--mdc-switch-selected-track-color: var(--md-sys-color-primary);--mdc-switch-selected-handle-color: var(--md-sys-color-on-primary);transform:scale(.8);pointer-events:none}.mock-pill span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:500}.preview-section{display:flex;flex-direction:column;gap:16px;padding:16px;background:var(--md-sys-color-surface-container-low);border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;margin-bottom:16px;box-shadow:var(--md-sys-elevation-level1);transition:background-color .3s,color .3s}.preview-section.dark-mode{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface);border-color:var(--md-sys-color-outline-variant)}.preview-section.dark-mode .preview-label{color:var(--md-sys-color-on-surface-variant)}.preview-controls{display:flex;justify-content:space-between;align-items:center}.preview-label{font-weight:500;font-size:.9rem;color:var(--md-sys-color-on-surface-variant)}.preview-chips{display:flex;justify-content:center;padding:16px 0}.praxis-filter-tags.outlined .mat-mdc-chip{background:transparent!important;--mat-chip-outline-width: 1px;--mat-chip-outline-color: var(--md-sys-color-outline-variant);box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)}.praxis-filter-tags.outlined mat-chip.active .mat-mdc-chip,.praxis-filter-tags.outlined .mat-mdc-chip.mat-mdc-chip-highlighted{--mat-chip-outline-color: var(--md-sys-color-primary) !important;box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)!important}.praxis-filter-tags.outlined mat-chip[ng-reflect-color=primary] .mat-mdc-chip{--mat-chip-outline-color: var(--md-sys-color-primary)}.praxis-filter-tags.outlined mat-chip[ng-reflect-color=accent] .mat-mdc-chip{--mat-chip-outline-color: var(--md-sys-color-tertiary)}.praxis-filter-tags.outlined mat-chip[ng-reflect-color=warn] .mat-mdc-chip{--mat-chip-outline-color: var(--md-sys-color-error)}.praxis-filter-tags .mat-mdc-standard-chip .mdc-evolution-chip__text-label{display:flex;align-items:center;gap:4px}.contrast-warning{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-radius:4px;font-size:.85rem}.contrast-warning mat-icon{font-size:20px;width:20px;height:20px}.preset-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:12px;margin-bottom:12px}.preset-card{display:flex;width:100%;flex-direction:column;gap:8px;padding:12px;text-align:left;font:inherit;color:inherit;background:transparent;border:1px solid var(--md-sys-color-outline-variant);border-radius:8px;cursor:pointer;transition:all .2s}.preset-card:hover{background:var(--md-sys-color-surface-container-high);border-color:var(--md-sys-color-outline)}.preset-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.preset-preview{height:24px;border-radius:4px;background:var(--md-sys-color-surface-variant)}.preset-preview.preview-minimal{background:transparent;border:1px solid var(--md-sys-color-outline)}.preset-preview.preview-primary{background:var(--md-sys-color-primary-container)}.preset-preview.preview-accent{background:var(--md-sys-color-tertiary-container)}.preset-preview.preview-warn{background:var(--md-sys-color-error-container)}.preset-info{display:flex;flex-direction:column}.preset-name{font-weight:500;font-size:.9rem}.preset-desc{font-size:.75rem;opacity:.7}.restore-btn{align-self:flex-start}.metadata-card-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:10px}.metadata-card{display:flex;flex-direction:column;gap:10px;padding:12px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low)}.metadata-card-header{display:flex;justify-content:space-between;align-items:flex-start;gap:10px}.metadata-card-title{display:flex;flex-direction:column;min-width:0}.metadata-card-title strong{font-size:.92rem;color:var(--md-sys-color-on-surface)}.metadata-card-title span{font-size:.78rem;color:var(--md-sys-color-on-surface-variant);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.metadata-card-badges{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:6px}.metadata-chip{display:inline-flex;align-items:center;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface-variant);font-size:.78rem;font-weight:500;padding:2px 8px;white-space:nowrap}.metadata-chip-override{border-color:color-mix(in srgb,var(--md-sys-color-primary) 40%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 38%,var(--md-sys-color-surface-container))}.metadata-card-summary{margin:0;font-size:.8rem;color:var(--md-sys-color-on-surface-variant)}.metadata-card-actions{display:flex;flex-wrap:wrap;gap:6px}.metadata-card-actions button{display:inline-flex;align-items:center;gap:4px}.metadata-card-actions button:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:1px}:host ::ng-deep .metadata-card-actions button[disabled]{opacity:.62}.json-tip{margin:6px 0 0;font-size:.85rem;color:var(--md-sys-color-on-surface-variant)}.json-error{margin-top:6px;font-size:.85rem;color:var(--md-sys-color-error)}@media(prefers-reduced-motion:reduce){.always-visible-section-anchor{animation:none;opacity:1;transform:none}.always-visible-quick-nav button{transition:none}}@media(max-width:680px){.order-layout-toolbar{flex-direction:column;align-items:stretch}.order-viewport-caption{align-self:flex-start}.order-layout-viewport{padding:8px}.always-visible-context{position:static;-webkit-backdrop-filter:none;backdrop-filter:none}.always-visible-summary{grid-template-columns:1fr}.always-visible-quick-nav{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}.order-pill{width:100%;max-width:100%}.order-pill-label{max-width:none}.order-pill-badges{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i4.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i4.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i10$2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i15$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i15$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i12.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i12.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i15.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i15.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i15.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "directive", type: i15.MatChipTrailingIcon, selector: "mat-chip-trailing-icon, [matChipTrailingIcon]" }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "directive", type: PraxisNumberWheelBlurDirective, selector: "input[type=number][praxisNumberWheelBlur]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
24010
24010
  }
24011
24011
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: FilterSettingsComponent, decorators: [{
24012
24012
  type: Component,
@@ -24748,7 +24748,7 @@ class CrudIntegrationEditorComponent {
24748
24748
 
24749
24749
  <div class="hint">As alterações são salvas junto com a ação "Salvar" do painel.</div>
24750
24750
  </div>
24751
- `, isInline: true, styles: [":host{--cie-on-surface-variant: var(--md-sys-color-on-surface-variant)}.crud-editor{display:block;width:100%;padding:8px}.config-section{padding:16px}.form-grid{display:grid;grid-template-columns:repeat(2,minmax(220px,1fr));gap:12px;align-items:center}.form-grid .mat-mdc-form-field{width:100%}.actions-list{display:flex;flex-direction:column;gap:8px}.action-row{display:grid;grid-template-columns:160px 160px 1fr 1fr;gap:8px;align-items:center}.action-name{font-weight:600}.hint{margin-top:8px;color:var(--cie-on-surface-variant)}.section-icon{margin-right:8px;color:var(--md-sys-color-primary)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}mat-form-field{width:100%}mat-expansion-panel{margin-bottom:8px;border-radius:8px;overflow:hidden}mat-expansion-panel-header{min-height:56px}mat-panel-description{color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
24751
+ `, isInline: true, styles: [":host{--cie-on-surface-variant: var(--md-sys-color-on-surface-variant)}.crud-editor{display:block;width:100%;padding:8px}.config-section{padding:16px}.form-grid{display:grid;grid-template-columns:repeat(2,minmax(220px,1fr));gap:12px;align-items:center}.form-grid .mat-mdc-form-field{width:100%}.actions-list{display:flex;flex-direction:column;gap:8px}.action-row{display:grid;grid-template-columns:160px 160px 1fr 1fr;gap:8px;align-items:center}.action-name{font-weight:600}.hint{margin-top:8px;color:var(--cie-on-surface-variant)}.section-icon{margin-right:8px;color:var(--md-sys-color-primary)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}mat-form-field{width:100%}mat-expansion-panel{margin-bottom:8px;border-radius:8px;overflow:hidden}mat-expansion-panel-header{min-height:56px}mat-panel-description{color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
24752
24752
  }
24753
24753
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: CrudIntegrationEditorComponent, decorators: [{
24754
24754
  type: Component,
@@ -25310,7 +25310,7 @@ class ConfirmDialogAppearanceEditorComponent {
25310
25310
  this.configChange.emit(next);
25311
25311
  }
25312
25312
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConfirmDialogAppearanceEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
25313
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: ConfirmDialogAppearanceEditorComponent, isStandalone: true, selector: "confirm-dialog-appearance-editor", inputs: { config: "config" }, outputs: { configChange: "configChange" }, ngImport: i0, template: "<mat-accordion multi>\n <mat-expansion-panel expanded>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon [praxisIcon]=\"'tune'\"></mat-icon>&nbsp;Apar\u00EAncia & Comportamento</mat-panel-title>\n <mat-panel-description> Tema, alinhamento e heran\u00E7a de presets </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <p class=\"dialog-editor-note\">\n Preced\u00EAncia: <strong>preset global</strong> \u2192 <strong>variante (delete)</strong> \u2192 <strong>override local</strong> (esta aba). Campos em branco herdam o valor do preset selecionado.\n </p>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tema</mat-label>\n <mat-select [ngModel]=\"deleteDialog.themeColor\" (ngModelChange)=\"update('themeColor', $event)\">\n <mat-option [value]=\"undefined\">Padr\u00E3o</mat-option>\n <mat-option value=\"light\">Claro</mat-option>\n <mat-option value=\"dark\">Escuro</mat-option>\n <mat-option value=\"primary\">Prim\u00E1rio</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"For\u00E7a o tema do di\u00E1logo quando necess\u00E1rio.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Alinhamento das a\u00E7\u00F5es</mat-label>\n <mat-select [ngModel]=\"deleteDialog.actionsLayout\" (ngModelChange)=\"update('actionsLayout', $event)\">\n <mat-option value=\"start\">Alinhado \u00E0 esquerda</mat-option>\n <mat-option value=\"center\">Centralizado</mat-option>\n <mat-option value=\"end\">Alinhado \u00E0 direita</mat-option>\n <mat-option value=\"stretched\">Estendido (preencher)</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Define como os bot\u00F5es se distribuem no rodap\u00E9.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-slide-toggle class=\"dialog-span\" [ngModel]=\"deleteDialog.hasBackdrop\" (ngModelChange)=\"update('hasBackdrop', $event)\">Mostrar backdrop</mat-slide-toggle>\n <mat-slide-toggle class=\"dialog-span\" [ngModel]=\"deleteDialog.disableClose\" (ngModelChange)=\"update('disableClose', $event)\">Desabilitar fechar (ESC/clique)</mat-slide-toggle>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon [praxisIcon]=\"'aspect_ratio'\"></mat-icon>&nbsp;Dimens\u00F5es</mat-panel-title>\n <mat-panel-description> Largura/altura e limites </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <p class=\"dialog-editor-note dialog-span\">\n Dica: use presets para manter consist\u00EAncia entre di\u00E1logos; valores manuais sobrescrevem o preset.\n </p>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tamanho (preset)</mat-label>\n <mat-select [ngModel]=\"selectedSizePreset\" (ngModelChange)=\"setSizePreset($event)\">\n <mat-option value=\"default\">Herdar (preset global)</mat-option>\n <mat-option value=\"sm\">sm (360px)</mat-option>\n <mat-option value=\"md\">md (420px)</mat-option>\n <mat-option value=\"lg\">lg (640px)</mat-option>\n <mat-option value=\"xl\">xl (800px)</mat-option>\n <mat-option value=\"tall\">tall (640px \u00D7 70vh)</mat-option>\n <mat-option value=\"full\">full (90vw \u00D7 90vh)</mat-option>\n <mat-option value=\"fluid\">fluid (100% \u00D7 80vh)</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Largura (width)</mat-label>\n <input matInput [placeholder]=\"getInheritedValue('width') || 'ex.: 420px'\" [ngModel]=\"deleteDialog.width\" (ngModelChange)=\"update('width', $event)\" />\n <mat-hint *ngIf=\"!deleteDialog.width && getInheritedValue('width')\">Herdado: {{ getInheritedValue('width') }}</mat-hint>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Altura (height)</mat-label>\n <input matInput [placeholder]=\"getInheritedValue('height') || 'ex.: auto'\" [ngModel]=\"deleteDialog.height\" (ngModelChange)=\"update('height', $event)\" />\n <mat-hint *ngIf=\"!deleteDialog.height && getInheritedValue('height')\">Herdado: {{ getInheritedValue('height') }}</mat-hint>\n </mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Largura m\u00EDnima (minWidth)</mat-label><input matInput placeholder=\"ex.: 320px\" [ngModel]=\"deleteDialog.minWidth\" (ngModelChange)=\"update('minWidth', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Largura m\u00E1xima (maxWidth)</mat-label><input matInput placeholder=\"ex.: 90vw\" [ngModel]=\"deleteDialog.maxWidth\" (ngModelChange)=\"update('maxWidth', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Altura m\u00EDnima (minHeight)</mat-label><input matInput placeholder=\"ex.: 200px\" [ngModel]=\"deleteDialog.minHeight\" (ngModelChange)=\"update('minHeight', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Altura m\u00E1xima (maxHeight)</mat-label><input matInput [placeholder]=\"getInheritedValue('maxHeight') || 'ex.: 80vh'\" [ngModel]=\"deleteDialog.maxHeight\" (ngModelChange)=\"update('maxHeight', $event)\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon>animation</mat-icon>&nbsp;Anima\u00E7\u00E3o</mat-panel-title>\n <mat-panel-description> Tipo, dire\u00E7\u00E3o, dura\u00E7\u00E3o </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [ngModel]=\"deleteDialog.animation?.type\" (ngModelChange)=\"update('animation.type', $event)\">\n <mat-option [value]=\"undefined\">Padr\u00E3o (translate)</mat-option>\n <mat-option value=\"translate\">translate</mat-option>\n <mat-option value=\"slide\">slide</mat-option>\n <mat-option value=\"fade\">fade</mat-option>\n <mat-option value=\"expand\">expand</mat-option>\n <mat-option value=\"zoom\">zoom</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Dire\u00E7\u00E3o</mat-label>\n <mat-select [ngModel]=\"deleteDialog.animation?.direction\" (ngModelChange)=\"update('animation.direction', $event)\">\n <mat-option [value]=\"undefined\">Padr\u00E3o</mat-option>\n <mat-option value=\"up\">para cima</mat-option>\n <mat-option value=\"down\">para baixo</mat-option>\n <mat-option value=\"left\">para a esquerda</mat-option>\n <mat-option value=\"right\">para a direita</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Dura\u00E7\u00E3o (ms)</mat-label>\n <input matInput type=\"number\" [ngModel]=\"deleteDialog.animation?.duration\" (ngModelChange)=\"update('animation.duration', $event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Easing</mat-label>\n <input matInput placeholder=\"cubic-bezier(...)\" [ngModel]=\"deleteDialog.animation?.easing\" (ngModelChange)=\"update('animation.easing', $event)\" />\n </mat-form-field>\n <p class=\"dialog-editor-note dialog-span\">\n Sugest\u00E3o: mantenha dura\u00E7\u00E3o entre 160\u2013240ms para a\u00E7\u00F5es r\u00E1pidas.\n </p>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon>palette</mat-icon>&nbsp;Estilos (tokens)</mat-panel-title>\n <mat-panel-description> Apar\u00EAncia do cont\u00EAiner e conte\u00FAdo </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <p class=\"dialog-editor-note dialog-span\">\n Prefira tokens M3 (ex.: <code>var(--md-sys-color-surface-container-high)</code>) para suportar light/dark.\n </p>\n <mat-form-field appearance=\"outline\"><mat-label>Border radius (shape)</mat-label><input matInput placeholder=\"ex.: 12px\" [ngModel]=\"deleteDialog.styles?.containerShape\" (ngModelChange)=\"update('styles.containerShape', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Padding a\u00E7\u00F5es</mat-label><input matInput placeholder=\"12px 16px\" [ngModel]=\"deleteDialog.styles?.actionsPadding\" (ngModelChange)=\"update('styles.actionsPadding', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Padding conte\u00FAdo</mat-label><input matInput placeholder=\"16px\" [ngModel]=\"deleteDialog.styles?.contentPadding\" (ngModelChange)=\"update('styles.contentPadding', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Padding t\u00EDtulo</mat-label><input matInput placeholder=\"12px 16px\" [ngModel]=\"deleteDialog.styles?.headlinePadding\" (ngModelChange)=\"update('styles.headlinePadding', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Padding conte\u00FAdo (com a\u00E7\u00F5es)</mat-label><input matInput placeholder=\"16px\" [ngModel]=\"deleteDialog.styles?.withActionsContentPadding\" (ngModelChange)=\"update('styles.withActionsContentPadding', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Cor do cont\u00EAiner</mat-label><input matInput placeholder=\"#262626\" [ngModel]=\"deleteDialog.styles?.containerColor\" (ngModelChange)=\"update('styles.containerColor', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Cor do t\u00EDtulo</mat-label><input matInput placeholder=\"var(--md-sys-color-on-surface)\" [ngModel]=\"deleteDialog.styles?.subheadColor\" (ngModelChange)=\"update('styles.subheadColor', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Cor do conte\u00FAdo</mat-label><input matInput placeholder=\"var(--md-sys-color-on-surface-variant)\" [ngModel]=\"deleteDialog.styles?.supportingTextColor\" (ngModelChange)=\"update('styles.supportingTextColor', $event)\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon>open_with</mat-icon>&nbsp;Posi\u00E7\u00E3o</mat-panel-title>\n <mat-panel-description> Offsets opcionais </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <p class=\"dialog-editor-note dialog-span\">\n Use offsets apenas quando o di\u00E1logo precisar ancorar em regi\u00F5es espec\u00EDficas da tela.\n </p>\n <mat-form-field appearance=\"outline\"><mat-label>Top</mat-label><input matInput placeholder=\"ex.: 10vh\" [ngModel]=\"deleteDialog.position?.top\" (ngModelChange)=\"update('position.top', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Right</mat-label><input matInput placeholder=\"ex.: 24px\" [ngModel]=\"deleteDialog.position?.right\" (ngModelChange)=\"update('position.right', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Bottom</mat-label><input matInput placeholder=\"ex.: 10vh\" [ngModel]=\"deleteDialog.position?.bottom\" (ngModelChange)=\"update('position.bottom', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Left</mat-label><input matInput placeholder=\"ex.: 24px\" [ngModel]=\"deleteDialog.position?.left\" (ngModelChange)=\"update('position.left', $event)\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon>code</mat-icon>&nbsp;Classes & Avan\u00E7ado</mat-panel-title>\n <mat-panel-description> CSS e z-index </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe do painel</mat-label><input matInput placeholder=\"ex.: my-panel\" [ngModel]=\"deleteDialog.panelClass\" (ngModelChange)=\"update('panelClass', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Classe do backdrop</mat-label><input matInput placeholder=\"ex.: my-backdrop\" [ngModel]=\"deleteDialog.backdropClass\" (ngModelChange)=\"update('backdropClass', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>z-index</mat-label><input matInput type=\"number\" placeholder=\"ex.: 1200\" [ngModel]=\"deleteDialog.zIndex\" (ngModelChange)=\"update('zIndex', $event)\" /></mat-form-field>\n <div class=\"dialog-editor-actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"resetOverrides()\">Resetar overrides</button>\n <span class=\"dialog-editor-actions-note\">Remove os valores locais para herdar do preset selecionado ou do preset global.</span>\n </div>\n </div>\n </mat-expansion-panel>\n</mat-accordion>\n", styles: [".dialog-editor-grid{display:grid;grid-template-columns:repeat(2,minmax(240px,1fr));gap:12px}.subgroup{grid-column:1/-1;display:grid;grid-template-columns:repeat(2,minmax(240px,1fr));gap:12px}h3{margin:0 0 8px;grid-column:1/-1}h4{margin:12px 0 0;grid-column:1/-1;font-weight:600}.dialog-editor-note{grid-column:1/-1;margin:0 0 8px;font-size:.85rem;color:var(--md-sys-color-on-surface-variant)}.dialog-editor-actions{grid-column:1/-1;display:flex;gap:8px;align-items:center;margin-top:8px}.dialog-editor-actions-note{font-size:.85rem;color:var(--md-sys-color-on-surface-variant)}.dialog-span{grid-column:1/-1}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}@media(max-width:900px){.dialog-editor-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i8.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
25313
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: ConfirmDialogAppearanceEditorComponent, isStandalone: true, selector: "confirm-dialog-appearance-editor", inputs: { config: "config" }, outputs: { configChange: "configChange" }, ngImport: i0, template: "<mat-accordion multi>\n <mat-expansion-panel expanded>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon [praxisIcon]=\"'tune'\"></mat-icon>&nbsp;Apar\u00EAncia & Comportamento</mat-panel-title>\n <mat-panel-description> Tema, alinhamento e heran\u00E7a de presets </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <p class=\"dialog-editor-note\">\n Preced\u00EAncia: <strong>preset global</strong> \u2192 <strong>variante (delete)</strong> \u2192 <strong>override local</strong> (esta aba). Campos em branco herdam o valor do preset selecionado.\n </p>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tema</mat-label>\n <mat-select [ngModel]=\"deleteDialog.themeColor\" (ngModelChange)=\"update('themeColor', $event)\">\n <mat-option [value]=\"undefined\">Padr\u00E3o</mat-option>\n <mat-option value=\"light\">Claro</mat-option>\n <mat-option value=\"dark\">Escuro</mat-option>\n <mat-option value=\"primary\">Prim\u00E1rio</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"For\u00E7a o tema do di\u00E1logo quando necess\u00E1rio.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Alinhamento das a\u00E7\u00F5es</mat-label>\n <mat-select [ngModel]=\"deleteDialog.actionsLayout\" (ngModelChange)=\"update('actionsLayout', $event)\">\n <mat-option value=\"start\">Alinhado \u00E0 esquerda</mat-option>\n <mat-option value=\"center\">Centralizado</mat-option>\n <mat-option value=\"end\">Alinhado \u00E0 direita</mat-option>\n <mat-option value=\"stretched\">Estendido (preencher)</mat-option>\n </mat-select>\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n class=\"help-icon-button\"\n matTooltip=\"Define como os bot\u00F5es se distribuem no rodap\u00E9.\"\n >\n <mat-icon>help_outline</mat-icon>\n </button>\n </mat-form-field>\n <mat-slide-toggle class=\"dialog-span\" [ngModel]=\"deleteDialog.hasBackdrop\" (ngModelChange)=\"update('hasBackdrop', $event)\">Mostrar backdrop</mat-slide-toggle>\n <mat-slide-toggle class=\"dialog-span\" [ngModel]=\"deleteDialog.disableClose\" (ngModelChange)=\"update('disableClose', $event)\">Desabilitar fechar (ESC/clique)</mat-slide-toggle>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon [praxisIcon]=\"'aspect_ratio'\"></mat-icon>&nbsp;Dimens\u00F5es</mat-panel-title>\n <mat-panel-description> Largura/altura e limites </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <p class=\"dialog-editor-note dialog-span\">\n Dica: use presets para manter consist\u00EAncia entre di\u00E1logos; valores manuais sobrescrevem o preset.\n </p>\n <mat-form-field appearance=\"outline\">\n <mat-label>Tamanho (preset)</mat-label>\n <mat-select [ngModel]=\"selectedSizePreset\" (ngModelChange)=\"setSizePreset($event)\">\n <mat-option value=\"default\">Herdar (preset global)</mat-option>\n <mat-option value=\"sm\">sm (360px)</mat-option>\n <mat-option value=\"md\">md (420px)</mat-option>\n <mat-option value=\"lg\">lg (640px)</mat-option>\n <mat-option value=\"xl\">xl (800px)</mat-option>\n <mat-option value=\"tall\">tall (640px \u00D7 70vh)</mat-option>\n <mat-option value=\"full\">full (90vw \u00D7 90vh)</mat-option>\n <mat-option value=\"fluid\">fluid (100% \u00D7 80vh)</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Largura (width)</mat-label>\n <input matInput [placeholder]=\"getInheritedValue('width') || 'ex.: 420px'\" [ngModel]=\"deleteDialog.width\" (ngModelChange)=\"update('width', $event)\" />\n <mat-hint *ngIf=\"!deleteDialog.width && getInheritedValue('width')\">Herdado: {{ getInheritedValue('width') }}</mat-hint>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Altura (height)</mat-label>\n <input matInput [placeholder]=\"getInheritedValue('height') || 'ex.: auto'\" [ngModel]=\"deleteDialog.height\" (ngModelChange)=\"update('height', $event)\" />\n <mat-hint *ngIf=\"!deleteDialog.height && getInheritedValue('height')\">Herdado: {{ getInheritedValue('height') }}</mat-hint>\n </mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Largura m\u00EDnima (minWidth)</mat-label><input matInput placeholder=\"ex.: 320px\" [ngModel]=\"deleteDialog.minWidth\" (ngModelChange)=\"update('minWidth', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Largura m\u00E1xima (maxWidth)</mat-label><input matInput placeholder=\"ex.: 90vw\" [ngModel]=\"deleteDialog.maxWidth\" (ngModelChange)=\"update('maxWidth', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Altura m\u00EDnima (minHeight)</mat-label><input matInput placeholder=\"ex.: 200px\" [ngModel]=\"deleteDialog.minHeight\" (ngModelChange)=\"update('minHeight', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Altura m\u00E1xima (maxHeight)</mat-label><input matInput [placeholder]=\"getInheritedValue('maxHeight') || 'ex.: 80vh'\" [ngModel]=\"deleteDialog.maxHeight\" (ngModelChange)=\"update('maxHeight', $event)\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon>animation</mat-icon>&nbsp;Anima\u00E7\u00E3o</mat-panel-title>\n <mat-panel-description> Tipo, dire\u00E7\u00E3o, dura\u00E7\u00E3o </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Tipo</mat-label>\n <mat-select [ngModel]=\"deleteDialog.animation?.type\" (ngModelChange)=\"update('animation.type', $event)\">\n <mat-option [value]=\"undefined\">Padr\u00E3o (translate)</mat-option>\n <mat-option value=\"translate\">translate</mat-option>\n <mat-option value=\"slide\">slide</mat-option>\n <mat-option value=\"fade\">fade</mat-option>\n <mat-option value=\"expand\">expand</mat-option>\n <mat-option value=\"zoom\">zoom</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Dire\u00E7\u00E3o</mat-label>\n <mat-select [ngModel]=\"deleteDialog.animation?.direction\" (ngModelChange)=\"update('animation.direction', $event)\">\n <mat-option [value]=\"undefined\">Padr\u00E3o</mat-option>\n <mat-option value=\"up\">para cima</mat-option>\n <mat-option value=\"down\">para baixo</mat-option>\n <mat-option value=\"left\">para a esquerda</mat-option>\n <mat-option value=\"right\">para a direita</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Dura\u00E7\u00E3o (ms)</mat-label>\n <input matInput type=\"number\" [ngModel]=\"deleteDialog.animation?.duration\" (ngModelChange)=\"update('animation.duration', $event)\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Easing</mat-label>\n <input matInput placeholder=\"cubic-bezier(...)\" [ngModel]=\"deleteDialog.animation?.easing\" (ngModelChange)=\"update('animation.easing', $event)\" />\n </mat-form-field>\n <p class=\"dialog-editor-note dialog-span\">\n Sugest\u00E3o: mantenha dura\u00E7\u00E3o entre 160\u2013240ms para a\u00E7\u00F5es r\u00E1pidas.\n </p>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon>palette</mat-icon>&nbsp;Estilos (tokens)</mat-panel-title>\n <mat-panel-description> Apar\u00EAncia do cont\u00EAiner e conte\u00FAdo </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <p class=\"dialog-editor-note dialog-span\">\n Prefira tokens M3 (ex.: <code>var(--md-sys-color-surface-container-high)</code>) para suportar light/dark.\n </p>\n <mat-form-field appearance=\"outline\"><mat-label>Border radius (shape)</mat-label><input matInput placeholder=\"ex.: 12px\" [ngModel]=\"deleteDialog.styles?.containerShape\" (ngModelChange)=\"update('styles.containerShape', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Padding a\u00E7\u00F5es</mat-label><input matInput placeholder=\"12px 16px\" [ngModel]=\"deleteDialog.styles?.actionsPadding\" (ngModelChange)=\"update('styles.actionsPadding', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Padding conte\u00FAdo</mat-label><input matInput placeholder=\"16px\" [ngModel]=\"deleteDialog.styles?.contentPadding\" (ngModelChange)=\"update('styles.contentPadding', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Padding t\u00EDtulo</mat-label><input matInput placeholder=\"12px 16px\" [ngModel]=\"deleteDialog.styles?.headlinePadding\" (ngModelChange)=\"update('styles.headlinePadding', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Padding conte\u00FAdo (com a\u00E7\u00F5es)</mat-label><input matInput placeholder=\"16px\" [ngModel]=\"deleteDialog.styles?.withActionsContentPadding\" (ngModelChange)=\"update('styles.withActionsContentPadding', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Cor do cont\u00EAiner</mat-label><input matInput placeholder=\"#262626\" [ngModel]=\"deleteDialog.styles?.containerColor\" (ngModelChange)=\"update('styles.containerColor', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Cor do t\u00EDtulo</mat-label><input matInput placeholder=\"var(--md-sys-color-on-surface)\" [ngModel]=\"deleteDialog.styles?.subheadColor\" (ngModelChange)=\"update('styles.subheadColor', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Cor do conte\u00FAdo</mat-label><input matInput placeholder=\"var(--md-sys-color-on-surface-variant)\" [ngModel]=\"deleteDialog.styles?.supportingTextColor\" (ngModelChange)=\"update('styles.supportingTextColor', $event)\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon>open_with</mat-icon>&nbsp;Posi\u00E7\u00E3o</mat-panel-title>\n <mat-panel-description> Offsets opcionais </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <p class=\"dialog-editor-note dialog-span\">\n Use offsets apenas quando o di\u00E1logo precisar ancorar em regi\u00F5es espec\u00EDficas da tela.\n </p>\n <mat-form-field appearance=\"outline\"><mat-label>Top</mat-label><input matInput placeholder=\"ex.: 10vh\" [ngModel]=\"deleteDialog.position?.top\" (ngModelChange)=\"update('position.top', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Right</mat-label><input matInput placeholder=\"ex.: 24px\" [ngModel]=\"deleteDialog.position?.right\" (ngModelChange)=\"update('position.right', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Bottom</mat-label><input matInput placeholder=\"ex.: 10vh\" [ngModel]=\"deleteDialog.position?.bottom\" (ngModelChange)=\"update('position.bottom', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Left</mat-label><input matInput placeholder=\"ex.: 24px\" [ngModel]=\"deleteDialog.position?.left\" (ngModelChange)=\"update('position.left', $event)\" /></mat-form-field>\n </div>\n </mat-expansion-panel>\n\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon>code</mat-icon>&nbsp;Classes & Avan\u00E7ado</mat-panel-title>\n <mat-panel-description> CSS e z-index </mat-panel-description>\n </mat-expansion-panel-header>\n <div class=\"dialog-editor-grid\">\n <mat-form-field appearance=\"outline\"><mat-label>Classe do painel</mat-label><input matInput placeholder=\"ex.: my-panel\" [ngModel]=\"deleteDialog.panelClass\" (ngModelChange)=\"update('panelClass', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>Classe do backdrop</mat-label><input matInput placeholder=\"ex.: my-backdrop\" [ngModel]=\"deleteDialog.backdropClass\" (ngModelChange)=\"update('backdropClass', $event)\" /></mat-form-field>\n <mat-form-field appearance=\"outline\"><mat-label>z-index</mat-label><input matInput type=\"number\" placeholder=\"ex.: 1200\" [ngModel]=\"deleteDialog.zIndex\" (ngModelChange)=\"update('zIndex', $event)\" /></mat-form-field>\n <div class=\"dialog-editor-actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"resetOverrides()\">Resetar overrides</button>\n <span class=\"dialog-editor-actions-note\">Remove os valores locais para herdar do preset selecionado ou do preset global.</span>\n </div>\n </div>\n </mat-expansion-panel>\n</mat-accordion>\n", styles: [".dialog-editor-grid{display:grid;grid-template-columns:repeat(2,minmax(240px,1fr));gap:12px}.subgroup{grid-column:1/-1;display:grid;grid-template-columns:repeat(2,minmax(240px,1fr));gap:12px}h3{margin:0 0 8px;grid-column:1/-1}h4{margin:12px 0 0;grid-column:1/-1;font-weight:600}.dialog-editor-note{grid-column:1/-1;margin:0 0 8px;font-size:.85rem;color:var(--md-sys-color-on-surface-variant)}.dialog-editor-actions{grid-column:1/-1;display:flex;gap:8px;align-items:center;margin-top:8px}.dialog-editor-actions-note{font-size:.85rem;color:var(--md-sys-color-on-surface-variant)}.dialog-span{grid-column:1/-1}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.help-icon-button mat-icon{font-size:18px;line-height:18px;width:18px;height:18px}@media(max-width:900px){.dialog-editor-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i8.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
25314
25314
  }
25315
25315
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConfirmDialogAppearanceEditorComponent, decorators: [{
25316
25316
  type: Component,
@@ -28118,7 +28118,7 @@ class TableRulesEditorComponent {
28118
28118
 
28119
28119
  </mat-accordion>
28120
28120
  </div>
28121
- `, isInline: true, styles: [".rules-editor{display:flex;flex-direction:column;gap:12px}.block{border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;background:linear-gradient(180deg,var(--md-sys-color-surface-container-low),var(--md-sys-color-surface));-webkit-backdrop-filter:saturate(140%) blur(2px);backdrop-filter:saturate(140%) blur(2px);transition:all .2s ease}.block.is-expanded{box-shadow:var(--md-sys-elevation-level2)}.block-header{display:flex;align-items:center;gap:8px;padding:6px 12px;min-height:40px;background:linear-gradient(180deg,var(--md-sys-color-surface-container-low),var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant);transition:all .2s ease}.block-title{font-weight:600;font-size:.95rem;letter-spacing:.5px;display:flex;align-items:center;gap:6px}.block-subtitle{opacity:.7;font-size:.8rem;margin-left:8px}.block-body{padding:12px;display:flex;flex-direction:column;gap:12px}.a-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}.mode-tabs{--mat-tab-header-inactive-label-text-color: var(--md-sys-color-on-surface-variant)}.basic-grid{display:grid;grid-template-columns:repeat(3,minmax(180px,1fr));gap:12px;align-items:start}.rules-grid mat-form-field:nth-of-type(1){grid-column:1}.rules-grid mat-form-field:nth-of-type(2){grid-column:2}.rules-grid .value-host{grid-column:3;min-width:0}@media(max-width:991.98px){.basic-grid{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.rules-grid .value-host{grid-column:1 / -1}}.basic-grid .mat-mdc-form-field .mdc-floating-label{font-size:.85rem}.spacer{flex:1}.effects-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}.quick-effects{display:block}.qe-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px;align-items:start}.qe-group{display:flex;flex-direction:column;gap:6px}.qe-title{font-size:.85rem;opacity:.8}.qe-inline{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.qe-presets{display:grid;grid-template-columns:repeat(auto-fill,minmax(32px,1fr));gap:8px;align-items:center;max-width:280px}.qe-presets .mat-mdc-icon-button.mat-mdc-button-base{justify-self:start}.qe-presets .mat-stroked-button{grid-column:1 / -1;justify-self:start}.qe-inline .mat-mdc-icon-button.mat-mdc-button-base{width:32px;height:32px;padding:0}.qe-inline .mat-mdc-icon-button .mat-icon{font-size:18px;line-height:32px;width:18px;height:18px;transition:all .2s ease}.qe-label{display:flex;gap:6px;align-items:center;font-size:.85rem}.qe-number{width:84px;padding:6px}.qe-suffix{opacity:.7}.qe-select{width:120px}.qe-text{min-width:160px;padding:6px}.qe-toggle-group{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.qe-desc{font-size:.8rem;opacity:.75}.effects-preview{grid-column:1 / -1}.effects-preview-box{display:flex;align-items:center;gap:8px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:6px;padding:6px 8px;background:var(--md-sys-color-surface-container-low);width:100%;min-height:36px;transition:all .2s ease}.pfx-badge-preview{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;border-radius:999px;font-size:12px;line-height:16px;transition:all .2s ease}.pfx-badge-preview.v-filled.c-primary{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.pfx-badge-preview.v-filled.c-accent{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container)}.pfx-badge-preview.v-filled.c-warn{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.pfx-badge-preview.v-outlined{border:1px solid var(--md-sys-color-outline-variant)}.pfx-badge-preview.v-soft{background:var(--md-sys-color-surface-container-highest)}.dsl-box .full{width:100%}.range-grid{display:grid;grid-template-columns:repeat(2,minmax(160px,1fr));gap:12px;align-items:center}.no-value-hint{align-self:center;opacity:.7;font-size:.85rem}.errors{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);padding:8px 12px;border:1px solid var(--md-sys-color-error);border-radius:6px}.group-card{border:1px solid var(--md-sys-color-outline-variant);padding:8px 12px;border-radius:10px;display:flex;flex-direction:column;gap:8px;background:var(--md-sys-color-surface-container-lowest);transition:all .2s ease}.group-header,.group-actions{display:flex;gap:8px;align-items:center}.group-list{display:grid;gap:6px}.group-item{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:6px;background:var(--md-sys-color-surface-container-low);transition:all .2s ease}.item-main{display:flex;align-items:center;gap:8px}.drag-handle{cursor:grab;opacity:.7}.expr{font-family:monospace;font-size:.85rem}.group-footer{display:flex;gap:8px;align-items:center}.subgroups{display:grid;gap:8px;margin-top:8px}.subgroup{border:1px dashed var(--md-sys-color-outline-variant);border-radius:6px;padding:6px 8px;background:var(--md-sys-color-surface-container-low);transition:all .2s ease}.sub-header{display:flex;align-items:center;gap:8px}.sub-body{display:flex;align-items:center;justify-content:space-between;gap:12px}.rules-list .list-header{padding:4px 0}.rule-item .rule-content{display:flex;gap:12px;align-items:center;justify-content:space-between;width:100%}.rule-main{display:flex;flex-direction:column;gap:6px;min-width:0}.rule-cond{font-family:monospace;font-size:.9rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.chip{display:inline-block;padding:2px 6px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;font-size:12px;margin-right:6px}.rule-actions{display:flex;gap:6px;align-items:center}.preview{background:var(--md-sys-color-surface-container-low);padding:8px 12px;border:1px solid var(--md-sys-color-outline-variant);border-radius:6px}.preview-rows{display:grid;gap:6px}.p-row{display:flex;align-items:center;gap:8px}.row-title{width:72px;opacity:.7}.row-effects{display:flex;gap:6px;flex-wrap:wrap}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rules-nav-chips{margin-bottom:6px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1$2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i15$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i15$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i11.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i11.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i15$3.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i15$3.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i15.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i15.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i15.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i17$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i17$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i4.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i4.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i12.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i8.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "component", type: TableConfigToolbarComponent, selector: "pfx-table-config-toolbar", inputs: ["applyDisabled", "ariaLabel", "exportLabel", "importLabel", "resetLabel", "resetLabelShort", "applyLabel"], outputs: ["export", "import", "reset", "apply"] }, { kind: "component", type: RuleEffectsPanelComponent, selector: "praxis-rule-effects-panel", inputs: ["scope", "value"], outputs: ["valueChange", "apply", "reset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
28121
+ `, isInline: true, styles: [".rules-editor{display:flex;flex-direction:column;gap:12px}.block{border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;background:linear-gradient(180deg,var(--md-sys-color-surface-container-low),var(--md-sys-color-surface));-webkit-backdrop-filter:saturate(140%) blur(2px);backdrop-filter:saturate(140%) blur(2px);transition:all .2s ease}.block.is-expanded{box-shadow:var(--md-sys-elevation-level2)}.block-header{display:flex;align-items:center;gap:8px;padding:6px 12px;min-height:40px;background:linear-gradient(180deg,var(--md-sys-color-surface-container-low),var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant);transition:all .2s ease}.block-title{font-weight:600;font-size:.95rem;letter-spacing:.5px;display:flex;align-items:center;gap:6px}.block-subtitle{opacity:.7;font-size:.8rem;margin-left:8px}.block-body{padding:12px;display:flex;flex-direction:column;gap:12px}.a-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}.mode-tabs{--mat-tab-header-inactive-label-text-color: var(--md-sys-color-on-surface-variant)}.basic-grid{display:grid;grid-template-columns:repeat(3,minmax(180px,1fr));gap:12px;align-items:start}.rules-grid mat-form-field:nth-of-type(1){grid-column:1}.rules-grid mat-form-field:nth-of-type(2){grid-column:2}.rules-grid .value-host{grid-column:3;min-width:0}@media(max-width:991.98px){.basic-grid{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.rules-grid .value-host{grid-column:1 / -1}}.basic-grid .mat-mdc-form-field .mdc-floating-label{font-size:.85rem}.spacer{flex:1}.effects-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}.quick-effects{display:block}.qe-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px;align-items:start}.qe-group{display:flex;flex-direction:column;gap:6px}.qe-title{font-size:.85rem;opacity:.8}.qe-inline{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.qe-presets{display:grid;grid-template-columns:repeat(auto-fill,minmax(32px,1fr));gap:8px;align-items:center;max-width:280px}.qe-presets .mat-mdc-icon-button.mat-mdc-button-base{justify-self:start}.qe-presets .mat-stroked-button{grid-column:1 / -1;justify-self:start}.qe-inline .mat-mdc-icon-button.mat-mdc-button-base{width:32px;height:32px;padding:0}.qe-inline .mat-mdc-icon-button .mat-icon{font-size:18px;line-height:32px;width:18px;height:18px;transition:all .2s ease}.qe-label{display:flex;gap:6px;align-items:center;font-size:.85rem}.qe-number{width:84px;padding:6px}.qe-suffix{opacity:.7}.qe-select{width:120px}.qe-text{min-width:160px;padding:6px}.qe-toggle-group{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.qe-desc{font-size:.8rem;opacity:.75}.effects-preview{grid-column:1 / -1}.effects-preview-box{display:flex;align-items:center;gap:8px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:6px;padding:6px 8px;background:var(--md-sys-color-surface-container-low);width:100%;min-height:36px;transition:all .2s ease}.pfx-badge-preview{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;border-radius:999px;font-size:12px;line-height:16px;transition:all .2s ease}.pfx-badge-preview.v-filled.c-primary{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.pfx-badge-preview.v-filled.c-accent{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container)}.pfx-badge-preview.v-filled.c-warn{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container)}.pfx-badge-preview.v-outlined{border:1px solid var(--md-sys-color-outline-variant)}.pfx-badge-preview.v-soft{background:var(--md-sys-color-surface-container-highest)}.dsl-box .full{width:100%}.range-grid{display:grid;grid-template-columns:repeat(2,minmax(160px,1fr));gap:12px;align-items:center}.no-value-hint{align-self:center;opacity:.7;font-size:.85rem}.errors{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);padding:8px 12px;border:1px solid var(--md-sys-color-error);border-radius:6px}.group-card{border:1px solid var(--md-sys-color-outline-variant);padding:8px 12px;border-radius:10px;display:flex;flex-direction:column;gap:8px;background:var(--md-sys-color-surface-container-lowest);transition:all .2s ease}.group-header,.group-actions{display:flex;gap:8px;align-items:center}.group-list{display:grid;gap:6px}.group-item{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:6px;background:var(--md-sys-color-surface-container-low);transition:all .2s ease}.item-main{display:flex;align-items:center;gap:8px}.drag-handle{cursor:grab;opacity:.7}.expr{font-family:monospace;font-size:.85rem}.group-footer{display:flex;gap:8px;align-items:center}.subgroups{display:grid;gap:8px;margin-top:8px}.subgroup{border:1px dashed var(--md-sys-color-outline-variant);border-radius:6px;padding:6px 8px;background:var(--md-sys-color-surface-container-low);transition:all .2s ease}.sub-header{display:flex;align-items:center;gap:8px}.sub-body{display:flex;align-items:center;justify-content:space-between;gap:12px}.rules-list .list-header{padding:4px 0}.rule-item .rule-content{display:flex;gap:12px;align-items:center;justify-content:space-between;width:100%}.rule-main{display:flex;flex-direction:column;gap:6px;min-width:0}.rule-cond{font-family:monospace;font-size:.9rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.chip{display:inline-block;padding:2px 6px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;font-size:12px;margin-right:6px}.rule-actions{display:flex;gap:6px;align-items:center}.preview{background:var(--md-sys-color-surface-container-low);padding:8px 12px;border:1px solid var(--md-sys-color-outline-variant);border-radius:6px}.preview-rows{display:grid;gap:6px}.p-row{display:flex;align-items:center;gap:8px}.row-title{width:72px;opacity:.7}.row-effects{display:flex;gap:6px;flex-wrap:wrap}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rules-nav-chips{margin-bottom:6px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i15$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i15$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i11.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i11.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i15$3.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i15$3.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i15.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i15.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i15.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i17$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i17$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i4.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i4.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i12.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i8.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "component", type: TableConfigToolbarComponent, selector: "pfx-table-config-toolbar", inputs: ["applyDisabled", "ariaLabel", "exportLabel", "importLabel", "resetLabel", "resetLabelShort", "applyLabel"], outputs: ["export", "import", "reset", "apply"] }, { kind: "component", type: RuleEffectsPanelComponent, selector: "praxis-rule-effects-panel", inputs: ["scope", "value"], outputs: ["valueChange", "apply", "reset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
28122
28122
  }
28123
28123
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TableRulesEditorComponent, decorators: [{
28124
28124
  type: Component,
@@ -29723,7 +29723,7 @@ class PraxisTableConfigEditor {
29723
29723
  this.behaviorFeedbackBurstTypes.clear();
29724
29724
  }
29725
29725
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisTableConfigEditor, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.TableConfigService }], target: i0.ɵɵFactoryTarget.Component });
29726
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisTableConfigEditor, isStandalone: true, selector: "praxis-table-config-editor", providers: [TableConfigService], viewQueries: [{ propertyName: "filterSettingsEditor", first: true, predicate: ["tableFilterSettingsRef"], descendants: true }, { propertyName: "behaviorEditor", first: true, predicate: BehaviorConfigEditorComponent, descendants: true }, { propertyName: "crudEditorSetter", first: true, predicate: ["crudEditorRef"], descendants: true }], ngImport: i0, template: " <mat-tab-group class=\"config-tabs\" [(selectedIndex)]=\"activeSectionIndex\">\n <mat-tab *ngFor=\"let section of sections\">\n <ng-template mat-tab-label>\n @if (section.icon) { <mat-icon [praxisIcon]=\"section.icon\"></mat-icon> }\n <span [attr.data-testid]=\"'config-tab-' + section.id\">{{ section.label }}</span>\n </ng-template>\n <div class=\"tab-content\">\n <ng-container [ngSwitch]=\"section.id\">\n <div *ngSwitchCase=\"'connect'\" class=\"connect-grid\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Recurso</mat-label>\n <input matInput [(ngModel)]=\"resourcePath\" (ngModelChange)=\"onResourcePathChange($event)\" placeholder=\"ex.: employees\" />\n <mat-icon matSuffix>link</mat-icon>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Chave prim\u00E1ria</mat-label>\n <input matInput [(ngModel)]=\"idField\" (ngModelChange)=\"onIdFieldChange($event)\" placeholder=\"ex.: id, uuid, codigo\" />\n <mat-icon matSuffix>fingerprint</mat-icon>\n </mat-form-field>\n <p class=\"connect-note\">Defina o recurso da API e, se necess\u00E1rio, a chave prim\u00E1ria.</p>\n\n <!-- Diverg\u00EAncia: idField -->\n @if (idFieldDiverges) { <div class=\"alert alert--warning connect-alert\">\n <mat-icon class=\"alert__icon\">warning</mat-icon>\n <div class=\"alert__text connect-alert__text\">\n A chave prim\u00E1ria no servidor diverge da configura\u00E7\u00E3o atual.\n <span class=\"connect-alert__meta\">(config: {{ idField || 'id' }} | servidor: {{ serverIdField || 'id' }})</span>\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onReconcileIdField()\">Reconciliar</button>\n </div> }\n\n <!-- Diverg\u00EAncia: serverHash -->\n @if (schemaHashDiverges) { <div class=\"alert alert--info connect-alert\">\n <mat-icon class=\"alert__icon\">info</mat-icon>\n <div class=\"alert__text connect-alert__text\">\n O snapshot de schema salvo diverge do schema atual do servidor.\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onAcceptServerHash()\">Atualizar metadados</button>\n </div> }\n\n @if (!schemaHashDiverges && schemaSnapshotMissing) { <div class=\"alert alert--info connect-alert\">\n <mat-icon class=\"alert__icon\">info</mat-icon>\n <div class=\"alert__text connect-alert__text\">\n Existe schema atual no servidor, mas ainda n\u00E3o h\u00E1 snapshot persistido para reconcilia\u00E7\u00E3o.\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onAcceptServerHash()\">Salvar snapshot</button>\n </div> }\n </div>\n\n <div *ngSwitchCase=\"'overview'\" class=\"overview-grid\">\n <div class=\"overview-row\">\n <mat-form-field appearance=\"outline\" class=\"hs-field\">\n <mat-label>Scroll Horizontal</mat-label>\n <mat-select [(ngModel)]=\"horizontalScroll\" (ngModelChange)=\"onHorizontalScrollChange($event)\">\n <mat-option value=\"auto\">Auto (padr\u00E3o)</mat-option>\n <mat-option value=\"wrap\">Wrap (quebrar linhas)</mat-option>\n <mat-option value=\"none\">Host controla</mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"help small\">Controla como a tabela lida com largura horizontal e barra de rolagem.</div>\n </div>\n @if (isEffectiveLocalMode()) { <div class=\"alert alert--info overview-mode-alert\">\n <mat-icon class=\"alert__icon\">info</mat-icon>\n <div class=\"alert__text\">\n Modo local efetivo ativo: estrat\u00E9gias de pagina\u00E7\u00E3o e ordena\u00E7\u00E3o em servidor ficam bloqueadas e s\u00E3o salvas como cliente.\n </div>\n </div> }\n <behavior-config-editor\n [config]=\"editedConfig\"\n [resourcePath]=\"resourcePath\"\n [forceClientStrategies]=\"isEffectiveLocalMode()\"\n (configChange)=\"onBehaviorConfigChange($event)\"\n (behaviorChange)=\"onBehaviorChange($event)\"\n ></behavior-config-editor>\n </div>\n\n <columns-config-editor\n *ngSwitchCase=\"'columns'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n (columnChange)=\"onColumnChange($event)\"\n ></columns-config-editor>\n\n <table-rules-editor\n *ngSwitchCase=\"'rules'\"\n [config]=\"editedConfig\"\n [resourcePath]=\"resourcePath\"\n (configChange)=\"onRulesConfigChange($event)\"\n ></table-rules-editor>\n\n <header-appearance-editor\n *ngSwitchCase=\"'header'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n ></header-appearance-editor>\n\n <toolbar-actions-editor\n *ngSwitchCase=\"'toolbar'\"\n [config]=\"editedConfig\"\n (configChange)=\"onToolbarActionsConfigChange($event)\"\n (toolbarActionsChange)=\"onToolbarActionsChange($event)\"\n ></toolbar-actions-editor>\n\n <!-- Aba extra para integra\u00E7\u00F5es CRUD (vis\u00EDvel quando em contexto CRUD) -->\n <crud-integration-editor\n #crudEditorRef\n *ngSwitchCase=\"'crud'\"\n [tableId]=\"crudContext?.tableId || 'default'\"\n [crudContext]=\"crudContext\"\n [componentKeyId]=\"crudContext?.componentKeyId\"\n ></crud-integration-editor>\n\n <filter-settings\n #tableFilterSettingsRef\n *ngSwitchCase=\"'filters'\"\n [metadata]=\"getFilterSettingsMetas()\"\n [metadataSource]=\"isUsingFilterDtoMetas() ? 'filter-dto' : 'columns'\"\n [metadataLoading]=\"filterDtoMetasLoading\"\n [metadataErrorMsg]=\"filterDtoMetasErrorMsg\"\n [settings]=\"\n editedConfig.behavior?.filtering?.advancedFilters?.settings\n \"\n (settingsChange)=\"onFilterSettingsChange($event)\"\n ></filter-settings>\n\n <messages-localization-editor\n *ngSwitchCase=\"'messages'\"\n [config]=\"editedConfig\"\n (configChange)=\"onMessagesLocalizationConfigChange($event)\"\n (messagesLocalizationChange)=\"\n onMessagesLocalizationChange($event)\n \"\n ></messages-localization-editor>\n\n <confirm-dialog-appearance-editor\n *ngSwitchCase=\"'dialogs'\"\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n ></confirm-dialog-appearance-editor>\n\n\n <json-config-editor\n *ngSwitchCase=\"'json'\"\n [document]=\"buildJsonAuthoringDocument()\"\n (documentChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n ></json-config-editor>\n </ng-container>\n </div>\n </mat-tab>\n </mat-tab-group>\n@if (statusMessage) { <div class=\"config-editor-status\">\n <span\n class=\"status-text\"\n [class.error]=\"hasErrors\"\n [class.success]=\"hasSuccess\"\n >{{ statusMessage }}</span\n >\n </div> }\n", styles: ["@charset \"UTF-8\";.config-tabs{flex:1 1 auto;display:flex;flex-direction:column}.config-tabs .mat-mdc-tab{min-width:120px}.config-tabs .mat-mdc-tab-body-wrapper,.config-tabs .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.config-tabs .mat-mdc-tab-body-content{height:100%;min-height:0;overflow:visible}.tab-content{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;padding:8px 8px 56px;box-sizing:border-box;overflow:visible}.overview-grid{display:grid;grid-template-columns:1fr;gap:12px}.overview-grid .overview-row{display:grid;grid-template-columns:280px 1fr;align-items:end;gap:12px}.overview-grid .overview-row .help.small{opacity:.75;font-size:12px}.overview-mode-alert{align-items:center}.connect-grid{display:grid;gap:12px;padding:8px;grid-template-columns:1fr 240px;align-items:start}.connect-note{grid-column:1/-1;margin:0;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.connect-alert{grid-column:1/-1;align-items:center}.connect-alert__text{flex:1}.connect-alert__meta{opacity:.85}.educational-card{margin-bottom:24px;background:var(--md-sys-color-surface-container-low);border-left:4px solid var(--md-sys-color-primary);flex-shrink:0}.config-editor-status{padding:12px 16px;margin-top:auto;border-top:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);flex-shrink:0;position:relative}.status-text{font-size:.875rem;line-height:1.2}.status-text.error{color:var(--md-sys-color-error)}.status-text.success{color:var(--md-sys-color-primary)}@media(max-width:768px){.tab-content{padding:8px}.config-editor-status{padding:12px 16px}.connect-grid{grid-template-columns:1fr}.overview-grid .overview-row{grid-template-columns:1fr;align-items:start}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i4.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i4.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i4.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: JsonConfigEditorComponent, selector: "json-config-editor", inputs: ["document"], outputs: ["documentChange", "validationChange", "editorEvent"] }, { kind: "component", type: ColumnsConfigEditorComponent, selector: "columns-config-editor", inputs: ["config"], outputs: ["configChange", "columnChange"] }, { kind: "component", type: BehaviorConfigEditorComponent, selector: "behavior-config-editor", inputs: ["config", "resourcePath", "forceClientStrategies"], outputs: ["configChange", "behaviorChange"] }, { kind: "component", type: HeaderAppearanceEditorComponent, selector: "header-appearance-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: ToolbarActionsEditorComponent, selector: "toolbar-actions-editor", inputs: ["config"], outputs: ["configChange", "toolbarActionsChange"] }, { kind: "component", type: MessagesLocalizationEditorComponent, selector: "messages-localization-editor", inputs: ["config"], outputs: ["configChange", "messagesLocalizationChange"] }, { kind: "component", type: FilterSettingsComponent, selector: "filter-settings", inputs: ["metadata", "metadataSource", "metadataLoading", "metadataErrorMsg", "settings", "configKey"], outputs: ["settingsChange"] }, { kind: "component", type: CrudIntegrationEditorComponent, selector: "crud-integration-editor", inputs: ["tableId", "crudContext", "componentKeyId"] }, { kind: "component", type: ConfirmDialogAppearanceEditorComponent, selector: "confirm-dialog-appearance-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: TableRulesEditorComponent, selector: "table-rules-editor", inputs: ["config", "resourcePath", "fields", "i18nRules", "dslFunctionRegistry", "debugLogs", "debugLevel"], outputs: ["configChange"] }] });
29726
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisTableConfigEditor, isStandalone: true, selector: "praxis-table-config-editor", providers: [TableConfigService], viewQueries: [{ propertyName: "filterSettingsEditor", first: true, predicate: ["tableFilterSettingsRef"], descendants: true }, { propertyName: "behaviorEditor", first: true, predicate: BehaviorConfigEditorComponent, descendants: true }, { propertyName: "crudEditorSetter", first: true, predicate: ["crudEditorRef"], descendants: true }], ngImport: i0, template: " <mat-tab-group class=\"config-tabs\" [(selectedIndex)]=\"activeSectionIndex\">\n <mat-tab *ngFor=\"let section of sections\">\n <ng-template mat-tab-label>\n @if (section.icon) { <mat-icon [praxisIcon]=\"section.icon\"></mat-icon> }\n <span [attr.data-testid]=\"'config-tab-' + section.id\">{{ section.label }}</span>\n </ng-template>\n <div class=\"tab-content\">\n <ng-container [ngSwitch]=\"section.id\">\n <div *ngSwitchCase=\"'connect'\" class=\"connect-grid\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Recurso</mat-label>\n <input matInput [(ngModel)]=\"resourcePath\" (ngModelChange)=\"onResourcePathChange($event)\" placeholder=\"ex.: employees\" />\n <mat-icon matSuffix>link</mat-icon>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Chave prim\u00E1ria</mat-label>\n <input matInput [(ngModel)]=\"idField\" (ngModelChange)=\"onIdFieldChange($event)\" placeholder=\"ex.: id, uuid, codigo\" />\n <mat-icon matSuffix>fingerprint</mat-icon>\n </mat-form-field>\n <p class=\"connect-note\">Defina o recurso da API e, se necess\u00E1rio, a chave prim\u00E1ria.</p>\n\n <!-- Diverg\u00EAncia: idField -->\n @if (idFieldDiverges) { <div class=\"alert alert--warning connect-alert\">\n <mat-icon class=\"alert__icon\">warning</mat-icon>\n <div class=\"alert__text connect-alert__text\">\n A chave prim\u00E1ria no servidor diverge da configura\u00E7\u00E3o atual.\n <span class=\"connect-alert__meta\">(config: {{ idField || 'id' }} | servidor: {{ serverIdField || 'id' }})</span>\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onReconcileIdField()\">Reconciliar</button>\n </div> }\n\n <!-- Diverg\u00EAncia: serverHash -->\n @if (schemaHashDiverges) { <div class=\"alert alert--info connect-alert\">\n <mat-icon class=\"alert__icon\">info</mat-icon>\n <div class=\"alert__text connect-alert__text\">\n O snapshot de schema salvo diverge do schema atual do servidor.\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onAcceptServerHash()\">Atualizar metadados</button>\n </div> }\n\n @if (!schemaHashDiverges && schemaSnapshotMissing) { <div class=\"alert alert--info connect-alert\">\n <mat-icon class=\"alert__icon\">info</mat-icon>\n <div class=\"alert__text connect-alert__text\">\n Existe schema atual no servidor, mas ainda n\u00E3o h\u00E1 snapshot persistido para reconcilia\u00E7\u00E3o.\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onAcceptServerHash()\">Salvar snapshot</button>\n </div> }\n </div>\n\n <div *ngSwitchCase=\"'overview'\" class=\"overview-grid\">\n <div class=\"overview-row\">\n <mat-form-field appearance=\"outline\" class=\"hs-field\">\n <mat-label>Scroll Horizontal</mat-label>\n <mat-select [(ngModel)]=\"horizontalScroll\" (ngModelChange)=\"onHorizontalScrollChange($event)\">\n <mat-option value=\"auto\">Auto (padr\u00E3o)</mat-option>\n <mat-option value=\"wrap\">Wrap (quebrar linhas)</mat-option>\n <mat-option value=\"none\">Host controla</mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"help small\">Controla como a tabela lida com largura horizontal e barra de rolagem.</div>\n </div>\n @if (isEffectiveLocalMode()) { <div class=\"alert alert--info overview-mode-alert\">\n <mat-icon class=\"alert__icon\">info</mat-icon>\n <div class=\"alert__text\">\n Modo local efetivo ativo: estrat\u00E9gias de pagina\u00E7\u00E3o e ordena\u00E7\u00E3o em servidor ficam bloqueadas e s\u00E3o salvas como cliente.\n </div>\n </div> }\n <behavior-config-editor\n [config]=\"editedConfig\"\n [resourcePath]=\"resourcePath\"\n [forceClientStrategies]=\"isEffectiveLocalMode()\"\n (configChange)=\"onBehaviorConfigChange($event)\"\n (behaviorChange)=\"onBehaviorChange($event)\"\n ></behavior-config-editor>\n </div>\n\n <columns-config-editor\n *ngSwitchCase=\"'columns'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n (columnChange)=\"onColumnChange($event)\"\n ></columns-config-editor>\n\n <table-rules-editor\n *ngSwitchCase=\"'rules'\"\n [config]=\"editedConfig\"\n [resourcePath]=\"resourcePath\"\n (configChange)=\"onRulesConfigChange($event)\"\n ></table-rules-editor>\n\n <header-appearance-editor\n *ngSwitchCase=\"'header'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n ></header-appearance-editor>\n\n <toolbar-actions-editor\n *ngSwitchCase=\"'toolbar'\"\n [config]=\"editedConfig\"\n (configChange)=\"onToolbarActionsConfigChange($event)\"\n (toolbarActionsChange)=\"onToolbarActionsChange($event)\"\n ></toolbar-actions-editor>\n\n <!-- Aba extra para integra\u00E7\u00F5es CRUD (vis\u00EDvel quando em contexto CRUD) -->\n <crud-integration-editor\n #crudEditorRef\n *ngSwitchCase=\"'crud'\"\n [tableId]=\"crudContext?.tableId || 'default'\"\n [crudContext]=\"crudContext\"\n [componentKeyId]=\"crudContext?.componentKeyId\"\n ></crud-integration-editor>\n\n <filter-settings\n #tableFilterSettingsRef\n *ngSwitchCase=\"'filters'\"\n [metadata]=\"getFilterSettingsMetas()\"\n [metadataSource]=\"isUsingFilterDtoMetas() ? 'filter-dto' : 'columns'\"\n [metadataLoading]=\"filterDtoMetasLoading\"\n [metadataErrorMsg]=\"filterDtoMetasErrorMsg\"\n [settings]=\"\n editedConfig.behavior?.filtering?.advancedFilters?.settings\n \"\n (settingsChange)=\"onFilterSettingsChange($event)\"\n ></filter-settings>\n\n <messages-localization-editor\n *ngSwitchCase=\"'messages'\"\n [config]=\"editedConfig\"\n (configChange)=\"onMessagesLocalizationConfigChange($event)\"\n (messagesLocalizationChange)=\"\n onMessagesLocalizationChange($event)\n \"\n ></messages-localization-editor>\n\n <confirm-dialog-appearance-editor\n *ngSwitchCase=\"'dialogs'\"\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n ></confirm-dialog-appearance-editor>\n\n\n <json-config-editor\n *ngSwitchCase=\"'json'\"\n [document]=\"buildJsonAuthoringDocument()\"\n (documentChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n ></json-config-editor>\n </ng-container>\n </div>\n </mat-tab>\n </mat-tab-group>\n@if (statusMessage) { <div class=\"config-editor-status\">\n <span\n class=\"status-text\"\n [class.error]=\"hasErrors\"\n [class.success]=\"hasSuccess\"\n >{{ statusMessage }}</span\n >\n </div> }\n", styles: ["@charset \"UTF-8\";.config-tabs{flex:1 1 auto;display:flex;flex-direction:column}.config-tabs .mat-mdc-tab{min-width:120px}.config-tabs .mat-mdc-tab-body-wrapper,.config-tabs .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.config-tabs .mat-mdc-tab-body-content{height:100%;min-height:0;overflow:visible}.tab-content{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;padding:8px 8px 56px;box-sizing:border-box;overflow:visible}.overview-grid{display:grid;grid-template-columns:1fr;gap:12px}.overview-grid .overview-row{display:grid;grid-template-columns:280px 1fr;align-items:end;gap:12px}.overview-grid .overview-row .help.small{opacity:.75;font-size:12px}.overview-mode-alert{align-items:center}.connect-grid{display:grid;gap:12px;padding:8px;grid-template-columns:1fr 240px;align-items:start}.connect-note{grid-column:1/-1;margin:0;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.connect-alert{grid-column:1/-1;align-items:center}.connect-alert__text{flex:1}.connect-alert__meta{opacity:.85}.educational-card{margin-bottom:24px;background:var(--md-sys-color-surface-container-low);border-left:4px solid var(--md-sys-color-primary);flex-shrink:0}.config-editor-status{padding:12px 16px;margin-top:auto;border-top:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);flex-shrink:0;position:relative}.status-text{font-size:.875rem;line-height:1.2}.status-text.error{color:var(--md-sys-color-error)}.status-text.success{color:var(--md-sys-color-primary)}@media(max-width:768px){.tab-content{padding:8px}.config-editor-status{padding:12px 16px}.connect-grid{grid-template-columns:1fr}.overview-grid .overview-row{grid-template-columns:1fr;align-items:start}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i4.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i4.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i4.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: JsonConfigEditorComponent, selector: "json-config-editor", inputs: ["document"], outputs: ["documentChange", "validationChange", "editorEvent"] }, { kind: "component", type: ColumnsConfigEditorComponent, selector: "columns-config-editor", inputs: ["config"], outputs: ["configChange", "columnChange"] }, { kind: "component", type: BehaviorConfigEditorComponent, selector: "behavior-config-editor", inputs: ["config", "resourcePath", "forceClientStrategies"], outputs: ["configChange", "behaviorChange"] }, { kind: "component", type: HeaderAppearanceEditorComponent, selector: "header-appearance-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: ToolbarActionsEditorComponent, selector: "toolbar-actions-editor", inputs: ["config"], outputs: ["configChange", "toolbarActionsChange"] }, { kind: "component", type: MessagesLocalizationEditorComponent, selector: "messages-localization-editor", inputs: ["config"], outputs: ["configChange", "messagesLocalizationChange"] }, { kind: "component", type: FilterSettingsComponent, selector: "filter-settings", inputs: ["metadata", "metadataSource", "metadataLoading", "metadataErrorMsg", "settings", "configKey"], outputs: ["settingsChange"] }, { kind: "component", type: CrudIntegrationEditorComponent, selector: "crud-integration-editor", inputs: ["tableId", "crudContext", "componentKeyId"] }, { kind: "component", type: ConfirmDialogAppearanceEditorComponent, selector: "confirm-dialog-appearance-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: TableRulesEditorComponent, selector: "table-rules-editor", inputs: ["config", "resourcePath", "fields", "i18nRules", "dslFunctionRegistry", "debugLogs", "debugLevel"], outputs: ["configChange"] }] });
29727
29727
  }
29728
29728
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisTableConfigEditor, decorators: [{
29729
29729
  type: Component,
@@ -30001,11 +30001,14 @@ class PraxisFilter {
30001
30001
  * Keys are field names from the filter DTO schema.
30002
30002
  */
30003
30003
  alwaysVisibleFieldMetadataOverrides = {};
30004
+ /** Runtime field-level metadata overrides applied by the metadata editor. */
30005
+ fieldMetadataOverrides = {};
30004
30006
  /** Additional selected field ids to render before pinned always-visible */
30005
30007
  selectedFieldIds = [];
30006
30008
  tags;
30007
30009
  allowSaveTags;
30008
30010
  persistenceKey;
30011
+ disablePersistence = false;
30009
30012
  i18n;
30010
30013
  changeDebounceMs = 300;
30011
30014
  /** Controla a exibição do botão de preferências dentro do filtro */
@@ -30077,6 +30080,7 @@ class PraxisFilter {
30077
30080
  gridSelectedMetas = [];
30078
30081
  gridAlwaysVisibleMetas = [];
30079
30082
  toggleMetas = [];
30083
+ activeEditableFieldName = null;
30080
30084
  advancedConfig;
30081
30085
  displayedTags = [];
30082
30086
  savedTags = [];
@@ -30197,7 +30201,17 @@ class PraxisFilter {
30197
30201
  useResourcePathFallback: true,
30198
30202
  });
30199
30203
  }
30204
+ isPersistenceDisabled() {
30205
+ if (this.disablePersistence)
30206
+ return true;
30207
+ const queryValue = this.route?.snapshot.queryParamMap.get('disablePersistence');
30208
+ return queryValue === '1' || queryValue === 'true';
30209
+ }
30200
30210
  resolveConfigKey() {
30211
+ if (this.isPersistenceDisabled()) {
30212
+ this.configKey = null;
30213
+ return null;
30214
+ }
30201
30215
  const key = this.componentKeyId();
30202
30216
  this.configKey = key;
30203
30217
  return key;
@@ -30291,6 +30305,21 @@ class PraxisFilter {
30291
30305
  }
30292
30306
  return this.fallbackLogger;
30293
30307
  }
30308
+ get activeEditableFieldMeta() {
30309
+ return this.getEditableFieldMeta(this.activeEditableFieldName);
30310
+ }
30311
+ get activeEditableFieldLabel() {
30312
+ const meta = this.activeEditableFieldMeta;
30313
+ if (!meta)
30314
+ return null;
30315
+ return String(meta.label || meta.name || '').trim() || null;
30316
+ }
30317
+ isFieldAuthoringEnabled() {
30318
+ if (this.enableCustomization) {
30319
+ return true;
30320
+ }
30321
+ return this.isLocalE2eAuthoringOptInEnabled();
30322
+ }
30294
30323
  buildFilterLogOptions(data, actionId) {
30295
30324
  return {
30296
30325
  context: {
@@ -30367,6 +30396,40 @@ class PraxisFilter {
30367
30396
  }
30368
30397
  catch { }
30369
30398
  }
30399
+ resolveInputDto() {
30400
+ return this.cleanFilterPayload((this.value || {}));
30401
+ }
30402
+ resolveInitialDto(saved) {
30403
+ if (this.value !== undefined) {
30404
+ return this.resolveInputDto();
30405
+ }
30406
+ return this.cleanFilterPayload((saved || {}));
30407
+ }
30408
+ syncFormsFromDto() {
30409
+ const dto = this.cleanFilterPayload(this.dto || {});
30410
+ Object.keys(this.alwaysForm.controls || {}).forEach((key) => {
30411
+ const control = this.alwaysForm.get(key);
30412
+ if (!control)
30413
+ return;
30414
+ if (Object.prototype.hasOwnProperty.call(dto, key)) {
30415
+ control.setValue(dto[key], { emitEvent: false });
30416
+ }
30417
+ else {
30418
+ control.reset(undefined, { emitEvent: false });
30419
+ }
30420
+ });
30421
+ Object.keys(this.advancedForm?.controls || {}).forEach((key) => {
30422
+ const control = this.advancedForm?.get(key);
30423
+ if (!control)
30424
+ return;
30425
+ if (Object.prototype.hasOwnProperty.call(dto, key)) {
30426
+ control.setValue(dto[key], { emitEvent: false });
30427
+ }
30428
+ else {
30429
+ control.reset(undefined, { emitEvent: false });
30430
+ }
30431
+ });
30432
+ }
30370
30433
  async ngOnInit() {
30371
30434
  this.logFilterDebug('[PFILTER] ngOnInit: config + state', {
30372
30435
  resourcePath: this.resourcePath,
@@ -30402,6 +30465,10 @@ class PraxisFilter {
30402
30465
  if (Object.keys(cfgOverrides).length) {
30403
30466
  this.alwaysVisibleFieldMetadataOverrides = cfgOverrides;
30404
30467
  }
30468
+ const fieldOverrides = this.cloneFieldMetadataOverrides(cfg.fieldMetadataOverrides);
30469
+ if (Object.keys(fieldOverrides).length) {
30470
+ this.fieldMetadataOverrides = fieldOverrides;
30471
+ }
30405
30472
  if (this.allowSaveTags === undefined && cfg.allowSaveTags !== undefined) {
30406
30473
  this.allowSaveTags = cfg.allowSaveTags;
30407
30474
  }
@@ -30506,15 +30573,14 @@ class PraxisFilter {
30506
30573
  this.updateDisplayedTags();
30507
30574
  // carregar filtros persistidos (DTO)
30508
30575
  const dtoKey = this.filterDtoKey();
30576
+ let savedDto = null;
30509
30577
  if (dtoKey) {
30510
30578
  const saved = await firstValueFrom(this.configStorage.loadConfig(dtoKey));
30511
30579
  if (saved) {
30512
- this.dto = { ...saved };
30580
+ savedDto = saved;
30513
30581
  }
30514
30582
  }
30515
- if (!Object.keys(this.dto).length && this.value) {
30516
- this.dto = { ...this.value };
30517
- }
30583
+ this.dto = this.resolveInitialDto(savedDto);
30518
30584
  this.setActiveFiltersCount(Object.keys(this.dto).length);
30519
30585
  this.normalizeMode();
30520
30586
  // Só então aplicar a preferência de advancedOpen conforme o modo efetivo
@@ -30656,6 +30722,11 @@ class PraxisFilter {
30656
30722
  if (changes['tags'] && !changes['tags'].firstChange) {
30657
30723
  this.updateDisplayedTags();
30658
30724
  }
30725
+ if (changes['value'] && !changes['value'].firstChange) {
30726
+ this.dto = this.resolveInputDto();
30727
+ this.setActiveFiltersCount(Object.keys(this.dto).length);
30728
+ this.syncFormsFromDto();
30729
+ }
30659
30730
  if (changes['resourcePath'] && !changes['resourcePath'].firstChange) {
30660
30731
  this.logFilterDebug('[PFILTER] ngOnChanges: reconfigure CRUD');
30661
30732
  this.crud.configure(this.resourcePath);
@@ -30765,6 +30836,7 @@ class PraxisFilter {
30765
30836
  const hasAlwaysVisibleFields = Object.prototype.hasOwnProperty.call(cfg, 'alwaysVisibleFields');
30766
30837
  const hasSelectedFieldIds = Object.prototype.hasOwnProperty.call(cfg, 'selectedFieldIds');
30767
30838
  const hasAlwaysVisibleOverrides = Object.prototype.hasOwnProperty.call(cfg, 'alwaysVisibleFieldMetadataOverrides');
30839
+ const hasFieldMetadataOverrides = Object.prototype.hasOwnProperty.call(cfg, 'fieldMetadataOverrides');
30768
30840
  const nextAlways = hasAlwaysVisibleFields
30769
30841
  ? Array.isArray(cfg.alwaysVisibleFields)
30770
30842
  ? [...cfg.alwaysVisibleFields]
@@ -30778,12 +30850,17 @@ class PraxisFilter {
30778
30850
  const nextOverrides = hasAlwaysVisibleOverrides
30779
30851
  ? this.cloneAlwaysVisibleMetadataOverrides(cfg.alwaysVisibleFieldMetadataOverrides)
30780
30852
  : this.cloneAlwaysVisibleMetadataOverrides(this.alwaysVisibleFieldMetadataOverrides);
30853
+ const nextFieldOverrides = hasFieldMetadataOverrides
30854
+ ? this.cloneFieldMetadataOverrides(cfg.fieldMetadataOverrides)
30855
+ : this.cloneFieldMetadataOverrides(this.fieldMetadataOverrides);
30781
30856
  const alwaysChanged = !this.areStringArraysEqual(this.alwaysVisibleFields, nextAlways);
30782
30857
  const selectedChanged = !this.areStringArraysEqual(this.selectedFieldIds, nextSelected);
30783
30858
  const overridesChanged = !this.areMetadataOverrideMapsEqual(this.alwaysVisibleFieldMetadataOverrides, nextOverrides);
30859
+ const fieldOverridesChanged = !this.areMetadataOverrideMapsEqual(this.fieldMetadataOverrides, nextFieldOverrides);
30784
30860
  this.alwaysVisibleFields = nextAlways;
30785
30861
  this.selectedFieldIds = nextSelected;
30786
30862
  this.alwaysVisibleFieldMetadataOverrides = nextOverrides;
30863
+ this.fieldMetadataOverrides = nextFieldOverrides;
30787
30864
  if (cfg.allowSaveTags !== undefined) {
30788
30865
  this.allowSaveTags = cfg.allowSaveTags;
30789
30866
  }
@@ -30819,7 +30896,7 @@ class PraxisFilter {
30819
30896
  prevInlineTime !== this.useInlineTimeVariant ||
30820
30897
  prevInlineTimeRange !== this.useInlineTimeRangeVariant ||
30821
30898
  prevInlineTreeSelect !== this.useInlineTreeSelectVariant;
30822
- if (alwaysChanged || selectedChanged || overridesChanged || inlineVariantsChanged) {
30899
+ if (alwaysChanged || selectedChanged || overridesChanged || fieldOverridesChanged || inlineVariantsChanged) {
30823
30900
  if (this.schemaMetas) {
30824
30901
  this.applySchemaMetas();
30825
30902
  }
@@ -30841,6 +30918,12 @@ class PraxisFilter {
30841
30918
  dto: { ...this.dto },
30842
30919
  settings: {
30843
30920
  alwaysVisibleFields: this.alwaysVisibleFields,
30921
+ ...(() => {
30922
+ const overrides = this.cloneFieldMetadataOverrides(this.fieldMetadataOverrides);
30923
+ return Object.keys(overrides).length
30924
+ ? { fieldMetadataOverrides: overrides }
30925
+ : {};
30926
+ })(),
30844
30927
  ...(() => {
30845
30928
  const overrides = this.cloneAlwaysVisibleMetadataOverrides(this.alwaysVisibleFieldMetadataOverrides);
30846
30929
  return Object.keys(overrides).length
@@ -30883,6 +30966,7 @@ class PraxisFilter {
30883
30966
  });
30884
30967
  const applyChanges = (cfg) => {
30885
30968
  this.alwaysVisibleFields = cfg.alwaysVisibleFields ?? [];
30969
+ this.fieldMetadataOverrides = this.cloneFieldMetadataOverrides(cfg.fieldMetadataOverrides);
30886
30970
  this.alwaysVisibleFieldMetadataOverrides =
30887
30971
  this.cloneAlwaysVisibleMetadataOverrides(cfg.alwaysVisibleFieldMetadataOverrides);
30888
30972
  this.advancedOpen = false;
@@ -30959,10 +31043,19 @@ class PraxisFilter {
30959
31043
  const persistConfig = (cfg, message) => {
30960
31044
  this.saving = true;
30961
31045
  try {
31046
+ const persistedCfg = {
31047
+ ...cfg,
31048
+ ...(() => {
31049
+ const overrides = this.cloneFieldMetadataOverrides(this.fieldMetadataOverrides);
31050
+ return Object.keys(overrides).length
31051
+ ? { fieldMetadataOverrides: overrides }
31052
+ : {};
31053
+ })(),
31054
+ };
30962
31055
  if (this.configKey) {
30963
- this.filterConfig.save(this.configKey, cfg);
31056
+ this.filterConfig.save(this.configKey, persistedCfg);
30964
31057
  try {
30965
- this.lastSavedConfigJson = JSON.stringify(cfg);
31058
+ this.lastSavedConfigJson = JSON.stringify(persistedCfg);
30966
31059
  }
30967
31060
  catch {
30968
31061
  this.lastSavedConfigJson = null;
@@ -31652,11 +31745,15 @@ class PraxisFilter {
31652
31745
  this._dbgLastApplyMetasAt = Date.now();
31653
31746
  this.logFilterWarn('[PFILTER] applySchemaMetas: start', {
31654
31747
  alwaysVisibleFields: this.alwaysVisibleFields,
31748
+ fieldOverrideFields: Object.keys(this.fieldMetadataOverrides || {}),
31655
31749
  alwaysVisibleOverrideFields: Object.keys(this.alwaysVisibleFieldMetadataOverrides || {}),
31656
31750
  hasSchema: !!this.schemaMetas,
31657
31751
  schemaCount: this.schemaMetas?.length ?? 0,
31658
31752
  });
31659
- const metas = (this.schemaMetas ?? []).map((meta) => this.withInferredFilterControlType(meta));
31753
+ const fieldOverrides = this.cloneFieldMetadataOverrides(this.fieldMetadataOverrides);
31754
+ const metas = (this.schemaMetas ?? [])
31755
+ .map((meta) => this.withInferredFilterControlType(meta))
31756
+ .map((meta) => this.mergeFieldMetadataOverride(meta, fieldOverrides[meta.name]));
31660
31757
  this.alwaysVisibleMetas = [];
31661
31758
  this.selectedMetas = [];
31662
31759
  this.compactSelectedMetas = [];
@@ -31974,6 +32071,9 @@ class PraxisFilter {
31974
32071
  this.compactAlwaysVisibleMetas = this.alwaysVisibleMetas.filter(isInlineCompactControl);
31975
32072
  this.gridSelectedMetas = this.selectedMetas.filter((m) => !isInlineCompactControl(m));
31976
32073
  this.gridAlwaysVisibleMetas = this.alwaysVisibleMetas.filter((m) => !isInlineCompactControl(m));
32074
+ if (this.activeEditableFieldName && !this.getEditableFieldMeta(this.activeEditableFieldName)) {
32075
+ this.activeEditableFieldName = null;
32076
+ }
31977
32077
  // Registrar controles para ambos os grupos dentro do mesmo FormGroup
31978
32078
  this.logFilterWarn('[PFILTER] applySchemaMetas: selected/always/toggles', {
31979
32079
  selectedCount: this.selectedMetas.length,
@@ -32242,6 +32342,9 @@ class PraxisFilter {
32242
32342
  cloneAlwaysVisibleMetadataOverrides(overrides) {
32243
32343
  return this.sanitizeAlwaysVisibleMetadataOverrides(overrides);
32244
32344
  }
32345
+ cloneFieldMetadataOverrides(overrides) {
32346
+ return this.sanitizeAlwaysVisibleMetadataOverrides(overrides);
32347
+ }
32245
32348
  sanitizeAlwaysVisibleMetadataOverrides(overrides) {
32246
32349
  if (!overrides || typeof overrides !== 'object' || Array.isArray(overrides)) {
32247
32350
  return {};
@@ -32317,6 +32420,9 @@ class PraxisFilter {
32317
32420
  return undefined;
32318
32421
  }
32319
32422
  mergeAlwaysVisibleMetadata(base, override) {
32423
+ return this.mergeFieldMetadataOverride(base, override);
32424
+ }
32425
+ mergeFieldMetadataOverride(base, override) {
32320
32426
  if (!override || typeof override !== 'object' || Array.isArray(override)) {
32321
32427
  return base;
32322
32428
  }
@@ -32422,9 +32528,134 @@ class PraxisFilter {
32422
32528
  names: Array.from(map?.keys?.() || []),
32423
32529
  });
32424
32530
  }
32531
+ onFieldInteraction(event) {
32532
+ if (!this.isFieldAuthoringEnabled())
32533
+ return;
32534
+ const fieldName = this.resolveFieldNameFromEvent(event);
32535
+ if (!fieldName)
32536
+ return;
32537
+ if (!this.getEditableFieldMeta(fieldName))
32538
+ return;
32539
+ this.activeEditableFieldName = fieldName;
32540
+ }
32541
+ openSelectedFieldEditor() {
32542
+ const meta = this.activeEditableFieldMeta;
32543
+ if (!meta)
32544
+ return;
32545
+ const controlType = meta.controlType || FieldControlType.INPUT;
32546
+ const fieldName = meta.name;
32547
+ const seed = this.buildFieldMetadataEditorSeed(meta);
32548
+ import('@praxisui/metadata-editor')
32549
+ .then((m) => {
32550
+ const { FieldMetadataEditorComponent } = m;
32551
+ this.openFieldMetadataEditorInternal(FieldMetadataEditorComponent, controlType, seed, fieldName);
32552
+ })
32553
+ .catch((error) => {
32554
+ this.getLogger().error('PFILTER:field-editor:load:error', this.buildFilterLogOptions({ error, fieldName }, 'field-editor.load'));
32555
+ });
32556
+ }
32557
+ isLocalE2eAuthoringOptInEnabled() {
32558
+ if (typeof window === 'undefined' || !window?.localStorage) {
32559
+ return false;
32560
+ }
32561
+ const resourcePath = String(this.resourcePath || '').trim().toLowerCase();
32562
+ const componentInstanceId = String(this.componentInstanceId || '').trim().toLowerCase();
32563
+ const isLocalHarness = resourcePath.startsWith('/local/') ||
32564
+ resourcePath.includes('/e2e-') ||
32565
+ componentInstanceId.includes('e2e');
32566
+ if (!isLocalHarness) {
32567
+ return false;
32568
+ }
32569
+ return window.localStorage.getItem('praxis.customization.enabled') === 'true';
32570
+ }
32571
+ openFieldMetadataEditorInternal(editorComponent, controlType, seed, fieldName) {
32572
+ const ref = this.settingsPanel.open({
32573
+ id: `filter-field-meta.${this.formId || this.filterId || 'filter'}.${fieldName}`,
32574
+ title: this.activeEditableFieldLabel || fieldName,
32575
+ titleIcon: 'tune',
32576
+ content: {
32577
+ component: editorComponent,
32578
+ inputs: { controlType, seed },
32579
+ },
32580
+ });
32581
+ if (!ref)
32582
+ return;
32583
+ const handlePatch = (patch) => {
32584
+ if (!patch)
32585
+ return;
32586
+ this.applyFieldMetadataPatch(fieldName, patch);
32587
+ };
32588
+ if (ref.applied$?.pipe) {
32589
+ ref.applied$
32590
+ .pipe(takeUntilDestroyed(this.destroyRef))
32591
+ .subscribe((patch) => handlePatch(patch));
32592
+ }
32593
+ if (ref.saved$?.pipe) {
32594
+ ref.saved$
32595
+ .pipe(takeUntilDestroyed(this.destroyRef))
32596
+ .subscribe((patch) => handlePatch(patch));
32597
+ }
32598
+ }
32599
+ applyFieldMetadataPatch(fieldName, patch) {
32600
+ const nextOverrides = this.cloneFieldMetadataOverrides(this.fieldMetadataOverrides);
32601
+ const current = nextOverrides[fieldName] || {};
32602
+ nextOverrides[fieldName] = this.sanitizeMetadataOverrideValue({ ...current, ...patch }, 0);
32603
+ this.fieldMetadataOverrides = nextOverrides;
32604
+ if (this.alwaysVisibleFields?.includes(fieldName)) {
32605
+ const currentAlways = this.cloneAlwaysVisibleMetadataOverrides(this.alwaysVisibleFieldMetadataOverrides);
32606
+ currentAlways[fieldName] = nextOverrides[fieldName];
32607
+ this.alwaysVisibleFieldMetadataOverrides = currentAlways;
32608
+ }
32609
+ if (this.schemaMetas?.length) {
32610
+ this.applySchemaQueued = false;
32611
+ this.applySchemaMetasNow();
32612
+ }
32613
+ this.saveConfig();
32614
+ }
32615
+ buildFieldMetadataEditorSeed(meta) {
32616
+ const source = this.sanitizeMetadataOverrideValue(meta, 0) || {};
32617
+ const seed = { ...source };
32618
+ if (Array.isArray(meta.options)) {
32619
+ try {
32620
+ seed['options'] = JSON.stringify(meta.options, null, 2);
32621
+ }
32622
+ catch { }
32623
+ }
32624
+ if (Array.isArray(meta.nodes)) {
32625
+ try {
32626
+ seed['options'] = JSON.stringify(meta.nodes, null, 2);
32627
+ }
32628
+ catch { }
32629
+ }
32630
+ if (meta.filterCriteria && typeof meta.filterCriteria === 'object') {
32631
+ try {
32632
+ seed['filterCriteria'] = JSON.stringify(meta.filterCriteria, null, 2);
32633
+ }
32634
+ catch { }
32635
+ }
32636
+ return seed;
32637
+ }
32638
+ getEditableFieldMeta(fieldName) {
32639
+ if (!fieldName)
32640
+ return null;
32641
+ return (this.toggleMetas.find((meta) => meta.name === fieldName) ||
32642
+ this.compactSelectedMetas.find((meta) => meta.name === fieldName) ||
32643
+ this.compactAlwaysVisibleMetas.find((meta) => meta.name === fieldName) ||
32644
+ this.gridSelectedMetas.find((meta) => meta.name === fieldName) ||
32645
+ this.gridAlwaysVisibleMetas.find((meta) => meta.name === fieldName) ||
32646
+ null);
32647
+ }
32648
+ resolveFieldNameFromEvent(event) {
32649
+ const target = event.target;
32650
+ if (!target?.closest)
32651
+ return null;
32652
+ const host = target.closest('[data-field-name]');
32653
+ const fieldName = host?.getAttribute('data-field-name');
32654
+ return fieldName ? String(fieldName).trim() : null;
32655
+ }
32425
32656
  onAdvancedReady(event) {
32426
32657
  this.advancedForm = event.formGroup;
32427
- this.advancedForm.patchValue(this.dto, { emitEvent: false });
32658
+ this.syncFormsFromDto();
32428
32659
  // Atualiza estado de validade inicial
32429
32660
  this.advancedValid = this.advancedForm.valid;
32430
32661
  }
@@ -32961,6 +33192,7 @@ class PraxisFilter {
32961
33192
  this.advancedForm?.reset(undefined, { emitEvent: false });
32962
33193
  this.dto = {};
32963
33194
  this.setActiveFiltersCount(0);
33195
+ this.syncFormsFromDto();
32964
33196
  this.clear.emit();
32965
33197
  this.change.emit({});
32966
33198
  this.clearPersisted();
@@ -33033,7 +33265,7 @@ class PraxisFilter {
33033
33265
  this.advancedOpen = true;
33034
33266
  this.saveConfig();
33035
33267
  try {
33036
- const { FilterFormDialogHostComponent } = await import('./praxisui-table-filter-form-dialog-host.component-C2rQnHE1.mjs');
33268
+ const { FilterFormDialogHostComponent } = await import('./praxisui-table-filter-form-dialog-host.component-EHoM1uuJ.mjs');
33037
33269
  const formId = this.formId || this.filterId || 'filter';
33038
33270
  const ref = this.dialog.open(FilterFormDialogHostComponent, {
33039
33271
  width: '780px',
@@ -33131,9 +33363,13 @@ class PraxisFilter {
33131
33363
  this.applySchemaMetas();
33132
33364
  }
33133
33365
  saveConfig() {
33366
+ const fieldOverrides = this.cloneFieldMetadataOverrides(this.fieldMetadataOverrides);
33134
33367
  const metadataOverrides = this.cloneAlwaysVisibleMetadataOverrides(this.alwaysVisibleFieldMetadataOverrides);
33135
33368
  const config = {
33136
33369
  alwaysVisibleFields: this.alwaysVisibleFields,
33370
+ ...(Object.keys(fieldOverrides).length
33371
+ ? { fieldMetadataOverrides: fieldOverrides }
33372
+ : {}),
33137
33373
  ...(Object.keys(metadataOverrides).length
33138
33374
  ? { alwaysVisibleFieldMetadataOverrides: metadataOverrides }
33139
33375
  : {}),
@@ -33354,8 +33590,8 @@ class PraxisFilter {
33354
33590
  // no-op
33355
33591
  }
33356
33592
  }
33357
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisFilter, deps: [{ token: i1.GenericCrudService }, { token: ASYNC_CONFIG_STORAGE }, { token: i0.DestroyRef }, { token: FilterConfigService }, { token: i3$1.SettingsPanelService }, { token: i2$1.MatSnackBar }, { token: i1$3.MatDialog }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i1.DynamicFormService }, { token: i1.SchemaNormalizerService }, { token: i1.ComponentKeyService }, { token: i6$2.ActivatedRoute, optional: true }, { token: i1.LoggerService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
33358
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisFilter, isStandalone: true, selector: "praxis-filter", inputs: { resourcePath: "resourcePath", fieldMetadata: "fieldMetadata", filterId: "filterId", formId: "formId", componentInstanceId: "componentInstanceId", mode: "mode", notifyIfOutdated: "notifyIfOutdated", snoozeMs: "snoozeMs", autoOpenSettingsOnOutdated: "autoOpenSettingsOnOutdated", enableCustomization: "enableCustomization", value: "value", alwaysVisibleFields: "alwaysVisibleFields", alwaysVisibleFieldMetadataOverrides: "alwaysVisibleFieldMetadataOverrides", selectedFieldIds: "selectedFieldIds", tags: "tags", allowSaveTags: "allowSaveTags", persistenceKey: "persistenceKey", i18n: "i18n", changeDebounceMs: "changeDebounceMs", showFilterSettings: "showFilterSettings", confirmTagDelete: "confirmTagDelete", placeBooleansInActions: "placeBooleansInActions", showToggleLabels: "showToggleLabels", useInlineSelectVariant: "useInlineSelectVariant", useInlineSearchableSelectVariant: "useInlineSearchableSelectVariant", useInlineMultiSelectVariant: "useInlineMultiSelectVariant", useInlineInputVariant: "useInlineInputVariant", useInlineToggleVariant: "useInlineToggleVariant", useInlineRangeVariant: "useInlineRangeVariant", useInlineDateVariant: "useInlineDateVariant", useInlineDateRangeVariant: "useInlineDateRangeVariant", useInlineTimeVariant: "useInlineTimeVariant", useInlineTimeRangeVariant: "useInlineTimeRangeVariant", useInlineTreeSelectVariant: "useInlineTreeSelectVariant", alwaysMinWidth: "alwaysMinWidth", alwaysColsMd: "alwaysColsMd", alwaysColsLg: "alwaysColsLg", tagColor: "tagColor", tagVariant: "tagVariant", tagButtonColor: "tagButtonColor", actionsButtonColor: "actionsButtonColor", actionsVariant: "actionsVariant", overlayVariant: "overlayVariant", overlayBackdrop: "overlayBackdrop", advancedOpenMode: "advancedOpenMode", advancedClearButtonsEnabled: "advancedClearButtonsEnabled" }, outputs: { submit: "submit", change: "change", clear: "clear", modeChange: "modeChange", requestSearch: "requestSearch", tagsChange: "tagsChange", selectedFieldIdsChange: "selectedFieldIdsChange", metaChanged: "metaChanged", schemaStatusChange: "schemaStatusChange" }, host: { listeners: { "window:resize": "onWindowResize()", "document:keydown": "onGlobalKeydown($event)" }, properties: { "style.--pfx-always-min": "alwaysMinWidth + \"px\"", "style.--pfx-always-cols-md": "alwaysColsMd", "style.--pfx-always-cols-lg": "alwaysColsLg" } }, viewQueries: [{ propertyName: "anchorRef", first: true, predicate: ["anchorRef"], descendants: true, read: CdkOverlayOrigin }, { propertyName: "addAnchor", first: true, predicate: ["addAnchor"], descendants: true, read: CdkOverlayOrigin }, { propertyName: "advancedButton", first: true, predicate: ["advancedButton"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<mat-progress-bar *ngIf=\"saving\" mode=\"indeterminate\"></mat-progress-bar>\n<div class=\"schema-error-banner\" *ngIf=\"schemaError\" role=\"alert\" aria-live=\"polite\">\n <mat-icon [praxisIcon]=\"'error_outline'\" aria-hidden=\"true\"></mat-icon>\n <span class=\"schema-error-message\">{{ i18nLabels.errorLoadingFilters || 'Erro ao carregar filtros.' }}</span>\n <button\n mat-stroked-button\n class=\"schema-error-retry\"\n type=\"button\"\n (click)=\"retrySchemaLoad()\"\n [attr.aria-label]=\"i18nLabels.retry || 'Tentar novamente'\"\n >\n {{ i18nLabels.retry || 'Tentar novamente' }}\n </button>\n</div>\n\n<form class=\"praxis-filter-bar\" [class.is-open]=\"advancedOpen\"\n [class.has-compact]=\"compactSelectedMetas.length || compactAlwaysVisibleMetas.length\"\n (submit)=\"onSubmit(); $event.preventDefault()\">\n <div class=\"inline-actions\" [class.actions-outlined]=\"actionsVariant==='outlined'\">\n <div class=\"actions-anchor\" #anchorRef=\"cdkOverlayOrigin\" cdkOverlayOrigin></div>\n <div class=\"inline-toggles\" *ngIf=\"toggleMetas.length\">\n <ng-container dynamicFieldLoader [fields]=\"toggleMetas\" [formGroup]=\"alwaysForm\"\n (componentsCreated)=\"onToggleComponents($event)\"></ng-container>\n </div>\n\n <div class=\"action-cluster action-cluster--manage\">\n <button #advancedButton mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\" type=\"button\"\n [matBadge]=\"activeFiltersCount\" [matBadgeHidden]=\"!activeFiltersCount\" matBadgeSize=\"small\"\n matBadgeColor=\"primary\" [matBadgeOverlap]=\"false\" (click)=\"toggleAdvanced()\"\n [attr.aria-label]=\"getAdvancedAriaLabel()\" [attr.aria-expanded]=\"advancedOpen\"\n [matTooltip]=\"getAdvancedTooltip()\"\n matTooltipPosition=\"below\"\n [attr.aria-controls]=\"advancedPanelId\">\n <mat-icon [praxisIcon]=\"'filter_list'\"></mat-icon>\n </button>\n\n <button mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\" [attr.aria-label]=\"getAddAriaLabel()\" [matTooltip]=\"getAddTooltip()\"\n matTooltipPosition=\"below\" [matBadge]=\"selectedFieldIds.length || 0\"\n [matBadgeHidden]=\"!(selectedFieldIds.length)\" matBadgeSize=\"small\" matBadgeColor=\"primary\"\n [matBadgeOverlap]=\"false\" (click)=\"addSelect.open()\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n\n <mat-select #addSelect multiple panelClass=\"praxis-add-select-panel\" panelWidth=\"min(340px, calc(100vw - 24px))\" [value]=\"selectedFieldIds\"\n class=\"cluster-select cluster-select--hidden\"\n [aria-label]=\"getAddAriaLabel()\" (openedChange)=\"onAddOpened($event)\"\n (selectionChange)=\"onAddSelectionChange(addSelect.value)\">\n <mat-option disabled class=\"add-search\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ i18nLabels.filtersSearch || i18nLabels.searchPlaceholder }}</mat-label>\n <input matInput (input)=\"onAddQuery(($any($event.target)).value)\" />\n </mat-form-field>\n </mat-option>\n <mat-option class=\"add-select-all\" (click)=\"toggleSelectAll()\"\n [class.partial]=\"isSomeSelected() && !isAllSelected()\">\n {{ i18nLabels.selectAll || 'Selecionar todos' }}<span class=\"select-all-partial\" *ngIf=\"isSomeSelected() && !isAllSelected()\">\n {{ i18nLabels.selectAllPartial || '(parcial)' }}</span>\n </mat-option>\n <mat-option *ngFor=\"let it of addItems; trackBy: trackById\" [value]=\"it.id\">\n {{ it.label }}\n </mat-option>\n </mat-select>\n\n <button mat-icon-button class=\"cluster-btn separator-before\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\" (click)=\"openSettings()\" *ngIf=\"showFilterSettings\" [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"getSettingsTooltip()\"\n matTooltipPosition=\"below\" [attr.aria-label]=\"getSettingsAriaLabel()\">\n <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n </div>\n\n <div class=\"action-cluster action-cluster--query\">\n <button\n mat-icon-button\n class=\"cluster-btn\"\n [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\"\n (click)=\"onClear()\"\n [attr.aria-label]=\"i18nLabels.clear\"\n [matTooltip]=\"i18nLabels.clear\"\n matTooltipPosition=\"below\"\n >\n <mat-icon [praxisIcon]=\"'cleaning_services'\"></mat-icon>\n </button>\n\n <button\n mat-icon-button\n class=\"cluster-btn\"\n [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"submit\"\n [attr.aria-label]=\"i18nLabels.apply\"\n [matTooltip]=\"i18nLabels.apply\"\n matTooltipPosition=\"below\"\n >\n <mat-icon [praxisIcon]=\"'search'\"></mat-icon>\n </button>\n </div>\n\n <span class=\"sr-only\" aria-live=\"polite\">{{ getAddAriaLabel() }}</span>\n </div>\n\n <div class=\"compact-fields\" *ngIf=\"compactSelectedMetas.length || compactAlwaysVisibleMetas.length\">\n <ng-container *ngIf=\"compactSelectedMetas.length\" dynamicFieldLoader [fields]=\"compactSelectedMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onSelectedComponents($event)\"></ng-container>\n <ng-container *ngIf=\"compactAlwaysVisibleMetas.length\" dynamicFieldLoader [fields]=\"compactAlwaysVisibleMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onAlwaysComponents($event)\"></ng-container>\n </div>\n\n <div class=\"fields-grid\" *ngIf=\"gridSelectedMetas.length || gridAlwaysVisibleMetas.length\">\n <ng-container *ngIf=\"gridSelectedMetas.length\" dynamicFieldLoader [fields]=\"gridSelectedMetas\" [formGroup]=\"alwaysForm\"\n (componentsCreated)=\"onSelectedComponents($event)\"></ng-container>\n <ng-container *ngIf=\"gridAlwaysVisibleMetas.length\" dynamicFieldLoader [fields]=\"gridAlwaysVisibleMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onAlwaysComponents($event)\"></ng-container>\n </div>\n\n <span class=\"sr-only\" aria-live=\"polite\">\n {{ activeFiltersCount ? (activeFiltersCount + ' filtros ativos') : '' }}\n </span>\n <button type=\"submit\" class=\"hidden-submit\" aria-hidden=\"true\" tabindex=\"-1\"></button>\n</form>\n\n<div class=\"praxis-filter-tags\" *ngIf=\"displayedTags.length\" [class.outlined]=\"tagVariant==='outlined'\">\n <mat-chip-set [attr.aria-label]=\"i18nLabels.shortcutsLabel || 'Atalhos'\">\n <mat-chip *ngFor=\"let tag of displayedTags\" [class.active]=\"isActiveTag(tag)\"\n [color]=\"tagVariant === 'outlined' ? null : (isActiveTag(tag) ? 'accent' : (tagColor === 'basic' ? null : tagColor))\"\n [highlighted]=\"tagVariant === 'filled' && tagColor !== 'basic'\" (click)=\"applyTag(tag)\"\n (keydown.enter)=\"applyTag(tag)\" (keydown.space)=\"applyTag(tag)\" tabindex=\"0\" role=\"button\"\n [attr.aria-pressed]=\"isActiveTag(tag)\">\n <ng-container *ngIf=\"editingTagId !== tag.id; else editChip\">\n <span class=\"chip-leading\" *ngIf=\"isActiveTag(tag)\">\n <mat-icon class=\"leading-check\">check</mat-icon>\n </span>\n <span class=\"chip-label\">{{ tag.label }}</span>\n <span class=\"chip-trailing\" *ngIf=\"isUserTag(tag); else roTag\">\n <button mat-icon-button [color]=\"tagButtonColor === 'basic' ? null : tagButtonColor\"\n [matMenuTriggerFor]=\"tagMenu\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getTagActionsAriaLabel(tag)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #tagMenu=\"matMenu\" xPosition=\"before\">\n <button mat-menu-item (click)=\"startEditTag(tag, $event)\">\n <mat-icon>edit</mat-icon>\n <span>{{ i18nLabels.renameShortcut }}</span>\n </button>\n <button mat-menu-item (click)=\"deleteTag(tag)\">\n <mat-icon>delete</mat-icon>\n <span>{{ i18nLabels.removeShortcut }}</span>\n </button>\n </mat-menu>\n </span>\n <ng-template #roTag>\n <span class=\"chip-readonly\" [matTooltip]=\"i18nLabels.readonlyShortcut\">\n <mat-icon>lock</mat-icon>\n </span>\n </ng-template>\n </ng-container>\n <ng-template #editChip>\n <input matInput class=\"chip-editor\" [formControl]=\"editingTagLabel\" autofocus\n [matTooltip]=\"'Enter para salvar, Esc para cancelar'\" matTooltipPosition=\"below\"\n (keydown.enter)=\"commitEditTag(tag, $event)\" (keydown.escape)=\"cancelEditTag($event)\"\n (blur)=\"commitEditTag(tag, $event)\" (click)=\"$event.stopPropagation()\" />\n </ng-template>\n </mat-chip>\n </mat-chip-set>\n</div>\n", styles: ["@charset \"UTF-8\";:root{--pfx-filter-h: 38px;--pfx-filter-align-offset: 2px;--pfx-gap-x: 12px;--pfx-gap-y: 8px;--pfx-always-max-desktop: 380px;--pfx-slider-span-desktop: 2;--pfx-advanced-pad-x: 24px;--pfx-field-min: 280px;--pfx-overlay-margin-y: 16px;--pfx-overlay-margin-x: 16px}:host-context(.theme-light){--pfx-surface-border: var(--md-sys-color-outline)}:host{--border-color: var(--md-sys-color-outline-variant);--border-color-hover: var(--md-sys-color-outline);--pfx-overlay-surface: var(--md-sys-color-surface-container);--pfx-overlay-surface-elev: var(--md-sys-color-surface-container-high);--pfx-overlay-surface-variant: var(--md-sys-color-surface-variant);--pfx-overlay-on-surface: var(--md-sys-color-on-surface);--pfx-overlay-on-surface-variant: var(--md-sys-color-on-surface-variant);display:block;width:100%;min-width:0;flex:1 1 auto}.schema-error-banner{display:flex;align-items:center;gap:8px;margin:0 0 8px;padding:8px 10px;border-radius:10px;border:1px solid color-mix(in srgb,var(--md-sys-color-error) 50%,transparent);background:color-mix(in srgb,var(--md-sys-color-error-container) 85%,transparent);color:var(--md-sys-color-on-error-container)}.schema-error-message{min-width:0;flex:1 1 auto;font-size:.8125rem}:host ::ng-deep .schema-error-retry.mat-mdc-outlined-button{--mdc-outlined-button-outline-color: color-mix( in srgb, var(--md-sys-color-error) 55%, var(--md-sys-color-outline) )}.praxis-filter-bar{display:grid;width:100%;grid-template-columns:minmax(0,1fr) auto;column-gap:6px;row-gap:6px;align-items:start}.inline-actions .actions-anchor{width:0;height:0;overflow:hidden}.inline-actions{grid-column:2;grid-row:1;flex:0 0 auto;display:flex;gap:6px;justify-self:end;align-self:start;width:fit-content;white-space:nowrap;height:var(--pfx-filter-h);align-items:center;padding:0 2px}.action-cluster{flex:0 0 auto;display:inline-flex;align-items:center;gap:2px;min-height:36px;padding:2px;border-radius:999px;border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-highest)}.action-cluster--manage{position:relative;border-color:color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-high)}:host ::ng-deep .action-cluster .mat-mdc-icon-button,:host ::ng-deep .action-cluster .cluster-btn.mat-mdc-icon-button{width:32px;height:32px;padding:0;--mat-icon-button-state-layer-size: 32px}.inline-actions.actions-outlined button.mat-mdc-icon-button{border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));border-radius:50%}.inline-actions.actions-outlined .action-cluster button.mat-mdc-icon-button{border-color:transparent}.separator-before{position:relative;margin-left:10px}.separator-before:before{content:\"\";position:absolute;left:-7px;top:50%;width:1px;height:18px;transform:translateY(-50%);background:color-mix(in srgb,var(--md-sys-color-outline) 72%,transparent)}.inline-actions mat-icon{width:20px;height:20px;font-size:20px}.fields-grid{grid-column:1;grid-row:1;display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--pfx-always-min, 220px),1fr));grid-auto-flow:row dense;gap:6px}.compact-fields{grid-column:1;grid-row:1;display:flex;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:center;gap:6px;min-width:0}:host ::ng-deep .compact-fields .pfx-field-shell,:host ::ng-deep .compact-fields .pfx-field-shell-wrapper,:host ::ng-deep .compact-fields .pfx-field-shell-host{--pfx-field-shell-width: fit-content;--pfx-field-shell-field-width: auto;width:fit-content!important;max-width:100%;min-width:0;flex:0 1 auto!important}:host ::ng-deep .compact-fields>.pfx-field-shell,:host ::ng-deep .compact-fields>praxis-field-shell{flex:0 1 auto!important;width:fit-content!important;max-width:100%;min-width:0}:host ::ng-deep .compact-fields .pfx-field-shell .mat-mdc-form-field{width:auto!important;max-width:100%;margin-bottom:0}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=inlineDateRange] .mat-mdc-form-field{width:var(--pdx-inline-date-range-shell-width, auto)!important;max-width:100%!important}.praxis-filter-bar.has-compact .compact-fields{grid-column:1;grid-row:1}.praxis-filter-bar.has-compact .fields-grid{grid-column:1/-1;grid-row:2}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider] mat-slider,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] mat-slider,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] mat-slider{width:100%;display:block}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider] .pdx-slider-wrapper,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-slider-wrapper,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-slider-wrapper{padding-top:2px}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-range-slider-container,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-range-slider-container{padding:2px 0 0}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-slider-label,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-slider-label{margin-bottom:4px;line-height:1.15}:host ::ng-deep .fields-grid .mat-mdc-text-field-wrapper.mdc-text-field--outlined{min-height:var(--pfx-filter-h);align-items:center}:host ::ng-deep .fields-grid .mat-mdc-form-field-infix{min-height:var(--pfx-filter-h)}:host ::ng-deep .fields-grid .mat-mdc-select-trigger{height:var(--pfx-filter-h);align-items:center}:host ::ng-deep .fields-grid .mat-mdc-form-field{width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSearchableSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSearchableSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineMultiSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineMultiSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineInput]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineInput] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineToggle]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineToggle] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineRange]{justify-self:start}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=inlineRange]{max-width:min(340px,100%)}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDate]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDate] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDateRange]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDateRange] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .mat-mdc-form-field-subscript-wrapper{min-height:0;margin-top:0}:host ::ng-deep .fields-grid .mat-mdc-form-field{margin-bottom:0}.praxis-filter-tags.outlined .mat-mdc-chip{background:transparent!important;--mat-chip-outline-width: 1px;--mat-chip-outline-color: var(--md-sys-color-outline-variant);box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)}.praxis-filter-tags.outlined mat-chip.active .mat-mdc-chip,.praxis-filter-tags.outlined .mat-mdc-chip.mat-mdc-chip-highlighted{--mat-chip-outline-color: var(--md-sys-color-primary) !important;box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)!important}.praxis-filter-tags .mat-mdc-standard-chip .mdc-evolution-chip__text-label{display:flex;align-items:center;justify-content:center;gap:4px;line-height:1.2;font-size:.875rem}.praxis-filter-tags .chip-leading,.praxis-filter-tags .chip-trailing{display:inline-flex;align-items:center}.praxis-filter-tags .leading-check{width:18px;height:18px;font-size:18px;line-height:1}.praxis-filter-tags .chip-label{position:relative;top:-6px}.praxis-filter-tags .chip-trailing .mat-mdc-icon-button{width:28px;height:28px;padding:0;display:flex;align-items:center;justify-content:center;line-height:28px}.praxis-filter-tags .mat-mdc-standard-chip{--mat-chip-container-height: 36px}.praxis-filter-advanced{display:flex;flex-direction:column;min-width:400px;max-width:90vw;min-height:260px;max-height:min(80vh,720px);margin:var(--pfx-overlay-margin-y) var(--pfx-overlay-margin-x);background-color:var(--pfx-overlay-surface)!important;background:var(--pfx-overlay-surface)!important;color:var(--pfx-overlay-on-surface);border:1px solid var(--border-color);border-radius:12px;box-shadow:var(--md-sys-elevation-level3)}.advanced-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px var(--pfx-advanced-pad-x) 10px;border-bottom:1px solid var(--border-color);background:var(--pfx-overlay-surface)}.advanced-title-block{display:flex;flex-direction:column;gap:2px}.advanced-title{font-size:1rem;font-weight:600;color:var(--pfx-overlay-on-surface)}.advanced-subtitle{font-size:.85rem;color:var(--pfx-overlay-on-surface-variant)}.advanced-close{align-self:flex-start}.praxis-filter-overlay.mobile .praxis-filter-advanced{height:100vh;max-height:100vh;margin:0;border-radius:0}:host ::ng-deep .praxis-overlay-backdrop{background:var(--md-sys-color-scrim);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}:host ::ng-deep .praxis-filter-overlay.frosted .praxis-filter-advanced{background:var(--pfx-overlay-surface-variant)!important;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-color:var(--border-color)}:host ::ng-deep .praxis-filter-overlay.frosted .advanced-header,:host ::ng-deep .praxis-filter-overlay.frosted .advanced-actions{background:var(--pfx-overlay-surface-variant)!important}.advanced-body{padding:12px var(--pfx-advanced-pad-x) 72px;overflow:auto;flex:1 1 auto;overscroll-behavior:contain}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-row{display:grid!important;grid-template-columns:repeat(auto-fit,minmax(var(--pfx-field-min),1fr));gap:var(--pfx-gap-y) var(--pfx-gap-x)}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-column{min-width:0}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-column .mat-mdc-form-field{width:100%}.advanced-actions{position:sticky;bottom:0;z-index:2;display:flex;justify-content:flex-end;gap:8px;padding:var(--pfx-gap-y) var(--pfx-advanced-pad-x);background-color:var(--pfx-overlay-surface)!important;background:var(--pfx-overlay-surface)!important;border-top:1px solid var(--border-color);box-shadow:0 -1px 0 var(--md-sys-color-outline-variant)}.advanced-actions .mat-mdc-button-base{height:40px}.advanced-actions .mat-mdc-raised-button.mat-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}:host ::ng-deep .praxis-filter-advanced .mat-mdc-text-field-wrapper.mdc-text-field--outlined{--mdc-outlined-text-field-outline-color: var(--border-color);--mdc-outlined-text-field-hover-outline-color: var(--border-color-hover);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-label-text-color: var(--pfx-overlay-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--pfx-overlay-on-surface);--mdc-outlined-text-field-container-color: var(--pfx-overlay-surface)}:host ::ng-deep .praxis-filter-advanced .mat-mdc-select-trigger,:host ::ng-deep .praxis-filter-advanced .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .praxis-filter-advanced .mat-mdc-form-field-infix{color:var(--pfx-overlay-on-surface)}@media(min-width:600px){.fields-grid{gap:6px 8px}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-row{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:960px){.fields-grid{gap:6px 10px}}@media(min-width:1200px){.fields-grid{grid-template-columns:repeat(auto-fit,minmax(var(--pfx-always-min, 220px),var(--pfx-always-max-desktop, 380px)));justify-content:start;align-content:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeslider]{grid-column:span var(--pfx-slider-span-desktop, 2)}}.inline-toggles{display:flex;align-items:center;gap:8px;margin:0 4px 0 6px}:host ::ng-deep .inline-actions .mat-mdc-slide-toggle{height:var(--pfx-filter-h);display:flex;align-items:center}:host ::ng-deep .inline-actions .mat-mdc-slide-toggle .mdc-form-field{align-items:center}::ng-deep .praxis-filter-overlay .praxis-filter-advanced .praxis-filter-form .filter-row{display:grid!important;gap:var(--pfx-gap-y, 1px) var(--pfx-gap-x, 6px)}@media(min-width:600px){::ng-deep .praxis-filter-overlay .praxis-filter-advanced .praxis-filter-form .filter-row{grid-template-columns:repeat(2,minmax(0,1fr))}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important}.hidden-submit{position:absolute!important;width:0!important;height:0!important;padding:0!important;margin:0!important;border:0!important;opacity:0!important;pointer-events:none!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important;overflow:hidden!important}:host ::ng-deep .inline-actions [matBadge] .mat-badge-content{top:-6px;right:-6px;min-width:16px;height:16px;padding:0 4px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;font-size:10px;font-weight:700;line-height:16px;letter-spacing:0;text-indent:0;color:var(--md-sys-color-on-primary, #fff)}:host ::ng-deep .inline-actions [matBadge][matbadgecolor=warn] .mat-badge-content,:host ::ng-deep .inline-actions [matBadge].mat-badge-warn .mat-badge-content{color:var(--md-sys-color-on-error, #fff)}.praxis-filter-bar :where(.mat-mdc-slide-toggle .mdc-switch__icons){display:none!important}.praxis-filter-bar{--mdc-switch-unselected-icon-size: 0px;--mdc-switch-selected-icon-size: 0px;--pfx-always-min: 220px}.praxis-filter-card{display:flex;flex-direction:column;gap:6px;padding:8px 12px;border-radius:12px;border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface)}:host ::ng-deep .praxis-add-select-panel{width:min(340px,100vw - 24px)!important;min-width:min(280px,100vw - 24px)!important;max-width:calc(100vw - 24px)!important;max-height:min(56vh,420px);margin-top:8px;padding:6px 0;border-radius:14px;overflow:auto;background:var(--md-sys-color-surface-container-highest);border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));box-shadow:var(--md-sys-elevation-level3)}:host ::ng-deep .cdk-overlay-pane:has(.praxis-add-select-panel){width:auto!important;min-width:0!important;max-width:calc(100vw - 24px)!important}:host ::ng-deep .praxis-add-select-panel .mat-mdc-option{min-height:36px}:host ::ng-deep .praxis-add-select-panel .add-search{position:sticky;top:0;background:var(--md-sys-color-surface-container-highest);z-index:1;padding:0 8px 6px;cursor:default}:host ::ng-deep .praxis-add-select-panel .add-search .mat-mdc-form-field{width:100%}:host ::ng-deep .praxis-add-select-panel .add-search .mat-mdc-form-field-subscript-wrapper{display:none}.inline-actions .add-trigger{display:inline-flex;align-items:center;gap:6px;height:32px;width:100%;max-width:100%;min-width:0;padding:0 10px;border-radius:0;border:0;background:transparent;overflow:visible}.inline-actions .add-trigger--icon{justify-content:center;width:32px;min-width:32px;padding:0}:host ::ng-deep .inline-actions .add-trigger mat-icon{width:18px;height:18px;font-size:18px;flex:0 0 auto}.inline-actions .add-trigger-label{display:inline-block;flex:1 1 auto;min-width:0;max-width:100%;text-align:left;direction:ltr;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.82rem;line-height:1}:host ::ng-deep .action-cluster--manage .mat-mdc-select{flex:0 0 auto;width:180px;min-width:0;max-width:180px}:host ::ng-deep .action-cluster--manage .cluster-select--hidden.mat-mdc-select{position:absolute;width:1px;min-width:1px;max-width:1px;height:1px;opacity:0;pointer-events:none;overflow:hidden}:host ::ng-deep .action-cluster--manage .mat-mdc-select-trigger{min-height:32px;padding:0}:host ::ng-deep .action-cluster--manage .mat-mdc-select-value,:host ::ng-deep .action-cluster--manage .mat-mdc-select-value-text,:host ::ng-deep .action-cluster--manage .mat-mdc-select-min-line{width:auto;min-width:0;max-width:100%;display:inline-flex;align-items:center;justify-content:flex-start;overflow:visible}.praxis-filter-card .summary-header{display:flex;align-items:center;gap:10px}.praxis-filter-card .summary-avatar{width:32px;height:32px;border-radius:50%;object-fit:cover}.praxis-filter-card .summary-title{font-weight:600}.praxis-filter-card .summary-subtitle{opacity:.8;font-size:.875rem}.praxis-filter-card .summary-badges{display:flex;flex-wrap:wrap;gap:6px}.praxis-filter-card .summary-badges span{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:var(--md-sys-color-primary-container);border:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-primary-container);font-size:12px}.praxis-filter-card .card-actions{display:flex;gap:8px}:host ::ng-deep .inline-actions .mat-mdc-select-arrow-wrapper{display:none}.inline-actions .add-filter-btn{height:36px;border-radius:18px;padding:0 16px 0 12px}.inline-actions .add-filter-btn mat-icon{margin-right:8px;margin-left:-4px}:host ::ng-deep .praxis-add-select-panel .add-select-all.partial .select-all-partial{opacity:.7;font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i15.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i15.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i15$2.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i15$4.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i17.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i17.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i17.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i11$1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: A11yModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }] });
33593
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisFilter, deps: [{ token: i1.GenericCrudService }, { token: ASYNC_CONFIG_STORAGE }, { token: i0.DestroyRef }, { token: FilterConfigService }, { token: i3$1.SettingsPanelService }, { token: i2$2.MatSnackBar }, { token: i1$2.MatDialog }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i1.DynamicFormService }, { token: i1.SchemaNormalizerService }, { token: i1.ComponentKeyService }, { token: i6$2.ActivatedRoute, optional: true }, { token: i1.LoggerService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
33594
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisFilter, isStandalone: true, selector: "praxis-filter", inputs: { resourcePath: "resourcePath", fieldMetadata: "fieldMetadata", filterId: "filterId", formId: "formId", componentInstanceId: "componentInstanceId", mode: "mode", notifyIfOutdated: "notifyIfOutdated", snoozeMs: "snoozeMs", autoOpenSettingsOnOutdated: "autoOpenSettingsOnOutdated", enableCustomization: "enableCustomization", value: "value", alwaysVisibleFields: "alwaysVisibleFields", alwaysVisibleFieldMetadataOverrides: "alwaysVisibleFieldMetadataOverrides", selectedFieldIds: "selectedFieldIds", tags: "tags", allowSaveTags: "allowSaveTags", persistenceKey: "persistenceKey", disablePersistence: "disablePersistence", i18n: "i18n", changeDebounceMs: "changeDebounceMs", showFilterSettings: "showFilterSettings", confirmTagDelete: "confirmTagDelete", placeBooleansInActions: "placeBooleansInActions", showToggleLabels: "showToggleLabels", useInlineSelectVariant: "useInlineSelectVariant", useInlineSearchableSelectVariant: "useInlineSearchableSelectVariant", useInlineMultiSelectVariant: "useInlineMultiSelectVariant", useInlineInputVariant: "useInlineInputVariant", useInlineToggleVariant: "useInlineToggleVariant", useInlineRangeVariant: "useInlineRangeVariant", useInlineDateVariant: "useInlineDateVariant", useInlineDateRangeVariant: "useInlineDateRangeVariant", useInlineTimeVariant: "useInlineTimeVariant", useInlineTimeRangeVariant: "useInlineTimeRangeVariant", useInlineTreeSelectVariant: "useInlineTreeSelectVariant", alwaysMinWidth: "alwaysMinWidth", alwaysColsMd: "alwaysColsMd", alwaysColsLg: "alwaysColsLg", tagColor: "tagColor", tagVariant: "tagVariant", tagButtonColor: "tagButtonColor", actionsButtonColor: "actionsButtonColor", actionsVariant: "actionsVariant", overlayVariant: "overlayVariant", overlayBackdrop: "overlayBackdrop", advancedOpenMode: "advancedOpenMode", advancedClearButtonsEnabled: "advancedClearButtonsEnabled" }, outputs: { submit: "submit", change: "change", clear: "clear", modeChange: "modeChange", requestSearch: "requestSearch", tagsChange: "tagsChange", selectedFieldIdsChange: "selectedFieldIdsChange", metaChanged: "metaChanged", schemaStatusChange: "schemaStatusChange" }, host: { listeners: { "window:resize": "onWindowResize()", "document:keydown": "onGlobalKeydown($event)" }, properties: { "style.--pfx-always-min": "alwaysMinWidth + \"px\"", "style.--pfx-always-cols-md": "alwaysColsMd", "style.--pfx-always-cols-lg": "alwaysColsLg" } }, viewQueries: [{ propertyName: "anchorRef", first: true, predicate: ["anchorRef"], descendants: true, read: CdkOverlayOrigin }, { propertyName: "addAnchor", first: true, predicate: ["addAnchor"], descendants: true, read: CdkOverlayOrigin }, { propertyName: "advancedButton", first: true, predicate: ["advancedButton"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<mat-progress-bar *ngIf=\"saving\" mode=\"indeterminate\"></mat-progress-bar>\n<div class=\"schema-error-banner\" *ngIf=\"schemaError\" role=\"alert\" aria-live=\"polite\">\n <mat-icon [praxisIcon]=\"'error_outline'\" aria-hidden=\"true\"></mat-icon>\n <span class=\"schema-error-message\">{{ i18nLabels.errorLoadingFilters || 'Erro ao carregar filtros.' }}</span>\n <button\n mat-stroked-button\n class=\"schema-error-retry\"\n type=\"button\"\n (click)=\"retrySchemaLoad()\"\n [attr.aria-label]=\"i18nLabels.retry || 'Tentar novamente'\"\n >\n {{ i18nLabels.retry || 'Tentar novamente' }}\n </button>\n</div>\n\n<form class=\"praxis-filter-bar\" [class.is-open]=\"advancedOpen\"\n [class.has-compact]=\"compactSelectedMetas.length || compactAlwaysVisibleMetas.length\"\n (click)=\"onFieldInteraction($event)\"\n (focusin)=\"onFieldInteraction($event)\"\n (submit)=\"onSubmit(); $event.preventDefault()\">\n <div class=\"inline-actions\" [class.actions-outlined]=\"actionsVariant==='outlined'\">\n <div class=\"actions-anchor\" #anchorRef=\"cdkOverlayOrigin\" cdkOverlayOrigin></div>\n <div class=\"inline-toggles\" *ngIf=\"toggleMetas.length\">\n <ng-container dynamicFieldLoader [fields]=\"toggleMetas\" [formGroup]=\"alwaysForm\"\n (componentsCreated)=\"onToggleComponents($event)\"></ng-container>\n </div>\n\n <div class=\"action-cluster action-cluster--manage\">\n <button #advancedButton mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\" type=\"button\"\n [matBadge]=\"activeFiltersCount\" [matBadgeHidden]=\"!activeFiltersCount\" matBadgeSize=\"small\"\n matBadgeColor=\"primary\" [matBadgeOverlap]=\"false\" (click)=\"toggleAdvanced()\"\n [attr.aria-label]=\"getAdvancedAriaLabel()\" [attr.aria-expanded]=\"advancedOpen\"\n [matTooltip]=\"getAdvancedTooltip()\"\n matTooltipPosition=\"below\"\n [attr.aria-controls]=\"advancedPanelId\">\n <mat-icon [praxisIcon]=\"'filter_list'\"></mat-icon>\n </button>\n\n <button mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\" [attr.aria-label]=\"getAddAriaLabel()\" [matTooltip]=\"getAddTooltip()\"\n matTooltipPosition=\"below\" [matBadge]=\"selectedFieldIds.length || 0\"\n [matBadgeHidden]=\"!(selectedFieldIds.length)\" matBadgeSize=\"small\" matBadgeColor=\"primary\"\n [matBadgeOverlap]=\"false\" (click)=\"addSelect.open()\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n\n <mat-select #addSelect multiple panelClass=\"praxis-add-select-panel\" panelWidth=\"min(340px, calc(100vw - 24px))\" [value]=\"selectedFieldIds\"\n class=\"cluster-select cluster-select--hidden\"\n [aria-label]=\"getAddAriaLabel()\" (openedChange)=\"onAddOpened($event)\"\n (selectionChange)=\"onAddSelectionChange(addSelect.value)\">\n <mat-option disabled class=\"add-search\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ i18nLabels.filtersSearch || i18nLabels.searchPlaceholder }}</mat-label>\n <input matInput (input)=\"onAddQuery(($any($event.target)).value)\" />\n </mat-form-field>\n </mat-option>\n <mat-option class=\"add-select-all\" (click)=\"toggleSelectAll()\"\n [class.partial]=\"isSomeSelected() && !isAllSelected()\">\n {{ i18nLabels.selectAll || 'Selecionar todos' }}<span class=\"select-all-partial\" *ngIf=\"isSomeSelected() && !isAllSelected()\">\n {{ i18nLabels.selectAllPartial || '(parcial)' }}</span>\n </mat-option>\n <mat-option *ngFor=\"let it of addItems; trackBy: trackById\" [value]=\"it.id\">\n {{ it.label }}\n </mat-option>\n </mat-select>\n\n <button mat-icon-button class=\"cluster-btn separator-before\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\" (click)=\"openSettings()\" *ngIf=\"showFilterSettings\" [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"getSettingsTooltip()\"\n matTooltipPosition=\"below\" [attr.aria-label]=\"getSettingsAriaLabel()\">\n <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n\n <button\n *ngIf=\"isFieldAuthoringEnabled() && activeEditableFieldMeta\"\n mat-icon-button\n class=\"cluster-btn\"\n [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\"\n data-testid=\"filter-field-settings-trigger\"\n [attr.aria-label]=\"activeEditableFieldLabel\"\n (click)=\"openSelectedFieldEditor()\"\n >\n <mat-icon [praxisIcon]=\"'tune'\"></mat-icon>\n </button>\n </div>\n\n <div class=\"action-cluster action-cluster--query\">\n <button\n mat-icon-button\n class=\"cluster-btn\"\n [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\"\n (click)=\"onClear()\"\n [attr.aria-label]=\"i18nLabels.clear\"\n [matTooltip]=\"i18nLabels.clear\"\n matTooltipPosition=\"below\"\n >\n <mat-icon [praxisIcon]=\"'cleaning_services'\"></mat-icon>\n </button>\n\n <button\n mat-icon-button\n class=\"cluster-btn\"\n [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"submit\"\n [attr.aria-label]=\"i18nLabels.apply\"\n [matTooltip]=\"i18nLabels.apply\"\n matTooltipPosition=\"below\"\n >\n <mat-icon [praxisIcon]=\"'search'\"></mat-icon>\n </button>\n </div>\n\n <span class=\"sr-only\" aria-live=\"polite\">{{ getAddAriaLabel() }}</span>\n </div>\n\n <div class=\"compact-fields\" *ngIf=\"compactSelectedMetas.length || compactAlwaysVisibleMetas.length\">\n <ng-container *ngIf=\"compactSelectedMetas.length\" dynamicFieldLoader [fields]=\"compactSelectedMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onSelectedComponents($event)\"></ng-container>\n <ng-container *ngIf=\"compactAlwaysVisibleMetas.length\" dynamicFieldLoader [fields]=\"compactAlwaysVisibleMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onAlwaysComponents($event)\"></ng-container>\n </div>\n\n <div class=\"fields-grid\" *ngIf=\"gridSelectedMetas.length || gridAlwaysVisibleMetas.length\">\n <ng-container *ngIf=\"gridSelectedMetas.length\" dynamicFieldLoader [fields]=\"gridSelectedMetas\" [formGroup]=\"alwaysForm\"\n (componentsCreated)=\"onSelectedComponents($event)\"></ng-container>\n <ng-container *ngIf=\"gridAlwaysVisibleMetas.length\" dynamicFieldLoader [fields]=\"gridAlwaysVisibleMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onAlwaysComponents($event)\"></ng-container>\n </div>\n\n <span class=\"sr-only\" aria-live=\"polite\">\n {{ activeFiltersCount ? (activeFiltersCount + ' filtros ativos') : '' }}\n </span>\n <button type=\"submit\" class=\"hidden-submit\" aria-hidden=\"true\" tabindex=\"-1\"></button>\n</form>\n\n<div class=\"praxis-filter-tags\" *ngIf=\"displayedTags.length\" [class.outlined]=\"tagVariant==='outlined'\">\n <mat-chip-set [attr.aria-label]=\"i18nLabels.shortcutsLabel || 'Atalhos'\">\n <mat-chip *ngFor=\"let tag of displayedTags\" [class.active]=\"isActiveTag(tag)\"\n [color]=\"tagVariant === 'outlined' ? null : (isActiveTag(tag) ? 'accent' : (tagColor === 'basic' ? null : tagColor))\"\n [highlighted]=\"tagVariant === 'filled' && tagColor !== 'basic'\" (click)=\"applyTag(tag)\"\n (keydown.enter)=\"applyTag(tag)\" (keydown.space)=\"applyTag(tag)\" tabindex=\"0\" role=\"button\"\n [attr.aria-pressed]=\"isActiveTag(tag)\">\n <ng-container *ngIf=\"editingTagId !== tag.id; else editChip\">\n <span class=\"chip-leading\" *ngIf=\"isActiveTag(tag)\">\n <mat-icon class=\"leading-check\">check</mat-icon>\n </span>\n <span class=\"chip-label\">{{ tag.label }}</span>\n <span class=\"chip-trailing\" *ngIf=\"isUserTag(tag); else roTag\">\n <button mat-icon-button [color]=\"tagButtonColor === 'basic' ? null : tagButtonColor\"\n [matMenuTriggerFor]=\"tagMenu\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getTagActionsAriaLabel(tag)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #tagMenu=\"matMenu\" xPosition=\"before\">\n <button mat-menu-item (click)=\"startEditTag(tag, $event)\">\n <mat-icon>edit</mat-icon>\n <span>{{ i18nLabels.renameShortcut }}</span>\n </button>\n <button mat-menu-item (click)=\"deleteTag(tag)\">\n <mat-icon>delete</mat-icon>\n <span>{{ i18nLabels.removeShortcut }}</span>\n </button>\n </mat-menu>\n </span>\n <ng-template #roTag>\n <span class=\"chip-readonly\" [matTooltip]=\"i18nLabels.readonlyShortcut\">\n <mat-icon>lock</mat-icon>\n </span>\n </ng-template>\n </ng-container>\n <ng-template #editChip>\n <input matInput class=\"chip-editor\" [formControl]=\"editingTagLabel\" autofocus\n [matTooltip]=\"'Enter para salvar, Esc para cancelar'\" matTooltipPosition=\"below\"\n (keydown.enter)=\"commitEditTag(tag, $event)\" (keydown.escape)=\"cancelEditTag($event)\"\n (blur)=\"commitEditTag(tag, $event)\" (click)=\"$event.stopPropagation()\" />\n </ng-template>\n </mat-chip>\n </mat-chip-set>\n</div>\n", styles: ["@charset \"UTF-8\";:root{--pfx-filter-h: 38px;--pfx-filter-align-offset: 2px;--pfx-gap-x: 12px;--pfx-gap-y: 8px;--pfx-always-max-desktop: 380px;--pfx-slider-span-desktop: 2;--pfx-advanced-pad-x: 24px;--pfx-field-min: 280px;--pfx-overlay-margin-y: 16px;--pfx-overlay-margin-x: 16px}:host-context(.theme-light){--pfx-surface-border: var(--md-sys-color-outline)}:host{--border-color: var(--md-sys-color-outline-variant);--border-color-hover: var(--md-sys-color-outline);--pfx-overlay-surface: var(--md-sys-color-surface-container);--pfx-overlay-surface-elev: var(--md-sys-color-surface-container-high);--pfx-overlay-surface-variant: var(--md-sys-color-surface-variant);--pfx-overlay-on-surface: var(--md-sys-color-on-surface);--pfx-overlay-on-surface-variant: var(--md-sys-color-on-surface-variant);display:block;width:100%;min-width:0;flex:1 1 auto}.schema-error-banner{display:flex;align-items:center;gap:8px;margin:0 0 8px;padding:8px 10px;border-radius:10px;border:1px solid color-mix(in srgb,var(--md-sys-color-error) 50%,transparent);background:color-mix(in srgb,var(--md-sys-color-error-container) 85%,transparent);color:var(--md-sys-color-on-error-container)}.schema-error-message{min-width:0;flex:1 1 auto;font-size:.8125rem}:host ::ng-deep .schema-error-retry.mat-mdc-outlined-button{--mdc-outlined-button-outline-color: color-mix( in srgb, var(--md-sys-color-error) 55%, var(--md-sys-color-outline) )}.praxis-filter-bar{display:grid;width:100%;grid-template-columns:minmax(0,1fr) auto;column-gap:6px;row-gap:6px;align-items:start}.inline-actions .actions-anchor{width:0;height:0;overflow:hidden}.inline-actions{grid-column:2;grid-row:1;flex:0 0 auto;display:flex;gap:6px;justify-self:end;align-self:start;width:fit-content;white-space:nowrap;height:var(--pfx-filter-h);align-items:center;padding:0 2px}.action-cluster{flex:0 0 auto;display:inline-flex;align-items:center;gap:2px;min-height:36px;padding:2px;border-radius:999px;border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-highest)}.action-cluster--manage{position:relative;border-color:color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-high)}:host ::ng-deep .action-cluster .mat-mdc-icon-button,:host ::ng-deep .action-cluster .cluster-btn.mat-mdc-icon-button{width:32px;height:32px;padding:0;--mat-icon-button-state-layer-size: 32px}.inline-actions.actions-outlined button.mat-mdc-icon-button{border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));border-radius:50%}.inline-actions.actions-outlined .action-cluster button.mat-mdc-icon-button{border-color:transparent}.separator-before{position:relative;margin-left:10px}.separator-before:before{content:\"\";position:absolute;left:-7px;top:50%;width:1px;height:18px;transform:translateY(-50%);background:color-mix(in srgb,var(--md-sys-color-outline) 72%,transparent)}.inline-actions mat-icon{width:20px;height:20px;font-size:20px}.fields-grid{grid-column:1;grid-row:1;display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--pfx-always-min, 220px),1fr));grid-auto-flow:row dense;gap:6px}.compact-fields{grid-column:1;grid-row:1;display:flex;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:center;gap:6px;min-width:0}:host ::ng-deep .compact-fields .pfx-field-shell,:host ::ng-deep .compact-fields .pfx-field-shell-wrapper,:host ::ng-deep .compact-fields .pfx-field-shell-host{--pfx-field-shell-width: fit-content;--pfx-field-shell-field-width: auto;width:fit-content!important;max-width:100%;min-width:0;flex:0 1 auto!important}:host ::ng-deep .compact-fields>.pfx-field-shell,:host ::ng-deep .compact-fields>praxis-field-shell{flex:0 1 auto!important;width:fit-content!important;max-width:100%;min-width:0}:host ::ng-deep .compact-fields .pfx-field-shell .mat-mdc-form-field{width:auto!important;max-width:100%;margin-bottom:0}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=inlineDateRange] .mat-mdc-form-field{width:var(--pdx-inline-date-range-shell-width, auto)!important;max-width:100%!important}.praxis-filter-bar.has-compact .compact-fields{grid-column:1;grid-row:1}.praxis-filter-bar.has-compact .fields-grid{grid-column:1/-1;grid-row:2}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider] mat-slider,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] mat-slider,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] mat-slider{width:100%;display:block}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider] .pdx-slider-wrapper,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-slider-wrapper,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-slider-wrapper{padding-top:2px}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-range-slider-container,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-range-slider-container{padding:2px 0 0}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-slider-label,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-slider-label{margin-bottom:4px;line-height:1.15}:host ::ng-deep .fields-grid .mat-mdc-text-field-wrapper.mdc-text-field--outlined{min-height:var(--pfx-filter-h);align-items:center}:host ::ng-deep .fields-grid .mat-mdc-form-field-infix{min-height:var(--pfx-filter-h)}:host ::ng-deep .fields-grid .mat-mdc-select-trigger{height:var(--pfx-filter-h);align-items:center}:host ::ng-deep .fields-grid .mat-mdc-form-field{width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSearchableSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSearchableSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineMultiSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineMultiSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineInput]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineInput] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineToggle]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineToggle] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineRange]{justify-self:start}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=inlineRange]{max-width:min(340px,100%)}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDate]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDate] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDateRange]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDateRange] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .mat-mdc-form-field-subscript-wrapper{min-height:0;margin-top:0}:host ::ng-deep .fields-grid .mat-mdc-form-field{margin-bottom:0}.praxis-filter-tags.outlined .mat-mdc-chip{background:transparent!important;--mat-chip-outline-width: 1px;--mat-chip-outline-color: var(--md-sys-color-outline-variant);box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)}.praxis-filter-tags.outlined mat-chip.active .mat-mdc-chip,.praxis-filter-tags.outlined .mat-mdc-chip.mat-mdc-chip-highlighted{--mat-chip-outline-color: var(--md-sys-color-primary) !important;box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)!important}.praxis-filter-tags .mat-mdc-standard-chip .mdc-evolution-chip__text-label{display:flex;align-items:center;justify-content:center;gap:4px;line-height:1.2;font-size:.875rem}.praxis-filter-tags .chip-leading,.praxis-filter-tags .chip-trailing{display:inline-flex;align-items:center}.praxis-filter-tags .leading-check{width:18px;height:18px;font-size:18px;line-height:1}.praxis-filter-tags .chip-label{position:relative;top:-6px}.praxis-filter-tags .chip-trailing .mat-mdc-icon-button{width:28px;height:28px;padding:0;display:flex;align-items:center;justify-content:center;line-height:28px}.praxis-filter-tags .mat-mdc-standard-chip{--mat-chip-container-height: 36px}.praxis-filter-advanced{display:flex;flex-direction:column;min-width:400px;max-width:90vw;min-height:260px;max-height:min(80vh,720px);margin:var(--pfx-overlay-margin-y) var(--pfx-overlay-margin-x);background-color:var(--pfx-overlay-surface)!important;background:var(--pfx-overlay-surface)!important;color:var(--pfx-overlay-on-surface);border:1px solid var(--border-color);border-radius:12px;box-shadow:var(--md-sys-elevation-level3)}.advanced-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px var(--pfx-advanced-pad-x) 10px;border-bottom:1px solid var(--border-color);background:var(--pfx-overlay-surface)}.advanced-title-block{display:flex;flex-direction:column;gap:2px}.advanced-title{font-size:1rem;font-weight:600;color:var(--pfx-overlay-on-surface)}.advanced-subtitle{font-size:.85rem;color:var(--pfx-overlay-on-surface-variant)}.advanced-close{align-self:flex-start}.praxis-filter-overlay.mobile .praxis-filter-advanced{height:100vh;max-height:100vh;margin:0;border-radius:0}:host ::ng-deep .praxis-overlay-backdrop{background:var(--md-sys-color-scrim);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}:host ::ng-deep .praxis-filter-overlay.frosted .praxis-filter-advanced{background:var(--pfx-overlay-surface-variant)!important;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-color:var(--border-color)}:host ::ng-deep .praxis-filter-overlay.frosted .advanced-header,:host ::ng-deep .praxis-filter-overlay.frosted .advanced-actions{background:var(--pfx-overlay-surface-variant)!important}.advanced-body{padding:12px var(--pfx-advanced-pad-x) 72px;overflow:auto;flex:1 1 auto;overscroll-behavior:contain}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-row{display:grid!important;grid-template-columns:repeat(auto-fit,minmax(var(--pfx-field-min),1fr));gap:var(--pfx-gap-y) var(--pfx-gap-x)}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-column{min-width:0}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-column .mat-mdc-form-field{width:100%}.advanced-actions{position:sticky;bottom:0;z-index:2;display:flex;justify-content:flex-end;gap:8px;padding:var(--pfx-gap-y) var(--pfx-advanced-pad-x);background-color:var(--pfx-overlay-surface)!important;background:var(--pfx-overlay-surface)!important;border-top:1px solid var(--border-color);box-shadow:0 -1px 0 var(--md-sys-color-outline-variant)}.advanced-actions .mat-mdc-button-base{height:40px}.advanced-actions .mat-mdc-raised-button.mat-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}:host ::ng-deep .praxis-filter-advanced .mat-mdc-text-field-wrapper.mdc-text-field--outlined{--mdc-outlined-text-field-outline-color: var(--border-color);--mdc-outlined-text-field-hover-outline-color: var(--border-color-hover);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-label-text-color: var(--pfx-overlay-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--pfx-overlay-on-surface);--mdc-outlined-text-field-container-color: var(--pfx-overlay-surface)}:host ::ng-deep .praxis-filter-advanced .mat-mdc-select-trigger,:host ::ng-deep .praxis-filter-advanced .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .praxis-filter-advanced .mat-mdc-form-field-infix{color:var(--pfx-overlay-on-surface)}@media(min-width:600px){.fields-grid{gap:6px 8px}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-row{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:960px){.fields-grid{gap:6px 10px}}@media(min-width:1200px){.fields-grid{grid-template-columns:repeat(auto-fit,minmax(var(--pfx-always-min, 220px),var(--pfx-always-max-desktop, 380px)));justify-content:start;align-content:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeslider]{grid-column:span var(--pfx-slider-span-desktop, 2)}}.inline-toggles{display:flex;align-items:center;gap:8px;margin:0 4px 0 6px}:host ::ng-deep .inline-actions .mat-mdc-slide-toggle{height:var(--pfx-filter-h);display:flex;align-items:center}:host ::ng-deep .inline-actions .mat-mdc-slide-toggle .mdc-form-field{align-items:center}::ng-deep .praxis-filter-overlay .praxis-filter-advanced .praxis-filter-form .filter-row{display:grid!important;gap:var(--pfx-gap-y, 1px) var(--pfx-gap-x, 6px)}@media(min-width:600px){::ng-deep .praxis-filter-overlay .praxis-filter-advanced .praxis-filter-form .filter-row{grid-template-columns:repeat(2,minmax(0,1fr))}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important}.hidden-submit{position:absolute!important;width:0!important;height:0!important;padding:0!important;margin:0!important;border:0!important;opacity:0!important;pointer-events:none!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important;overflow:hidden!important}:host ::ng-deep .inline-actions [matBadge] .mat-badge-content{top:-6px;right:-6px;min-width:16px;height:16px;padding:0 4px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;font-size:10px;font-weight:700;line-height:16px;letter-spacing:0;text-indent:0;color:var(--md-sys-color-on-primary, #fff)}:host ::ng-deep .inline-actions [matBadge][matbadgecolor=warn] .mat-badge-content,:host ::ng-deep .inline-actions [matBadge].mat-badge-warn .mat-badge-content{color:var(--md-sys-color-on-error, #fff)}.praxis-filter-bar :where(.mat-mdc-slide-toggle .mdc-switch__icons){display:none!important}.praxis-filter-bar{--mdc-switch-unselected-icon-size: 0px;--mdc-switch-selected-icon-size: 0px;--pfx-always-min: 220px}.praxis-filter-card{display:flex;flex-direction:column;gap:6px;padding:8px 12px;border-radius:12px;border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface)}:host ::ng-deep .praxis-add-select-panel{width:min(340px,100vw - 24px)!important;min-width:min(280px,100vw - 24px)!important;max-width:calc(100vw - 24px)!important;max-height:min(56vh,420px);margin-top:8px;padding:6px 0;border-radius:14px;overflow:auto;background:var(--md-sys-color-surface-container-highest);border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));box-shadow:var(--md-sys-elevation-level3)}:host ::ng-deep .cdk-overlay-pane:has(.praxis-add-select-panel){width:auto!important;min-width:0!important;max-width:calc(100vw - 24px)!important}:host ::ng-deep .praxis-add-select-panel .mat-mdc-option{min-height:36px}:host ::ng-deep .praxis-add-select-panel .add-search{position:sticky;top:0;background:var(--md-sys-color-surface-container-highest);z-index:1;padding:0 8px 6px;cursor:default}:host ::ng-deep .praxis-add-select-panel .add-search .mat-mdc-form-field{width:100%}:host ::ng-deep .praxis-add-select-panel .add-search .mat-mdc-form-field-subscript-wrapper{display:none}.inline-actions .add-trigger{display:inline-flex;align-items:center;gap:6px;height:32px;width:100%;max-width:100%;min-width:0;padding:0 10px;border-radius:0;border:0;background:transparent;overflow:visible}.inline-actions .add-trigger--icon{justify-content:center;width:32px;min-width:32px;padding:0}:host ::ng-deep .inline-actions .add-trigger mat-icon{width:18px;height:18px;font-size:18px;flex:0 0 auto}.inline-actions .add-trigger-label{display:inline-block;flex:1 1 auto;min-width:0;max-width:100%;text-align:left;direction:ltr;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.82rem;line-height:1}:host ::ng-deep .action-cluster--manage .mat-mdc-select{flex:0 0 auto;width:180px;min-width:0;max-width:180px}:host ::ng-deep .action-cluster--manage .cluster-select--hidden.mat-mdc-select{position:absolute;width:1px;min-width:1px;max-width:1px;height:1px;opacity:0;pointer-events:none;overflow:hidden}:host ::ng-deep .action-cluster--manage .mat-mdc-select-trigger{min-height:32px;padding:0}:host ::ng-deep .action-cluster--manage .mat-mdc-select-value,:host ::ng-deep .action-cluster--manage .mat-mdc-select-value-text,:host ::ng-deep .action-cluster--manage .mat-mdc-select-min-line{width:auto;min-width:0;max-width:100%;display:inline-flex;align-items:center;justify-content:flex-start;overflow:visible}.praxis-filter-card .summary-header{display:flex;align-items:center;gap:10px}.praxis-filter-card .summary-avatar{width:32px;height:32px;border-radius:50%;object-fit:cover}.praxis-filter-card .summary-title{font-weight:600}.praxis-filter-card .summary-subtitle{opacity:.8;font-size:.875rem}.praxis-filter-card .summary-badges{display:flex;flex-wrap:wrap;gap:6px}.praxis-filter-card .summary-badges span{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:var(--md-sys-color-primary-container);border:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-primary-container);font-size:12px}.praxis-filter-card .card-actions{display:flex;gap:8px}:host ::ng-deep .inline-actions .mat-mdc-select-arrow-wrapper{display:none}.inline-actions .add-filter-btn{height:36px;border-radius:18px;padding:0 16px 0 12px}.inline-actions .add-filter-btn mat-icon{margin-right:8px;margin-left:-4px}:host ::ng-deep .praxis-add-select-panel .add-select-all.partial .select-all-partial{opacity:.7;font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i15.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i15.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i15$2.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i15$4.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i17.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i17.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i17.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i11$1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: A11yModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }] });
33359
33595
  }
33360
33596
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisFilter, decorators: [{
33361
33597
  type: Component,
@@ -33383,11 +33619,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
33383
33619
  '[style.--pfx-always-min]': 'alwaysMinWidth + "px"',
33384
33620
  '[style.--pfx-always-cols-md]': 'alwaysColsMd',
33385
33621
  '[style.--pfx-always-cols-lg]': 'alwaysColsLg',
33386
- }, template: "<mat-progress-bar *ngIf=\"saving\" mode=\"indeterminate\"></mat-progress-bar>\n<div class=\"schema-error-banner\" *ngIf=\"schemaError\" role=\"alert\" aria-live=\"polite\">\n <mat-icon [praxisIcon]=\"'error_outline'\" aria-hidden=\"true\"></mat-icon>\n <span class=\"schema-error-message\">{{ i18nLabels.errorLoadingFilters || 'Erro ao carregar filtros.' }}</span>\n <button\n mat-stroked-button\n class=\"schema-error-retry\"\n type=\"button\"\n (click)=\"retrySchemaLoad()\"\n [attr.aria-label]=\"i18nLabels.retry || 'Tentar novamente'\"\n >\n {{ i18nLabels.retry || 'Tentar novamente' }}\n </button>\n</div>\n\n<form class=\"praxis-filter-bar\" [class.is-open]=\"advancedOpen\"\n [class.has-compact]=\"compactSelectedMetas.length || compactAlwaysVisibleMetas.length\"\n (submit)=\"onSubmit(); $event.preventDefault()\">\n <div class=\"inline-actions\" [class.actions-outlined]=\"actionsVariant==='outlined'\">\n <div class=\"actions-anchor\" #anchorRef=\"cdkOverlayOrigin\" cdkOverlayOrigin></div>\n <div class=\"inline-toggles\" *ngIf=\"toggleMetas.length\">\n <ng-container dynamicFieldLoader [fields]=\"toggleMetas\" [formGroup]=\"alwaysForm\"\n (componentsCreated)=\"onToggleComponents($event)\"></ng-container>\n </div>\n\n <div class=\"action-cluster action-cluster--manage\">\n <button #advancedButton mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\" type=\"button\"\n [matBadge]=\"activeFiltersCount\" [matBadgeHidden]=\"!activeFiltersCount\" matBadgeSize=\"small\"\n matBadgeColor=\"primary\" [matBadgeOverlap]=\"false\" (click)=\"toggleAdvanced()\"\n [attr.aria-label]=\"getAdvancedAriaLabel()\" [attr.aria-expanded]=\"advancedOpen\"\n [matTooltip]=\"getAdvancedTooltip()\"\n matTooltipPosition=\"below\"\n [attr.aria-controls]=\"advancedPanelId\">\n <mat-icon [praxisIcon]=\"'filter_list'\"></mat-icon>\n </button>\n\n <button mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\" [attr.aria-label]=\"getAddAriaLabel()\" [matTooltip]=\"getAddTooltip()\"\n matTooltipPosition=\"below\" [matBadge]=\"selectedFieldIds.length || 0\"\n [matBadgeHidden]=\"!(selectedFieldIds.length)\" matBadgeSize=\"small\" matBadgeColor=\"primary\"\n [matBadgeOverlap]=\"false\" (click)=\"addSelect.open()\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n\n <mat-select #addSelect multiple panelClass=\"praxis-add-select-panel\" panelWidth=\"min(340px, calc(100vw - 24px))\" [value]=\"selectedFieldIds\"\n class=\"cluster-select cluster-select--hidden\"\n [aria-label]=\"getAddAriaLabel()\" (openedChange)=\"onAddOpened($event)\"\n (selectionChange)=\"onAddSelectionChange(addSelect.value)\">\n <mat-option disabled class=\"add-search\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ i18nLabels.filtersSearch || i18nLabels.searchPlaceholder }}</mat-label>\n <input matInput (input)=\"onAddQuery(($any($event.target)).value)\" />\n </mat-form-field>\n </mat-option>\n <mat-option class=\"add-select-all\" (click)=\"toggleSelectAll()\"\n [class.partial]=\"isSomeSelected() && !isAllSelected()\">\n {{ i18nLabels.selectAll || 'Selecionar todos' }}<span class=\"select-all-partial\" *ngIf=\"isSomeSelected() && !isAllSelected()\">\n {{ i18nLabels.selectAllPartial || '(parcial)' }}</span>\n </mat-option>\n <mat-option *ngFor=\"let it of addItems; trackBy: trackById\" [value]=\"it.id\">\n {{ it.label }}\n </mat-option>\n </mat-select>\n\n <button mat-icon-button class=\"cluster-btn separator-before\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\" (click)=\"openSettings()\" *ngIf=\"showFilterSettings\" [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"getSettingsTooltip()\"\n matTooltipPosition=\"below\" [attr.aria-label]=\"getSettingsAriaLabel()\">\n <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n </div>\n\n <div class=\"action-cluster action-cluster--query\">\n <button\n mat-icon-button\n class=\"cluster-btn\"\n [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\"\n (click)=\"onClear()\"\n [attr.aria-label]=\"i18nLabels.clear\"\n [matTooltip]=\"i18nLabels.clear\"\n matTooltipPosition=\"below\"\n >\n <mat-icon [praxisIcon]=\"'cleaning_services'\"></mat-icon>\n </button>\n\n <button\n mat-icon-button\n class=\"cluster-btn\"\n [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"submit\"\n [attr.aria-label]=\"i18nLabels.apply\"\n [matTooltip]=\"i18nLabels.apply\"\n matTooltipPosition=\"below\"\n >\n <mat-icon [praxisIcon]=\"'search'\"></mat-icon>\n </button>\n </div>\n\n <span class=\"sr-only\" aria-live=\"polite\">{{ getAddAriaLabel() }}</span>\n </div>\n\n <div class=\"compact-fields\" *ngIf=\"compactSelectedMetas.length || compactAlwaysVisibleMetas.length\">\n <ng-container *ngIf=\"compactSelectedMetas.length\" dynamicFieldLoader [fields]=\"compactSelectedMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onSelectedComponents($event)\"></ng-container>\n <ng-container *ngIf=\"compactAlwaysVisibleMetas.length\" dynamicFieldLoader [fields]=\"compactAlwaysVisibleMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onAlwaysComponents($event)\"></ng-container>\n </div>\n\n <div class=\"fields-grid\" *ngIf=\"gridSelectedMetas.length || gridAlwaysVisibleMetas.length\">\n <ng-container *ngIf=\"gridSelectedMetas.length\" dynamicFieldLoader [fields]=\"gridSelectedMetas\" [formGroup]=\"alwaysForm\"\n (componentsCreated)=\"onSelectedComponents($event)\"></ng-container>\n <ng-container *ngIf=\"gridAlwaysVisibleMetas.length\" dynamicFieldLoader [fields]=\"gridAlwaysVisibleMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onAlwaysComponents($event)\"></ng-container>\n </div>\n\n <span class=\"sr-only\" aria-live=\"polite\">\n {{ activeFiltersCount ? (activeFiltersCount + ' filtros ativos') : '' }}\n </span>\n <button type=\"submit\" class=\"hidden-submit\" aria-hidden=\"true\" tabindex=\"-1\"></button>\n</form>\n\n<div class=\"praxis-filter-tags\" *ngIf=\"displayedTags.length\" [class.outlined]=\"tagVariant==='outlined'\">\n <mat-chip-set [attr.aria-label]=\"i18nLabels.shortcutsLabel || 'Atalhos'\">\n <mat-chip *ngFor=\"let tag of displayedTags\" [class.active]=\"isActiveTag(tag)\"\n [color]=\"tagVariant === 'outlined' ? null : (isActiveTag(tag) ? 'accent' : (tagColor === 'basic' ? null : tagColor))\"\n [highlighted]=\"tagVariant === 'filled' && tagColor !== 'basic'\" (click)=\"applyTag(tag)\"\n (keydown.enter)=\"applyTag(tag)\" (keydown.space)=\"applyTag(tag)\" tabindex=\"0\" role=\"button\"\n [attr.aria-pressed]=\"isActiveTag(tag)\">\n <ng-container *ngIf=\"editingTagId !== tag.id; else editChip\">\n <span class=\"chip-leading\" *ngIf=\"isActiveTag(tag)\">\n <mat-icon class=\"leading-check\">check</mat-icon>\n </span>\n <span class=\"chip-label\">{{ tag.label }}</span>\n <span class=\"chip-trailing\" *ngIf=\"isUserTag(tag); else roTag\">\n <button mat-icon-button [color]=\"tagButtonColor === 'basic' ? null : tagButtonColor\"\n [matMenuTriggerFor]=\"tagMenu\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getTagActionsAriaLabel(tag)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #tagMenu=\"matMenu\" xPosition=\"before\">\n <button mat-menu-item (click)=\"startEditTag(tag, $event)\">\n <mat-icon>edit</mat-icon>\n <span>{{ i18nLabels.renameShortcut }}</span>\n </button>\n <button mat-menu-item (click)=\"deleteTag(tag)\">\n <mat-icon>delete</mat-icon>\n <span>{{ i18nLabels.removeShortcut }}</span>\n </button>\n </mat-menu>\n </span>\n <ng-template #roTag>\n <span class=\"chip-readonly\" [matTooltip]=\"i18nLabels.readonlyShortcut\">\n <mat-icon>lock</mat-icon>\n </span>\n </ng-template>\n </ng-container>\n <ng-template #editChip>\n <input matInput class=\"chip-editor\" [formControl]=\"editingTagLabel\" autofocus\n [matTooltip]=\"'Enter para salvar, Esc para cancelar'\" matTooltipPosition=\"below\"\n (keydown.enter)=\"commitEditTag(tag, $event)\" (keydown.escape)=\"cancelEditTag($event)\"\n (blur)=\"commitEditTag(tag, $event)\" (click)=\"$event.stopPropagation()\" />\n </ng-template>\n </mat-chip>\n </mat-chip-set>\n</div>\n", styles: ["@charset \"UTF-8\";:root{--pfx-filter-h: 38px;--pfx-filter-align-offset: 2px;--pfx-gap-x: 12px;--pfx-gap-y: 8px;--pfx-always-max-desktop: 380px;--pfx-slider-span-desktop: 2;--pfx-advanced-pad-x: 24px;--pfx-field-min: 280px;--pfx-overlay-margin-y: 16px;--pfx-overlay-margin-x: 16px}:host-context(.theme-light){--pfx-surface-border: var(--md-sys-color-outline)}:host{--border-color: var(--md-sys-color-outline-variant);--border-color-hover: var(--md-sys-color-outline);--pfx-overlay-surface: var(--md-sys-color-surface-container);--pfx-overlay-surface-elev: var(--md-sys-color-surface-container-high);--pfx-overlay-surface-variant: var(--md-sys-color-surface-variant);--pfx-overlay-on-surface: var(--md-sys-color-on-surface);--pfx-overlay-on-surface-variant: var(--md-sys-color-on-surface-variant);display:block;width:100%;min-width:0;flex:1 1 auto}.schema-error-banner{display:flex;align-items:center;gap:8px;margin:0 0 8px;padding:8px 10px;border-radius:10px;border:1px solid color-mix(in srgb,var(--md-sys-color-error) 50%,transparent);background:color-mix(in srgb,var(--md-sys-color-error-container) 85%,transparent);color:var(--md-sys-color-on-error-container)}.schema-error-message{min-width:0;flex:1 1 auto;font-size:.8125rem}:host ::ng-deep .schema-error-retry.mat-mdc-outlined-button{--mdc-outlined-button-outline-color: color-mix( in srgb, var(--md-sys-color-error) 55%, var(--md-sys-color-outline) )}.praxis-filter-bar{display:grid;width:100%;grid-template-columns:minmax(0,1fr) auto;column-gap:6px;row-gap:6px;align-items:start}.inline-actions .actions-anchor{width:0;height:0;overflow:hidden}.inline-actions{grid-column:2;grid-row:1;flex:0 0 auto;display:flex;gap:6px;justify-self:end;align-self:start;width:fit-content;white-space:nowrap;height:var(--pfx-filter-h);align-items:center;padding:0 2px}.action-cluster{flex:0 0 auto;display:inline-flex;align-items:center;gap:2px;min-height:36px;padding:2px;border-radius:999px;border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-highest)}.action-cluster--manage{position:relative;border-color:color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-high)}:host ::ng-deep .action-cluster .mat-mdc-icon-button,:host ::ng-deep .action-cluster .cluster-btn.mat-mdc-icon-button{width:32px;height:32px;padding:0;--mat-icon-button-state-layer-size: 32px}.inline-actions.actions-outlined button.mat-mdc-icon-button{border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));border-radius:50%}.inline-actions.actions-outlined .action-cluster button.mat-mdc-icon-button{border-color:transparent}.separator-before{position:relative;margin-left:10px}.separator-before:before{content:\"\";position:absolute;left:-7px;top:50%;width:1px;height:18px;transform:translateY(-50%);background:color-mix(in srgb,var(--md-sys-color-outline) 72%,transparent)}.inline-actions mat-icon{width:20px;height:20px;font-size:20px}.fields-grid{grid-column:1;grid-row:1;display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--pfx-always-min, 220px),1fr));grid-auto-flow:row dense;gap:6px}.compact-fields{grid-column:1;grid-row:1;display:flex;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:center;gap:6px;min-width:0}:host ::ng-deep .compact-fields .pfx-field-shell,:host ::ng-deep .compact-fields .pfx-field-shell-wrapper,:host ::ng-deep .compact-fields .pfx-field-shell-host{--pfx-field-shell-width: fit-content;--pfx-field-shell-field-width: auto;width:fit-content!important;max-width:100%;min-width:0;flex:0 1 auto!important}:host ::ng-deep .compact-fields>.pfx-field-shell,:host ::ng-deep .compact-fields>praxis-field-shell{flex:0 1 auto!important;width:fit-content!important;max-width:100%;min-width:0}:host ::ng-deep .compact-fields .pfx-field-shell .mat-mdc-form-field{width:auto!important;max-width:100%;margin-bottom:0}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=inlineDateRange] .mat-mdc-form-field{width:var(--pdx-inline-date-range-shell-width, auto)!important;max-width:100%!important}.praxis-filter-bar.has-compact .compact-fields{grid-column:1;grid-row:1}.praxis-filter-bar.has-compact .fields-grid{grid-column:1/-1;grid-row:2}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider] mat-slider,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] mat-slider,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] mat-slider{width:100%;display:block}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider] .pdx-slider-wrapper,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-slider-wrapper,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-slider-wrapper{padding-top:2px}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-range-slider-container,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-range-slider-container{padding:2px 0 0}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-slider-label,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-slider-label{margin-bottom:4px;line-height:1.15}:host ::ng-deep .fields-grid .mat-mdc-text-field-wrapper.mdc-text-field--outlined{min-height:var(--pfx-filter-h);align-items:center}:host ::ng-deep .fields-grid .mat-mdc-form-field-infix{min-height:var(--pfx-filter-h)}:host ::ng-deep .fields-grid .mat-mdc-select-trigger{height:var(--pfx-filter-h);align-items:center}:host ::ng-deep .fields-grid .mat-mdc-form-field{width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSearchableSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSearchableSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineMultiSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineMultiSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineInput]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineInput] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineToggle]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineToggle] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineRange]{justify-self:start}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=inlineRange]{max-width:min(340px,100%)}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDate]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDate] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDateRange]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDateRange] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .mat-mdc-form-field-subscript-wrapper{min-height:0;margin-top:0}:host ::ng-deep .fields-grid .mat-mdc-form-field{margin-bottom:0}.praxis-filter-tags.outlined .mat-mdc-chip{background:transparent!important;--mat-chip-outline-width: 1px;--mat-chip-outline-color: var(--md-sys-color-outline-variant);box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)}.praxis-filter-tags.outlined mat-chip.active .mat-mdc-chip,.praxis-filter-tags.outlined .mat-mdc-chip.mat-mdc-chip-highlighted{--mat-chip-outline-color: var(--md-sys-color-primary) !important;box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)!important}.praxis-filter-tags .mat-mdc-standard-chip .mdc-evolution-chip__text-label{display:flex;align-items:center;justify-content:center;gap:4px;line-height:1.2;font-size:.875rem}.praxis-filter-tags .chip-leading,.praxis-filter-tags .chip-trailing{display:inline-flex;align-items:center}.praxis-filter-tags .leading-check{width:18px;height:18px;font-size:18px;line-height:1}.praxis-filter-tags .chip-label{position:relative;top:-6px}.praxis-filter-tags .chip-trailing .mat-mdc-icon-button{width:28px;height:28px;padding:0;display:flex;align-items:center;justify-content:center;line-height:28px}.praxis-filter-tags .mat-mdc-standard-chip{--mat-chip-container-height: 36px}.praxis-filter-advanced{display:flex;flex-direction:column;min-width:400px;max-width:90vw;min-height:260px;max-height:min(80vh,720px);margin:var(--pfx-overlay-margin-y) var(--pfx-overlay-margin-x);background-color:var(--pfx-overlay-surface)!important;background:var(--pfx-overlay-surface)!important;color:var(--pfx-overlay-on-surface);border:1px solid var(--border-color);border-radius:12px;box-shadow:var(--md-sys-elevation-level3)}.advanced-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px var(--pfx-advanced-pad-x) 10px;border-bottom:1px solid var(--border-color);background:var(--pfx-overlay-surface)}.advanced-title-block{display:flex;flex-direction:column;gap:2px}.advanced-title{font-size:1rem;font-weight:600;color:var(--pfx-overlay-on-surface)}.advanced-subtitle{font-size:.85rem;color:var(--pfx-overlay-on-surface-variant)}.advanced-close{align-self:flex-start}.praxis-filter-overlay.mobile .praxis-filter-advanced{height:100vh;max-height:100vh;margin:0;border-radius:0}:host ::ng-deep .praxis-overlay-backdrop{background:var(--md-sys-color-scrim);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}:host ::ng-deep .praxis-filter-overlay.frosted .praxis-filter-advanced{background:var(--pfx-overlay-surface-variant)!important;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-color:var(--border-color)}:host ::ng-deep .praxis-filter-overlay.frosted .advanced-header,:host ::ng-deep .praxis-filter-overlay.frosted .advanced-actions{background:var(--pfx-overlay-surface-variant)!important}.advanced-body{padding:12px var(--pfx-advanced-pad-x) 72px;overflow:auto;flex:1 1 auto;overscroll-behavior:contain}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-row{display:grid!important;grid-template-columns:repeat(auto-fit,minmax(var(--pfx-field-min),1fr));gap:var(--pfx-gap-y) var(--pfx-gap-x)}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-column{min-width:0}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-column .mat-mdc-form-field{width:100%}.advanced-actions{position:sticky;bottom:0;z-index:2;display:flex;justify-content:flex-end;gap:8px;padding:var(--pfx-gap-y) var(--pfx-advanced-pad-x);background-color:var(--pfx-overlay-surface)!important;background:var(--pfx-overlay-surface)!important;border-top:1px solid var(--border-color);box-shadow:0 -1px 0 var(--md-sys-color-outline-variant)}.advanced-actions .mat-mdc-button-base{height:40px}.advanced-actions .mat-mdc-raised-button.mat-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}:host ::ng-deep .praxis-filter-advanced .mat-mdc-text-field-wrapper.mdc-text-field--outlined{--mdc-outlined-text-field-outline-color: var(--border-color);--mdc-outlined-text-field-hover-outline-color: var(--border-color-hover);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-label-text-color: var(--pfx-overlay-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--pfx-overlay-on-surface);--mdc-outlined-text-field-container-color: var(--pfx-overlay-surface)}:host ::ng-deep .praxis-filter-advanced .mat-mdc-select-trigger,:host ::ng-deep .praxis-filter-advanced .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .praxis-filter-advanced .mat-mdc-form-field-infix{color:var(--pfx-overlay-on-surface)}@media(min-width:600px){.fields-grid{gap:6px 8px}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-row{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:960px){.fields-grid{gap:6px 10px}}@media(min-width:1200px){.fields-grid{grid-template-columns:repeat(auto-fit,minmax(var(--pfx-always-min, 220px),var(--pfx-always-max-desktop, 380px)));justify-content:start;align-content:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeslider]{grid-column:span var(--pfx-slider-span-desktop, 2)}}.inline-toggles{display:flex;align-items:center;gap:8px;margin:0 4px 0 6px}:host ::ng-deep .inline-actions .mat-mdc-slide-toggle{height:var(--pfx-filter-h);display:flex;align-items:center}:host ::ng-deep .inline-actions .mat-mdc-slide-toggle .mdc-form-field{align-items:center}::ng-deep .praxis-filter-overlay .praxis-filter-advanced .praxis-filter-form .filter-row{display:grid!important;gap:var(--pfx-gap-y, 1px) var(--pfx-gap-x, 6px)}@media(min-width:600px){::ng-deep .praxis-filter-overlay .praxis-filter-advanced .praxis-filter-form .filter-row{grid-template-columns:repeat(2,minmax(0,1fr))}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important}.hidden-submit{position:absolute!important;width:0!important;height:0!important;padding:0!important;margin:0!important;border:0!important;opacity:0!important;pointer-events:none!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important;overflow:hidden!important}:host ::ng-deep .inline-actions [matBadge] .mat-badge-content{top:-6px;right:-6px;min-width:16px;height:16px;padding:0 4px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;font-size:10px;font-weight:700;line-height:16px;letter-spacing:0;text-indent:0;color:var(--md-sys-color-on-primary, #fff)}:host ::ng-deep .inline-actions [matBadge][matbadgecolor=warn] .mat-badge-content,:host ::ng-deep .inline-actions [matBadge].mat-badge-warn .mat-badge-content{color:var(--md-sys-color-on-error, #fff)}.praxis-filter-bar :where(.mat-mdc-slide-toggle .mdc-switch__icons){display:none!important}.praxis-filter-bar{--mdc-switch-unselected-icon-size: 0px;--mdc-switch-selected-icon-size: 0px;--pfx-always-min: 220px}.praxis-filter-card{display:flex;flex-direction:column;gap:6px;padding:8px 12px;border-radius:12px;border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface)}:host ::ng-deep .praxis-add-select-panel{width:min(340px,100vw - 24px)!important;min-width:min(280px,100vw - 24px)!important;max-width:calc(100vw - 24px)!important;max-height:min(56vh,420px);margin-top:8px;padding:6px 0;border-radius:14px;overflow:auto;background:var(--md-sys-color-surface-container-highest);border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));box-shadow:var(--md-sys-elevation-level3)}:host ::ng-deep .cdk-overlay-pane:has(.praxis-add-select-panel){width:auto!important;min-width:0!important;max-width:calc(100vw - 24px)!important}:host ::ng-deep .praxis-add-select-panel .mat-mdc-option{min-height:36px}:host ::ng-deep .praxis-add-select-panel .add-search{position:sticky;top:0;background:var(--md-sys-color-surface-container-highest);z-index:1;padding:0 8px 6px;cursor:default}:host ::ng-deep .praxis-add-select-panel .add-search .mat-mdc-form-field{width:100%}:host ::ng-deep .praxis-add-select-panel .add-search .mat-mdc-form-field-subscript-wrapper{display:none}.inline-actions .add-trigger{display:inline-flex;align-items:center;gap:6px;height:32px;width:100%;max-width:100%;min-width:0;padding:0 10px;border-radius:0;border:0;background:transparent;overflow:visible}.inline-actions .add-trigger--icon{justify-content:center;width:32px;min-width:32px;padding:0}:host ::ng-deep .inline-actions .add-trigger mat-icon{width:18px;height:18px;font-size:18px;flex:0 0 auto}.inline-actions .add-trigger-label{display:inline-block;flex:1 1 auto;min-width:0;max-width:100%;text-align:left;direction:ltr;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.82rem;line-height:1}:host ::ng-deep .action-cluster--manage .mat-mdc-select{flex:0 0 auto;width:180px;min-width:0;max-width:180px}:host ::ng-deep .action-cluster--manage .cluster-select--hidden.mat-mdc-select{position:absolute;width:1px;min-width:1px;max-width:1px;height:1px;opacity:0;pointer-events:none;overflow:hidden}:host ::ng-deep .action-cluster--manage .mat-mdc-select-trigger{min-height:32px;padding:0}:host ::ng-deep .action-cluster--manage .mat-mdc-select-value,:host ::ng-deep .action-cluster--manage .mat-mdc-select-value-text,:host ::ng-deep .action-cluster--manage .mat-mdc-select-min-line{width:auto;min-width:0;max-width:100%;display:inline-flex;align-items:center;justify-content:flex-start;overflow:visible}.praxis-filter-card .summary-header{display:flex;align-items:center;gap:10px}.praxis-filter-card .summary-avatar{width:32px;height:32px;border-radius:50%;object-fit:cover}.praxis-filter-card .summary-title{font-weight:600}.praxis-filter-card .summary-subtitle{opacity:.8;font-size:.875rem}.praxis-filter-card .summary-badges{display:flex;flex-wrap:wrap;gap:6px}.praxis-filter-card .summary-badges span{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:var(--md-sys-color-primary-container);border:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-primary-container);font-size:12px}.praxis-filter-card .card-actions{display:flex;gap:8px}:host ::ng-deep .inline-actions .mat-mdc-select-arrow-wrapper{display:none}.inline-actions .add-filter-btn{height:36px;border-radius:18px;padding:0 16px 0 12px}.inline-actions .add-filter-btn mat-icon{margin-right:8px;margin-left:-4px}:host ::ng-deep .praxis-add-select-panel .add-select-all.partial .select-all-partial{opacity:.7;font-style:italic}\n"] }]
33622
+ }, template: "<mat-progress-bar *ngIf=\"saving\" mode=\"indeterminate\"></mat-progress-bar>\n<div class=\"schema-error-banner\" *ngIf=\"schemaError\" role=\"alert\" aria-live=\"polite\">\n <mat-icon [praxisIcon]=\"'error_outline'\" aria-hidden=\"true\"></mat-icon>\n <span class=\"schema-error-message\">{{ i18nLabels.errorLoadingFilters || 'Erro ao carregar filtros.' }}</span>\n <button\n mat-stroked-button\n class=\"schema-error-retry\"\n type=\"button\"\n (click)=\"retrySchemaLoad()\"\n [attr.aria-label]=\"i18nLabels.retry || 'Tentar novamente'\"\n >\n {{ i18nLabels.retry || 'Tentar novamente' }}\n </button>\n</div>\n\n<form class=\"praxis-filter-bar\" [class.is-open]=\"advancedOpen\"\n [class.has-compact]=\"compactSelectedMetas.length || compactAlwaysVisibleMetas.length\"\n (click)=\"onFieldInteraction($event)\"\n (focusin)=\"onFieldInteraction($event)\"\n (submit)=\"onSubmit(); $event.preventDefault()\">\n <div class=\"inline-actions\" [class.actions-outlined]=\"actionsVariant==='outlined'\">\n <div class=\"actions-anchor\" #anchorRef=\"cdkOverlayOrigin\" cdkOverlayOrigin></div>\n <div class=\"inline-toggles\" *ngIf=\"toggleMetas.length\">\n <ng-container dynamicFieldLoader [fields]=\"toggleMetas\" [formGroup]=\"alwaysForm\"\n (componentsCreated)=\"onToggleComponents($event)\"></ng-container>\n </div>\n\n <div class=\"action-cluster action-cluster--manage\">\n <button #advancedButton mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\" type=\"button\"\n [matBadge]=\"activeFiltersCount\" [matBadgeHidden]=\"!activeFiltersCount\" matBadgeSize=\"small\"\n matBadgeColor=\"primary\" [matBadgeOverlap]=\"false\" (click)=\"toggleAdvanced()\"\n [attr.aria-label]=\"getAdvancedAriaLabel()\" [attr.aria-expanded]=\"advancedOpen\"\n [matTooltip]=\"getAdvancedTooltip()\"\n matTooltipPosition=\"below\"\n [attr.aria-controls]=\"advancedPanelId\">\n <mat-icon [praxisIcon]=\"'filter_list'\"></mat-icon>\n </button>\n\n <button mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\" [attr.aria-label]=\"getAddAriaLabel()\" [matTooltip]=\"getAddTooltip()\"\n matTooltipPosition=\"below\" [matBadge]=\"selectedFieldIds.length || 0\"\n [matBadgeHidden]=\"!(selectedFieldIds.length)\" matBadgeSize=\"small\" matBadgeColor=\"primary\"\n [matBadgeOverlap]=\"false\" (click)=\"addSelect.open()\">\n <mat-icon [praxisIcon]=\"'add'\"></mat-icon>\n </button>\n\n <mat-select #addSelect multiple panelClass=\"praxis-add-select-panel\" panelWidth=\"min(340px, calc(100vw - 24px))\" [value]=\"selectedFieldIds\"\n class=\"cluster-select cluster-select--hidden\"\n [aria-label]=\"getAddAriaLabel()\" (openedChange)=\"onAddOpened($event)\"\n (selectionChange)=\"onAddSelectionChange(addSelect.value)\">\n <mat-option disabled class=\"add-search\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ i18nLabels.filtersSearch || i18nLabels.searchPlaceholder }}</mat-label>\n <input matInput (input)=\"onAddQuery(($any($event.target)).value)\" />\n </mat-form-field>\n </mat-option>\n <mat-option class=\"add-select-all\" (click)=\"toggleSelectAll()\"\n [class.partial]=\"isSomeSelected() && !isAllSelected()\">\n {{ i18nLabels.selectAll || 'Selecionar todos' }}<span class=\"select-all-partial\" *ngIf=\"isSomeSelected() && !isAllSelected()\">\n {{ i18nLabels.selectAllPartial || '(parcial)' }}</span>\n </mat-option>\n <mat-option *ngFor=\"let it of addItems; trackBy: trackById\" [value]=\"it.id\">\n {{ it.label }}\n </mat-option>\n </mat-select>\n\n <button mat-icon-button class=\"cluster-btn separator-before\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\" (click)=\"openSettings()\" *ngIf=\"showFilterSettings\" [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\" matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"getSettingsTooltip()\"\n matTooltipPosition=\"below\" [attr.aria-label]=\"getSettingsAriaLabel()\">\n <mat-icon [praxisIcon]=\"'settings'\"></mat-icon>\n </button>\n\n <button\n *ngIf=\"isFieldAuthoringEnabled() && activeEditableFieldMeta\"\n mat-icon-button\n class=\"cluster-btn\"\n [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\"\n data-testid=\"filter-field-settings-trigger\"\n [attr.aria-label]=\"activeEditableFieldLabel\"\n (click)=\"openSelectedFieldEditor()\"\n >\n <mat-icon [praxisIcon]=\"'tune'\"></mat-icon>\n </button>\n </div>\n\n <div class=\"action-cluster action-cluster--query\">\n <button\n mat-icon-button\n class=\"cluster-btn\"\n [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"button\"\n (click)=\"onClear()\"\n [attr.aria-label]=\"i18nLabels.clear\"\n [matTooltip]=\"i18nLabels.clear\"\n matTooltipPosition=\"below\"\n >\n <mat-icon [praxisIcon]=\"'cleaning_services'\"></mat-icon>\n </button>\n\n <button\n mat-icon-button\n class=\"cluster-btn\"\n [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\"\n type=\"submit\"\n [attr.aria-label]=\"i18nLabels.apply\"\n [matTooltip]=\"i18nLabels.apply\"\n matTooltipPosition=\"below\"\n >\n <mat-icon [praxisIcon]=\"'search'\"></mat-icon>\n </button>\n </div>\n\n <span class=\"sr-only\" aria-live=\"polite\">{{ getAddAriaLabel() }}</span>\n </div>\n\n <div class=\"compact-fields\" *ngIf=\"compactSelectedMetas.length || compactAlwaysVisibleMetas.length\">\n <ng-container *ngIf=\"compactSelectedMetas.length\" dynamicFieldLoader [fields]=\"compactSelectedMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onSelectedComponents($event)\"></ng-container>\n <ng-container *ngIf=\"compactAlwaysVisibleMetas.length\" dynamicFieldLoader [fields]=\"compactAlwaysVisibleMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onAlwaysComponents($event)\"></ng-container>\n </div>\n\n <div class=\"fields-grid\" *ngIf=\"gridSelectedMetas.length || gridAlwaysVisibleMetas.length\">\n <ng-container *ngIf=\"gridSelectedMetas.length\" dynamicFieldLoader [fields]=\"gridSelectedMetas\" [formGroup]=\"alwaysForm\"\n (componentsCreated)=\"onSelectedComponents($event)\"></ng-container>\n <ng-container *ngIf=\"gridAlwaysVisibleMetas.length\" dynamicFieldLoader [fields]=\"gridAlwaysVisibleMetas\"\n [formGroup]=\"alwaysForm\" (componentsCreated)=\"onAlwaysComponents($event)\"></ng-container>\n </div>\n\n <span class=\"sr-only\" aria-live=\"polite\">\n {{ activeFiltersCount ? (activeFiltersCount + ' filtros ativos') : '' }}\n </span>\n <button type=\"submit\" class=\"hidden-submit\" aria-hidden=\"true\" tabindex=\"-1\"></button>\n</form>\n\n<div class=\"praxis-filter-tags\" *ngIf=\"displayedTags.length\" [class.outlined]=\"tagVariant==='outlined'\">\n <mat-chip-set [attr.aria-label]=\"i18nLabels.shortcutsLabel || 'Atalhos'\">\n <mat-chip *ngFor=\"let tag of displayedTags\" [class.active]=\"isActiveTag(tag)\"\n [color]=\"tagVariant === 'outlined' ? null : (isActiveTag(tag) ? 'accent' : (tagColor === 'basic' ? null : tagColor))\"\n [highlighted]=\"tagVariant === 'filled' && tagColor !== 'basic'\" (click)=\"applyTag(tag)\"\n (keydown.enter)=\"applyTag(tag)\" (keydown.space)=\"applyTag(tag)\" tabindex=\"0\" role=\"button\"\n [attr.aria-pressed]=\"isActiveTag(tag)\">\n <ng-container *ngIf=\"editingTagId !== tag.id; else editChip\">\n <span class=\"chip-leading\" *ngIf=\"isActiveTag(tag)\">\n <mat-icon class=\"leading-check\">check</mat-icon>\n </span>\n <span class=\"chip-label\">{{ tag.label }}</span>\n <span class=\"chip-trailing\" *ngIf=\"isUserTag(tag); else roTag\">\n <button mat-icon-button [color]=\"tagButtonColor === 'basic' ? null : tagButtonColor\"\n [matMenuTriggerFor]=\"tagMenu\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getTagActionsAriaLabel(tag)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #tagMenu=\"matMenu\" xPosition=\"before\">\n <button mat-menu-item (click)=\"startEditTag(tag, $event)\">\n <mat-icon>edit</mat-icon>\n <span>{{ i18nLabels.renameShortcut }}</span>\n </button>\n <button mat-menu-item (click)=\"deleteTag(tag)\">\n <mat-icon>delete</mat-icon>\n <span>{{ i18nLabels.removeShortcut }}</span>\n </button>\n </mat-menu>\n </span>\n <ng-template #roTag>\n <span class=\"chip-readonly\" [matTooltip]=\"i18nLabels.readonlyShortcut\">\n <mat-icon>lock</mat-icon>\n </span>\n </ng-template>\n </ng-container>\n <ng-template #editChip>\n <input matInput class=\"chip-editor\" [formControl]=\"editingTagLabel\" autofocus\n [matTooltip]=\"'Enter para salvar, Esc para cancelar'\" matTooltipPosition=\"below\"\n (keydown.enter)=\"commitEditTag(tag, $event)\" (keydown.escape)=\"cancelEditTag($event)\"\n (blur)=\"commitEditTag(tag, $event)\" (click)=\"$event.stopPropagation()\" />\n </ng-template>\n </mat-chip>\n </mat-chip-set>\n</div>\n", styles: ["@charset \"UTF-8\";:root{--pfx-filter-h: 38px;--pfx-filter-align-offset: 2px;--pfx-gap-x: 12px;--pfx-gap-y: 8px;--pfx-always-max-desktop: 380px;--pfx-slider-span-desktop: 2;--pfx-advanced-pad-x: 24px;--pfx-field-min: 280px;--pfx-overlay-margin-y: 16px;--pfx-overlay-margin-x: 16px}:host-context(.theme-light){--pfx-surface-border: var(--md-sys-color-outline)}:host{--border-color: var(--md-sys-color-outline-variant);--border-color-hover: var(--md-sys-color-outline);--pfx-overlay-surface: var(--md-sys-color-surface-container);--pfx-overlay-surface-elev: var(--md-sys-color-surface-container-high);--pfx-overlay-surface-variant: var(--md-sys-color-surface-variant);--pfx-overlay-on-surface: var(--md-sys-color-on-surface);--pfx-overlay-on-surface-variant: var(--md-sys-color-on-surface-variant);display:block;width:100%;min-width:0;flex:1 1 auto}.schema-error-banner{display:flex;align-items:center;gap:8px;margin:0 0 8px;padding:8px 10px;border-radius:10px;border:1px solid color-mix(in srgb,var(--md-sys-color-error) 50%,transparent);background:color-mix(in srgb,var(--md-sys-color-error-container) 85%,transparent);color:var(--md-sys-color-on-error-container)}.schema-error-message{min-width:0;flex:1 1 auto;font-size:.8125rem}:host ::ng-deep .schema-error-retry.mat-mdc-outlined-button{--mdc-outlined-button-outline-color: color-mix( in srgb, var(--md-sys-color-error) 55%, var(--md-sys-color-outline) )}.praxis-filter-bar{display:grid;width:100%;grid-template-columns:minmax(0,1fr) auto;column-gap:6px;row-gap:6px;align-items:start}.inline-actions .actions-anchor{width:0;height:0;overflow:hidden}.inline-actions{grid-column:2;grid-row:1;flex:0 0 auto;display:flex;gap:6px;justify-self:end;align-self:start;width:fit-content;white-space:nowrap;height:var(--pfx-filter-h);align-items:center;padding:0 2px}.action-cluster{flex:0 0 auto;display:inline-flex;align-items:center;gap:2px;min-height:36px;padding:2px;border-radius:999px;border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-highest)}.action-cluster--manage{position:relative;border-color:color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container-high)}:host ::ng-deep .action-cluster .mat-mdc-icon-button,:host ::ng-deep .action-cluster .cluster-btn.mat-mdc-icon-button{width:32px;height:32px;padding:0;--mat-icon-button-state-layer-size: 32px}.inline-actions.actions-outlined button.mat-mdc-icon-button{border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));border-radius:50%}.inline-actions.actions-outlined .action-cluster button.mat-mdc-icon-button{border-color:transparent}.separator-before{position:relative;margin-left:10px}.separator-before:before{content:\"\";position:absolute;left:-7px;top:50%;width:1px;height:18px;transform:translateY(-50%);background:color-mix(in srgb,var(--md-sys-color-outline) 72%,transparent)}.inline-actions mat-icon{width:20px;height:20px;font-size:20px}.fields-grid{grid-column:1;grid-row:1;display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--pfx-always-min, 220px),1fr));grid-auto-flow:row dense;gap:6px}.compact-fields{grid-column:1;grid-row:1;display:flex;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:center;gap:6px;min-width:0}:host ::ng-deep .compact-fields .pfx-field-shell,:host ::ng-deep .compact-fields .pfx-field-shell-wrapper,:host ::ng-deep .compact-fields .pfx-field-shell-host{--pfx-field-shell-width: fit-content;--pfx-field-shell-field-width: auto;width:fit-content!important;max-width:100%;min-width:0;flex:0 1 auto!important}:host ::ng-deep .compact-fields>.pfx-field-shell,:host ::ng-deep .compact-fields>praxis-field-shell{flex:0 1 auto!important;width:fit-content!important;max-width:100%;min-width:0}:host ::ng-deep .compact-fields .pfx-field-shell .mat-mdc-form-field{width:auto!important;max-width:100%;margin-bottom:0}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=inlineDateRange] .mat-mdc-form-field{width:var(--pdx-inline-date-range-shell-width, auto)!important;max-width:100%!important}.praxis-filter-bar.has-compact .compact-fields{grid-column:1;grid-row:1}.praxis-filter-bar.has-compact .fields-grid{grid-column:1/-1;grid-row:2}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider] mat-slider,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] mat-slider,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] mat-slider{width:100%;display:block}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider] .pdx-slider-wrapper,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-slider-wrapper,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-slider-wrapper{padding-top:2px}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-range-slider-container,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-range-slider-container{padding:2px 0 0}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider] .pdx-slider-label,:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider] .pdx-slider-label{margin-bottom:4px;line-height:1.15}:host ::ng-deep .fields-grid .mat-mdc-text-field-wrapper.mdc-text-field--outlined{min-height:var(--pfx-filter-h);align-items:center}:host ::ng-deep .fields-grid .mat-mdc-form-field-infix{min-height:var(--pfx-filter-h)}:host ::ng-deep .fields-grid .mat-mdc-select-trigger{height:var(--pfx-filter-h);align-items:center}:host ::ng-deep .fields-grid .mat-mdc-form-field{width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSearchableSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineSearchableSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineMultiSelect]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineMultiSelect] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineInput]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineInput] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineToggle]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineToggle] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineRange]{justify-self:start}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=inlineRange]{max-width:min(340px,100%)}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDate]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDate] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDateRange]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=inlineDateRange] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .mat-mdc-form-field-subscript-wrapper{min-height:0;margin-top:0}:host ::ng-deep .fields-grid .mat-mdc-form-field{margin-bottom:0}.praxis-filter-tags.outlined .mat-mdc-chip{background:transparent!important;--mat-chip-outline-width: 1px;--mat-chip-outline-color: var(--md-sys-color-outline-variant);box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)}.praxis-filter-tags.outlined mat-chip.active .mat-mdc-chip,.praxis-filter-tags.outlined .mat-mdc-chip.mat-mdc-chip-highlighted{--mat-chip-outline-color: var(--md-sys-color-primary) !important;box-shadow:inset 0 0 0 var(--mat-chip-outline-width) var(--mat-chip-outline-color)!important}.praxis-filter-tags .mat-mdc-standard-chip .mdc-evolution-chip__text-label{display:flex;align-items:center;justify-content:center;gap:4px;line-height:1.2;font-size:.875rem}.praxis-filter-tags .chip-leading,.praxis-filter-tags .chip-trailing{display:inline-flex;align-items:center}.praxis-filter-tags .leading-check{width:18px;height:18px;font-size:18px;line-height:1}.praxis-filter-tags .chip-label{position:relative;top:-6px}.praxis-filter-tags .chip-trailing .mat-mdc-icon-button{width:28px;height:28px;padding:0;display:flex;align-items:center;justify-content:center;line-height:28px}.praxis-filter-tags .mat-mdc-standard-chip{--mat-chip-container-height: 36px}.praxis-filter-advanced{display:flex;flex-direction:column;min-width:400px;max-width:90vw;min-height:260px;max-height:min(80vh,720px);margin:var(--pfx-overlay-margin-y) var(--pfx-overlay-margin-x);background-color:var(--pfx-overlay-surface)!important;background:var(--pfx-overlay-surface)!important;color:var(--pfx-overlay-on-surface);border:1px solid var(--border-color);border-radius:12px;box-shadow:var(--md-sys-elevation-level3)}.advanced-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px var(--pfx-advanced-pad-x) 10px;border-bottom:1px solid var(--border-color);background:var(--pfx-overlay-surface)}.advanced-title-block{display:flex;flex-direction:column;gap:2px}.advanced-title{font-size:1rem;font-weight:600;color:var(--pfx-overlay-on-surface)}.advanced-subtitle{font-size:.85rem;color:var(--pfx-overlay-on-surface-variant)}.advanced-close{align-self:flex-start}.praxis-filter-overlay.mobile .praxis-filter-advanced{height:100vh;max-height:100vh;margin:0;border-radius:0}:host ::ng-deep .praxis-overlay-backdrop{background:var(--md-sys-color-scrim);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}:host ::ng-deep .praxis-filter-overlay.frosted .praxis-filter-advanced{background:var(--pfx-overlay-surface-variant)!important;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-color:var(--border-color)}:host ::ng-deep .praxis-filter-overlay.frosted .advanced-header,:host ::ng-deep .praxis-filter-overlay.frosted .advanced-actions{background:var(--pfx-overlay-surface-variant)!important}.advanced-body{padding:12px var(--pfx-advanced-pad-x) 72px;overflow:auto;flex:1 1 auto;overscroll-behavior:contain}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-row{display:grid!important;grid-template-columns:repeat(auto-fit,minmax(var(--pfx-field-min),1fr));gap:var(--pfx-gap-y) var(--pfx-gap-x)}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-column{min-width:0}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-column .mat-mdc-form-field{width:100%}.advanced-actions{position:sticky;bottom:0;z-index:2;display:flex;justify-content:flex-end;gap:8px;padding:var(--pfx-gap-y) var(--pfx-advanced-pad-x);background-color:var(--pfx-overlay-surface)!important;background:var(--pfx-overlay-surface)!important;border-top:1px solid var(--border-color);box-shadow:0 -1px 0 var(--md-sys-color-outline-variant)}.advanced-actions .mat-mdc-button-base{height:40px}.advanced-actions .mat-mdc-raised-button.mat-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}:host ::ng-deep .praxis-filter-advanced .mat-mdc-text-field-wrapper.mdc-text-field--outlined{--mdc-outlined-text-field-outline-color: var(--border-color);--mdc-outlined-text-field-hover-outline-color: var(--border-color-hover);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-label-text-color: var(--pfx-overlay-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--pfx-overlay-on-surface);--mdc-outlined-text-field-container-color: var(--pfx-overlay-surface)}:host ::ng-deep .praxis-filter-advanced .mat-mdc-select-trigger,:host ::ng-deep .praxis-filter-advanced .mat-mdc-form-field-subscript-wrapper,:host ::ng-deep .praxis-filter-advanced .mat-mdc-form-field-infix{color:var(--pfx-overlay-on-surface)}@media(min-width:600px){.fields-grid{gap:6px 8px}:host ::ng-deep .praxis-filter-advanced .praxis-filter-form .filter-row{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:960px){.fields-grid{gap:6px 10px}}@media(min-width:1200px){.fields-grid{grid-template-columns:repeat(auto-fit,minmax(var(--pfx-always-min, 220px),var(--pfx-always-max-desktop, 380px)));justify-content:start;align-content:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=slider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=range-slider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeSlider],:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=rangeslider]{grid-column:span var(--pfx-slider-span-desktop, 2)}}.inline-toggles{display:flex;align-items:center;gap:8px;margin:0 4px 0 6px}:host ::ng-deep .inline-actions .mat-mdc-slide-toggle{height:var(--pfx-filter-h);display:flex;align-items:center}:host ::ng-deep .inline-actions .mat-mdc-slide-toggle .mdc-form-field{align-items:center}::ng-deep .praxis-filter-overlay .praxis-filter-advanced .praxis-filter-form .filter-row{display:grid!important;gap:var(--pfx-gap-y, 1px) var(--pfx-gap-x, 6px)}@media(min-width:600px){::ng-deep .praxis-filter-overlay .praxis-filter-advanced .praxis-filter-form .filter-row{grid-template-columns:repeat(2,minmax(0,1fr))}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important}.hidden-submit{position:absolute!important;width:0!important;height:0!important;padding:0!important;margin:0!important;border:0!important;opacity:0!important;pointer-events:none!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important;overflow:hidden!important}:host ::ng-deep .inline-actions [matBadge] .mat-badge-content{top:-6px;right:-6px;min-width:16px;height:16px;padding:0 4px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;font-size:10px;font-weight:700;line-height:16px;letter-spacing:0;text-indent:0;color:var(--md-sys-color-on-primary, #fff)}:host ::ng-deep .inline-actions [matBadge][matbadgecolor=warn] .mat-badge-content,:host ::ng-deep .inline-actions [matBadge].mat-badge-warn .mat-badge-content{color:var(--md-sys-color-on-error, #fff)}.praxis-filter-bar :where(.mat-mdc-slide-toggle .mdc-switch__icons){display:none!important}.praxis-filter-bar{--mdc-switch-unselected-icon-size: 0px;--mdc-switch-selected-icon-size: 0px;--pfx-always-min: 220px}.praxis-filter-card{display:flex;flex-direction:column;gap:6px;padding:8px 12px;border-radius:12px;border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface)}:host ::ng-deep .praxis-add-select-panel{width:min(340px,100vw - 24px)!important;min-width:min(280px,100vw - 24px)!important;max-width:calc(100vw - 24px)!important;max-height:min(56vh,420px);margin-top:8px;padding:6px 0;border-radius:14px;overflow:auto;background:var(--md-sys-color-surface-container-highest);border:1px solid var(--pfx-surface-border, var(--md-sys-color-outline-variant));box-shadow:var(--md-sys-elevation-level3)}:host ::ng-deep .cdk-overlay-pane:has(.praxis-add-select-panel){width:auto!important;min-width:0!important;max-width:calc(100vw - 24px)!important}:host ::ng-deep .praxis-add-select-panel .mat-mdc-option{min-height:36px}:host ::ng-deep .praxis-add-select-panel .add-search{position:sticky;top:0;background:var(--md-sys-color-surface-container-highest);z-index:1;padding:0 8px 6px;cursor:default}:host ::ng-deep .praxis-add-select-panel .add-search .mat-mdc-form-field{width:100%}:host ::ng-deep .praxis-add-select-panel .add-search .mat-mdc-form-field-subscript-wrapper{display:none}.inline-actions .add-trigger{display:inline-flex;align-items:center;gap:6px;height:32px;width:100%;max-width:100%;min-width:0;padding:0 10px;border-radius:0;border:0;background:transparent;overflow:visible}.inline-actions .add-trigger--icon{justify-content:center;width:32px;min-width:32px;padding:0}:host ::ng-deep .inline-actions .add-trigger mat-icon{width:18px;height:18px;font-size:18px;flex:0 0 auto}.inline-actions .add-trigger-label{display:inline-block;flex:1 1 auto;min-width:0;max-width:100%;text-align:left;direction:ltr;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.82rem;line-height:1}:host ::ng-deep .action-cluster--manage .mat-mdc-select{flex:0 0 auto;width:180px;min-width:0;max-width:180px}:host ::ng-deep .action-cluster--manage .cluster-select--hidden.mat-mdc-select{position:absolute;width:1px;min-width:1px;max-width:1px;height:1px;opacity:0;pointer-events:none;overflow:hidden}:host ::ng-deep .action-cluster--manage .mat-mdc-select-trigger{min-height:32px;padding:0}:host ::ng-deep .action-cluster--manage .mat-mdc-select-value,:host ::ng-deep .action-cluster--manage .mat-mdc-select-value-text,:host ::ng-deep .action-cluster--manage .mat-mdc-select-min-line{width:auto;min-width:0;max-width:100%;display:inline-flex;align-items:center;justify-content:flex-start;overflow:visible}.praxis-filter-card .summary-header{display:flex;align-items:center;gap:10px}.praxis-filter-card .summary-avatar{width:32px;height:32px;border-radius:50%;object-fit:cover}.praxis-filter-card .summary-title{font-weight:600}.praxis-filter-card .summary-subtitle{opacity:.8;font-size:.875rem}.praxis-filter-card .summary-badges{display:flex;flex-wrap:wrap;gap:6px}.praxis-filter-card .summary-badges span{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:var(--md-sys-color-primary-container);border:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-primary-container);font-size:12px}.praxis-filter-card .card-actions{display:flex;gap:8px}:host ::ng-deep .inline-actions .mat-mdc-select-arrow-wrapper{display:none}.inline-actions .add-filter-btn{height:36px;border-radius:18px;padding:0 16px 0 12px}.inline-actions .add-filter-btn mat-icon{margin-right:8px;margin-left:-4px}:host ::ng-deep .praxis-add-select-panel .add-select-all.partial .select-all-partial{opacity:.7;font-style:italic}\n"] }]
33387
33623
  }], ctorParameters: () => [{ type: i1.GenericCrudService }, { type: undefined, decorators: [{
33388
33624
  type: Inject,
33389
33625
  args: [ASYNC_CONFIG_STORAGE]
33390
- }] }, { type: i0.DestroyRef }, { type: FilterConfigService }, { type: i3$1.SettingsPanelService }, { type: i2$1.MatSnackBar }, { type: i1$3.MatDialog }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i1.DynamicFormService }, { type: i1.SchemaNormalizerService }, { type: i1.ComponentKeyService }, { type: i6$2.ActivatedRoute, decorators: [{
33626
+ }] }, { type: i0.DestroyRef }, { type: FilterConfigService }, { type: i3$1.SettingsPanelService }, { type: i2$2.MatSnackBar }, { type: i1$2.MatDialog }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i1.DynamicFormService }, { type: i1.SchemaNormalizerService }, { type: i1.ComponentKeyService }, { type: i6$2.ActivatedRoute, decorators: [{
33391
33627
  type: Optional
33392
33628
  }] }, { type: i1.LoggerService, decorators: [{
33393
33629
  type: Optional
@@ -33426,6 +33662,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
33426
33662
  type: Input
33427
33663
  }], persistenceKey: [{
33428
33664
  type: Input
33665
+ }], disablePersistence: [{
33666
+ type: Input
33429
33667
  }], i18n: [{
33430
33668
  type: Input
33431
33669
  }], changeDebounceMs: [{
@@ -42024,13 +42262,13 @@ class PraxisTable {
42024
42262
  this.removeViewportChangeListeners = null;
42025
42263
  disposePraxisTableDslRuntimeRegistry(this.dslRuntimeContextKey);
42026
42264
  }
42027
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisTable, deps: [{ token: i0.ChangeDetectorRef }, { token: i3$1.SettingsPanelService }, { token: i1.GenericCrudService }, { token: TableDefaultsProvider }, { token: FilterConfigService }, { token: DataFormattingService }, { token: i6$3.PraxisDialog }, { token: i2$1.MatSnackBar }, { token: ASYNC_CONFIG_STORAGE }, { token: CONNECTION_STORAGE }, { token: i0.ElementRef }, { token: i1.GlobalConfigService }, { token: i1.ComponentKeyService }, { token: i1.LoadingOrchestrator }, { token: PRAXIS_LOADING_RENDERER, optional: true }, { token: i6$2.ActivatedRoute, optional: true }, { token: i1.LoggerService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
42265
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisTable, deps: [{ token: i0.ChangeDetectorRef }, { token: i3$1.SettingsPanelService }, { token: i1.GenericCrudService }, { token: TableDefaultsProvider }, { token: FilterConfigService }, { token: DataFormattingService }, { token: i6$3.PraxisDialog }, { token: i2$2.MatSnackBar }, { token: ASYNC_CONFIG_STORAGE }, { token: CONNECTION_STORAGE }, { token: i0.ElementRef }, { token: i1.GlobalConfigService }, { token: i1.ComponentKeyService }, { token: i1.LoadingOrchestrator }, { token: PRAXIS_LOADING_RENDERER, optional: true }, { token: i6$2.ActivatedRoute, optional: true }, { token: i1.LoggerService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
42028
42266
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisTable, isStandalone: true, selector: "praxis-table", inputs: { config: "config", resourcePath: "resourcePath", data: "data", tableId: "tableId", componentInstanceId: "componentInstanceId", title: "title", subtitle: "subtitle", icon: "icon", autoDelete: "autoDelete", notifyIfOutdated: "notifyIfOutdated", snoozeMs: "snoozeMs", autoOpenSettingsOnOutdated: "autoOpenSettingsOnOutdated", crudContext: "crudContext", dslFunctionRegistry: "dslFunctionRegistry", enableCustomization: ["enableCustomization", "enableCustomization", booleanAttribute], dense: "dense" }, outputs: { rowClick: "rowClick", rowDoubleClick: "rowDoubleClick", rowExpansionChange: "rowExpansionChange", rowAction: "rowAction", toolbarAction: "toolbarAction", bulkAction: "bulkAction", columnReorder: "columnReorder", columnReorderAttempt: "columnReorderAttempt", beforeDelete: "beforeDelete", afterDelete: "afterDelete", deleteError: "deleteError", beforeBulkDelete: "beforeBulkDelete", afterBulkDelete: "afterBulkDelete", bulkDeleteError: "bulkDeleteError", schemaStatusChange: "schemaStatusChange", metadataChange: "metadataChange", loadingStateChange: "loadingStateChange" }, host: { properties: { "class.density-compact": "this.hostDensityCompactClass", "class.density-comfortable": "this.hostDensityComfortableClass", "class.density-spacious": "this.hostDensitySpaciousClass", "class.row-borders": "this.hostRowBordersClass", "class.col-borders": "this.hostColumnBordersClass" } }, providers: [
42029
42267
  GenericCrudService,
42030
42268
  TableDefaultsProvider,
42031
42269
  FilterConfigService,
42032
42270
  DataFormattingService
42033
- ], queries: [{ propertyName: "toolbar", first: true, predicate: PraxisTableToolbar, descendants: true }, { propertyName: "projectedFilter", first: true, predicate: ["projectedFilter"], descendants: true }], viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }, { propertyName: "materialTable", first: true, predicate: MatTable, descendants: true }, { propertyName: "internalFilter", first: true, predicate: PraxisFilter, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (shouldShowEmptyState()) {\n <praxis-empty-state-card\n icon=\"link\"\n [title]=\"'Conecte a tabela \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para carregar colunas e dados automaticamente.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"\n ></praxis-empty-state-card>\n}\n\n<!-- Error State with Quick Connect CTA -->\n@if (isRemoteMode() && (schemaError || dataError)) {\n<div class=\"ptable-error\" role=\"alert\" aria-live=\"assertive\">\n <mat-icon color=\"warn\" aria-hidden=\"true\">error</mat-icon>\n <div class=\"ptable-error__content\">\n <div class=\"ptable-error__title\">Erro</div>\n <div>{{ errorMessage || 'Ocorreu um erro ao carregar a tabela.' }}</div>\n </div>\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\">\n <mat-icon>bolt</mat-icon>\n Conectar a recurso\n </button>\n @if (!schemaError) { <button mat-stroked-button (click)=\"retryData()\">Tentar novamente</button> }\n @if (schemaError) { <button mat-stroked-button (click)=\"reloadSchema()\">Recarregar colunas</button> }\n </div>\n}\n\n<!-- Inline banner for schema change (only in edit mode) -->\n@if (shouldShowOutdatedInline()) {\n<div class=\"ptable-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"onReconcileRequested()\">\n <mat-icon>sync</mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n </div>\n}\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError && toolbarV2) {\n <div class=\"praxis-table-header\" [class.edit-mode]=\"enableCustomization\" [class.stacked]=\"showToolbar\">\n @if (showToolbar && shouldShowToolbarTopPlacement()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n [showActionsGroup]=\"shouldShowToolbarActionsTop()\"\n [showMobileActions]=\"shouldShowToolbarActionsTop()\"\n (toolbarAction)=\"onToolbarAction($event)\"\n (reset)=\"onResetPreferences()\"\n >\n @if (shouldRenderAdvancedFilter()) {\n <praxis-filter\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n \n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (submit)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n }\n <ng-content select=\"[advancedFilter]\" />\n <ng-content select=\"[toolbar]\" />\n \n <!-- AI Assistant in Toolbar -->\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\" end-actions></praxis-ai-assistant>\n }\n }\n\n @if (enableCustomization) {\n <button end-actions mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </praxis-table-toolbar>\n }\n @if (!showToolbar && enableCustomization) {\n <div class=\"ptable-header-actions\">\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n }\n }\n <button mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\" (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n @if (isRemoteMode()) {\n <button mat-icon-button (click)=\"disconnect()\" aria-label=\"Desconectar\" matTooltip=\"Desconectar da fonte de dados\">\n <mat-icon>link_off</mat-icon>\n </button>\n }\n </div>\n }\n </div>\n} @else {\n @if (shouldRenderDataSurface() && !schemaError && !dataError) {\n @if (showToolbar && shouldShowToolbarTopPlacement()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n [showActionsGroup]=\"shouldShowToolbarActionsTop()\"\n [showMobileActions]=\"shouldShowToolbarActionsTop()\"\n (toolbarAction)=\"onToolbarAction($event)\"\n (reset)=\"onResetPreferences()\"\n >\n @if (shouldRenderAdvancedFilter()) {\n <praxis-filter\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n \n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (submit)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n }\n <ng-content select=\"[advancedFilter]\" />\n <ng-content select=\"[toolbar]\" />\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\" end-actions></praxis-ai-assistant>\n }\n }\n @if (enableCustomization) {\n <button end-actions mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </praxis-table-toolbar>\n }\n @if (!showToolbar && enableCustomization) {\n <div class=\"ptable-header-actions\">\n <button mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\" (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n </div>\n }\n }\n}\n<div class=\"px-scroll-viewport\"\n cdkScrollable\n [class.scroll-auto]=\"horizontalScroll === 'auto'\"\n [class.scroll-wrap]=\"horizontalScroll === 'wrap'\"\n [class.scroll-none]=\"horizontalScroll === 'none'\">\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError) {\n<div class=\"praxis-visually-hidden-status\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ columnReorderStatusMessage }}\n</div>\n@if (columnReorderVisualStatusMessage) {\n <div class=\"praxis-column-reorder-status\" role=\"note\">\n {{ columnReorderVisualStatusMessage }}\n </div>\n}\n<table\n mat-table\n data-testid=\"table-column-drag-drop-list\"\n [dataSource]=\"dataSource\"\n [multiTemplateDataRows]=\"isRowExpansionRuntimeEnabled()\"\n cdkDropList\n [cdkDropListDisabled]=\"!isColumnDraggingEnabled()\"\n [cdkDropListData]=\"visibleDataColumnsForDrag\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onColumnDrop($event)\"\n matSort\n (matSortChange)=\"onSortChange($event)\"\n [matSortDisabled]=\"!getSortingEnabled()\"\n [ngClass]=\"getTableElevationClassName()\"\n [class.table-stack-top]=\"showToolbar\"\n [class.pfx-column-drag-enabled]=\"isColumnDraggingEnabled()\"\n [class.pfx-column-drag-indicator]=\"isColumnDragIndicatorEnabled()\"\n>\n @if (config.behavior?.selection?.enabled) {\n <ng-container\n matColumnDef=\"_select\"\n >\n <th mat-header-cell *matHeaderCellDef>\n @if (canSelectAll()) {\n <mat-checkbox\n (change)=\"masterToggle()\"\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n ></mat-checkbox>\n }\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n [checked]=\"selection.isSelected(row)\"\n ></mat-checkbox>\n </td>\n </ng-container>\n }\n @if (isRowExpansionRuntimeEnabled()) {\n <ng-container matColumnDef=\"_expander\">\n <th mat-header-cell *matHeaderCellDef class=\"pfx-expansion-col-header\">\n <span class=\"praxis-visually-hidden-status\">Expandir detalhes da linha</span>\n </th>\n <td mat-cell *matCellDef=\"let row; let i = index\" class=\"pfx-expansion-col-cell\">\n <button\n mat-icon-button\n class=\"pfx-expansion-toggle\"\n [disabled]=\"!isRowExpandable(row, i) || !isExpansionIconTriggerEnabled()\"\n [attr.aria-expanded]=\"isRowExpanded(row, i) ? 'true' : 'false'\"\n [attr.aria-controls]=\"getRowExpansionDetailId(row, i)\"\n [attr.aria-label]=\"getRowExpansionToggleAriaLabel(row, i)\"\n (click)=\"onExpansionToggleFromIcon(row, i, $event)\"\n (keydown)=\"onExpansionToggleKeydown($event, row, i)\"\n >\n <mat-icon [praxisIcon]=\"isRowExpanded(row, i)\n ? getExpansionExpandedIcon()\n : getExpansionCollapsedIcon()\"></mat-icon>\n </button>\n </td>\n </ng-container>\n }\n @for (column of visibleColumns; track column.field) {\n <ng-container\n [matColumnDef]=\"column.field\"\n [sticky]=\"column.sticky === true || column.sticky === 'start'\"\n [stickyEnd]=\"column.sticky === 'end'\"\n >\n <th\n mat-header-cell\n *matHeaderCellDef\n mat-sort-header\n cdkDrag\n [cdkDragData]=\"column\"\n cdkDragLockAxis=\"x\"\n cdkDragPreviewClass=\"pfx-column-drag-preview\"\n (cdkDragStarted)=\"onColumnDragStarted(column)\"\n (cdkDragEnded)=\"onColumnDragEnded($event, column)\"\n (keydown)=\"onColumnDragHandleKeydown($event, column)\"\n [cdkDragDisabled]=\"!isColumnDraggingEnabled() || !isColumnDraggable(column)\"\n [class.praxis-header-draggable]=\"isColumnDraggingEnabled() && isColumnDraggable(column)\"\n [disabled]=\"!getSortingEnabled() || column.sortable === false\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnHeaderAttrStyle(column)\"\n [attr.aria-label]=\"isColumnDraggingEnabled() && isColumnDraggable(column) ? getColumnDragHandleAriaLabel(column) : null\"\n >\n <span class=\"praxis-header-label\" data-testid=\"column-header-label\">\n @if (isColumnDraggingEnabled() && isColumnDraggable(column)) {\n <span\n class=\"praxis-column-drag-handle\"\n data-testid=\"column-drag-handle\"\n [attr.data-column-field]=\"column.field\"\n aria-hidden=\"true\"\n >\n <mat-icon [praxisIcon]=\"'drag_indicator'\"></mat-icon>\n </span>\n }\n <span class=\"praxis-header-label-text\">{{ column.header }}</span>\n </span>\n </th>\n <td\n mat-cell\n *matCellDef=\"let element\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnCellAttrStyle(column)\"\n [ngClass]=\"getCellClasses(element, column)\"\n [ngStyle]=\"getCellNgStyle(element, column)\"\n >\n <div\n class=\"pfx-cell-content\"\n [ngClass]=\"getCellContentClasses(element, column)\"\n [ngStyle]=\"getCellContentNgStyle(element, column)\"\n >\n <ng-container [ngSwitch]=\"getEffectiveRendererType(element, column)\">\n <!-- Icon renderer -->\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon\n [color]=\"getIconColor(element, column) || null\"\n [ngStyle]=\"getIconStyle(element, column)\"\n [attr.aria-label]=\"getIconAriaLabel(element, column) || null\"\n >{{ getIconName(element, column) }}</mat-icon\n >\n </ng-container>\n\n <!-- Image renderer -->\n <ng-container *ngSwitchCase=\"'image'\">\n <img\n class=\"pfx-cell-image\"\n [src]=\"getImageSrc(element, column)\"\n [attr.alt]=\"getImageAlt(element, column) || ''\"\n [attr.loading]=\"getImageLazy(element, column) ? 'lazy' : null\"\n [style.width.px]=\"getImageWidth(element, column)\"\n [style.height.px]=\"getImageHeight(element, column)\"\n [class.shape-rounded]=\"getImageShape(element, column) === 'rounded'\"\n [class.shape-circle]=\"getImageShape(element, column) === 'circle'\"\n [style.object-fit]=\"getImageFit(element, column)\"\n />\n </ng-container>\n\n <!-- Badge renderer -->\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(element, column)\">\n @if (getBadgeIcon(element, column); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }\n <span class=\"pfx-badge-text\">{{ getBadgeText(element, column) }}</span>\n </span>\n </ng-container>\n\n <!-- Link renderer -->\n <ng-container *ngSwitchCase=\"'link'\">\n <a\n class=\"pfx-link\"\n [attr.href]=\"getLinkHref(element, column) || null\"\n [attr.target]=\"getLinkTarget(element, column) || null\"\n [attr.rel]=\"getLinkRel(element, column) || null\"\n (click)=\"$event.stopPropagation()\"\n >{{ getLinkText(element, column) }}</a\n >\n </ng-container>\n\n <!-- Button renderer -->\n <ng-container *ngSwitchCase=\"'button'\">\n <ng-container [ngSwitch]=\"getButtonVariant(element, column)\">\n <button\n *ngSwitchCase=\"'outlined'\"\n mat-stroked-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n <button\n *ngSwitchCase=\"'text'\"\n mat-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n <button\n *ngSwitchDefault\n mat-flat-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n </ng-container>\n </ng-container>\n\n <!-- Chip renderer -->\n <ng-container *ngSwitchCase=\"'chip'\">\n <span class=\"pfx-chip\" [ngClass]=\"getChipClasses(element, column)\">\n @if (getChipIcon(element, column); as ci) { <mat-icon class=\"pfx-chip-icon\">{{ ci }}</mat-icon> }\n <span class=\"pfx-chip-text\">{{ getChipText(element, column) }}</span>\n </span>\n </ng-container>\n\n <!-- Progress renderer -->\n <ng-container *ngSwitchCase=\"'progress'\">\n <div class=\"pfx-progress\">\n <div class=\"pfx-progress-bar\" [style.width.%]=\"getProgressWidthPercentStyle(element, column)\" [style.background]=\"getProgressBackgroundStyle(element, column)\"></div>\n @if (getProgressShowLabel(element, column)) { <div class=\"pfx-progress-label\">{{ getProgressValue(element, column) }}%</div> }\n </div>\n </ng-container>\n\n <!-- Avatar renderer -->\n <ng-container *ngSwitchCase=\"'avatar'\">\n @if (getAvatarSrc(element, column); as asrc) {\n <img class=\"pfx-avatar\" [src]=\"asrc\" [attr.alt]=\"getAvatarAlt(element, column) || ''\" [ngStyle]=\"getAvatarStyle(element, column)\" [class.shape-rounded]=\"getAvatarShape(element, column) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, column) === 'circle'\" loading=\"lazy\" />\n } @else {\n <span class=\"pfx-avatar pfx-avatar--initials\" [ngStyle]=\"getAvatarStyle(element, column)\" [class.shape-rounded]=\"getAvatarShape(element, column) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, column) === 'circle'\">{{ getAvatarInitials(element, column) }}</span>\n }\n </ng-container>\n\n <!-- Toggle renderer -->\n <ng-container *ngSwitchCase=\"'toggle'\">\n <mat-slide-toggle\n [checked]=\"getToggleState(element, column)\"\n [disabled]=\"isToggleDisabled(element, column)\"\n [attr.aria-label]=\"getToggleAriaLabel(element, column) || 'Alternar'\"\n (change)=\"onToggleChange(element, column, $event)\"\n (click)=\"$event.stopPropagation()\"\n ></mat-slide-toggle>\n </ng-container>\n\n <!-- Menu renderer -->\n <ng-container *ngSwitchCase=\"'menu'\">\n <button mat-icon-button [matMenuTriggerFor]=\"menuRef\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getMenuAriaLabel(element, column) || 'Menu'\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menuRef=\"matMenu\">\n <button mat-menu-item *ngFor=\"let it of getMenuItems(element, column)\" (click)=\"onMenuItemClick(it, element, $event)\" [disabled]=\"!it.__visible\" >\n @if (it.icon) { <mat-icon>{{ it.icon }}</mat-icon> }\n <span>{{ it.label }}</span>\n </button>\n </mat-menu>\n </ng-container>\n\n <!-- Rating renderer -->\n <ng-container *ngSwitchCase=\"'rating'\">\n <praxis-table-rating\n class=\"pfx-rating-cell\"\n [itemsCount]=\"getRatingMax(element, column)\"\n [value]=\"getRatingValue(element, column)\"\n [size]=\"getRatingSize(element, column)\"\n [ratingColor]=\"getRatingColor(element, column)\"\n [outlineColor]=\"getRatingOutlineColor(element, column)\"\n [ariaLabel]=\"getRatingAriaLabel(element, column) || column.header\">\n </praxis-table-rating>\n </ng-container>\n\n <!-- HTML renderer (sanitizado) -->\n <ng-container *ngSwitchCase=\"'html'\">\n <span [innerHTML]=\"getSafeHtml(element, column)\"></span>\n </ng-container>\n\n <!-- Compose renderer -->\n <ng-container *ngSwitchCase=\"'compose'\">\n <span class=\"pfx-cell-compose\" [ngClass]=\"getComposeClasses(element, column)\" [ngStyle]=\"getComposeGapStyle(element, column)\">\n <ng-container *ngFor=\"let it of getComposeItems(element, column)\">\n <ng-container [ngSwitch]=\"getItemEffectiveType(element, column, it)\">\n <!-- Reuse helpers by projecting item as faux column -->\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon [color]=\"getIconColor(element, asItemColumn(column, it)) || null\" [ngStyle]=\"getIconStyle(element, asItemColumn(column, it))\" [attr.aria-label]=\"getIconAriaLabel(element, asItemColumn(column, it)) || null\">{{ getIconName(element, asItemColumn(column, it)) }}</mat-icon>\n </ng-container>\n <ng-container *ngSwitchCase=\"'image'\">\n <img class=\"pfx-cell-image\" [src]=\"getImageSrc(element, asItemColumn(column, it))\" [attr.alt]=\"getImageAlt(element, asItemColumn(column, it)) || ''\" [attr.loading]=\"getImageLazy(element, asItemColumn(column, it)) ? 'lazy' : null\" [style.width.px]=\"getImageWidth(element, asItemColumn(column, it))\" [style.height.px]=\"getImageHeight(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getImageShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getImageShape(element, asItemColumn(column, it)) === 'circle'\" [style.object-fit]=\"getImageFit(element, asItemColumn(column, it))\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(element, asItemColumn(column, it))\">@if (getBadgeIcon(element, asItemColumn(column, it)); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }<span class=\"pfx-badge-text\">{{ getBadgeText(element, asItemColumn(column, it)) }}</span></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'link'\">\n <a class=\"pfx-link\" [attr.href]=\"getLinkHref(element, asItemColumn(column, it)) || null\" [attr.target]=\"getLinkTarget(element, asItemColumn(column, it)) || null\" [attr.rel]=\"getLinkRel(element, asItemColumn(column, it)) || null\" (click)=\"$event.stopPropagation()\">{{ getLinkText(element, asItemColumn(column, it)) }}</a>\n </ng-container>\n <ng-container *ngSwitchCase=\"'button'\">\n <ng-container [ngSwitch]=\"getButtonVariant(element, asItemColumn(column, it))\">\n <button *ngSwitchCase=\"'outlined'\" mat-stroked-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n <button *ngSwitchCase=\"'text'\" mat-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n <button *ngSwitchDefault mat-flat-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'chip'\">\n <span class=\"pfx-chip\" [ngClass]=\"getChipClasses(element, asItemColumn(column, it))\">@if (getChipIcon(element, asItemColumn(column, it)); as ci) { <mat-icon class=\"pfx-chip-icon\">{{ ci }}</mat-icon> }<span class=\"pfx-chip-text\">{{ getChipText(element, asItemColumn(column, it)) }}</span></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'progress'\">\n <div class=\"pfx-progress\"><div class=\"pfx-progress-bar\" [style.width.%]=\"getProgressWidthPercentStyle(element, asItemColumn(column, it))\" [style.background]=\"getProgressBackgroundStyle(element, asItemColumn(column, it))\"></div>@if (getProgressShowLabel(element, asItemColumn(column, it))) { <div class=\"pfx-progress-label\">{{ getProgressValue(element, asItemColumn(column, it)) }}%</div> }</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'avatar'\">\n @if (getAvatarSrc(element, asItemColumn(column, it)); as asrc) {\n <img class=\"pfx-avatar\" [src]=\"asrc\" [attr.alt]=\"getAvatarAlt(element, asItemColumn(column, it)) || ''\" [ngStyle]=\"getAvatarStyle(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getAvatarShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, asItemColumn(column, it)) === 'circle'\" loading=\"lazy\" />\n } @else {\n <span class=\"pfx-avatar pfx-avatar--initials\" [ngStyle]=\"getAvatarStyle(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getAvatarShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, asItemColumn(column, it)) === 'circle'\">{{ getAvatarInitials(element, asItemColumn(column, it)) }}</span>\n }\n </ng-container>\n <ng-container *ngSwitchCase=\"'toggle'\">\n <mat-slide-toggle [checked]=\"getToggleState(element, asItemColumn(column, it))\" [disabled]=\"isToggleDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getToggleAriaLabel(element, asItemColumn(column, it)) || 'Alternar'\" (change)=\"onToggleChange(element, asItemColumn(column, it), $event)\" (click)=\"$event.stopPropagation()\"></mat-slide-toggle>\n </ng-container>\n <ng-container *ngSwitchCase=\"'menu'\">\n <button mat-icon-button [matMenuTriggerFor]=\"menuRef\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getMenuAriaLabel(element, asItemColumn(column, it)) || 'Menu'\"><mat-icon>more_vert</mat-icon></button>\n <mat-menu #menuRef=\"matMenu\">\n <button mat-menu-item *ngFor=\"let mi of getMenuItems(element, asItemColumn(column, it))\" (click)=\"onMenuItemClick(mi, element, $event)\" [disabled]=\"!mi.__visible\">\n @if (mi.icon) { <mat-icon>{{ mi.icon }}</mat-icon> }\n <span>{{ mi.label }}</span>\n </button>\n </mat-menu>\n </ng-container>\n <ng-container *ngSwitchCase=\"'rating'\">\n <praxis-table-rating\n class=\"pfx-rating-cell\"\n [itemsCount]=\"getRatingMax(element, asItemColumn(column, it))\"\n [value]=\"getRatingValue(element, asItemColumn(column, it))\"\n [size]=\"getRatingSize(element, asItemColumn(column, it))\"\n [ratingColor]=\"getRatingColor(element, asItemColumn(column, it))\"\n [outlineColor]=\"getRatingOutlineColor(element, asItemColumn(column, it))\"\n [ariaLabel]=\"getRatingAriaLabel(element, asItemColumn(column, it)) || column.header\">\n </praxis-table-rating>\n </ng-container>\n <ng-container *ngSwitchCase=\"'html'\">\n <span [innerHTML]=\"getSafeHtml(element, asItemColumn(column, it))\"></span>\n </ng-container>\n <!-- Value item: render base cell text alongside visuals -->\n <ng-container *ngSwitchCase=\"'value'\">\n <span class=\"pfx-cell-value\">{{ getComposeItemValue(element, column, it) }}</span>\n </ng-container>\n </ng-container>\n </ng-container>\n </span>\n </ng-container>\n\n <!-- Default text rendering -->\n <ng-container *ngSwitchDefault>\n {{ getCellValue(element, column) }}\n </ng-container>\n </ng-container>\n </div>\n </td>\n </ng-container>\n }\n @if (config.actions?.row?.enabled) {\n <ng-container matColumnDef=\"_actions\" [sticky]=\"config.actions?.row?.sticky === true || config.actions?.row?.sticky === 'start'\" [stickyEnd]=\"config.actions?.row?.sticky === 'end'\">\n <th mat-header-cell *matHeaderCellDef #actionsHeaderCell [style.width]=\"getRowActionsWidthStyle()\" class=\"praxis-actions-header\" [class.align-start]=\"getActionsHeaderAlign() === 'start'\" [class.align-center]=\"getActionsHeaderAlign() === 'center'\" [class.align-end]=\"getActionsHeaderAlign() === 'end'\">\n <div class=\"praxis-actions-header__content\" [matTooltip]=\"getActionsHeaderTooltip() || ''\" [matTooltipDisabled]=\"!getActionsHeaderTooltip()\">\n @if (getActionsHeaderIcon(); as hi) { <mat-icon [praxisIcon]=\"hi\"></mat-icon> }\n @if (getActionsHeaderLabel(); as hl) { <span class=\"label\">{{ hl }}</span> }\n </div>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"praxis-actions-cell\"\n [class.dense]=\"dense\"\n [style.width]=\"getRowActionsWidthStyle()\"\n >\n <div class=\"praxis-actions-cell__content\">\n <!-- A\u00E7\u00F5es inline -->\n <!-- Inline actions: icons mode -->\n @if (config.actions?.row?.display === 'icons' || !config.actions?.row?.display) {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button\n mat-icon-button\n class=\"praxis-icon-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [matTooltip]=\"a.label || getActionId(a)\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"praxis-tooltip\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\"\n >\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n </button>\n </ng-container>\n }\n\n <!-- Inline actions: buttons mode (show label + icon) -->\n @if (config.actions?.row?.display === 'buttons') {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button\n mat-flat-button\n class=\"praxis-row-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\"\n >\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n }\n\n <!-- Menu de overflow -->\n @if (hasOverflowRowActions(row)) {\n <button\n mat-icon-button\n class=\"praxis-icon-btn praxis-more-btn\"\n [matMenuTriggerFor]=\"rowMoreMenu\"\n [color]=\"getRowMenuButtonColor() || null\"\n aria-label=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"getRowMenuIcon()\"></mat-icon>\n </button>\n }\n <mat-menu #rowMoreMenu=\"matMenu\" xPosition=\"before\">\n <ng-container\n *ngFor=\"let a of getOverflowRowActions(row); trackBy: trackAction\"\n >\n <button\n mat-menu-item\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [disabled]=\"isActionDisabled(a, row)\"\n >\n <mat-icon [color]=\"a.color || null\" [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n </mat-menu>\n </div>\n </td>\n </ng-container>\n }\n\n <tr\n mat-header-row\n *matHeaderRowDef=\"displayedColumns\"\n ></tr>\n @if (!isVirtualized()) {\n <tr\n mat-row\n *matRowDef=\"let row; let i = index; columns: displayedColumns\"\n [class.pfx-row-selected]=\"selection.isSelected(row)\"\n [class.pfx-row-expanded]=\"isRowExpansionRuntimeEnabled() && isRowExpanded(row, i)\"\n [attr.aria-selected]=\"config.behavior?.selection?.enabled ? (selection.isSelected(row) ? 'true' : 'false') : null\"\n [attr.aria-expanded]=\"isRowExpansionRuntimeEnabled() ? (isRowExpanded(row, i) ? 'true' : 'false') : null\"\n [ngClass]=\"getRowClasses(row)\"\n [ngStyle]=\"getRowNgStyle(row)\"\n [matTooltip]=\"getRowTooltip(row) || null\"\n [matTooltipDisabled]=\"!getRowTooltip(row)\"\n [matTooltipPosition]=\"getRowTooltipPosition(row)\"\n [matTooltipShowDelay]=\"getRowTooltipShowDelay(row)\"\n (click)=\"onRowClicked(row, i, $event)\"\n (dblclick)=\"onRowDoubleClicked(row, i)\"\n ></tr>\n @if (isRowExpansionRuntimeEnabled()) {\n <ng-container matColumnDef=\"_detail\">\n <td\n mat-cell\n *matCellDef=\"let row; let i = index\"\n class=\"pfx-expansion-detail-cell\"\n [attr.colspan]=\"displayedColumns.length\"\n >\n <section\n class=\"pfx-expansion-detail-panel\"\n [ngClass]=\"getExpansionMotionPresetClass()\"\n [ngStyle]=\"getExpansionMotionStyle()\"\n [attr.id]=\"getRowExpansionDetailId(row, i)\"\n role=\"region\"\n [attr.aria-label]=\"getRowExpansionRegionAriaLabel(row, i)\"\n [attr.aria-busy]=\"getExpansionDetailViewState(row, i).status === 'loading' ? 'true' : 'false'\"\n >\n @let detailState = getExpansionDetailViewState(row, i);\n @if (detailState.status === 'loading') {\n <div class=\"pfx-expansion-detail-message\" role=\"status\" aria-live=\"polite\">\n Carregando detail schema...\n </div>\n } @else if (detailState.status !== 'ready') {\n <div\n class=\"pfx-expansion-detail-message pfx-expansion-detail-message--error\"\n role=\"alert\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n >\n {{ detailState.message || 'Detail indispon\u00EDvel para esta linha.' }}\n </div>\n } @else {\n @if (getExpansionDetailLayout(detailState.schema) === 'tabs') {\n @let detailTabs = getExpansionDetailTabs(detailState.schema);\n @if (detailTabs.length) {\n <div class=\"pfx-expansion-detail-tabs\" role=\"tablist\" aria-label=\"Se\u00E7\u00F5es do detail\">\n @for (tab of detailTabs; track $index; let tabIndex = $index) {\n <button\n type=\"button\"\n class=\"pfx-expansion-detail-tab-btn\"\n role=\"tab\"\n [attr.id]=\"getExpansionDetailTabId(row, i, tab, tabIndex)\"\n [attr.aria-controls]=\"getExpansionDetailPanelId(row, i, tab, tabIndex)\"\n [attr.aria-selected]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs) ? 'true' : 'false'\"\n [attr.tabindex]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs) ? '0' : '-1'\"\n [class.is-active]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs)\"\n (click)=\"onExpansionDetailTabSelect(row, i, tab, tabIndex, $event)\"\n (keydown)=\"onExpansionDetailTabKeydown($event, row, i, tabIndex, detailTabs)\"\n >\n {{ getExpansionDetailNodeTitle(tab, 'Tab') }}\n </button>\n }\n </div>\n @for (tab of detailTabs; track $index; let tabIndex = $index) {\n @if (isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs)) {\n <div\n class=\"pfx-expansion-detail-tab-panel\"\n role=\"tabpanel\"\n [attr.id]=\"getExpansionDetailPanelId(row, i, tab, tabIndex)\"\n [attr.aria-labelledby]=\"getExpansionDetailTabId(row, i, tab, tabIndex)\"\n >\n @for (childNode of getExpansionDetailNodeChildren(tab); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: childNode, row: row, index: i }\n \"\n ></ng-container>\n }\n </div>\n }\n }\n } @else {\n <div class=\"pfx-expansion-detail-message\">\n Schema em layout tabs sem abas v\u00E1lidas.\n </div>\n }\n } @else {\n <div class=\"pfx-expansion-detail-stack\">\n @for (node of getExpansionDetailItems(detailState.schema); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: node, row: row, index: i }\n \"\n ></ng-container>\n }\n </div>\n }\n }\n\n <ng-template #expansionDetailNodeTemplate let-node let-row=\"row\" let-index=\"index\">\n @switch (getExpansionDetailNodeType(node)) {\n @case ('card') {\n <article class=\"pfx-expansion-node pfx-expansion-node-card\">\n <header class=\"pfx-expansion-node-card__header\">\n <h5 class=\"pfx-expansion-node-card__title\">\n {{ getExpansionDetailNodeTitle(node, 'Card') }}\n </h5>\n @if (node?.subtitle) {\n <p class=\"pfx-expansion-node-card__subtitle\">{{ node?.subtitle }}</p>\n }\n </header>\n @for (childNode of getExpansionDetailNodeChildren(node); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: childNode, row: row, index: index }\n \"\n ></ng-container>\n }\n </article>\n }\n @case ('value') {\n <div class=\"pfx-expansion-node pfx-expansion-node-value\">\n <span class=\"pfx-expansion-node-value__label\">\n {{ getExpansionDetailNodeTitle(node, 'Valor') }}\n </span>\n <strong class=\"pfx-expansion-node-value__content\">\n {{ getExpansionDetailValue(row, node) }}\n </strong>\n </div>\n }\n @case ('list') {\n <section class=\"pfx-expansion-node pfx-expansion-node-list\">\n <h6 class=\"pfx-expansion-node-list__title\">\n {{ getExpansionDetailNodeTitle(node, 'Lista') }}\n </h6>\n @let listItems = getExpansionDetailListItems(row, node);\n @if (listItems.length) {\n <ul>\n @for (entry of listItems; track $index) {\n <li>{{ entry }}</li>\n }\n </ul>\n } @else {\n <p class=\"pfx-expansion-node-placeholder\">Sem itens.</p>\n }\n </section>\n }\n @case ('richText') {\n <div\n class=\"pfx-expansion-node pfx-expansion-node-richtext\"\n [innerHTML]=\"getExpansionDetailRichText(node)\"\n ></div>\n }\n @case ('formRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Formul\u00E1rio referenciado: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('tableRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Tabela referenciada: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('chartRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Gr\u00E1fico referenciado: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('templateRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Template referenciado: <code>{{ node?.id || node?.templateId || 'sem-id' }}</code>\n </div>\n }\n @case ('action') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n A\u00E7\u00E3o declarada: <code>{{ node?.id || node?.actionId || 'sem-id' }}</code>\n </div>\n }\n @case ('tab') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Node <code>tab</code> fora de contexto de tabs.\n </div>\n }\n @default {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Node n\u00E3o suportado: <code>{{ getExpansionDetailNodeType(node) }}</code>\n </div>\n }\n }\n </ng-template>\n </section>\n </td>\n </ng-container>\n <tr\n mat-row\n *matRowDef=\"let row; columns: expansionDetailRowColumns; when: isExpansionDetailRow\"\n class=\"pfx-expansion-detail-row\"\n ></tr>\n }\n }\n</table>\n}\n\n<!-- Virtual rows path (header preserved above) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && isVirtualized()) {\n <cdk-virtual-scroll-viewport\n class=\"ptable-viewport\"\n [itemSize]=\"getVirtItemHeight()\"\n [minBufferPx]=\"getVirtBufferSize() * getVirtItemHeight()\"\n [maxBufferPx]=\"getVirtBufferSize() * getVirtItemHeight() * 2\"\n [style.minHeight]=\"getVirtMinHeightHostStyle()\"\n >\n <table\n class=\"mat-mdc-table\"\n [ngClass]=\"getTableElevationClassName()\"\n [style.width]=\"getVirtualTableWidthStyle()\"\n >\n <tbody>\n <tr class=\"mat-mdc-row\"\n *cdkVirtualFor=\"let row of dataSource.data; let i = index; trackBy: trackByRow\"\n [class.pfx-row-selected]=\"selection.isSelected(row)\"\n [attr.aria-selected]=\"config.behavior?.selection?.enabled ? (selection.isSelected(row) ? 'true' : 'false') : null\"\n [ngClass]=\"getRowClasses(row)\"\n [ngStyle]=\"getRowNgStyle(row)\"\n [matTooltip]=\"getRowTooltip(row) || null\"\n [matTooltipDisabled]=\"!getRowTooltip(row)\"\n [matTooltipPosition]=\"getRowTooltipPosition(row)\"\n [matTooltipShowDelay]=\"getRowTooltipShowDelay(row)\"\n (click)=\"onRowClicked(row, i, $event)\"\n (dblclick)=\"onRowDoubleClicked(row, i)\">\n <!-- Selection column -->\n @if (config.behavior?.selection?.enabled) { <td class=\"mat-mdc-cell\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td> }\n <!-- Data columns -->\n @for (column of visibleColumns; track column.field) {\n <td class=\"mat-mdc-cell\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnCellAttrStyle(column)\"\n [ngClass]=\"getCellClasses(row, column)\"\n [ngStyle]=\"getCellNgStyle(row, column)\">\n <div\n class=\"pfx-cell-content\"\n [ngClass]=\"getCellContentClasses(row, column)\"\n [ngStyle]=\"getCellContentNgStyle(row, column)\"\n >\n <ng-container [ngSwitch]=\"getEffectiveRendererType(row, column)\">\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon [color]=\"getIconColor(row, column) || null\"\n [ngStyle]=\"getIconStyle(row, column)\"\n [attr.aria-label]=\"getIconAriaLabel(row, column) || null\">\n {{ getIconName(row, column) }}\n </mat-icon>\n </ng-container>\n <ng-container *ngSwitchCase=\"'image'\">\n <img class=\"pfx-cell-image\"\n [src]=\"getImageSrc(row, column)\"\n [attr.alt]=\"getImageAlt(row, column) || ''\"\n [attr.loading]=\"getImageLazy(row, column) ? 'lazy' : null\"\n [style.width.px]=\"getImageWidth(row, column)\"\n [style.height.px]=\"getImageHeight(row, column)\"\n [class.shape-rounded]=\"getImageShape(row, column) === 'rounded'\"\n [class.shape-circle]=\"getImageShape(row, column) === 'circle'\"\n [style.object-fit]=\"getImageFit(row, column)\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(row, column)\">\n @if (getBadgeIcon(row, column); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }\n <span class=\"pfx-badge-text\">{{ getBadgeText(row, column) }}</span>\n </span>\n </ng-container>\n <ng-container *ngSwitchDefault>\n {{ getCellValue(row, column) }}\n </ng-container>\n </ng-container>\n </div>\n </td>\n }\n\n <!-- Actions column -->\n @if (config.actions?.row?.enabled) {\n <td class=\"mat-mdc-cell praxis-actions-cell\" [class.dense]=\"dense\" [style.width]=\"getRowActionsWidthStyle()\">\n <div class=\"praxis-actions-cell__content\">\n @if (config.actions?.row?.display === 'icons' || !config.actions?.row?.display) {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button mat-icon-button class=\"praxis-icon-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [matTooltip]=\"a.label || getActionId(a)\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"praxis-tooltip\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\">\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n </button>\n </ng-container>\n }\n @if (config.actions?.row?.display === 'buttons') {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button mat-flat-button class=\"praxis-row-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\">\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n }\n @if (hasOverflowRowActions(row)) {\n <button mat-icon-button class=\"praxis-icon-btn praxis-more-btn\"\n [matMenuTriggerFor]=\"rowMoreMenuV\"\n [color]=\"getRowMenuButtonColor() || null\"\n aria-label=\"Mais a\u00E7\u00F5es\">\n <mat-icon [praxisIcon]=\"getRowMenuIcon()\"></mat-icon>\n </button>\n }\n <mat-menu #rowMoreMenuV=\"matMenu\" xPosition=\"before\">\n <ng-container *ngFor=\"let a of getOverflowRowActions(row); trackBy: trackAction\">\n <button mat-menu-item (click)=\"onRowAction(getActionId(a), row, $event)\" [disabled]=\"isActionDisabled(a, row)\">\n <mat-icon [color]=\"a.color || null\" [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n </mat-menu>\n </div>\n </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n}\n\n</div>\n@if (\n shouldRenderDataSurface()\n && !schemaError\n && !dataError\n && shouldRenderFloatingBulkActions()\n && getFloatingBulkActions().length\n && !shouldHideFloatingBulkActions()\n) {\n <div [class]=\"'praxis-floating-bulk-actions ' + getFloatingBulkPositionClass()\">\n @for (action of getFloatingBulkActions(); track getActionId(action)) {\n <button\n mat-mini-fab\n [color]=\"action.color || 'primary'\"\n [disabled]=\"isFloatingBulkActionDisabled(action)\"\n (click)=\"onToolbarAction({ action: getActionId(action), actionConfig: action })\"\n [attr.aria-label]=\"action.label || getActionId(action)\"\n [matTooltip]=\"action.label || getActionId(action)\"\n matTooltipPosition=\"left\"\n >\n <mat-icon [praxisIcon]=\"action.icon || 'done_all'\"></mat-icon>\n </button>\n }\n </div>\n}\n<!-- Barra de a\u00E7\u00F5es no rodap\u00E9 (opcional) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && showToolbar && shouldRenderFooterToolbar()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [class.footer-flat]=\"hasBottomPaginator()\"\n class=\"praxis-toolbar-footer\"\n placement=\"footer\"\n [showMain]=\"shouldShowFooterToolbarMain()\"\n [showEndActions]=\"shouldShowFooterToolbarEndActions()\"\n [showReset]=\"shouldShowFooterToolbarReset()\"\n [showActionsGroup]=\"shouldShowToolbarActionsBottom()\"\n [showMobileActions]=\"shouldShowToolbarActionsBottom()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n (toolbarAction)=\"onToolbarAction($event)\"\n >\n <praxis-filter\n *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\"\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (submit)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n <ng-container *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\">\n <ng-content select=\"[advancedFilter]\"></ng-content>\n </ng-container>\n <ng-container *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\">\n <ng-content select=\"[toolbar]\"></ng-content>\n </ng-container>\n @if (shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()) {\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant\n [adapter]=\"aiAdapter\"\n end-actions\n ></praxis-ai-assistant>\n }\n }\n }\n <button\n *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter() && enableCustomization\"\n end-actions\n mat-icon-button\n color=\"primary\"\n data-role=\"table-settings\"\n data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\"\n aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\"\n >\n <mat-icon>settings</mat-icon>\n </button>\n </praxis-table-toolbar>\n}\n<!-- Paginadores (top/bottom) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && getPaginationEnabled() && (config.behavior?.pagination?.position === 'top' || config.behavior?.pagination?.position === 'both')) {\n <mat-paginator\n [length]=\"getPaginationLength()\"\n [pageSize]=\"getPaginationPageSize()\"\n [pageSizeOptions]=\"getPaginationPageSizeOptions()\"\n [showFirstLastButtons]=\"getPaginationShowFirstLast()\"\n (page)=\"onPageChange($event)\"\n [class.compact]=\"config.behavior?.pagination?.style === 'compact'\"\n >\n </mat-paginator>\n}\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError && getPaginationEnabled() && (config.behavior?.pagination?.position === 'bottom' || config.behavior?.pagination?.position === 'both' || !config.behavior?.pagination?.position)) {\n <mat-paginator\n [length]=\"getPaginationLength()\"\n [pageSize]=\"getPaginationPageSize()\"\n [pageSizeOptions]=\"getPaginationPageSizeOptions()\"\n [showFirstLastButtons]=\"getPaginationShowFirstLast()\"\n (page)=\"onPageChange($event)\"\n [class.compact]=\"config.behavior?.pagination?.style === 'compact'\"\n [class.footer-stack]=\"shouldShowToolbarActionsBottom()\"\n >\n </mat-paginator>\n}\n", styles: ["@charset \"UTF-8\";table{width:100%}.praxis-visually-hidden-status{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.praxis-column-reorder-status{margin:8px 0;padding:10px 12px;border-radius:8px;border:1px solid var(--p-table-border-color);background:var(--p-table-row-hover-bg);color:var(--p-table-header-fg);font-size:12px;line-height:1.4;box-shadow:0 4px 12px #00000014;animation:pfx-column-reorder-status-in var(--p-table-drag-status-enter-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}@keyframes pfx-column-reorder-status-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.praxis-actions-cell{height:100%;padding-inline:12px;white-space:nowrap}.pfx-expansion-col-header,.pfx-expansion-col-cell{width:52px;min-width:52px;text-align:center}.pfx-expansion-toggle:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pfx-expansion-detail-row{background:var(--md-sys-color-surface-container-low)}.pfx-expansion-detail-cell{padding:0!important;border-bottom:1px solid var(--p-table-border-color)}.pfx-expansion-detail-panel{padding:12px 16px;border-left:3px solid var(--md-sys-color-primary)}.pfx-expansion-detail-panel.pfx-expansion-motion-none{animation:none;transition:none}.pfx-expansion-detail-panel.pfx-expansion-motion-subtle-slide{animation:pfx-expansion-subtle-slide-in var(--pfx-expansion-motion-duration, .16s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1))}.pfx-expansion-detail-panel.pfx-expansion-motion-accordion{animation:pfx-expansion-accordion-in var(--pfx-expansion-motion-duration, .18s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1));transform-origin:top center}.pfx-expansion-detail-panel.pfx-expansion-motion-fade-scale{animation:pfx-expansion-fade-scale-in var(--pfx-expansion-motion-duration, .16s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1));transform-origin:top center}@keyframes pfx-expansion-subtle-slide-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes pfx-expansion-accordion-in{0%{opacity:0;transform:scaleY(.96)}to{opacity:1;transform:scaleY(1)}}@keyframes pfx-expansion-fade-scale-in{0%{opacity:0;transform:translateY(-2px) scale(.985)}to{opacity:1;transform:translateY(0) scale(1)}}.pfx-expansion-detail-schema{margin:0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px;line-height:1.4;white-space:pre-wrap;word-break:break-word;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-detail-message{font-size:13px;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-detail-message--error{color:var(--md-sys-color-error)}.pfx-expansion-detail-stack{display:grid;gap:10px}.pfx-expansion-detail-tabs{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px}.pfx-expansion-detail-tab-btn{border:1px solid var(--p-table-border-color);background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface);border-radius:999px;padding:6px 12px;font-size:12px;line-height:1.2;cursor:pointer}.pfx-expansion-detail-tab-btn.is-active{border-color:var(--md-sys-color-primary);color:var(--md-sys-color-primary);font-weight:600}.pfx-expansion-detail-tab-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pfx-expansion-detail-tab-panel{display:grid;gap:10px}.pfx-expansion-node{border:1px solid var(--p-table-border-color);border-radius:8px;padding:10px 12px;background:var(--md-sys-color-surface)}.pfx-expansion-node-card__header{margin-bottom:8px}.pfx-expansion-node-card__title{margin:0;font-size:14px;line-height:1.3}.pfx-expansion-node-card__subtitle{margin:4px 0 0;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-node-value{display:flex;align-items:baseline;gap:8px}.pfx-expansion-node-value__label{color:var(--md-sys-color-on-surface-variant);font-size:12px}.pfx-expansion-node-value__content{font-size:14px}.pfx-expansion-node-list__title{margin:0 0 6px;font-size:13px}.pfx-expansion-node-list ul{margin:0;padding-left:18px}.pfx-expansion-node-richtext :where(p,ul,ol,h1,h2,h3,h4,h5,h6){margin-top:0;margin-bottom:8px}.pfx-expansion-node-placeholder{font-size:12px;color:var(--md-sys-color-on-surface-variant)}:host.density-compact{--p-header-padding: 8px 12px;--p-cell-padding: 8px 12px;--p-actions-btn-size: 32px;--p-actions-icon-size: 18px}:host.density-comfortable{--p-header-padding: 12px 16px;--p-cell-padding: 12px 16px;--p-actions-btn-size: 40px;--p-actions-icon-size: 22px}:host.density-spacious{--p-header-padding: 16px 20px;--p-cell-padding: 16px 20px;--p-actions-btn-size: 44px;--p-actions-icon-size: 24px}:host.density-compact ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 8px 12px)}:host.density-comfortable ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 12px 16px)}:host.density-spacious ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 16px 20px)}:host.density-compact .praxis-actions-cell{padding-inline:8px}:host.density-spacious .praxis-actions-cell{padding-inline:16px}.praxis-actions-cell__content{display:flex;align-items:center;justify-content:flex-end;gap:8px;width:100%}.praxis-actions-cell.dense .praxis-actions-cell__content{gap:6px}.praxis-icon-btn{width:var(--p-actions-btn-size, 40px);height:var(--p-actions-btn-size, 40px);border:0;background:transparent;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:9999px;cursor:pointer;--mat-icon-button-state-layer-size: var(--p-actions-btn-size, 40px)}.praxis-icon-btn:hover{background:var(--md-sys-color-surface-variant)}.praxis-icon-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.praxis-icon-btn mat-icon,.praxis-icon-btn .mat-icon{font-size:var(--p-actions-icon-size, 22px);width:var(--p-actions-icon-size, 22px);height:var(--p-actions-icon-size, 22px);line-height:var(--p-actions-icon-size, 22px)}.praxis-more-btn{width:var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));height:var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));--mat-icon-button-state-layer-size: var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));background-image:var(--p-actions-more-btn-gradient, none);background-size:100% 100%;background-repeat:no-repeat}.praxis-more-btn mat-icon,.praxis-more-btn .mat-icon{font-size:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));width:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));height:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));line-height:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));color:var(--p-actions-more-icon-color);background-image:var(--p-actions-more-icon-gradient, none);-webkit-background-clip:text;background-clip:text}.praxis-icon-btn.destructive mat-icon{color:var(--md-sys-color-error)}.mat-mdc-tooltip.praxis-tooltip{margin-top:-8px;margin-bottom:8px}.spacer{flex:1 1 auto}.praxis-table-header{display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;margin:16px 0 12px;width:100%;clear:both;position:relative}.praxis-table-header.stacked{margin:0}.praxis-table-header>praxis-table-toolbar{flex:1 0 100%}.praxis-floating-bulk-actions{position:fixed;z-index:1001;display:inline-flex;align-items:center;gap:8px;padding:8px;border-radius:999px;background:var(--md-sys-color-surface-container-highest);box-shadow:0 8px 20px #00000029}.praxis-floating-bulk-actions.pos-bottom-right{right:20px;bottom:20px}.praxis-floating-bulk-actions.pos-bottom-left{left:20px;bottom:20px}.praxis-floating-bulk-actions.pos-top-right{right:20px;top:20px}.praxis-floating-bulk-actions.pos-top-left{left:20px;top:20px}@media(max-width:768px){.praxis-floating-bulk-actions{gap:6px;padding:6px}.praxis-floating-bulk-actions.pos-bottom-right{right:12px;left:auto;bottom:12px}.praxis-floating-bulk-actions.pos-bottom-left{left:12px;right:auto;bottom:12px}.praxis-floating-bulk-actions.pos-top-right{right:12px;left:auto;top:12px}.praxis-floating-bulk-actions.pos-top-left{left:12px;right:auto;top:12px}}:host{display:block;width:100%;min-width:0;max-width:100%;--pfx-toolbar-pad-y: 6px;--pfx-toolbar-pad-x: 12px;--p-table-bg: var(--md-sys-color-surface-container-highest);--p-table-text-color: var(--md-sys-color-on-surface);--p-table-header-bg: var(--md-sys-color-surface-container-highest);--p-table-header-fg: var(--md-sys-color-on-surface);--p-table-border-color: var(--md-sys-color-outline-variant);--p-table-row-even-bg: var(--md-sys-color-surface-container);--p-table-row-hover-bg: var(--md-sys-color-surface-container-high);--p-table-row-selected-bg: var(--md-sys-color-primary-container);--p-table-badge-soft-primary-bg: var(--md-sys-color-primary-container);--p-table-badge-soft-primary-fg: var(--md-sys-color-on-primary-container);--p-table-badge-soft-accent-bg: var(--md-sys-color-secondary-container);--p-table-badge-soft-accent-fg: var(--md-sys-color-on-secondary-container);--p-table-badge-soft-warn-bg: var(--md-sys-color-error-container);--p-table-badge-soft-warn-fg: var(--md-sys-color-on-error-container);--p-table-state-success-bg: var(--md-sys-color-tertiary-container);--p-table-state-success-fg: var(--md-sys-color-on-tertiary-container);--p-table-state-warning-bg: var(--md-sys-color-secondary-container);--p-table-state-warning-fg: var(--md-sys-color-on-secondary-container);--p-table-state-danger-bg: var(--md-sys-color-error-container);--p-table-state-danger-fg: var(--md-sys-color-on-error-container);--p-table-state-highlight-bg: var(--md-sys-color-primary-container);--p-table-state-highlight-fg: var(--md-sys-color-on-primary-container);--p-table-drag-handle-size: 14px;--p-table-drag-handle-color: var(--md-sys-color-on-surface-variant);--p-table-drag-handle-hover-color: var(--md-sys-color-on-surface);--p-table-drag-handle-base-opacity: 0;--p-table-drag-handle-visible-opacity: .72;--p-table-drag-handle-active-opacity: 1;--p-table-drag-handle-transition-duration: .16s;--p-table-reorder-transition-duration: .16s;--p-table-drag-preview-scale: 1.01;--p-table-drag-status-enter-duration: .18s;--p-table-drag-preview-shadow: 0 14px 32px rgba(0, 0, 0, .28), 0 0 0 1px var(--p-table-border-color)}:host ::ng-deep .mat-mdc-table{background:var(--p-table-bg);color:var(--p-table-text-color);border-radius:12px 12px 0 0;width:100%;box-shadow:var(--p-table-surface-shadow);transition:box-shadow var(--p-table-selection-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .mat-mdc-table:hover{box-shadow:var(--p-table-surface-shadow-hover, var(--p-table-surface-shadow))}:host ::ng-deep .mat-mdc-table.table-stack-top{border-top-left-radius:0;border-top-right-radius:0}:host ::ng-deep .praxis-toolbar-footer{border:0 solid var(--p-table-border-color);border-top:0;border-radius:0;background:var(--p-table-bg)}:host ::ng-deep .mat-mdc-paginator.footer-stack{border-top-left-radius:0;border-top-right-radius:0;border-top:0}:host ::ng-deep .mat-mdc-paginator.footer-stack .mat-mdc-paginator-container{padding:8px 12px}:host [data-role=table-settings].mat-mdc-icon-button{--mdc-icon-button-icon-color: var(--md-sys-color-primary);color:var(--md-sys-color-primary)}.pfx-link{color:var(--md-sys-color-primary);text-decoration:underline;cursor:pointer}.pfx-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:10px;font-size:12px;line-height:1;border:1px solid transparent}.pfx-chip-icon{font-size:14px;width:14px;height:14px}.pfx-chip--outlined{background:transparent;border-color:var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}.pfx-chip--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-chip--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-chip--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-chip--soft-primary{background:var(--p-table-badge-soft-primary-bg);color:var(--p-table-badge-soft-primary-fg)}.pfx-chip--soft-accent{background:var(--p-table-badge-soft-accent-bg);color:var(--p-table-badge-soft-accent-fg)}.pfx-chip--soft-warn{background:var(--p-table-badge-soft-warn-bg);color:var(--p-table-badge-soft-warn-fg)}.pfx-progress{position:relative;width:100%;max-width:140px;height:8px;background:var(--md-sys-color-surface-container-highest);border-radius:4px;overflow:hidden;display:inline-block;vertical-align:middle}.pfx-progress-bar{height:100%;background:var(--md-sys-color-primary);transition:width .2s ease}.pfx-progress-label{margin-left:8px;font-size:12px;opacity:.8;display:inline-block;vertical-align:middle}.pfx-avatar{display:inline-flex;align-items:center;justify-content:center;background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface);border-radius:4px;overflow:hidden;font-weight:600}.pfx-avatar.shape-rounded{border-radius:8px}.pfx-avatar.shape-circle{border-radius:999px}.pfx-avatar--initials{text-transform:uppercase;font-size:12px}.pfx-cell-compose{display:inline-flex;align-items:center;gap:6px}.pfx-cell-compose.dir-col{flex-direction:column;align-items:stretch}.pfx-cell-compose.align-start{justify-content:flex-start}.pfx-cell-compose.align-center{justify-content:center}.pfx-cell-compose.align-end{justify-content:flex-end}.pfx-cell-compose.wrap{flex-wrap:wrap}.pfx-cell-compose.ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.px-scroll-viewport{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}.px-scroll-viewport.scroll-none{overflow-x:visible}.px-scroll-viewport.scroll-auto ::ng-deep .mat-mdc-table{width:max-content;min-width:100%}.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-header-cell,.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-cell{white-space:normal;text-overflow:initial}.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-table{width:100%}:host ::ng-deep .mat-mdc-header-row{position:sticky;top:0;z-index:1;background:var(--p-table-header-bg);color:var(--p-table-header-fg);box-shadow:var(--p-table-header-shadow, 0 1px 0 var(--p-table-border-color));border-bottom:1px solid var(--p-table-border-color)}:host ::ng-deep .mat-mdc-header-cell,:host ::ng-deep .mat-sort-header-content,:host ::ng-deep .mat-mdc-header-row .mat-icon{color:var(--p-table-header-fg)!important;font-weight:600}:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow,:host ::ng-deep .mat-mdc-header-cell:hover .mat-sort-header-arrow{color:var(--p-table-header-fg)!important}:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-indicator,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-stem,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer-left,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer-right{border-color:var(--p-table-header-fg)!important;background:var(--p-table-header-fg)!important}:host ::ng-deep .mat-mdc-header-cell{padding:var(--p-header-padding, 12px 16px)!important;font-size:var(--p-header-font-size, inherit);font-weight:var(--p-header-font-weight, 600);letter-spacing:var(--p-header-letter-spacing, normal);text-transform:var(--p-header-text-transform, none);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-container{display:flex;align-items:center;width:100%;gap:4px;cursor:inherit}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable{-webkit-user-select:none;user-select:none;cursor:grab;padding-left:0!important}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable.cdk-drag-dragging{cursor:grabbing}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-content{display:inline-flex;align-items:center;gap:4px;flex:1 1 auto;min-width:0}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-header-label{display:inline-flex;align-items:center;gap:4px;flex:1 1 auto;min-width:0}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-header-label-text{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle{-webkit-appearance:none;appearance:none;border:0;background:transparent;color:var(--p-table-drag-handle-color);width:var(--p-table-drag-handle-size);min-width:var(--p-table-drag-handle-size);flex:0 0 var(--p-table-drag-handle-size);height:var(--p-table-drag-handle-size);padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:0;cursor:inherit;pointer-events:none;touch-action:none;opacity:var(--p-table-drag-handle-base-opacity, .42);transform:none;order:-1;margin-inline-end:0;transition:opacity var(--p-table-drag-handle-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1)),color var(--p-table-drag-handle-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:hover .praxis-column-drag-handle,:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:focus-within .praxis-column-drag-handle{opacity:var(--p-table-drag-handle-visible-opacity, .72);color:var(--p-table-drag-handle-hover-color, var(--p-table-drag-handle-color))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle:active{opacity:var(--p-table-drag-handle-active-opacity, 1);cursor:grabbing}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle .mat-icon{font-size:14px;width:14px;height:14px;line-height:14px;transition:transform .18s var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:hover .praxis-column-drag-handle .mat-icon{transform:none}:host ::ng-deep .pfx-column-drag-indicator .cdk-drop-list-dragging .mat-mdc-header-cell:not(.cdk-drag-placeholder){transition:transform var(--p-table-reorder-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-indicator .mat-mdc-header-cell.cdk-drag-animating{transition:transform var(--p-table-reorder-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}.pfx-column-drag-preview{box-sizing:border-box;display:flex;align-items:center;border-radius:10px;border:1px solid var(--p-table-border-color);background:linear-gradient(135deg,var(--p-table-header-bg) 0%,var(--p-table-row-hover-bg) 100%);color:var(--p-table-header-fg);box-shadow:var(--p-table-drag-preview-shadow);transform:scale(var(--p-table-drag-preview-scale, 1.01));pointer-events:none;z-index:1000}.pfx-column-drag-preview .praxis-column-drag-handle,.pfx-column-drag-preview .mat-sort-header-arrow,.pfx-column-drag-preview .mat-sort-header-indicator,.pfx-column-drag-preview .mat-sort-header-stem,.pfx-column-drag-preview .mat-sort-header-pointer,.pfx-column-drag-preview .mat-sort-header-pointer-left,.pfx-column-drag-preview .mat-sort-header-pointer-right{display:none!important}.pfx-column-drag-preview .mat-sort-header-container{display:flex;align-items:center;width:100%;min-height:100%;padding-right:0!important}.pfx-column-drag-preview .mat-sort-header-content,.pfx-column-drag-preview .praxis-header-label{display:inline-flex;align-items:center;min-width:0;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .pfx-column-drag-indicator .cdk-drag-placeholder{opacity:1;border:1px dashed var(--p-table-border-color);background:var(--p-table-row-hover-bg)}:host ::ng-deep .pfx-column-drag-indicator .cdk-drag-placeholder *{opacity:0}:host ::ng-deep .pfx-column-drag-indicator .mat-mdc-header-cell.cdk-drag-dragging{opacity:.58}@media(prefers-reduced-motion:reduce){:host ::ng-deep .pfx-column-drag-indicator .cdk-drop-list-dragging .mat-mdc-header-cell:not(.cdk-drag-placeholder){transition:none}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle,:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle .mat-icon,.pfx-column-drag-preview{transition:none;transform:none}.praxis-column-reorder-status{animation:none}.pfx-expansion-detail-panel{animation:none!important;transition:none!important;transform:none!important}:host ::ng-deep .mat-mdc-row{transition:none}:host ::ng-deep .mat-mdc-table{transition:none}}.praxis-actions-header{text-align:right}.praxis-actions-header.align-start{text-align:left}.praxis-actions-header.align-center{text-align:center}.praxis-actions-header.align-end{text-align:right}.praxis-actions-header .praxis-actions-header__content{display:inline-flex;align-items:center;gap:var(--p-actions-header-gap, 6px);color:var(--p-actions-header-color, inherit)}.praxis-actions-header .praxis-actions-header__content .mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}:host ::ng-deep .mat-mdc-header-cell .mat-sort-header-container{padding-right:20px}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-container{padding-right:12px}@media(pointer:coarse){:host{--p-table-drag-handle-size: 18px;--p-table-drag-handle-base-opacity: .56;--p-table-drag-handle-visible-opacity: .92}}:host ::ng-deep .mat-mdc-cell{color:var(--p-table-text-color);font-size:var(--p-cell-font-size, inherit);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .mat-mdc-cell .pfx-cell-content,:host ::ng-deep .mat-cell .pfx-cell-content{display:inline-flex;align-items:center;gap:6px;width:100%;min-width:0;overflow:hidden}:host ::ng-deep .mat-mdc-row:hover{background:var(--p-table-row-hover-bg)}:host ::ng-deep .mat-mdc-row{transition:background-color var(--p-table-hover-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1)),box-shadow var(--p-table-selection-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .mat-mdc-row:nth-child(2n){background:var(--p-table-row-even-bg)}:host ::ng-deep .mat-mdc-row:nth-child(2n):hover{background:var(--p-table-row-hover-bg)}:host ::ng-deep .mat-mdc-row.pfx-row-selected,:host ::ng-deep .mat-mdc-row.pfx-row-selected:hover{background:var(--p-table-row-selected-bg)}:host.row-borders ::ng-deep .mat-mdc-row .mat-mdc-cell{border-bottom:1px solid var(--p-table-border-color)}:host.row-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell{border-bottom:none}:host.col-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell,:host.col-borders ::ng-deep .mat-mdc-row .mat-mdc-cell{border-right:1px solid var(--p-table-border-color)}:host.col-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell:last-child,:host.col-borders ::ng-deep .mat-mdc-row .mat-mdc-cell:last-child{border-right:none}.ptable-error{display:flex;align-items:center;gap:12px;padding:12px;margin:8px 0;border:1px solid var(--md-sys-color-error);border-radius:8px}.ptable-error__content{flex:1}.ptable-error__title{font-weight:600}.ptable-info-banner{display:flex;gap:12px;align-items:center;padding:8px 12px;margin:8px 0;border-radius:8px;border:1px solid var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.ptable-info-banner .text{flex:1;font-weight:600}.ptable-info-banner .actions{display:flex;gap:8px}.pfx-cell-image{display:inline-block;vertical-align:middle;background:var(--md-sys-color-surface-variant);border:1px solid var(--md-sys-color-outline-variant)}.pfx-cell-image.shape-rounded{border-radius:8px}.pfx-cell-image.shape-circle{border-radius:9999px}.pfx-badge{display:inline-flex;align-items:center;gap:6px;line-height:1;padding:4px 8px;border-radius:9999px;font-size:12px;font-weight:600;border:1px solid transparent}.pfx-badge .pfx-badge-icon{font-size:16px;width:16px;height:16px}.pfx-badge--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-badge--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-badge--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-badge--outlined{background:transparent;border-color:var(--md-sys-color-outline-variant);color:inherit}.pfx-badge--soft-primary{background:var(--p-table-badge-soft-primary-bg);color:var(--p-table-badge-soft-primary-fg)}.pfx-badge--soft-accent{background:var(--p-table-badge-soft-accent-bg);color:var(--p-table-badge-soft-accent-fg)}.pfx-badge--soft-warn{background:var(--p-table-badge-soft-warn-bg);color:var(--p-table-badge-soft-warn-fg)}.row--success,.row--success td,td.row--success{background-color:var(--p-table-state-success-bg)!important;color:var(--p-table-state-success-fg)!important}.row--warning,.row--warning td,td.row--warning{background-color:var(--p-table-state-warning-bg)!important;color:var(--p-table-state-warning-fg)!important}.row--danger,.row--danger td,td.row--danger{background-color:var(--p-table-state-danger-bg)!important;color:var(--p-table-state-danger-fg)!important}.row--highlight,.row--highlight td,td.row--highlight{background-color:var(--p-table-state-highlight-bg)!important;color:var(--p-table-state-highlight-fg)!important;font-weight:600}.row--muted,.row--muted td,td.row--muted{opacity:.7;filter:saturate(.6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1$2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1$2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i10$3.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: i11$1.ɵɵCdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i11$1.ɵɵCdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i11$1.ɵɵCdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i15$2.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i17.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i17.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i17.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i18.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i20.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i20.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i8$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i8$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i8$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i8$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i8$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i8$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i8$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i8$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i8$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i8$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisFilter, selector: "praxis-filter", inputs: ["resourcePath", "fieldMetadata", "filterId", "formId", "componentInstanceId", "mode", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "enableCustomization", "value", "alwaysVisibleFields", "alwaysVisibleFieldMetadataOverrides", "selectedFieldIds", "tags", "allowSaveTags", "persistenceKey", "i18n", "changeDebounceMs", "showFilterSettings", "confirmTagDelete", "placeBooleansInActions", "showToggleLabels", "useInlineSelectVariant", "useInlineSearchableSelectVariant", "useInlineMultiSelectVariant", "useInlineInputVariant", "useInlineToggleVariant", "useInlineRangeVariant", "useInlineDateVariant", "useInlineDateRangeVariant", "useInlineTimeVariant", "useInlineTimeRangeVariant", "useInlineTreeSelectVariant", "alwaysMinWidth", "alwaysColsMd", "alwaysColsLg", "tagColor", "tagVariant", "tagButtonColor", "actionsButtonColor", "actionsVariant", "overlayVariant", "overlayBackdrop", "advancedOpenMode", "advancedClearButtonsEnabled"], outputs: ["submit", "change", "clear", "modeChange", "requestSearch", "tagsChange", "selectedFieldIdsChange", "metaChanged", "schemaStatusChange"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisTableToolbar, selector: "praxis-table-toolbar", inputs: ["config", "backgroundColor", "placement", "showMain", "showActionsGroup", "showEndActions", "showMobileActions", "showReset", "dslContext", "dslFunctionRegistry"], outputs: ["toolbarAction", "reset"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone"] }, { kind: "component", type: TableRatingCellComponent, selector: "praxis-table-rating", inputs: ["itemsCount", "value", "size", "ratingColor", "outlineColor", "ariaLabel"] }], deferBlockDependencies: [() => [import('@praxisui/ai').then(m => m.PraxisAiAssistantComponent)], () => [import('@praxisui/ai').then(m => m.PraxisAiAssistantComponent)], () => [import('@praxisui/ai').then(m => m.PraxisAiAssistantComponent)], () => [import('@praxisui/ai').then(m => m.PraxisAiAssistantComponent)]] });
42271
+ ], queries: [{ propertyName: "toolbar", first: true, predicate: PraxisTableToolbar, descendants: true }, { propertyName: "projectedFilter", first: true, predicate: ["projectedFilter"], descendants: true }], viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }, { propertyName: "materialTable", first: true, predicate: MatTable, descendants: true }, { propertyName: "internalFilter", first: true, predicate: PraxisFilter, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (shouldShowEmptyState()) {\n <praxis-empty-state-card\n icon=\"link\"\n [title]=\"'Conecte a tabela \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para carregar colunas e dados automaticamente.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"\n ></praxis-empty-state-card>\n}\n\n<!-- Error State with Quick Connect CTA -->\n@if (isRemoteMode() && (schemaError || dataError)) {\n<div class=\"ptable-error\" role=\"alert\" aria-live=\"assertive\">\n <mat-icon color=\"warn\" aria-hidden=\"true\">error</mat-icon>\n <div class=\"ptable-error__content\">\n <div class=\"ptable-error__title\">Erro</div>\n <div>{{ errorMessage || 'Ocorreu um erro ao carregar a tabela.' }}</div>\n </div>\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\">\n <mat-icon>bolt</mat-icon>\n Conectar a recurso\n </button>\n @if (!schemaError) { <button mat-stroked-button (click)=\"retryData()\">Tentar novamente</button> }\n @if (schemaError) { <button mat-stroked-button (click)=\"reloadSchema()\">Recarregar colunas</button> }\n </div>\n}\n\n<!-- Inline banner for schema change (only in edit mode) -->\n@if (shouldShowOutdatedInline()) {\n<div class=\"ptable-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"onReconcileRequested()\">\n <mat-icon>sync</mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n </div>\n}\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError && toolbarV2) {\n <div class=\"praxis-table-header\" [class.edit-mode]=\"enableCustomization\" [class.stacked]=\"showToolbar\">\n @if (showToolbar && shouldShowToolbarTopPlacement()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n [showActionsGroup]=\"shouldShowToolbarActionsTop()\"\n [showMobileActions]=\"shouldShowToolbarActionsTop()\"\n (toolbarAction)=\"onToolbarAction($event)\"\n (reset)=\"onResetPreferences()\"\n >\n @if (shouldRenderAdvancedFilter()) {\n <praxis-filter\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n \n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (requestSearch)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n }\n <ng-content select=\"[advancedFilter]\" />\n <ng-content select=\"[toolbar]\" />\n \n <!-- AI Assistant in Toolbar -->\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\" end-actions></praxis-ai-assistant>\n }\n }\n\n @if (enableCustomization) {\n <button end-actions mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </praxis-table-toolbar>\n }\n @if (!showToolbar && enableCustomization) {\n <div class=\"ptable-header-actions\">\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n }\n }\n <button mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\" (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n @if (isRemoteMode()) {\n <button mat-icon-button (click)=\"disconnect()\" aria-label=\"Desconectar\" matTooltip=\"Desconectar da fonte de dados\">\n <mat-icon>link_off</mat-icon>\n </button>\n }\n </div>\n }\n </div>\n} @else {\n @if (shouldRenderDataSurface() && !schemaError && !dataError) {\n @if (showToolbar && shouldShowToolbarTopPlacement()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n [showActionsGroup]=\"shouldShowToolbarActionsTop()\"\n [showMobileActions]=\"shouldShowToolbarActionsTop()\"\n (toolbarAction)=\"onToolbarAction($event)\"\n (reset)=\"onResetPreferences()\"\n >\n @if (shouldRenderAdvancedFilter()) {\n <praxis-filter\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n \n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (requestSearch)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n }\n <ng-content select=\"[advancedFilter]\" />\n <ng-content select=\"[toolbar]\" />\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\" end-actions></praxis-ai-assistant>\n }\n }\n @if (enableCustomization) {\n <button end-actions mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </praxis-table-toolbar>\n }\n @if (!showToolbar && enableCustomization) {\n <div class=\"ptable-header-actions\">\n <button mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\" (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n </div>\n }\n }\n}\n<div class=\"px-scroll-viewport\"\n cdkScrollable\n [class.scroll-auto]=\"horizontalScroll === 'auto'\"\n [class.scroll-wrap]=\"horizontalScroll === 'wrap'\"\n [class.scroll-none]=\"horizontalScroll === 'none'\">\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError) {\n<div class=\"praxis-visually-hidden-status\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ columnReorderStatusMessage }}\n</div>\n@if (columnReorderVisualStatusMessage) {\n <div class=\"praxis-column-reorder-status\" role=\"note\">\n {{ columnReorderVisualStatusMessage }}\n </div>\n}\n<table\n mat-table\n data-testid=\"table-column-drag-drop-list\"\n [dataSource]=\"dataSource\"\n [multiTemplateDataRows]=\"isRowExpansionRuntimeEnabled()\"\n cdkDropList\n [cdkDropListDisabled]=\"!isColumnDraggingEnabled()\"\n [cdkDropListData]=\"visibleDataColumnsForDrag\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onColumnDrop($event)\"\n matSort\n (matSortChange)=\"onSortChange($event)\"\n [matSortDisabled]=\"!getSortingEnabled()\"\n [ngClass]=\"getTableElevationClassName()\"\n [class.table-stack-top]=\"showToolbar\"\n [class.pfx-column-drag-enabled]=\"isColumnDraggingEnabled()\"\n [class.pfx-column-drag-indicator]=\"isColumnDragIndicatorEnabled()\"\n>\n @if (config.behavior?.selection?.enabled) {\n <ng-container\n matColumnDef=\"_select\"\n >\n <th mat-header-cell *matHeaderCellDef>\n @if (canSelectAll()) {\n <mat-checkbox\n (change)=\"masterToggle()\"\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n ></mat-checkbox>\n }\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n [checked]=\"selection.isSelected(row)\"\n ></mat-checkbox>\n </td>\n </ng-container>\n }\n @if (isRowExpansionRuntimeEnabled()) {\n <ng-container matColumnDef=\"_expander\">\n <th mat-header-cell *matHeaderCellDef class=\"pfx-expansion-col-header\">\n <span class=\"praxis-visually-hidden-status\">Expandir detalhes da linha</span>\n </th>\n <td mat-cell *matCellDef=\"let row; let i = index\" class=\"pfx-expansion-col-cell\">\n <button\n mat-icon-button\n class=\"pfx-expansion-toggle\"\n [disabled]=\"!isRowExpandable(row, i) || !isExpansionIconTriggerEnabled()\"\n [attr.aria-expanded]=\"isRowExpanded(row, i) ? 'true' : 'false'\"\n [attr.aria-controls]=\"getRowExpansionDetailId(row, i)\"\n [attr.aria-label]=\"getRowExpansionToggleAriaLabel(row, i)\"\n (click)=\"onExpansionToggleFromIcon(row, i, $event)\"\n (keydown)=\"onExpansionToggleKeydown($event, row, i)\"\n >\n <mat-icon [praxisIcon]=\"isRowExpanded(row, i)\n ? getExpansionExpandedIcon()\n : getExpansionCollapsedIcon()\"></mat-icon>\n </button>\n </td>\n </ng-container>\n }\n @for (column of visibleColumns; track column.field) {\n <ng-container\n [matColumnDef]=\"column.field\"\n [sticky]=\"column.sticky === true || column.sticky === 'start'\"\n [stickyEnd]=\"column.sticky === 'end'\"\n >\n <th\n mat-header-cell\n *matHeaderCellDef\n mat-sort-header\n cdkDrag\n [cdkDragData]=\"column\"\n cdkDragLockAxis=\"x\"\n cdkDragPreviewClass=\"pfx-column-drag-preview\"\n (cdkDragStarted)=\"onColumnDragStarted(column)\"\n (cdkDragEnded)=\"onColumnDragEnded($event, column)\"\n (keydown)=\"onColumnDragHandleKeydown($event, column)\"\n [cdkDragDisabled]=\"!isColumnDraggingEnabled() || !isColumnDraggable(column)\"\n [class.praxis-header-draggable]=\"isColumnDraggingEnabled() && isColumnDraggable(column)\"\n [disabled]=\"!getSortingEnabled() || column.sortable === false\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnHeaderAttrStyle(column)\"\n [attr.aria-label]=\"isColumnDraggingEnabled() && isColumnDraggable(column) ? getColumnDragHandleAriaLabel(column) : null\"\n >\n <span class=\"praxis-header-label\" data-testid=\"column-header-label\">\n @if (isColumnDraggingEnabled() && isColumnDraggable(column)) {\n <span\n class=\"praxis-column-drag-handle\"\n data-testid=\"column-drag-handle\"\n [attr.data-column-field]=\"column.field\"\n aria-hidden=\"true\"\n >\n <mat-icon [praxisIcon]=\"'drag_indicator'\"></mat-icon>\n </span>\n }\n <span class=\"praxis-header-label-text\">{{ column.header }}</span>\n </span>\n </th>\n <td\n mat-cell\n *matCellDef=\"let element\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnCellAttrStyle(column)\"\n [ngClass]=\"getCellClasses(element, column)\"\n [ngStyle]=\"getCellNgStyle(element, column)\"\n >\n <div\n class=\"pfx-cell-content\"\n [ngClass]=\"getCellContentClasses(element, column)\"\n [ngStyle]=\"getCellContentNgStyle(element, column)\"\n >\n <ng-container [ngSwitch]=\"getEffectiveRendererType(element, column)\">\n <!-- Icon renderer -->\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon\n [color]=\"getIconColor(element, column) || null\"\n [ngStyle]=\"getIconStyle(element, column)\"\n [attr.aria-label]=\"getIconAriaLabel(element, column) || null\"\n >{{ getIconName(element, column) }}</mat-icon\n >\n </ng-container>\n\n <!-- Image renderer -->\n <ng-container *ngSwitchCase=\"'image'\">\n <img\n class=\"pfx-cell-image\"\n [src]=\"getImageSrc(element, column)\"\n [attr.alt]=\"getImageAlt(element, column) || ''\"\n [attr.loading]=\"getImageLazy(element, column) ? 'lazy' : null\"\n [style.width.px]=\"getImageWidth(element, column)\"\n [style.height.px]=\"getImageHeight(element, column)\"\n [class.shape-rounded]=\"getImageShape(element, column) === 'rounded'\"\n [class.shape-circle]=\"getImageShape(element, column) === 'circle'\"\n [style.object-fit]=\"getImageFit(element, column)\"\n />\n </ng-container>\n\n <!-- Badge renderer -->\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(element, column)\">\n @if (getBadgeIcon(element, column); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }\n <span class=\"pfx-badge-text\">{{ getBadgeText(element, column) }}</span>\n </span>\n </ng-container>\n\n <!-- Link renderer -->\n <ng-container *ngSwitchCase=\"'link'\">\n <a\n class=\"pfx-link\"\n [attr.href]=\"getLinkHref(element, column) || null\"\n [attr.target]=\"getLinkTarget(element, column) || null\"\n [attr.rel]=\"getLinkRel(element, column) || null\"\n (click)=\"$event.stopPropagation()\"\n >{{ getLinkText(element, column) }}</a\n >\n </ng-container>\n\n <!-- Button renderer -->\n <ng-container *ngSwitchCase=\"'button'\">\n <ng-container [ngSwitch]=\"getButtonVariant(element, column)\">\n <button\n *ngSwitchCase=\"'outlined'\"\n mat-stroked-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n <button\n *ngSwitchCase=\"'text'\"\n mat-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n <button\n *ngSwitchDefault\n mat-flat-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n </ng-container>\n </ng-container>\n\n <!-- Chip renderer -->\n <ng-container *ngSwitchCase=\"'chip'\">\n <span class=\"pfx-chip\" [ngClass]=\"getChipClasses(element, column)\">\n @if (getChipIcon(element, column); as ci) { <mat-icon class=\"pfx-chip-icon\">{{ ci }}</mat-icon> }\n <span class=\"pfx-chip-text\">{{ getChipText(element, column) }}</span>\n </span>\n </ng-container>\n\n <!-- Progress renderer -->\n <ng-container *ngSwitchCase=\"'progress'\">\n <div class=\"pfx-progress\">\n <div class=\"pfx-progress-bar\" [style.width.%]=\"getProgressWidthPercentStyle(element, column)\" [style.background]=\"getProgressBackgroundStyle(element, column)\"></div>\n @if (getProgressShowLabel(element, column)) { <div class=\"pfx-progress-label\">{{ getProgressValue(element, column) }}%</div> }\n </div>\n </ng-container>\n\n <!-- Avatar renderer -->\n <ng-container *ngSwitchCase=\"'avatar'\">\n @if (getAvatarSrc(element, column); as asrc) {\n <img class=\"pfx-avatar\" [src]=\"asrc\" [attr.alt]=\"getAvatarAlt(element, column) || ''\" [ngStyle]=\"getAvatarStyle(element, column)\" [class.shape-rounded]=\"getAvatarShape(element, column) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, column) === 'circle'\" loading=\"lazy\" />\n } @else {\n <span class=\"pfx-avatar pfx-avatar--initials\" [ngStyle]=\"getAvatarStyle(element, column)\" [class.shape-rounded]=\"getAvatarShape(element, column) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, column) === 'circle'\">{{ getAvatarInitials(element, column) }}</span>\n }\n </ng-container>\n\n <!-- Toggle renderer -->\n <ng-container *ngSwitchCase=\"'toggle'\">\n <mat-slide-toggle\n [checked]=\"getToggleState(element, column)\"\n [disabled]=\"isToggleDisabled(element, column)\"\n [attr.aria-label]=\"getToggleAriaLabel(element, column) || 'Alternar'\"\n (change)=\"onToggleChange(element, column, $event)\"\n (click)=\"$event.stopPropagation()\"\n ></mat-slide-toggle>\n </ng-container>\n\n <!-- Menu renderer -->\n <ng-container *ngSwitchCase=\"'menu'\">\n <button mat-icon-button [matMenuTriggerFor]=\"menuRef\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getMenuAriaLabel(element, column) || 'Menu'\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menuRef=\"matMenu\">\n <button mat-menu-item *ngFor=\"let it of getMenuItems(element, column)\" (click)=\"onMenuItemClick(it, element, $event)\" [disabled]=\"!it.__visible\" >\n @if (it.icon) { <mat-icon>{{ it.icon }}</mat-icon> }\n <span>{{ it.label }}</span>\n </button>\n </mat-menu>\n </ng-container>\n\n <!-- Rating renderer -->\n <ng-container *ngSwitchCase=\"'rating'\">\n <praxis-table-rating\n class=\"pfx-rating-cell\"\n [itemsCount]=\"getRatingMax(element, column)\"\n [value]=\"getRatingValue(element, column)\"\n [size]=\"getRatingSize(element, column)\"\n [ratingColor]=\"getRatingColor(element, column)\"\n [outlineColor]=\"getRatingOutlineColor(element, column)\"\n [ariaLabel]=\"getRatingAriaLabel(element, column) || column.header\">\n </praxis-table-rating>\n </ng-container>\n\n <!-- HTML renderer (sanitizado) -->\n <ng-container *ngSwitchCase=\"'html'\">\n <span [innerHTML]=\"getSafeHtml(element, column)\"></span>\n </ng-container>\n\n <!-- Compose renderer -->\n <ng-container *ngSwitchCase=\"'compose'\">\n <span class=\"pfx-cell-compose\" [ngClass]=\"getComposeClasses(element, column)\" [ngStyle]=\"getComposeGapStyle(element, column)\">\n <ng-container *ngFor=\"let it of getComposeItems(element, column)\">\n <ng-container [ngSwitch]=\"getItemEffectiveType(element, column, it)\">\n <!-- Reuse helpers by projecting item as faux column -->\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon [color]=\"getIconColor(element, asItemColumn(column, it)) || null\" [ngStyle]=\"getIconStyle(element, asItemColumn(column, it))\" [attr.aria-label]=\"getIconAriaLabel(element, asItemColumn(column, it)) || null\">{{ getIconName(element, asItemColumn(column, it)) }}</mat-icon>\n </ng-container>\n <ng-container *ngSwitchCase=\"'image'\">\n <img class=\"pfx-cell-image\" [src]=\"getImageSrc(element, asItemColumn(column, it))\" [attr.alt]=\"getImageAlt(element, asItemColumn(column, it)) || ''\" [attr.loading]=\"getImageLazy(element, asItemColumn(column, it)) ? 'lazy' : null\" [style.width.px]=\"getImageWidth(element, asItemColumn(column, it))\" [style.height.px]=\"getImageHeight(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getImageShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getImageShape(element, asItemColumn(column, it)) === 'circle'\" [style.object-fit]=\"getImageFit(element, asItemColumn(column, it))\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(element, asItemColumn(column, it))\">@if (getBadgeIcon(element, asItemColumn(column, it)); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }<span class=\"pfx-badge-text\">{{ getBadgeText(element, asItemColumn(column, it)) }}</span></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'link'\">\n <a class=\"pfx-link\" [attr.href]=\"getLinkHref(element, asItemColumn(column, it)) || null\" [attr.target]=\"getLinkTarget(element, asItemColumn(column, it)) || null\" [attr.rel]=\"getLinkRel(element, asItemColumn(column, it)) || null\" (click)=\"$event.stopPropagation()\">{{ getLinkText(element, asItemColumn(column, it)) }}</a>\n </ng-container>\n <ng-container *ngSwitchCase=\"'button'\">\n <ng-container [ngSwitch]=\"getButtonVariant(element, asItemColumn(column, it))\">\n <button *ngSwitchCase=\"'outlined'\" mat-stroked-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n <button *ngSwitchCase=\"'text'\" mat-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n <button *ngSwitchDefault mat-flat-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'chip'\">\n <span class=\"pfx-chip\" [ngClass]=\"getChipClasses(element, asItemColumn(column, it))\">@if (getChipIcon(element, asItemColumn(column, it)); as ci) { <mat-icon class=\"pfx-chip-icon\">{{ ci }}</mat-icon> }<span class=\"pfx-chip-text\">{{ getChipText(element, asItemColumn(column, it)) }}</span></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'progress'\">\n <div class=\"pfx-progress\"><div class=\"pfx-progress-bar\" [style.width.%]=\"getProgressWidthPercentStyle(element, asItemColumn(column, it))\" [style.background]=\"getProgressBackgroundStyle(element, asItemColumn(column, it))\"></div>@if (getProgressShowLabel(element, asItemColumn(column, it))) { <div class=\"pfx-progress-label\">{{ getProgressValue(element, asItemColumn(column, it)) }}%</div> }</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'avatar'\">\n @if (getAvatarSrc(element, asItemColumn(column, it)); as asrc) {\n <img class=\"pfx-avatar\" [src]=\"asrc\" [attr.alt]=\"getAvatarAlt(element, asItemColumn(column, it)) || ''\" [ngStyle]=\"getAvatarStyle(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getAvatarShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, asItemColumn(column, it)) === 'circle'\" loading=\"lazy\" />\n } @else {\n <span class=\"pfx-avatar pfx-avatar--initials\" [ngStyle]=\"getAvatarStyle(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getAvatarShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, asItemColumn(column, it)) === 'circle'\">{{ getAvatarInitials(element, asItemColumn(column, it)) }}</span>\n }\n </ng-container>\n <ng-container *ngSwitchCase=\"'toggle'\">\n <mat-slide-toggle [checked]=\"getToggleState(element, asItemColumn(column, it))\" [disabled]=\"isToggleDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getToggleAriaLabel(element, asItemColumn(column, it)) || 'Alternar'\" (change)=\"onToggleChange(element, asItemColumn(column, it), $event)\" (click)=\"$event.stopPropagation()\"></mat-slide-toggle>\n </ng-container>\n <ng-container *ngSwitchCase=\"'menu'\">\n <button mat-icon-button [matMenuTriggerFor]=\"menuRef\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getMenuAriaLabel(element, asItemColumn(column, it)) || 'Menu'\"><mat-icon>more_vert</mat-icon></button>\n <mat-menu #menuRef=\"matMenu\">\n <button mat-menu-item *ngFor=\"let mi of getMenuItems(element, asItemColumn(column, it))\" (click)=\"onMenuItemClick(mi, element, $event)\" [disabled]=\"!mi.__visible\">\n @if (mi.icon) { <mat-icon>{{ mi.icon }}</mat-icon> }\n <span>{{ mi.label }}</span>\n </button>\n </mat-menu>\n </ng-container>\n <ng-container *ngSwitchCase=\"'rating'\">\n <praxis-table-rating\n class=\"pfx-rating-cell\"\n [itemsCount]=\"getRatingMax(element, asItemColumn(column, it))\"\n [value]=\"getRatingValue(element, asItemColumn(column, it))\"\n [size]=\"getRatingSize(element, asItemColumn(column, it))\"\n [ratingColor]=\"getRatingColor(element, asItemColumn(column, it))\"\n [outlineColor]=\"getRatingOutlineColor(element, asItemColumn(column, it))\"\n [ariaLabel]=\"getRatingAriaLabel(element, asItemColumn(column, it)) || column.header\">\n </praxis-table-rating>\n </ng-container>\n <ng-container *ngSwitchCase=\"'html'\">\n <span [innerHTML]=\"getSafeHtml(element, asItemColumn(column, it))\"></span>\n </ng-container>\n <!-- Value item: render base cell text alongside visuals -->\n <ng-container *ngSwitchCase=\"'value'\">\n <span class=\"pfx-cell-value\">{{ getComposeItemValue(element, column, it) }}</span>\n </ng-container>\n </ng-container>\n </ng-container>\n </span>\n </ng-container>\n\n <!-- Default text rendering -->\n <ng-container *ngSwitchDefault>\n {{ getCellValue(element, column) }}\n </ng-container>\n </ng-container>\n </div>\n </td>\n </ng-container>\n }\n @if (config.actions?.row?.enabled) {\n <ng-container matColumnDef=\"_actions\" [sticky]=\"config.actions?.row?.sticky === true || config.actions?.row?.sticky === 'start'\" [stickyEnd]=\"config.actions?.row?.sticky === 'end'\">\n <th mat-header-cell *matHeaderCellDef #actionsHeaderCell [style.width]=\"getRowActionsWidthStyle()\" class=\"praxis-actions-header\" [class.align-start]=\"getActionsHeaderAlign() === 'start'\" [class.align-center]=\"getActionsHeaderAlign() === 'center'\" [class.align-end]=\"getActionsHeaderAlign() === 'end'\">\n <div class=\"praxis-actions-header__content\" [matTooltip]=\"getActionsHeaderTooltip() || ''\" [matTooltipDisabled]=\"!getActionsHeaderTooltip()\">\n @if (getActionsHeaderIcon(); as hi) { <mat-icon [praxisIcon]=\"hi\"></mat-icon> }\n @if (getActionsHeaderLabel(); as hl) { <span class=\"label\">{{ hl }}</span> }\n </div>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"praxis-actions-cell\"\n [class.dense]=\"dense\"\n [style.width]=\"getRowActionsWidthStyle()\"\n >\n <div class=\"praxis-actions-cell__content\">\n <!-- A\u00E7\u00F5es inline -->\n <!-- Inline actions: icons mode -->\n @if (config.actions?.row?.display === 'icons' || !config.actions?.row?.display) {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button\n mat-icon-button\n class=\"praxis-icon-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [matTooltip]=\"a.label || getActionId(a)\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"praxis-tooltip\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\"\n >\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n </button>\n </ng-container>\n }\n\n <!-- Inline actions: buttons mode (show label + icon) -->\n @if (config.actions?.row?.display === 'buttons') {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button\n mat-flat-button\n class=\"praxis-row-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\"\n >\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n }\n\n <!-- Menu de overflow -->\n @if (hasOverflowRowActions(row)) {\n <button\n mat-icon-button\n class=\"praxis-icon-btn praxis-more-btn\"\n [matMenuTriggerFor]=\"rowMoreMenu\"\n [color]=\"getRowMenuButtonColor() || null\"\n aria-label=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"getRowMenuIcon()\"></mat-icon>\n </button>\n }\n <mat-menu #rowMoreMenu=\"matMenu\" xPosition=\"before\">\n <ng-container\n *ngFor=\"let a of getOverflowRowActions(row); trackBy: trackAction\"\n >\n <button\n mat-menu-item\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [disabled]=\"isActionDisabled(a, row)\"\n >\n <mat-icon [color]=\"a.color || null\" [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n </mat-menu>\n </div>\n </td>\n </ng-container>\n }\n\n <tr\n mat-header-row\n *matHeaderRowDef=\"displayedColumns\"\n ></tr>\n @if (!isVirtualized()) {\n <tr\n mat-row\n *matRowDef=\"let row; let i = index; columns: displayedColumns\"\n [class.pfx-row-selected]=\"selection.isSelected(row)\"\n [class.pfx-row-expanded]=\"isRowExpansionRuntimeEnabled() && isRowExpanded(row, i)\"\n [attr.aria-selected]=\"config.behavior?.selection?.enabled ? (selection.isSelected(row) ? 'true' : 'false') : null\"\n [attr.aria-expanded]=\"isRowExpansionRuntimeEnabled() ? (isRowExpanded(row, i) ? 'true' : 'false') : null\"\n [ngClass]=\"getRowClasses(row)\"\n [ngStyle]=\"getRowNgStyle(row)\"\n [matTooltip]=\"getRowTooltip(row) || null\"\n [matTooltipDisabled]=\"!getRowTooltip(row)\"\n [matTooltipPosition]=\"getRowTooltipPosition(row)\"\n [matTooltipShowDelay]=\"getRowTooltipShowDelay(row)\"\n (click)=\"onRowClicked(row, i, $event)\"\n (dblclick)=\"onRowDoubleClicked(row, i)\"\n ></tr>\n @if (isRowExpansionRuntimeEnabled()) {\n <ng-container matColumnDef=\"_detail\">\n <td\n mat-cell\n *matCellDef=\"let row; let i = index\"\n class=\"pfx-expansion-detail-cell\"\n [attr.colspan]=\"displayedColumns.length\"\n >\n <section\n class=\"pfx-expansion-detail-panel\"\n [ngClass]=\"getExpansionMotionPresetClass()\"\n [ngStyle]=\"getExpansionMotionStyle()\"\n [attr.id]=\"getRowExpansionDetailId(row, i)\"\n role=\"region\"\n [attr.aria-label]=\"getRowExpansionRegionAriaLabel(row, i)\"\n [attr.aria-busy]=\"getExpansionDetailViewState(row, i).status === 'loading' ? 'true' : 'false'\"\n >\n @let detailState = getExpansionDetailViewState(row, i);\n @if (detailState.status === 'loading') {\n <div class=\"pfx-expansion-detail-message\" role=\"status\" aria-live=\"polite\">\n Carregando detail schema...\n </div>\n } @else if (detailState.status !== 'ready') {\n <div\n class=\"pfx-expansion-detail-message pfx-expansion-detail-message--error\"\n role=\"alert\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n >\n {{ detailState.message || 'Detail indispon\u00EDvel para esta linha.' }}\n </div>\n } @else {\n @if (getExpansionDetailLayout(detailState.schema) === 'tabs') {\n @let detailTabs = getExpansionDetailTabs(detailState.schema);\n @if (detailTabs.length) {\n <div class=\"pfx-expansion-detail-tabs\" role=\"tablist\" aria-label=\"Se\u00E7\u00F5es do detail\">\n @for (tab of detailTabs; track $index; let tabIndex = $index) {\n <button\n type=\"button\"\n class=\"pfx-expansion-detail-tab-btn\"\n role=\"tab\"\n [attr.id]=\"getExpansionDetailTabId(row, i, tab, tabIndex)\"\n [attr.aria-controls]=\"getExpansionDetailPanelId(row, i, tab, tabIndex)\"\n [attr.aria-selected]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs) ? 'true' : 'false'\"\n [attr.tabindex]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs) ? '0' : '-1'\"\n [class.is-active]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs)\"\n (click)=\"onExpansionDetailTabSelect(row, i, tab, tabIndex, $event)\"\n (keydown)=\"onExpansionDetailTabKeydown($event, row, i, tabIndex, detailTabs)\"\n >\n {{ getExpansionDetailNodeTitle(tab, 'Tab') }}\n </button>\n }\n </div>\n @for (tab of detailTabs; track $index; let tabIndex = $index) {\n @if (isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs)) {\n <div\n class=\"pfx-expansion-detail-tab-panel\"\n role=\"tabpanel\"\n [attr.id]=\"getExpansionDetailPanelId(row, i, tab, tabIndex)\"\n [attr.aria-labelledby]=\"getExpansionDetailTabId(row, i, tab, tabIndex)\"\n >\n @for (childNode of getExpansionDetailNodeChildren(tab); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: childNode, row: row, index: i }\n \"\n ></ng-container>\n }\n </div>\n }\n }\n } @else {\n <div class=\"pfx-expansion-detail-message\">\n Schema em layout tabs sem abas v\u00E1lidas.\n </div>\n }\n } @else {\n <div class=\"pfx-expansion-detail-stack\">\n @for (node of getExpansionDetailItems(detailState.schema); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: node, row: row, index: i }\n \"\n ></ng-container>\n }\n </div>\n }\n }\n\n <ng-template #expansionDetailNodeTemplate let-node let-row=\"row\" let-index=\"index\">\n @switch (getExpansionDetailNodeType(node)) {\n @case ('card') {\n <article class=\"pfx-expansion-node pfx-expansion-node-card\">\n <header class=\"pfx-expansion-node-card__header\">\n <h5 class=\"pfx-expansion-node-card__title\">\n {{ getExpansionDetailNodeTitle(node, 'Card') }}\n </h5>\n @if (node?.subtitle) {\n <p class=\"pfx-expansion-node-card__subtitle\">{{ node?.subtitle }}</p>\n }\n </header>\n @for (childNode of getExpansionDetailNodeChildren(node); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: childNode, row: row, index: index }\n \"\n ></ng-container>\n }\n </article>\n }\n @case ('value') {\n <div class=\"pfx-expansion-node pfx-expansion-node-value\">\n <span class=\"pfx-expansion-node-value__label\">\n {{ getExpansionDetailNodeTitle(node, 'Valor') }}\n </span>\n <strong class=\"pfx-expansion-node-value__content\">\n {{ getExpansionDetailValue(row, node) }}\n </strong>\n </div>\n }\n @case ('list') {\n <section class=\"pfx-expansion-node pfx-expansion-node-list\">\n <h6 class=\"pfx-expansion-node-list__title\">\n {{ getExpansionDetailNodeTitle(node, 'Lista') }}\n </h6>\n @let listItems = getExpansionDetailListItems(row, node);\n @if (listItems.length) {\n <ul>\n @for (entry of listItems; track $index) {\n <li>{{ entry }}</li>\n }\n </ul>\n } @else {\n <p class=\"pfx-expansion-node-placeholder\">Sem itens.</p>\n }\n </section>\n }\n @case ('richText') {\n <div\n class=\"pfx-expansion-node pfx-expansion-node-richtext\"\n [innerHTML]=\"getExpansionDetailRichText(node)\"\n ></div>\n }\n @case ('formRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Formul\u00E1rio referenciado: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('tableRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Tabela referenciada: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('chartRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Gr\u00E1fico referenciado: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('templateRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Template referenciado: <code>{{ node?.id || node?.templateId || 'sem-id' }}</code>\n </div>\n }\n @case ('action') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n A\u00E7\u00E3o declarada: <code>{{ node?.id || node?.actionId || 'sem-id' }}</code>\n </div>\n }\n @case ('tab') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Node <code>tab</code> fora de contexto de tabs.\n </div>\n }\n @default {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Node n\u00E3o suportado: <code>{{ getExpansionDetailNodeType(node) }}</code>\n </div>\n }\n }\n </ng-template>\n </section>\n </td>\n </ng-container>\n <tr\n mat-row\n *matRowDef=\"let row; columns: expansionDetailRowColumns; when: isExpansionDetailRow\"\n class=\"pfx-expansion-detail-row\"\n ></tr>\n }\n }\n</table>\n}\n\n<!-- Virtual rows path (header preserved above) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && isVirtualized()) {\n <cdk-virtual-scroll-viewport\n class=\"ptable-viewport\"\n [itemSize]=\"getVirtItemHeight()\"\n [minBufferPx]=\"getVirtBufferSize() * getVirtItemHeight()\"\n [maxBufferPx]=\"getVirtBufferSize() * getVirtItemHeight() * 2\"\n [style.minHeight]=\"getVirtMinHeightHostStyle()\"\n >\n <table\n class=\"mat-mdc-table\"\n [ngClass]=\"getTableElevationClassName()\"\n [style.width]=\"getVirtualTableWidthStyle()\"\n >\n <tbody>\n <tr class=\"mat-mdc-row\"\n *cdkVirtualFor=\"let row of dataSource.data; let i = index; trackBy: trackByRow\"\n [class.pfx-row-selected]=\"selection.isSelected(row)\"\n [attr.aria-selected]=\"config.behavior?.selection?.enabled ? (selection.isSelected(row) ? 'true' : 'false') : null\"\n [ngClass]=\"getRowClasses(row)\"\n [ngStyle]=\"getRowNgStyle(row)\"\n [matTooltip]=\"getRowTooltip(row) || null\"\n [matTooltipDisabled]=\"!getRowTooltip(row)\"\n [matTooltipPosition]=\"getRowTooltipPosition(row)\"\n [matTooltipShowDelay]=\"getRowTooltipShowDelay(row)\"\n (click)=\"onRowClicked(row, i, $event)\"\n (dblclick)=\"onRowDoubleClicked(row, i)\">\n <!-- Selection column -->\n @if (config.behavior?.selection?.enabled) { <td class=\"mat-mdc-cell\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td> }\n <!-- Data columns -->\n @for (column of visibleColumns; track column.field) {\n <td class=\"mat-mdc-cell\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnCellAttrStyle(column)\"\n [ngClass]=\"getCellClasses(row, column)\"\n [ngStyle]=\"getCellNgStyle(row, column)\">\n <div\n class=\"pfx-cell-content\"\n [ngClass]=\"getCellContentClasses(row, column)\"\n [ngStyle]=\"getCellContentNgStyle(row, column)\"\n >\n <ng-container [ngSwitch]=\"getEffectiveRendererType(row, column)\">\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon [color]=\"getIconColor(row, column) || null\"\n [ngStyle]=\"getIconStyle(row, column)\"\n [attr.aria-label]=\"getIconAriaLabel(row, column) || null\">\n {{ getIconName(row, column) }}\n </mat-icon>\n </ng-container>\n <ng-container *ngSwitchCase=\"'image'\">\n <img class=\"pfx-cell-image\"\n [src]=\"getImageSrc(row, column)\"\n [attr.alt]=\"getImageAlt(row, column) || ''\"\n [attr.loading]=\"getImageLazy(row, column) ? 'lazy' : null\"\n [style.width.px]=\"getImageWidth(row, column)\"\n [style.height.px]=\"getImageHeight(row, column)\"\n [class.shape-rounded]=\"getImageShape(row, column) === 'rounded'\"\n [class.shape-circle]=\"getImageShape(row, column) === 'circle'\"\n [style.object-fit]=\"getImageFit(row, column)\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(row, column)\">\n @if (getBadgeIcon(row, column); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }\n <span class=\"pfx-badge-text\">{{ getBadgeText(row, column) }}</span>\n </span>\n </ng-container>\n <ng-container *ngSwitchDefault>\n {{ getCellValue(row, column) }}\n </ng-container>\n </ng-container>\n </div>\n </td>\n }\n\n <!-- Actions column -->\n @if (config.actions?.row?.enabled) {\n <td class=\"mat-mdc-cell praxis-actions-cell\" [class.dense]=\"dense\" [style.width]=\"getRowActionsWidthStyle()\">\n <div class=\"praxis-actions-cell__content\">\n @if (config.actions?.row?.display === 'icons' || !config.actions?.row?.display) {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button mat-icon-button class=\"praxis-icon-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [matTooltip]=\"a.label || getActionId(a)\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"praxis-tooltip\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\">\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n </button>\n </ng-container>\n }\n @if (config.actions?.row?.display === 'buttons') {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button mat-flat-button class=\"praxis-row-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\">\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n }\n @if (hasOverflowRowActions(row)) {\n <button mat-icon-button class=\"praxis-icon-btn praxis-more-btn\"\n [matMenuTriggerFor]=\"rowMoreMenuV\"\n [color]=\"getRowMenuButtonColor() || null\"\n aria-label=\"Mais a\u00E7\u00F5es\">\n <mat-icon [praxisIcon]=\"getRowMenuIcon()\"></mat-icon>\n </button>\n }\n <mat-menu #rowMoreMenuV=\"matMenu\" xPosition=\"before\">\n <ng-container *ngFor=\"let a of getOverflowRowActions(row); trackBy: trackAction\">\n <button mat-menu-item (click)=\"onRowAction(getActionId(a), row, $event)\" [disabled]=\"isActionDisabled(a, row)\">\n <mat-icon [color]=\"a.color || null\" [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n </mat-menu>\n </div>\n </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n}\n\n</div>\n@if (\n shouldRenderDataSurface()\n && !schemaError\n && !dataError\n && shouldRenderFloatingBulkActions()\n && getFloatingBulkActions().length\n && !shouldHideFloatingBulkActions()\n) {\n <div [class]=\"'praxis-floating-bulk-actions ' + getFloatingBulkPositionClass()\">\n @for (action of getFloatingBulkActions(); track getActionId(action)) {\n <button\n mat-mini-fab\n [color]=\"action.color || 'primary'\"\n [disabled]=\"isFloatingBulkActionDisabled(action)\"\n (click)=\"onToolbarAction({ action: getActionId(action), actionConfig: action })\"\n [attr.aria-label]=\"action.label || getActionId(action)\"\n [matTooltip]=\"action.label || getActionId(action)\"\n matTooltipPosition=\"left\"\n >\n <mat-icon [praxisIcon]=\"action.icon || 'done_all'\"></mat-icon>\n </button>\n }\n </div>\n}\n<!-- Barra de a\u00E7\u00F5es no rodap\u00E9 (opcional) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && showToolbar && shouldRenderFooterToolbar()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [class.footer-flat]=\"hasBottomPaginator()\"\n class=\"praxis-toolbar-footer\"\n placement=\"footer\"\n [showMain]=\"shouldShowFooterToolbarMain()\"\n [showEndActions]=\"shouldShowFooterToolbarEndActions()\"\n [showReset]=\"shouldShowFooterToolbarReset()\"\n [showActionsGroup]=\"shouldShowToolbarActionsBottom()\"\n [showMobileActions]=\"shouldShowToolbarActionsBottom()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n (toolbarAction)=\"onToolbarAction($event)\"\n >\n <praxis-filter\n *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\"\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (requestSearch)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n <ng-container *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\">\n <ng-content select=\"[advancedFilter]\"></ng-content>\n </ng-container>\n <ng-container *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\">\n <ng-content select=\"[toolbar]\"></ng-content>\n </ng-container>\n @if (shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()) {\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant\n [adapter]=\"aiAdapter\"\n end-actions\n ></praxis-ai-assistant>\n }\n }\n }\n <button\n *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter() && enableCustomization\"\n end-actions\n mat-icon-button\n color=\"primary\"\n data-role=\"table-settings\"\n data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\"\n aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\"\n >\n <mat-icon>settings</mat-icon>\n </button>\n </praxis-table-toolbar>\n}\n<!-- Paginadores (top/bottom) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && getPaginationEnabled() && (config.behavior?.pagination?.position === 'top' || config.behavior?.pagination?.position === 'both')) {\n <mat-paginator\n [length]=\"getPaginationLength()\"\n [pageSize]=\"getPaginationPageSize()\"\n [pageSizeOptions]=\"getPaginationPageSizeOptions()\"\n [showFirstLastButtons]=\"getPaginationShowFirstLast()\"\n (page)=\"onPageChange($event)\"\n [class.compact]=\"config.behavior?.pagination?.style === 'compact'\"\n >\n </mat-paginator>\n}\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError && getPaginationEnabled() && (config.behavior?.pagination?.position === 'bottom' || config.behavior?.pagination?.position === 'both' || !config.behavior?.pagination?.position)) {\n <mat-paginator\n [length]=\"getPaginationLength()\"\n [pageSize]=\"getPaginationPageSize()\"\n [pageSizeOptions]=\"getPaginationPageSizeOptions()\"\n [showFirstLastButtons]=\"getPaginationShowFirstLast()\"\n (page)=\"onPageChange($event)\"\n [class.compact]=\"config.behavior?.pagination?.style === 'compact'\"\n [class.footer-stack]=\"shouldShowToolbarActionsBottom()\"\n >\n </mat-paginator>\n}\n", styles: ["@charset \"UTF-8\";table{width:100%}.praxis-visually-hidden-status{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.praxis-column-reorder-status{margin:8px 0;padding:10px 12px;border-radius:8px;border:1px solid var(--p-table-border-color);background:var(--p-table-row-hover-bg);color:var(--p-table-header-fg);font-size:12px;line-height:1.4;box-shadow:0 4px 12px #00000014;animation:pfx-column-reorder-status-in var(--p-table-drag-status-enter-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}@keyframes pfx-column-reorder-status-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.praxis-actions-cell{height:100%;padding-inline:12px;white-space:nowrap}.pfx-expansion-col-header,.pfx-expansion-col-cell{width:52px;min-width:52px;text-align:center}.pfx-expansion-toggle:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pfx-expansion-detail-row{background:var(--md-sys-color-surface-container-low)}.pfx-expansion-detail-cell{padding:0!important;border-bottom:1px solid var(--p-table-border-color)}.pfx-expansion-detail-panel{padding:12px 16px;border-left:3px solid var(--md-sys-color-primary)}.pfx-expansion-detail-panel.pfx-expansion-motion-none{animation:none;transition:none}.pfx-expansion-detail-panel.pfx-expansion-motion-subtle-slide{animation:pfx-expansion-subtle-slide-in var(--pfx-expansion-motion-duration, .16s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1))}.pfx-expansion-detail-panel.pfx-expansion-motion-accordion{animation:pfx-expansion-accordion-in var(--pfx-expansion-motion-duration, .18s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1));transform-origin:top center}.pfx-expansion-detail-panel.pfx-expansion-motion-fade-scale{animation:pfx-expansion-fade-scale-in var(--pfx-expansion-motion-duration, .16s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1));transform-origin:top center}@keyframes pfx-expansion-subtle-slide-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes pfx-expansion-accordion-in{0%{opacity:0;transform:scaleY(.96)}to{opacity:1;transform:scaleY(1)}}@keyframes pfx-expansion-fade-scale-in{0%{opacity:0;transform:translateY(-2px) scale(.985)}to{opacity:1;transform:translateY(0) scale(1)}}.pfx-expansion-detail-schema{margin:0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px;line-height:1.4;white-space:pre-wrap;word-break:break-word;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-detail-message{font-size:13px;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-detail-message--error{color:var(--md-sys-color-error)}.pfx-expansion-detail-stack{display:grid;gap:10px}.pfx-expansion-detail-tabs{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px}.pfx-expansion-detail-tab-btn{border:1px solid var(--p-table-border-color);background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface);border-radius:999px;padding:6px 12px;font-size:12px;line-height:1.2;cursor:pointer}.pfx-expansion-detail-tab-btn.is-active{border-color:var(--md-sys-color-primary);color:var(--md-sys-color-primary);font-weight:600}.pfx-expansion-detail-tab-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pfx-expansion-detail-tab-panel{display:grid;gap:10px}.pfx-expansion-node{border:1px solid var(--p-table-border-color);border-radius:8px;padding:10px 12px;background:var(--md-sys-color-surface)}.pfx-expansion-node-card__header{margin-bottom:8px}.pfx-expansion-node-card__title{margin:0;font-size:14px;line-height:1.3}.pfx-expansion-node-card__subtitle{margin:4px 0 0;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-node-value{display:flex;align-items:baseline;gap:8px}.pfx-expansion-node-value__label{color:var(--md-sys-color-on-surface-variant);font-size:12px}.pfx-expansion-node-value__content{font-size:14px}.pfx-expansion-node-list__title{margin:0 0 6px;font-size:13px}.pfx-expansion-node-list ul{margin:0;padding-left:18px}.pfx-expansion-node-richtext :where(p,ul,ol,h1,h2,h3,h4,h5,h6){margin-top:0;margin-bottom:8px}.pfx-expansion-node-placeholder{font-size:12px;color:var(--md-sys-color-on-surface-variant)}:host.density-compact{--p-header-padding: 8px 12px;--p-cell-padding: 8px 12px;--p-actions-btn-size: 32px;--p-actions-icon-size: 18px}:host.density-comfortable{--p-header-padding: 12px 16px;--p-cell-padding: 12px 16px;--p-actions-btn-size: 40px;--p-actions-icon-size: 22px}:host.density-spacious{--p-header-padding: 16px 20px;--p-cell-padding: 16px 20px;--p-actions-btn-size: 44px;--p-actions-icon-size: 24px}:host.density-compact ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 8px 12px)}:host.density-comfortable ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 12px 16px)}:host.density-spacious ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 16px 20px)}:host.density-compact .praxis-actions-cell{padding-inline:8px}:host.density-spacious .praxis-actions-cell{padding-inline:16px}.praxis-actions-cell__content{display:flex;align-items:center;justify-content:flex-end;gap:8px;width:100%}.praxis-actions-cell.dense .praxis-actions-cell__content{gap:6px}.praxis-icon-btn{width:var(--p-actions-btn-size, 40px);height:var(--p-actions-btn-size, 40px);border:0;background:transparent;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:9999px;cursor:pointer;--mat-icon-button-state-layer-size: var(--p-actions-btn-size, 40px)}.praxis-icon-btn:hover{background:var(--md-sys-color-surface-variant)}.praxis-icon-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.praxis-icon-btn mat-icon,.praxis-icon-btn .mat-icon{font-size:var(--p-actions-icon-size, 22px);width:var(--p-actions-icon-size, 22px);height:var(--p-actions-icon-size, 22px);line-height:var(--p-actions-icon-size, 22px)}.praxis-more-btn{width:var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));height:var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));--mat-icon-button-state-layer-size: var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));background-image:var(--p-actions-more-btn-gradient, none);background-size:100% 100%;background-repeat:no-repeat}.praxis-more-btn mat-icon,.praxis-more-btn .mat-icon{font-size:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));width:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));height:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));line-height:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));color:var(--p-actions-more-icon-color);background-image:var(--p-actions-more-icon-gradient, none);-webkit-background-clip:text;background-clip:text}.praxis-icon-btn.destructive mat-icon{color:var(--md-sys-color-error)}.mat-mdc-tooltip.praxis-tooltip{margin-top:-8px;margin-bottom:8px}.spacer{flex:1 1 auto}.praxis-table-header{display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;margin:16px 0 12px;width:100%;clear:both;position:relative}.praxis-table-header.stacked{margin:0}.praxis-table-header>praxis-table-toolbar{flex:1 0 100%}.praxis-floating-bulk-actions{position:fixed;z-index:1001;display:inline-flex;align-items:center;gap:8px;padding:8px;border-radius:999px;background:var(--md-sys-color-surface-container-highest);box-shadow:0 8px 20px #00000029}.praxis-floating-bulk-actions.pos-bottom-right{right:20px;bottom:20px}.praxis-floating-bulk-actions.pos-bottom-left{left:20px;bottom:20px}.praxis-floating-bulk-actions.pos-top-right{right:20px;top:20px}.praxis-floating-bulk-actions.pos-top-left{left:20px;top:20px}@media(max-width:768px){.praxis-floating-bulk-actions{gap:6px;padding:6px}.praxis-floating-bulk-actions.pos-bottom-right{right:12px;left:auto;bottom:12px}.praxis-floating-bulk-actions.pos-bottom-left{left:12px;right:auto;bottom:12px}.praxis-floating-bulk-actions.pos-top-right{right:12px;left:auto;top:12px}.praxis-floating-bulk-actions.pos-top-left{left:12px;right:auto;top:12px}}:host{display:block;width:100%;min-width:0;max-width:100%;--pfx-toolbar-pad-y: 6px;--pfx-toolbar-pad-x: 12px;--p-table-bg: var(--md-sys-color-surface-container-highest);--p-table-text-color: var(--md-sys-color-on-surface);--p-table-header-bg: var(--md-sys-color-surface-container-highest);--p-table-header-fg: var(--md-sys-color-on-surface);--p-table-border-color: var(--md-sys-color-outline-variant);--p-table-row-even-bg: var(--md-sys-color-surface-container);--p-table-row-hover-bg: var(--md-sys-color-surface-container-high);--p-table-row-selected-bg: var(--md-sys-color-primary-container);--p-table-badge-soft-primary-bg: var(--md-sys-color-primary-container);--p-table-badge-soft-primary-fg: var(--md-sys-color-on-primary-container);--p-table-badge-soft-accent-bg: var(--md-sys-color-secondary-container);--p-table-badge-soft-accent-fg: var(--md-sys-color-on-secondary-container);--p-table-badge-soft-warn-bg: var(--md-sys-color-error-container);--p-table-badge-soft-warn-fg: var(--md-sys-color-on-error-container);--p-table-state-success-bg: var(--md-sys-color-tertiary-container);--p-table-state-success-fg: var(--md-sys-color-on-tertiary-container);--p-table-state-warning-bg: var(--md-sys-color-secondary-container);--p-table-state-warning-fg: var(--md-sys-color-on-secondary-container);--p-table-state-danger-bg: var(--md-sys-color-error-container);--p-table-state-danger-fg: var(--md-sys-color-on-error-container);--p-table-state-highlight-bg: var(--md-sys-color-primary-container);--p-table-state-highlight-fg: var(--md-sys-color-on-primary-container);--p-table-drag-handle-size: 14px;--p-table-drag-handle-color: var(--md-sys-color-on-surface-variant);--p-table-drag-handle-hover-color: var(--md-sys-color-on-surface);--p-table-drag-handle-base-opacity: 0;--p-table-drag-handle-visible-opacity: .72;--p-table-drag-handle-active-opacity: 1;--p-table-drag-handle-transition-duration: .16s;--p-table-reorder-transition-duration: .16s;--p-table-drag-preview-scale: 1.01;--p-table-drag-status-enter-duration: .18s;--p-table-drag-preview-shadow: 0 14px 32px rgba(0, 0, 0, .28), 0 0 0 1px var(--p-table-border-color)}:host ::ng-deep .mat-mdc-table{background:var(--p-table-bg);color:var(--p-table-text-color);border-radius:12px 12px 0 0;width:100%;box-shadow:var(--p-table-surface-shadow);transition:box-shadow var(--p-table-selection-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .mat-mdc-table:hover{box-shadow:var(--p-table-surface-shadow-hover, var(--p-table-surface-shadow))}:host ::ng-deep .mat-mdc-table.table-stack-top{border-top-left-radius:0;border-top-right-radius:0}:host ::ng-deep .praxis-toolbar-footer{border:0 solid var(--p-table-border-color);border-top:0;border-radius:0;background:var(--p-table-bg)}:host ::ng-deep .mat-mdc-paginator.footer-stack{border-top-left-radius:0;border-top-right-radius:0;border-top:0}:host ::ng-deep .mat-mdc-paginator.footer-stack .mat-mdc-paginator-container{padding:8px 12px}:host [data-role=table-settings].mat-mdc-icon-button{--mdc-icon-button-icon-color: var(--md-sys-color-primary);color:var(--md-sys-color-primary)}.pfx-link{color:var(--md-sys-color-primary);text-decoration:underline;cursor:pointer}.pfx-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:10px;font-size:12px;line-height:1;border:1px solid transparent}.pfx-chip-icon{font-size:14px;width:14px;height:14px}.pfx-chip--outlined{background:transparent;border-color:var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}.pfx-chip--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-chip--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-chip--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-chip--soft-primary{background:var(--p-table-badge-soft-primary-bg);color:var(--p-table-badge-soft-primary-fg)}.pfx-chip--soft-accent{background:var(--p-table-badge-soft-accent-bg);color:var(--p-table-badge-soft-accent-fg)}.pfx-chip--soft-warn{background:var(--p-table-badge-soft-warn-bg);color:var(--p-table-badge-soft-warn-fg)}.pfx-progress{position:relative;width:100%;max-width:140px;height:8px;background:var(--md-sys-color-surface-container-highest);border-radius:4px;overflow:hidden;display:inline-block;vertical-align:middle}.pfx-progress-bar{height:100%;background:var(--md-sys-color-primary);transition:width .2s ease}.pfx-progress-label{margin-left:8px;font-size:12px;opacity:.8;display:inline-block;vertical-align:middle}.pfx-avatar{display:inline-flex;align-items:center;justify-content:center;background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface);border-radius:4px;overflow:hidden;font-weight:600}.pfx-avatar.shape-rounded{border-radius:8px}.pfx-avatar.shape-circle{border-radius:999px}.pfx-avatar--initials{text-transform:uppercase;font-size:12px}.pfx-cell-compose{display:inline-flex;align-items:center;gap:6px}.pfx-cell-compose.dir-col{flex-direction:column;align-items:stretch}.pfx-cell-compose.align-start{justify-content:flex-start}.pfx-cell-compose.align-center{justify-content:center}.pfx-cell-compose.align-end{justify-content:flex-end}.pfx-cell-compose.wrap{flex-wrap:wrap}.pfx-cell-compose.ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.px-scroll-viewport{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}.px-scroll-viewport.scroll-none{overflow-x:visible}.px-scroll-viewport.scroll-auto ::ng-deep .mat-mdc-table{width:max-content;min-width:100%}.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-header-cell,.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-cell{white-space:normal;text-overflow:initial}.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-table{width:100%}:host ::ng-deep .mat-mdc-header-row{position:sticky;top:0;z-index:1;background:var(--p-table-header-bg);color:var(--p-table-header-fg);box-shadow:var(--p-table-header-shadow, 0 1px 0 var(--p-table-border-color));border-bottom:1px solid var(--p-table-border-color)}:host ::ng-deep .mat-mdc-header-cell,:host ::ng-deep .mat-sort-header-content,:host ::ng-deep .mat-mdc-header-row .mat-icon{color:var(--p-table-header-fg)!important;font-weight:600}:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow,:host ::ng-deep .mat-mdc-header-cell:hover .mat-sort-header-arrow{color:var(--p-table-header-fg)!important}:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-indicator,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-stem,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer-left,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer-right{border-color:var(--p-table-header-fg)!important;background:var(--p-table-header-fg)!important}:host ::ng-deep .mat-mdc-header-cell{padding:var(--p-header-padding, 12px 16px)!important;font-size:var(--p-header-font-size, inherit);font-weight:var(--p-header-font-weight, 600);letter-spacing:var(--p-header-letter-spacing, normal);text-transform:var(--p-header-text-transform, none);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-container{display:flex;align-items:center;width:100%;gap:4px;cursor:inherit}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable{-webkit-user-select:none;user-select:none;cursor:grab;padding-left:0!important}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable.cdk-drag-dragging{cursor:grabbing}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-content{display:inline-flex;align-items:center;gap:4px;flex:1 1 auto;min-width:0}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-header-label{display:inline-flex;align-items:center;gap:4px;flex:1 1 auto;min-width:0}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-header-label-text{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle{-webkit-appearance:none;appearance:none;border:0;background:transparent;color:var(--p-table-drag-handle-color);width:var(--p-table-drag-handle-size);min-width:var(--p-table-drag-handle-size);flex:0 0 var(--p-table-drag-handle-size);height:var(--p-table-drag-handle-size);padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:0;cursor:inherit;pointer-events:none;touch-action:none;opacity:var(--p-table-drag-handle-base-opacity, .42);transform:none;order:-1;margin-inline-end:0;transition:opacity var(--p-table-drag-handle-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1)),color var(--p-table-drag-handle-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:hover .praxis-column-drag-handle,:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:focus-within .praxis-column-drag-handle{opacity:var(--p-table-drag-handle-visible-opacity, .72);color:var(--p-table-drag-handle-hover-color, var(--p-table-drag-handle-color))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle:active{opacity:var(--p-table-drag-handle-active-opacity, 1);cursor:grabbing}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle .mat-icon{font-size:14px;width:14px;height:14px;line-height:14px;transition:transform .18s var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:hover .praxis-column-drag-handle .mat-icon{transform:none}:host ::ng-deep .pfx-column-drag-indicator .cdk-drop-list-dragging .mat-mdc-header-cell:not(.cdk-drag-placeholder){transition:transform var(--p-table-reorder-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-indicator .mat-mdc-header-cell.cdk-drag-animating{transition:transform var(--p-table-reorder-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}.pfx-column-drag-preview{box-sizing:border-box;display:flex;align-items:center;border-radius:10px;border:1px solid var(--p-table-border-color);background:linear-gradient(135deg,var(--p-table-header-bg) 0%,var(--p-table-row-hover-bg) 100%);color:var(--p-table-header-fg);box-shadow:var(--p-table-drag-preview-shadow);transform:scale(var(--p-table-drag-preview-scale, 1.01));pointer-events:none;z-index:1000}.pfx-column-drag-preview .praxis-column-drag-handle,.pfx-column-drag-preview .mat-sort-header-arrow,.pfx-column-drag-preview .mat-sort-header-indicator,.pfx-column-drag-preview .mat-sort-header-stem,.pfx-column-drag-preview .mat-sort-header-pointer,.pfx-column-drag-preview .mat-sort-header-pointer-left,.pfx-column-drag-preview .mat-sort-header-pointer-right{display:none!important}.pfx-column-drag-preview .mat-sort-header-container{display:flex;align-items:center;width:100%;min-height:100%;padding-right:0!important}.pfx-column-drag-preview .mat-sort-header-content,.pfx-column-drag-preview .praxis-header-label{display:inline-flex;align-items:center;min-width:0;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .pfx-column-drag-indicator .cdk-drag-placeholder{opacity:1;border:1px dashed var(--p-table-border-color);background:var(--p-table-row-hover-bg)}:host ::ng-deep .pfx-column-drag-indicator .cdk-drag-placeholder *{opacity:0}:host ::ng-deep .pfx-column-drag-indicator .mat-mdc-header-cell.cdk-drag-dragging{opacity:.58}@media(prefers-reduced-motion:reduce){:host ::ng-deep .pfx-column-drag-indicator .cdk-drop-list-dragging .mat-mdc-header-cell:not(.cdk-drag-placeholder){transition:none}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle,:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle .mat-icon,.pfx-column-drag-preview{transition:none;transform:none}.praxis-column-reorder-status{animation:none}.pfx-expansion-detail-panel{animation:none!important;transition:none!important;transform:none!important}:host ::ng-deep .mat-mdc-row{transition:none}:host ::ng-deep .mat-mdc-table{transition:none}}.praxis-actions-header{text-align:right}.praxis-actions-header.align-start{text-align:left}.praxis-actions-header.align-center{text-align:center}.praxis-actions-header.align-end{text-align:right}.praxis-actions-header .praxis-actions-header__content{display:inline-flex;align-items:center;gap:var(--p-actions-header-gap, 6px);color:var(--p-actions-header-color, inherit)}.praxis-actions-header .praxis-actions-header__content .mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}:host ::ng-deep .mat-mdc-header-cell .mat-sort-header-container{padding-right:20px}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-container{padding-right:12px}@media(pointer:coarse){:host{--p-table-drag-handle-size: 18px;--p-table-drag-handle-base-opacity: .56;--p-table-drag-handle-visible-opacity: .92}}:host ::ng-deep .mat-mdc-cell{color:var(--p-table-text-color);font-size:var(--p-cell-font-size, inherit);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .mat-mdc-cell .pfx-cell-content,:host ::ng-deep .mat-cell .pfx-cell-content{display:inline-flex;align-items:center;gap:6px;width:100%;min-width:0;overflow:hidden}:host ::ng-deep .mat-mdc-row:hover{background:var(--p-table-row-hover-bg)}:host ::ng-deep .mat-mdc-row{transition:background-color var(--p-table-hover-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1)),box-shadow var(--p-table-selection-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .mat-mdc-row:nth-child(2n){background:var(--p-table-row-even-bg)}:host ::ng-deep .mat-mdc-row:nth-child(2n):hover{background:var(--p-table-row-hover-bg)}:host ::ng-deep .mat-mdc-row.pfx-row-selected,:host ::ng-deep .mat-mdc-row.pfx-row-selected:hover{background:var(--p-table-row-selected-bg)}:host.row-borders ::ng-deep .mat-mdc-row .mat-mdc-cell{border-bottom:1px solid var(--p-table-border-color)}:host.row-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell{border-bottom:none}:host.col-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell,:host.col-borders ::ng-deep .mat-mdc-row .mat-mdc-cell{border-right:1px solid var(--p-table-border-color)}:host.col-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell:last-child,:host.col-borders ::ng-deep .mat-mdc-row .mat-mdc-cell:last-child{border-right:none}.ptable-error{display:flex;align-items:center;gap:12px;padding:12px;margin:8px 0;border:1px solid var(--md-sys-color-error);border-radius:8px}.ptable-error__content{flex:1}.ptable-error__title{font-weight:600}.ptable-info-banner{display:flex;gap:12px;align-items:center;padding:8px 12px;margin:8px 0;border-radius:8px;border:1px solid var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.ptable-info-banner .text{flex:1;font-weight:600}.ptable-info-banner .actions{display:flex;gap:8px}.pfx-cell-image{display:inline-block;vertical-align:middle;background:var(--md-sys-color-surface-variant);border:1px solid var(--md-sys-color-outline-variant)}.pfx-cell-image.shape-rounded{border-radius:8px}.pfx-cell-image.shape-circle{border-radius:9999px}.pfx-badge{display:inline-flex;align-items:center;gap:6px;line-height:1;padding:4px 8px;border-radius:9999px;font-size:12px;font-weight:600;border:1px solid transparent}.pfx-badge .pfx-badge-icon{font-size:16px;width:16px;height:16px}.pfx-badge--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-badge--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-badge--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-badge--outlined{background:transparent;border-color:var(--md-sys-color-outline-variant);color:inherit}.pfx-badge--soft-primary{background:var(--p-table-badge-soft-primary-bg);color:var(--p-table-badge-soft-primary-fg)}.pfx-badge--soft-accent{background:var(--p-table-badge-soft-accent-bg);color:var(--p-table-badge-soft-accent-fg)}.pfx-badge--soft-warn{background:var(--p-table-badge-soft-warn-bg);color:var(--p-table-badge-soft-warn-fg)}.row--success,.row--success td,td.row--success{background-color:var(--p-table-state-success-bg)!important;color:var(--p-table-state-success-fg)!important}.row--warning,.row--warning td,td.row--warning{background-color:var(--p-table-state-warning-bg)!important;color:var(--p-table-state-warning-fg)!important}.row--danger,.row--danger td,td.row--danger{background-color:var(--p-table-state-danger-bg)!important;color:var(--p-table-state-danger-fg)!important}.row--highlight,.row--highlight td,td.row--highlight{background-color:var(--p-table-state-highlight-bg)!important;color:var(--p-table-state-highlight-fg)!important;font-weight:600}.row--muted,.row--muted td,td.row--muted{opacity:.7;filter:saturate(.6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i10$3.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: i11$1.ɵɵCdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i11$1.ɵɵCdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i11$1.ɵɵCdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i12.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i12.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i15$2.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i17.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i17.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i17.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i18.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i20.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i20.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i8$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i8$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i8$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i8$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i8$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i8$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i8$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i8$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i8$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i8$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisFilter, selector: "praxis-filter", inputs: ["resourcePath", "fieldMetadata", "filterId", "formId", "componentInstanceId", "mode", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "enableCustomization", "value", "alwaysVisibleFields", "alwaysVisibleFieldMetadataOverrides", "selectedFieldIds", "tags", "allowSaveTags", "persistenceKey", "disablePersistence", "i18n", "changeDebounceMs", "showFilterSettings", "confirmTagDelete", "placeBooleansInActions", "showToggleLabels", "useInlineSelectVariant", "useInlineSearchableSelectVariant", "useInlineMultiSelectVariant", "useInlineInputVariant", "useInlineToggleVariant", "useInlineRangeVariant", "useInlineDateVariant", "useInlineDateRangeVariant", "useInlineTimeVariant", "useInlineTimeRangeVariant", "useInlineTreeSelectVariant", "alwaysMinWidth", "alwaysColsMd", "alwaysColsLg", "tagColor", "tagVariant", "tagButtonColor", "actionsButtonColor", "actionsVariant", "overlayVariant", "overlayBackdrop", "advancedOpenMode", "advancedClearButtonsEnabled"], outputs: ["submit", "change", "clear", "modeChange", "requestSearch", "tagsChange", "selectedFieldIdsChange", "metaChanged", "schemaStatusChange"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisTableToolbar, selector: "praxis-table-toolbar", inputs: ["config", "backgroundColor", "placement", "showMain", "showActionsGroup", "showEndActions", "showMobileActions", "showReset", "dslContext", "dslFunctionRegistry"], outputs: ["toolbarAction", "reset"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone"] }, { kind: "component", type: TableRatingCellComponent, selector: "praxis-table-rating", inputs: ["itemsCount", "value", "size", "ratingColor", "outlineColor", "ariaLabel"] }], deferBlockDependencies: [() => [import('@praxisui/ai').then(m => m.PraxisAiAssistantComponent)], () => [import('@praxisui/ai').then(m => m.PraxisAiAssistantComponent)], () => [import('@praxisui/ai').then(m => m.PraxisAiAssistantComponent)], () => [import('@praxisui/ai').then(m => m.PraxisAiAssistantComponent)]] });
42034
42272
  }
42035
42273
  i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "20.3.17", ngImport: i0, type: PraxisTable, resolveDeferredDeps: () => [import('@praxisui/ai').then(m => m.PraxisAiAssistantComponent)], resolveMetadata: PraxisAiAssistantComponent => ({ decorators: [{
42036
42274
  type: Component,
@@ -42061,8 +42299,8 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "20.3.17", n
42061
42299
  TableDefaultsProvider,
42062
42300
  FilterConfigService,
42063
42301
  DataFormattingService
42064
- ], template: "@if (shouldShowEmptyState()) {\n <praxis-empty-state-card\n icon=\"link\"\n [title]=\"'Conecte a tabela \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para carregar colunas e dados automaticamente.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"\n ></praxis-empty-state-card>\n}\n\n<!-- Error State with Quick Connect CTA -->\n@if (isRemoteMode() && (schemaError || dataError)) {\n<div class=\"ptable-error\" role=\"alert\" aria-live=\"assertive\">\n <mat-icon color=\"warn\" aria-hidden=\"true\">error</mat-icon>\n <div class=\"ptable-error__content\">\n <div class=\"ptable-error__title\">Erro</div>\n <div>{{ errorMessage || 'Ocorreu um erro ao carregar a tabela.' }}</div>\n </div>\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\">\n <mat-icon>bolt</mat-icon>\n Conectar a recurso\n </button>\n @if (!schemaError) { <button mat-stroked-button (click)=\"retryData()\">Tentar novamente</button> }\n @if (schemaError) { <button mat-stroked-button (click)=\"reloadSchema()\">Recarregar colunas</button> }\n </div>\n}\n\n<!-- Inline banner for schema change (only in edit mode) -->\n@if (shouldShowOutdatedInline()) {\n<div class=\"ptable-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"onReconcileRequested()\">\n <mat-icon>sync</mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n </div>\n}\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError && toolbarV2) {\n <div class=\"praxis-table-header\" [class.edit-mode]=\"enableCustomization\" [class.stacked]=\"showToolbar\">\n @if (showToolbar && shouldShowToolbarTopPlacement()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n [showActionsGroup]=\"shouldShowToolbarActionsTop()\"\n [showMobileActions]=\"shouldShowToolbarActionsTop()\"\n (toolbarAction)=\"onToolbarAction($event)\"\n (reset)=\"onResetPreferences()\"\n >\n @if (shouldRenderAdvancedFilter()) {\n <praxis-filter\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n \n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (submit)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n }\n <ng-content select=\"[advancedFilter]\" />\n <ng-content select=\"[toolbar]\" />\n \n <!-- AI Assistant in Toolbar -->\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\" end-actions></praxis-ai-assistant>\n }\n }\n\n @if (enableCustomization) {\n <button end-actions mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </praxis-table-toolbar>\n }\n @if (!showToolbar && enableCustomization) {\n <div class=\"ptable-header-actions\">\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n }\n }\n <button mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\" (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n @if (isRemoteMode()) {\n <button mat-icon-button (click)=\"disconnect()\" aria-label=\"Desconectar\" matTooltip=\"Desconectar da fonte de dados\">\n <mat-icon>link_off</mat-icon>\n </button>\n }\n </div>\n }\n </div>\n} @else {\n @if (shouldRenderDataSurface() && !schemaError && !dataError) {\n @if (showToolbar && shouldShowToolbarTopPlacement()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n [showActionsGroup]=\"shouldShowToolbarActionsTop()\"\n [showMobileActions]=\"shouldShowToolbarActionsTop()\"\n (toolbarAction)=\"onToolbarAction($event)\"\n (reset)=\"onResetPreferences()\"\n >\n @if (shouldRenderAdvancedFilter()) {\n <praxis-filter\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n \n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (submit)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n }\n <ng-content select=\"[advancedFilter]\" />\n <ng-content select=\"[toolbar]\" />\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\" end-actions></praxis-ai-assistant>\n }\n }\n @if (enableCustomization) {\n <button end-actions mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </praxis-table-toolbar>\n }\n @if (!showToolbar && enableCustomization) {\n <div class=\"ptable-header-actions\">\n <button mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\" (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n </div>\n }\n }\n}\n<div class=\"px-scroll-viewport\"\n cdkScrollable\n [class.scroll-auto]=\"horizontalScroll === 'auto'\"\n [class.scroll-wrap]=\"horizontalScroll === 'wrap'\"\n [class.scroll-none]=\"horizontalScroll === 'none'\">\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError) {\n<div class=\"praxis-visually-hidden-status\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ columnReorderStatusMessage }}\n</div>\n@if (columnReorderVisualStatusMessage) {\n <div class=\"praxis-column-reorder-status\" role=\"note\">\n {{ columnReorderVisualStatusMessage }}\n </div>\n}\n<table\n mat-table\n data-testid=\"table-column-drag-drop-list\"\n [dataSource]=\"dataSource\"\n [multiTemplateDataRows]=\"isRowExpansionRuntimeEnabled()\"\n cdkDropList\n [cdkDropListDisabled]=\"!isColumnDraggingEnabled()\"\n [cdkDropListData]=\"visibleDataColumnsForDrag\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onColumnDrop($event)\"\n matSort\n (matSortChange)=\"onSortChange($event)\"\n [matSortDisabled]=\"!getSortingEnabled()\"\n [ngClass]=\"getTableElevationClassName()\"\n [class.table-stack-top]=\"showToolbar\"\n [class.pfx-column-drag-enabled]=\"isColumnDraggingEnabled()\"\n [class.pfx-column-drag-indicator]=\"isColumnDragIndicatorEnabled()\"\n>\n @if (config.behavior?.selection?.enabled) {\n <ng-container\n matColumnDef=\"_select\"\n >\n <th mat-header-cell *matHeaderCellDef>\n @if (canSelectAll()) {\n <mat-checkbox\n (change)=\"masterToggle()\"\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n ></mat-checkbox>\n }\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n [checked]=\"selection.isSelected(row)\"\n ></mat-checkbox>\n </td>\n </ng-container>\n }\n @if (isRowExpansionRuntimeEnabled()) {\n <ng-container matColumnDef=\"_expander\">\n <th mat-header-cell *matHeaderCellDef class=\"pfx-expansion-col-header\">\n <span class=\"praxis-visually-hidden-status\">Expandir detalhes da linha</span>\n </th>\n <td mat-cell *matCellDef=\"let row; let i = index\" class=\"pfx-expansion-col-cell\">\n <button\n mat-icon-button\n class=\"pfx-expansion-toggle\"\n [disabled]=\"!isRowExpandable(row, i) || !isExpansionIconTriggerEnabled()\"\n [attr.aria-expanded]=\"isRowExpanded(row, i) ? 'true' : 'false'\"\n [attr.aria-controls]=\"getRowExpansionDetailId(row, i)\"\n [attr.aria-label]=\"getRowExpansionToggleAriaLabel(row, i)\"\n (click)=\"onExpansionToggleFromIcon(row, i, $event)\"\n (keydown)=\"onExpansionToggleKeydown($event, row, i)\"\n >\n <mat-icon [praxisIcon]=\"isRowExpanded(row, i)\n ? getExpansionExpandedIcon()\n : getExpansionCollapsedIcon()\"></mat-icon>\n </button>\n </td>\n </ng-container>\n }\n @for (column of visibleColumns; track column.field) {\n <ng-container\n [matColumnDef]=\"column.field\"\n [sticky]=\"column.sticky === true || column.sticky === 'start'\"\n [stickyEnd]=\"column.sticky === 'end'\"\n >\n <th\n mat-header-cell\n *matHeaderCellDef\n mat-sort-header\n cdkDrag\n [cdkDragData]=\"column\"\n cdkDragLockAxis=\"x\"\n cdkDragPreviewClass=\"pfx-column-drag-preview\"\n (cdkDragStarted)=\"onColumnDragStarted(column)\"\n (cdkDragEnded)=\"onColumnDragEnded($event, column)\"\n (keydown)=\"onColumnDragHandleKeydown($event, column)\"\n [cdkDragDisabled]=\"!isColumnDraggingEnabled() || !isColumnDraggable(column)\"\n [class.praxis-header-draggable]=\"isColumnDraggingEnabled() && isColumnDraggable(column)\"\n [disabled]=\"!getSortingEnabled() || column.sortable === false\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnHeaderAttrStyle(column)\"\n [attr.aria-label]=\"isColumnDraggingEnabled() && isColumnDraggable(column) ? getColumnDragHandleAriaLabel(column) : null\"\n >\n <span class=\"praxis-header-label\" data-testid=\"column-header-label\">\n @if (isColumnDraggingEnabled() && isColumnDraggable(column)) {\n <span\n class=\"praxis-column-drag-handle\"\n data-testid=\"column-drag-handle\"\n [attr.data-column-field]=\"column.field\"\n aria-hidden=\"true\"\n >\n <mat-icon [praxisIcon]=\"'drag_indicator'\"></mat-icon>\n </span>\n }\n <span class=\"praxis-header-label-text\">{{ column.header }}</span>\n </span>\n </th>\n <td\n mat-cell\n *matCellDef=\"let element\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnCellAttrStyle(column)\"\n [ngClass]=\"getCellClasses(element, column)\"\n [ngStyle]=\"getCellNgStyle(element, column)\"\n >\n <div\n class=\"pfx-cell-content\"\n [ngClass]=\"getCellContentClasses(element, column)\"\n [ngStyle]=\"getCellContentNgStyle(element, column)\"\n >\n <ng-container [ngSwitch]=\"getEffectiveRendererType(element, column)\">\n <!-- Icon renderer -->\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon\n [color]=\"getIconColor(element, column) || null\"\n [ngStyle]=\"getIconStyle(element, column)\"\n [attr.aria-label]=\"getIconAriaLabel(element, column) || null\"\n >{{ getIconName(element, column) }}</mat-icon\n >\n </ng-container>\n\n <!-- Image renderer -->\n <ng-container *ngSwitchCase=\"'image'\">\n <img\n class=\"pfx-cell-image\"\n [src]=\"getImageSrc(element, column)\"\n [attr.alt]=\"getImageAlt(element, column) || ''\"\n [attr.loading]=\"getImageLazy(element, column) ? 'lazy' : null\"\n [style.width.px]=\"getImageWidth(element, column)\"\n [style.height.px]=\"getImageHeight(element, column)\"\n [class.shape-rounded]=\"getImageShape(element, column) === 'rounded'\"\n [class.shape-circle]=\"getImageShape(element, column) === 'circle'\"\n [style.object-fit]=\"getImageFit(element, column)\"\n />\n </ng-container>\n\n <!-- Badge renderer -->\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(element, column)\">\n @if (getBadgeIcon(element, column); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }\n <span class=\"pfx-badge-text\">{{ getBadgeText(element, column) }}</span>\n </span>\n </ng-container>\n\n <!-- Link renderer -->\n <ng-container *ngSwitchCase=\"'link'\">\n <a\n class=\"pfx-link\"\n [attr.href]=\"getLinkHref(element, column) || null\"\n [attr.target]=\"getLinkTarget(element, column) || null\"\n [attr.rel]=\"getLinkRel(element, column) || null\"\n (click)=\"$event.stopPropagation()\"\n >{{ getLinkText(element, column) }}</a\n >\n </ng-container>\n\n <!-- Button renderer -->\n <ng-container *ngSwitchCase=\"'button'\">\n <ng-container [ngSwitch]=\"getButtonVariant(element, column)\">\n <button\n *ngSwitchCase=\"'outlined'\"\n mat-stroked-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n <button\n *ngSwitchCase=\"'text'\"\n mat-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n <button\n *ngSwitchDefault\n mat-flat-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n </ng-container>\n </ng-container>\n\n <!-- Chip renderer -->\n <ng-container *ngSwitchCase=\"'chip'\">\n <span class=\"pfx-chip\" [ngClass]=\"getChipClasses(element, column)\">\n @if (getChipIcon(element, column); as ci) { <mat-icon class=\"pfx-chip-icon\">{{ ci }}</mat-icon> }\n <span class=\"pfx-chip-text\">{{ getChipText(element, column) }}</span>\n </span>\n </ng-container>\n\n <!-- Progress renderer -->\n <ng-container *ngSwitchCase=\"'progress'\">\n <div class=\"pfx-progress\">\n <div class=\"pfx-progress-bar\" [style.width.%]=\"getProgressWidthPercentStyle(element, column)\" [style.background]=\"getProgressBackgroundStyle(element, column)\"></div>\n @if (getProgressShowLabel(element, column)) { <div class=\"pfx-progress-label\">{{ getProgressValue(element, column) }}%</div> }\n </div>\n </ng-container>\n\n <!-- Avatar renderer -->\n <ng-container *ngSwitchCase=\"'avatar'\">\n @if (getAvatarSrc(element, column); as asrc) {\n <img class=\"pfx-avatar\" [src]=\"asrc\" [attr.alt]=\"getAvatarAlt(element, column) || ''\" [ngStyle]=\"getAvatarStyle(element, column)\" [class.shape-rounded]=\"getAvatarShape(element, column) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, column) === 'circle'\" loading=\"lazy\" />\n } @else {\n <span class=\"pfx-avatar pfx-avatar--initials\" [ngStyle]=\"getAvatarStyle(element, column)\" [class.shape-rounded]=\"getAvatarShape(element, column) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, column) === 'circle'\">{{ getAvatarInitials(element, column) }}</span>\n }\n </ng-container>\n\n <!-- Toggle renderer -->\n <ng-container *ngSwitchCase=\"'toggle'\">\n <mat-slide-toggle\n [checked]=\"getToggleState(element, column)\"\n [disabled]=\"isToggleDisabled(element, column)\"\n [attr.aria-label]=\"getToggleAriaLabel(element, column) || 'Alternar'\"\n (change)=\"onToggleChange(element, column, $event)\"\n (click)=\"$event.stopPropagation()\"\n ></mat-slide-toggle>\n </ng-container>\n\n <!-- Menu renderer -->\n <ng-container *ngSwitchCase=\"'menu'\">\n <button mat-icon-button [matMenuTriggerFor]=\"menuRef\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getMenuAriaLabel(element, column) || 'Menu'\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menuRef=\"matMenu\">\n <button mat-menu-item *ngFor=\"let it of getMenuItems(element, column)\" (click)=\"onMenuItemClick(it, element, $event)\" [disabled]=\"!it.__visible\" >\n @if (it.icon) { <mat-icon>{{ it.icon }}</mat-icon> }\n <span>{{ it.label }}</span>\n </button>\n </mat-menu>\n </ng-container>\n\n <!-- Rating renderer -->\n <ng-container *ngSwitchCase=\"'rating'\">\n <praxis-table-rating\n class=\"pfx-rating-cell\"\n [itemsCount]=\"getRatingMax(element, column)\"\n [value]=\"getRatingValue(element, column)\"\n [size]=\"getRatingSize(element, column)\"\n [ratingColor]=\"getRatingColor(element, column)\"\n [outlineColor]=\"getRatingOutlineColor(element, column)\"\n [ariaLabel]=\"getRatingAriaLabel(element, column) || column.header\">\n </praxis-table-rating>\n </ng-container>\n\n <!-- HTML renderer (sanitizado) -->\n <ng-container *ngSwitchCase=\"'html'\">\n <span [innerHTML]=\"getSafeHtml(element, column)\"></span>\n </ng-container>\n\n <!-- Compose renderer -->\n <ng-container *ngSwitchCase=\"'compose'\">\n <span class=\"pfx-cell-compose\" [ngClass]=\"getComposeClasses(element, column)\" [ngStyle]=\"getComposeGapStyle(element, column)\">\n <ng-container *ngFor=\"let it of getComposeItems(element, column)\">\n <ng-container [ngSwitch]=\"getItemEffectiveType(element, column, it)\">\n <!-- Reuse helpers by projecting item as faux column -->\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon [color]=\"getIconColor(element, asItemColumn(column, it)) || null\" [ngStyle]=\"getIconStyle(element, asItemColumn(column, it))\" [attr.aria-label]=\"getIconAriaLabel(element, asItemColumn(column, it)) || null\">{{ getIconName(element, asItemColumn(column, it)) }}</mat-icon>\n </ng-container>\n <ng-container *ngSwitchCase=\"'image'\">\n <img class=\"pfx-cell-image\" [src]=\"getImageSrc(element, asItemColumn(column, it))\" [attr.alt]=\"getImageAlt(element, asItemColumn(column, it)) || ''\" [attr.loading]=\"getImageLazy(element, asItemColumn(column, it)) ? 'lazy' : null\" [style.width.px]=\"getImageWidth(element, asItemColumn(column, it))\" [style.height.px]=\"getImageHeight(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getImageShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getImageShape(element, asItemColumn(column, it)) === 'circle'\" [style.object-fit]=\"getImageFit(element, asItemColumn(column, it))\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(element, asItemColumn(column, it))\">@if (getBadgeIcon(element, asItemColumn(column, it)); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }<span class=\"pfx-badge-text\">{{ getBadgeText(element, asItemColumn(column, it)) }}</span></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'link'\">\n <a class=\"pfx-link\" [attr.href]=\"getLinkHref(element, asItemColumn(column, it)) || null\" [attr.target]=\"getLinkTarget(element, asItemColumn(column, it)) || null\" [attr.rel]=\"getLinkRel(element, asItemColumn(column, it)) || null\" (click)=\"$event.stopPropagation()\">{{ getLinkText(element, asItemColumn(column, it)) }}</a>\n </ng-container>\n <ng-container *ngSwitchCase=\"'button'\">\n <ng-container [ngSwitch]=\"getButtonVariant(element, asItemColumn(column, it))\">\n <button *ngSwitchCase=\"'outlined'\" mat-stroked-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n <button *ngSwitchCase=\"'text'\" mat-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n <button *ngSwitchDefault mat-flat-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'chip'\">\n <span class=\"pfx-chip\" [ngClass]=\"getChipClasses(element, asItemColumn(column, it))\">@if (getChipIcon(element, asItemColumn(column, it)); as ci) { <mat-icon class=\"pfx-chip-icon\">{{ ci }}</mat-icon> }<span class=\"pfx-chip-text\">{{ getChipText(element, asItemColumn(column, it)) }}</span></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'progress'\">\n <div class=\"pfx-progress\"><div class=\"pfx-progress-bar\" [style.width.%]=\"getProgressWidthPercentStyle(element, asItemColumn(column, it))\" [style.background]=\"getProgressBackgroundStyle(element, asItemColumn(column, it))\"></div>@if (getProgressShowLabel(element, asItemColumn(column, it))) { <div class=\"pfx-progress-label\">{{ getProgressValue(element, asItemColumn(column, it)) }}%</div> }</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'avatar'\">\n @if (getAvatarSrc(element, asItemColumn(column, it)); as asrc) {\n <img class=\"pfx-avatar\" [src]=\"asrc\" [attr.alt]=\"getAvatarAlt(element, asItemColumn(column, it)) || ''\" [ngStyle]=\"getAvatarStyle(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getAvatarShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, asItemColumn(column, it)) === 'circle'\" loading=\"lazy\" />\n } @else {\n <span class=\"pfx-avatar pfx-avatar--initials\" [ngStyle]=\"getAvatarStyle(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getAvatarShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, asItemColumn(column, it)) === 'circle'\">{{ getAvatarInitials(element, asItemColumn(column, it)) }}</span>\n }\n </ng-container>\n <ng-container *ngSwitchCase=\"'toggle'\">\n <mat-slide-toggle [checked]=\"getToggleState(element, asItemColumn(column, it))\" [disabled]=\"isToggleDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getToggleAriaLabel(element, asItemColumn(column, it)) || 'Alternar'\" (change)=\"onToggleChange(element, asItemColumn(column, it), $event)\" (click)=\"$event.stopPropagation()\"></mat-slide-toggle>\n </ng-container>\n <ng-container *ngSwitchCase=\"'menu'\">\n <button mat-icon-button [matMenuTriggerFor]=\"menuRef\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getMenuAriaLabel(element, asItemColumn(column, it)) || 'Menu'\"><mat-icon>more_vert</mat-icon></button>\n <mat-menu #menuRef=\"matMenu\">\n <button mat-menu-item *ngFor=\"let mi of getMenuItems(element, asItemColumn(column, it))\" (click)=\"onMenuItemClick(mi, element, $event)\" [disabled]=\"!mi.__visible\">\n @if (mi.icon) { <mat-icon>{{ mi.icon }}</mat-icon> }\n <span>{{ mi.label }}</span>\n </button>\n </mat-menu>\n </ng-container>\n <ng-container *ngSwitchCase=\"'rating'\">\n <praxis-table-rating\n class=\"pfx-rating-cell\"\n [itemsCount]=\"getRatingMax(element, asItemColumn(column, it))\"\n [value]=\"getRatingValue(element, asItemColumn(column, it))\"\n [size]=\"getRatingSize(element, asItemColumn(column, it))\"\n [ratingColor]=\"getRatingColor(element, asItemColumn(column, it))\"\n [outlineColor]=\"getRatingOutlineColor(element, asItemColumn(column, it))\"\n [ariaLabel]=\"getRatingAriaLabel(element, asItemColumn(column, it)) || column.header\">\n </praxis-table-rating>\n </ng-container>\n <ng-container *ngSwitchCase=\"'html'\">\n <span [innerHTML]=\"getSafeHtml(element, asItemColumn(column, it))\"></span>\n </ng-container>\n <!-- Value item: render base cell text alongside visuals -->\n <ng-container *ngSwitchCase=\"'value'\">\n <span class=\"pfx-cell-value\">{{ getComposeItemValue(element, column, it) }}</span>\n </ng-container>\n </ng-container>\n </ng-container>\n </span>\n </ng-container>\n\n <!-- Default text rendering -->\n <ng-container *ngSwitchDefault>\n {{ getCellValue(element, column) }}\n </ng-container>\n </ng-container>\n </div>\n </td>\n </ng-container>\n }\n @if (config.actions?.row?.enabled) {\n <ng-container matColumnDef=\"_actions\" [sticky]=\"config.actions?.row?.sticky === true || config.actions?.row?.sticky === 'start'\" [stickyEnd]=\"config.actions?.row?.sticky === 'end'\">\n <th mat-header-cell *matHeaderCellDef #actionsHeaderCell [style.width]=\"getRowActionsWidthStyle()\" class=\"praxis-actions-header\" [class.align-start]=\"getActionsHeaderAlign() === 'start'\" [class.align-center]=\"getActionsHeaderAlign() === 'center'\" [class.align-end]=\"getActionsHeaderAlign() === 'end'\">\n <div class=\"praxis-actions-header__content\" [matTooltip]=\"getActionsHeaderTooltip() || ''\" [matTooltipDisabled]=\"!getActionsHeaderTooltip()\">\n @if (getActionsHeaderIcon(); as hi) { <mat-icon [praxisIcon]=\"hi\"></mat-icon> }\n @if (getActionsHeaderLabel(); as hl) { <span class=\"label\">{{ hl }}</span> }\n </div>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"praxis-actions-cell\"\n [class.dense]=\"dense\"\n [style.width]=\"getRowActionsWidthStyle()\"\n >\n <div class=\"praxis-actions-cell__content\">\n <!-- A\u00E7\u00F5es inline -->\n <!-- Inline actions: icons mode -->\n @if (config.actions?.row?.display === 'icons' || !config.actions?.row?.display) {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button\n mat-icon-button\n class=\"praxis-icon-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [matTooltip]=\"a.label || getActionId(a)\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"praxis-tooltip\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\"\n >\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n </button>\n </ng-container>\n }\n\n <!-- Inline actions: buttons mode (show label + icon) -->\n @if (config.actions?.row?.display === 'buttons') {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button\n mat-flat-button\n class=\"praxis-row-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\"\n >\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n }\n\n <!-- Menu de overflow -->\n @if (hasOverflowRowActions(row)) {\n <button\n mat-icon-button\n class=\"praxis-icon-btn praxis-more-btn\"\n [matMenuTriggerFor]=\"rowMoreMenu\"\n [color]=\"getRowMenuButtonColor() || null\"\n aria-label=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"getRowMenuIcon()\"></mat-icon>\n </button>\n }\n <mat-menu #rowMoreMenu=\"matMenu\" xPosition=\"before\">\n <ng-container\n *ngFor=\"let a of getOverflowRowActions(row); trackBy: trackAction\"\n >\n <button\n mat-menu-item\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [disabled]=\"isActionDisabled(a, row)\"\n >\n <mat-icon [color]=\"a.color || null\" [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n </mat-menu>\n </div>\n </td>\n </ng-container>\n }\n\n <tr\n mat-header-row\n *matHeaderRowDef=\"displayedColumns\"\n ></tr>\n @if (!isVirtualized()) {\n <tr\n mat-row\n *matRowDef=\"let row; let i = index; columns: displayedColumns\"\n [class.pfx-row-selected]=\"selection.isSelected(row)\"\n [class.pfx-row-expanded]=\"isRowExpansionRuntimeEnabled() && isRowExpanded(row, i)\"\n [attr.aria-selected]=\"config.behavior?.selection?.enabled ? (selection.isSelected(row) ? 'true' : 'false') : null\"\n [attr.aria-expanded]=\"isRowExpansionRuntimeEnabled() ? (isRowExpanded(row, i) ? 'true' : 'false') : null\"\n [ngClass]=\"getRowClasses(row)\"\n [ngStyle]=\"getRowNgStyle(row)\"\n [matTooltip]=\"getRowTooltip(row) || null\"\n [matTooltipDisabled]=\"!getRowTooltip(row)\"\n [matTooltipPosition]=\"getRowTooltipPosition(row)\"\n [matTooltipShowDelay]=\"getRowTooltipShowDelay(row)\"\n (click)=\"onRowClicked(row, i, $event)\"\n (dblclick)=\"onRowDoubleClicked(row, i)\"\n ></tr>\n @if (isRowExpansionRuntimeEnabled()) {\n <ng-container matColumnDef=\"_detail\">\n <td\n mat-cell\n *matCellDef=\"let row; let i = index\"\n class=\"pfx-expansion-detail-cell\"\n [attr.colspan]=\"displayedColumns.length\"\n >\n <section\n class=\"pfx-expansion-detail-panel\"\n [ngClass]=\"getExpansionMotionPresetClass()\"\n [ngStyle]=\"getExpansionMotionStyle()\"\n [attr.id]=\"getRowExpansionDetailId(row, i)\"\n role=\"region\"\n [attr.aria-label]=\"getRowExpansionRegionAriaLabel(row, i)\"\n [attr.aria-busy]=\"getExpansionDetailViewState(row, i).status === 'loading' ? 'true' : 'false'\"\n >\n @let detailState = getExpansionDetailViewState(row, i);\n @if (detailState.status === 'loading') {\n <div class=\"pfx-expansion-detail-message\" role=\"status\" aria-live=\"polite\">\n Carregando detail schema...\n </div>\n } @else if (detailState.status !== 'ready') {\n <div\n class=\"pfx-expansion-detail-message pfx-expansion-detail-message--error\"\n role=\"alert\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n >\n {{ detailState.message || 'Detail indispon\u00EDvel para esta linha.' }}\n </div>\n } @else {\n @if (getExpansionDetailLayout(detailState.schema) === 'tabs') {\n @let detailTabs = getExpansionDetailTabs(detailState.schema);\n @if (detailTabs.length) {\n <div class=\"pfx-expansion-detail-tabs\" role=\"tablist\" aria-label=\"Se\u00E7\u00F5es do detail\">\n @for (tab of detailTabs; track $index; let tabIndex = $index) {\n <button\n type=\"button\"\n class=\"pfx-expansion-detail-tab-btn\"\n role=\"tab\"\n [attr.id]=\"getExpansionDetailTabId(row, i, tab, tabIndex)\"\n [attr.aria-controls]=\"getExpansionDetailPanelId(row, i, tab, tabIndex)\"\n [attr.aria-selected]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs) ? 'true' : 'false'\"\n [attr.tabindex]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs) ? '0' : '-1'\"\n [class.is-active]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs)\"\n (click)=\"onExpansionDetailTabSelect(row, i, tab, tabIndex, $event)\"\n (keydown)=\"onExpansionDetailTabKeydown($event, row, i, tabIndex, detailTabs)\"\n >\n {{ getExpansionDetailNodeTitle(tab, 'Tab') }}\n </button>\n }\n </div>\n @for (tab of detailTabs; track $index; let tabIndex = $index) {\n @if (isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs)) {\n <div\n class=\"pfx-expansion-detail-tab-panel\"\n role=\"tabpanel\"\n [attr.id]=\"getExpansionDetailPanelId(row, i, tab, tabIndex)\"\n [attr.aria-labelledby]=\"getExpansionDetailTabId(row, i, tab, tabIndex)\"\n >\n @for (childNode of getExpansionDetailNodeChildren(tab); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: childNode, row: row, index: i }\n \"\n ></ng-container>\n }\n </div>\n }\n }\n } @else {\n <div class=\"pfx-expansion-detail-message\">\n Schema em layout tabs sem abas v\u00E1lidas.\n </div>\n }\n } @else {\n <div class=\"pfx-expansion-detail-stack\">\n @for (node of getExpansionDetailItems(detailState.schema); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: node, row: row, index: i }\n \"\n ></ng-container>\n }\n </div>\n }\n }\n\n <ng-template #expansionDetailNodeTemplate let-node let-row=\"row\" let-index=\"index\">\n @switch (getExpansionDetailNodeType(node)) {\n @case ('card') {\n <article class=\"pfx-expansion-node pfx-expansion-node-card\">\n <header class=\"pfx-expansion-node-card__header\">\n <h5 class=\"pfx-expansion-node-card__title\">\n {{ getExpansionDetailNodeTitle(node, 'Card') }}\n </h5>\n @if (node?.subtitle) {\n <p class=\"pfx-expansion-node-card__subtitle\">{{ node?.subtitle }}</p>\n }\n </header>\n @for (childNode of getExpansionDetailNodeChildren(node); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: childNode, row: row, index: index }\n \"\n ></ng-container>\n }\n </article>\n }\n @case ('value') {\n <div class=\"pfx-expansion-node pfx-expansion-node-value\">\n <span class=\"pfx-expansion-node-value__label\">\n {{ getExpansionDetailNodeTitle(node, 'Valor') }}\n </span>\n <strong class=\"pfx-expansion-node-value__content\">\n {{ getExpansionDetailValue(row, node) }}\n </strong>\n </div>\n }\n @case ('list') {\n <section class=\"pfx-expansion-node pfx-expansion-node-list\">\n <h6 class=\"pfx-expansion-node-list__title\">\n {{ getExpansionDetailNodeTitle(node, 'Lista') }}\n </h6>\n @let listItems = getExpansionDetailListItems(row, node);\n @if (listItems.length) {\n <ul>\n @for (entry of listItems; track $index) {\n <li>{{ entry }}</li>\n }\n </ul>\n } @else {\n <p class=\"pfx-expansion-node-placeholder\">Sem itens.</p>\n }\n </section>\n }\n @case ('richText') {\n <div\n class=\"pfx-expansion-node pfx-expansion-node-richtext\"\n [innerHTML]=\"getExpansionDetailRichText(node)\"\n ></div>\n }\n @case ('formRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Formul\u00E1rio referenciado: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('tableRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Tabela referenciada: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('chartRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Gr\u00E1fico referenciado: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('templateRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Template referenciado: <code>{{ node?.id || node?.templateId || 'sem-id' }}</code>\n </div>\n }\n @case ('action') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n A\u00E7\u00E3o declarada: <code>{{ node?.id || node?.actionId || 'sem-id' }}</code>\n </div>\n }\n @case ('tab') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Node <code>tab</code> fora de contexto de tabs.\n </div>\n }\n @default {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Node n\u00E3o suportado: <code>{{ getExpansionDetailNodeType(node) }}</code>\n </div>\n }\n }\n </ng-template>\n </section>\n </td>\n </ng-container>\n <tr\n mat-row\n *matRowDef=\"let row; columns: expansionDetailRowColumns; when: isExpansionDetailRow\"\n class=\"pfx-expansion-detail-row\"\n ></tr>\n }\n }\n</table>\n}\n\n<!-- Virtual rows path (header preserved above) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && isVirtualized()) {\n <cdk-virtual-scroll-viewport\n class=\"ptable-viewport\"\n [itemSize]=\"getVirtItemHeight()\"\n [minBufferPx]=\"getVirtBufferSize() * getVirtItemHeight()\"\n [maxBufferPx]=\"getVirtBufferSize() * getVirtItemHeight() * 2\"\n [style.minHeight]=\"getVirtMinHeightHostStyle()\"\n >\n <table\n class=\"mat-mdc-table\"\n [ngClass]=\"getTableElevationClassName()\"\n [style.width]=\"getVirtualTableWidthStyle()\"\n >\n <tbody>\n <tr class=\"mat-mdc-row\"\n *cdkVirtualFor=\"let row of dataSource.data; let i = index; trackBy: trackByRow\"\n [class.pfx-row-selected]=\"selection.isSelected(row)\"\n [attr.aria-selected]=\"config.behavior?.selection?.enabled ? (selection.isSelected(row) ? 'true' : 'false') : null\"\n [ngClass]=\"getRowClasses(row)\"\n [ngStyle]=\"getRowNgStyle(row)\"\n [matTooltip]=\"getRowTooltip(row) || null\"\n [matTooltipDisabled]=\"!getRowTooltip(row)\"\n [matTooltipPosition]=\"getRowTooltipPosition(row)\"\n [matTooltipShowDelay]=\"getRowTooltipShowDelay(row)\"\n (click)=\"onRowClicked(row, i, $event)\"\n (dblclick)=\"onRowDoubleClicked(row, i)\">\n <!-- Selection column -->\n @if (config.behavior?.selection?.enabled) { <td class=\"mat-mdc-cell\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td> }\n <!-- Data columns -->\n @for (column of visibleColumns; track column.field) {\n <td class=\"mat-mdc-cell\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnCellAttrStyle(column)\"\n [ngClass]=\"getCellClasses(row, column)\"\n [ngStyle]=\"getCellNgStyle(row, column)\">\n <div\n class=\"pfx-cell-content\"\n [ngClass]=\"getCellContentClasses(row, column)\"\n [ngStyle]=\"getCellContentNgStyle(row, column)\"\n >\n <ng-container [ngSwitch]=\"getEffectiveRendererType(row, column)\">\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon [color]=\"getIconColor(row, column) || null\"\n [ngStyle]=\"getIconStyle(row, column)\"\n [attr.aria-label]=\"getIconAriaLabel(row, column) || null\">\n {{ getIconName(row, column) }}\n </mat-icon>\n </ng-container>\n <ng-container *ngSwitchCase=\"'image'\">\n <img class=\"pfx-cell-image\"\n [src]=\"getImageSrc(row, column)\"\n [attr.alt]=\"getImageAlt(row, column) || ''\"\n [attr.loading]=\"getImageLazy(row, column) ? 'lazy' : null\"\n [style.width.px]=\"getImageWidth(row, column)\"\n [style.height.px]=\"getImageHeight(row, column)\"\n [class.shape-rounded]=\"getImageShape(row, column) === 'rounded'\"\n [class.shape-circle]=\"getImageShape(row, column) === 'circle'\"\n [style.object-fit]=\"getImageFit(row, column)\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(row, column)\">\n @if (getBadgeIcon(row, column); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }\n <span class=\"pfx-badge-text\">{{ getBadgeText(row, column) }}</span>\n </span>\n </ng-container>\n <ng-container *ngSwitchDefault>\n {{ getCellValue(row, column) }}\n </ng-container>\n </ng-container>\n </div>\n </td>\n }\n\n <!-- Actions column -->\n @if (config.actions?.row?.enabled) {\n <td class=\"mat-mdc-cell praxis-actions-cell\" [class.dense]=\"dense\" [style.width]=\"getRowActionsWidthStyle()\">\n <div class=\"praxis-actions-cell__content\">\n @if (config.actions?.row?.display === 'icons' || !config.actions?.row?.display) {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button mat-icon-button class=\"praxis-icon-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [matTooltip]=\"a.label || getActionId(a)\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"praxis-tooltip\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\">\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n </button>\n </ng-container>\n }\n @if (config.actions?.row?.display === 'buttons') {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button mat-flat-button class=\"praxis-row-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\">\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n }\n @if (hasOverflowRowActions(row)) {\n <button mat-icon-button class=\"praxis-icon-btn praxis-more-btn\"\n [matMenuTriggerFor]=\"rowMoreMenuV\"\n [color]=\"getRowMenuButtonColor() || null\"\n aria-label=\"Mais a\u00E7\u00F5es\">\n <mat-icon [praxisIcon]=\"getRowMenuIcon()\"></mat-icon>\n </button>\n }\n <mat-menu #rowMoreMenuV=\"matMenu\" xPosition=\"before\">\n <ng-container *ngFor=\"let a of getOverflowRowActions(row); trackBy: trackAction\">\n <button mat-menu-item (click)=\"onRowAction(getActionId(a), row, $event)\" [disabled]=\"isActionDisabled(a, row)\">\n <mat-icon [color]=\"a.color || null\" [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n </mat-menu>\n </div>\n </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n}\n\n</div>\n@if (\n shouldRenderDataSurface()\n && !schemaError\n && !dataError\n && shouldRenderFloatingBulkActions()\n && getFloatingBulkActions().length\n && !shouldHideFloatingBulkActions()\n) {\n <div [class]=\"'praxis-floating-bulk-actions ' + getFloatingBulkPositionClass()\">\n @for (action of getFloatingBulkActions(); track getActionId(action)) {\n <button\n mat-mini-fab\n [color]=\"action.color || 'primary'\"\n [disabled]=\"isFloatingBulkActionDisabled(action)\"\n (click)=\"onToolbarAction({ action: getActionId(action), actionConfig: action })\"\n [attr.aria-label]=\"action.label || getActionId(action)\"\n [matTooltip]=\"action.label || getActionId(action)\"\n matTooltipPosition=\"left\"\n >\n <mat-icon [praxisIcon]=\"action.icon || 'done_all'\"></mat-icon>\n </button>\n }\n </div>\n}\n<!-- Barra de a\u00E7\u00F5es no rodap\u00E9 (opcional) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && showToolbar && shouldRenderFooterToolbar()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [class.footer-flat]=\"hasBottomPaginator()\"\n class=\"praxis-toolbar-footer\"\n placement=\"footer\"\n [showMain]=\"shouldShowFooterToolbarMain()\"\n [showEndActions]=\"shouldShowFooterToolbarEndActions()\"\n [showReset]=\"shouldShowFooterToolbarReset()\"\n [showActionsGroup]=\"shouldShowToolbarActionsBottom()\"\n [showMobileActions]=\"shouldShowToolbarActionsBottom()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n (toolbarAction)=\"onToolbarAction($event)\"\n >\n <praxis-filter\n *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\"\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (submit)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n <ng-container *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\">\n <ng-content select=\"[advancedFilter]\"></ng-content>\n </ng-container>\n <ng-container *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\">\n <ng-content select=\"[toolbar]\"></ng-content>\n </ng-container>\n @if (shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()) {\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant\n [adapter]=\"aiAdapter\"\n end-actions\n ></praxis-ai-assistant>\n }\n }\n }\n <button\n *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter() && enableCustomization\"\n end-actions\n mat-icon-button\n color=\"primary\"\n data-role=\"table-settings\"\n data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\"\n aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\"\n >\n <mat-icon>settings</mat-icon>\n </button>\n </praxis-table-toolbar>\n}\n<!-- Paginadores (top/bottom) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && getPaginationEnabled() && (config.behavior?.pagination?.position === 'top' || config.behavior?.pagination?.position === 'both')) {\n <mat-paginator\n [length]=\"getPaginationLength()\"\n [pageSize]=\"getPaginationPageSize()\"\n [pageSizeOptions]=\"getPaginationPageSizeOptions()\"\n [showFirstLastButtons]=\"getPaginationShowFirstLast()\"\n (page)=\"onPageChange($event)\"\n [class.compact]=\"config.behavior?.pagination?.style === 'compact'\"\n >\n </mat-paginator>\n}\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError && getPaginationEnabled() && (config.behavior?.pagination?.position === 'bottom' || config.behavior?.pagination?.position === 'both' || !config.behavior?.pagination?.position)) {\n <mat-paginator\n [length]=\"getPaginationLength()\"\n [pageSize]=\"getPaginationPageSize()\"\n [pageSizeOptions]=\"getPaginationPageSizeOptions()\"\n [showFirstLastButtons]=\"getPaginationShowFirstLast()\"\n (page)=\"onPageChange($event)\"\n [class.compact]=\"config.behavior?.pagination?.style === 'compact'\"\n [class.footer-stack]=\"shouldShowToolbarActionsBottom()\"\n >\n </mat-paginator>\n}\n", styles: ["@charset \"UTF-8\";table{width:100%}.praxis-visually-hidden-status{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.praxis-column-reorder-status{margin:8px 0;padding:10px 12px;border-radius:8px;border:1px solid var(--p-table-border-color);background:var(--p-table-row-hover-bg);color:var(--p-table-header-fg);font-size:12px;line-height:1.4;box-shadow:0 4px 12px #00000014;animation:pfx-column-reorder-status-in var(--p-table-drag-status-enter-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}@keyframes pfx-column-reorder-status-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.praxis-actions-cell{height:100%;padding-inline:12px;white-space:nowrap}.pfx-expansion-col-header,.pfx-expansion-col-cell{width:52px;min-width:52px;text-align:center}.pfx-expansion-toggle:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pfx-expansion-detail-row{background:var(--md-sys-color-surface-container-low)}.pfx-expansion-detail-cell{padding:0!important;border-bottom:1px solid var(--p-table-border-color)}.pfx-expansion-detail-panel{padding:12px 16px;border-left:3px solid var(--md-sys-color-primary)}.pfx-expansion-detail-panel.pfx-expansion-motion-none{animation:none;transition:none}.pfx-expansion-detail-panel.pfx-expansion-motion-subtle-slide{animation:pfx-expansion-subtle-slide-in var(--pfx-expansion-motion-duration, .16s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1))}.pfx-expansion-detail-panel.pfx-expansion-motion-accordion{animation:pfx-expansion-accordion-in var(--pfx-expansion-motion-duration, .18s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1));transform-origin:top center}.pfx-expansion-detail-panel.pfx-expansion-motion-fade-scale{animation:pfx-expansion-fade-scale-in var(--pfx-expansion-motion-duration, .16s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1));transform-origin:top center}@keyframes pfx-expansion-subtle-slide-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes pfx-expansion-accordion-in{0%{opacity:0;transform:scaleY(.96)}to{opacity:1;transform:scaleY(1)}}@keyframes pfx-expansion-fade-scale-in{0%{opacity:0;transform:translateY(-2px) scale(.985)}to{opacity:1;transform:translateY(0) scale(1)}}.pfx-expansion-detail-schema{margin:0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px;line-height:1.4;white-space:pre-wrap;word-break:break-word;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-detail-message{font-size:13px;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-detail-message--error{color:var(--md-sys-color-error)}.pfx-expansion-detail-stack{display:grid;gap:10px}.pfx-expansion-detail-tabs{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px}.pfx-expansion-detail-tab-btn{border:1px solid var(--p-table-border-color);background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface);border-radius:999px;padding:6px 12px;font-size:12px;line-height:1.2;cursor:pointer}.pfx-expansion-detail-tab-btn.is-active{border-color:var(--md-sys-color-primary);color:var(--md-sys-color-primary);font-weight:600}.pfx-expansion-detail-tab-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pfx-expansion-detail-tab-panel{display:grid;gap:10px}.pfx-expansion-node{border:1px solid var(--p-table-border-color);border-radius:8px;padding:10px 12px;background:var(--md-sys-color-surface)}.pfx-expansion-node-card__header{margin-bottom:8px}.pfx-expansion-node-card__title{margin:0;font-size:14px;line-height:1.3}.pfx-expansion-node-card__subtitle{margin:4px 0 0;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-node-value{display:flex;align-items:baseline;gap:8px}.pfx-expansion-node-value__label{color:var(--md-sys-color-on-surface-variant);font-size:12px}.pfx-expansion-node-value__content{font-size:14px}.pfx-expansion-node-list__title{margin:0 0 6px;font-size:13px}.pfx-expansion-node-list ul{margin:0;padding-left:18px}.pfx-expansion-node-richtext :where(p,ul,ol,h1,h2,h3,h4,h5,h6){margin-top:0;margin-bottom:8px}.pfx-expansion-node-placeholder{font-size:12px;color:var(--md-sys-color-on-surface-variant)}:host.density-compact{--p-header-padding: 8px 12px;--p-cell-padding: 8px 12px;--p-actions-btn-size: 32px;--p-actions-icon-size: 18px}:host.density-comfortable{--p-header-padding: 12px 16px;--p-cell-padding: 12px 16px;--p-actions-btn-size: 40px;--p-actions-icon-size: 22px}:host.density-spacious{--p-header-padding: 16px 20px;--p-cell-padding: 16px 20px;--p-actions-btn-size: 44px;--p-actions-icon-size: 24px}:host.density-compact ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 8px 12px)}:host.density-comfortable ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 12px 16px)}:host.density-spacious ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 16px 20px)}:host.density-compact .praxis-actions-cell{padding-inline:8px}:host.density-spacious .praxis-actions-cell{padding-inline:16px}.praxis-actions-cell__content{display:flex;align-items:center;justify-content:flex-end;gap:8px;width:100%}.praxis-actions-cell.dense .praxis-actions-cell__content{gap:6px}.praxis-icon-btn{width:var(--p-actions-btn-size, 40px);height:var(--p-actions-btn-size, 40px);border:0;background:transparent;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:9999px;cursor:pointer;--mat-icon-button-state-layer-size: var(--p-actions-btn-size, 40px)}.praxis-icon-btn:hover{background:var(--md-sys-color-surface-variant)}.praxis-icon-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.praxis-icon-btn mat-icon,.praxis-icon-btn .mat-icon{font-size:var(--p-actions-icon-size, 22px);width:var(--p-actions-icon-size, 22px);height:var(--p-actions-icon-size, 22px);line-height:var(--p-actions-icon-size, 22px)}.praxis-more-btn{width:var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));height:var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));--mat-icon-button-state-layer-size: var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));background-image:var(--p-actions-more-btn-gradient, none);background-size:100% 100%;background-repeat:no-repeat}.praxis-more-btn mat-icon,.praxis-more-btn .mat-icon{font-size:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));width:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));height:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));line-height:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));color:var(--p-actions-more-icon-color);background-image:var(--p-actions-more-icon-gradient, none);-webkit-background-clip:text;background-clip:text}.praxis-icon-btn.destructive mat-icon{color:var(--md-sys-color-error)}.mat-mdc-tooltip.praxis-tooltip{margin-top:-8px;margin-bottom:8px}.spacer{flex:1 1 auto}.praxis-table-header{display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;margin:16px 0 12px;width:100%;clear:both;position:relative}.praxis-table-header.stacked{margin:0}.praxis-table-header>praxis-table-toolbar{flex:1 0 100%}.praxis-floating-bulk-actions{position:fixed;z-index:1001;display:inline-flex;align-items:center;gap:8px;padding:8px;border-radius:999px;background:var(--md-sys-color-surface-container-highest);box-shadow:0 8px 20px #00000029}.praxis-floating-bulk-actions.pos-bottom-right{right:20px;bottom:20px}.praxis-floating-bulk-actions.pos-bottom-left{left:20px;bottom:20px}.praxis-floating-bulk-actions.pos-top-right{right:20px;top:20px}.praxis-floating-bulk-actions.pos-top-left{left:20px;top:20px}@media(max-width:768px){.praxis-floating-bulk-actions{gap:6px;padding:6px}.praxis-floating-bulk-actions.pos-bottom-right{right:12px;left:auto;bottom:12px}.praxis-floating-bulk-actions.pos-bottom-left{left:12px;right:auto;bottom:12px}.praxis-floating-bulk-actions.pos-top-right{right:12px;left:auto;top:12px}.praxis-floating-bulk-actions.pos-top-left{left:12px;right:auto;top:12px}}:host{display:block;width:100%;min-width:0;max-width:100%;--pfx-toolbar-pad-y: 6px;--pfx-toolbar-pad-x: 12px;--p-table-bg: var(--md-sys-color-surface-container-highest);--p-table-text-color: var(--md-sys-color-on-surface);--p-table-header-bg: var(--md-sys-color-surface-container-highest);--p-table-header-fg: var(--md-sys-color-on-surface);--p-table-border-color: var(--md-sys-color-outline-variant);--p-table-row-even-bg: var(--md-sys-color-surface-container);--p-table-row-hover-bg: var(--md-sys-color-surface-container-high);--p-table-row-selected-bg: var(--md-sys-color-primary-container);--p-table-badge-soft-primary-bg: var(--md-sys-color-primary-container);--p-table-badge-soft-primary-fg: var(--md-sys-color-on-primary-container);--p-table-badge-soft-accent-bg: var(--md-sys-color-secondary-container);--p-table-badge-soft-accent-fg: var(--md-sys-color-on-secondary-container);--p-table-badge-soft-warn-bg: var(--md-sys-color-error-container);--p-table-badge-soft-warn-fg: var(--md-sys-color-on-error-container);--p-table-state-success-bg: var(--md-sys-color-tertiary-container);--p-table-state-success-fg: var(--md-sys-color-on-tertiary-container);--p-table-state-warning-bg: var(--md-sys-color-secondary-container);--p-table-state-warning-fg: var(--md-sys-color-on-secondary-container);--p-table-state-danger-bg: var(--md-sys-color-error-container);--p-table-state-danger-fg: var(--md-sys-color-on-error-container);--p-table-state-highlight-bg: var(--md-sys-color-primary-container);--p-table-state-highlight-fg: var(--md-sys-color-on-primary-container);--p-table-drag-handle-size: 14px;--p-table-drag-handle-color: var(--md-sys-color-on-surface-variant);--p-table-drag-handle-hover-color: var(--md-sys-color-on-surface);--p-table-drag-handle-base-opacity: 0;--p-table-drag-handle-visible-opacity: .72;--p-table-drag-handle-active-opacity: 1;--p-table-drag-handle-transition-duration: .16s;--p-table-reorder-transition-duration: .16s;--p-table-drag-preview-scale: 1.01;--p-table-drag-status-enter-duration: .18s;--p-table-drag-preview-shadow: 0 14px 32px rgba(0, 0, 0, .28), 0 0 0 1px var(--p-table-border-color)}:host ::ng-deep .mat-mdc-table{background:var(--p-table-bg);color:var(--p-table-text-color);border-radius:12px 12px 0 0;width:100%;box-shadow:var(--p-table-surface-shadow);transition:box-shadow var(--p-table-selection-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .mat-mdc-table:hover{box-shadow:var(--p-table-surface-shadow-hover, var(--p-table-surface-shadow))}:host ::ng-deep .mat-mdc-table.table-stack-top{border-top-left-radius:0;border-top-right-radius:0}:host ::ng-deep .praxis-toolbar-footer{border:0 solid var(--p-table-border-color);border-top:0;border-radius:0;background:var(--p-table-bg)}:host ::ng-deep .mat-mdc-paginator.footer-stack{border-top-left-radius:0;border-top-right-radius:0;border-top:0}:host ::ng-deep .mat-mdc-paginator.footer-stack .mat-mdc-paginator-container{padding:8px 12px}:host [data-role=table-settings].mat-mdc-icon-button{--mdc-icon-button-icon-color: var(--md-sys-color-primary);color:var(--md-sys-color-primary)}.pfx-link{color:var(--md-sys-color-primary);text-decoration:underline;cursor:pointer}.pfx-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:10px;font-size:12px;line-height:1;border:1px solid transparent}.pfx-chip-icon{font-size:14px;width:14px;height:14px}.pfx-chip--outlined{background:transparent;border-color:var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}.pfx-chip--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-chip--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-chip--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-chip--soft-primary{background:var(--p-table-badge-soft-primary-bg);color:var(--p-table-badge-soft-primary-fg)}.pfx-chip--soft-accent{background:var(--p-table-badge-soft-accent-bg);color:var(--p-table-badge-soft-accent-fg)}.pfx-chip--soft-warn{background:var(--p-table-badge-soft-warn-bg);color:var(--p-table-badge-soft-warn-fg)}.pfx-progress{position:relative;width:100%;max-width:140px;height:8px;background:var(--md-sys-color-surface-container-highest);border-radius:4px;overflow:hidden;display:inline-block;vertical-align:middle}.pfx-progress-bar{height:100%;background:var(--md-sys-color-primary);transition:width .2s ease}.pfx-progress-label{margin-left:8px;font-size:12px;opacity:.8;display:inline-block;vertical-align:middle}.pfx-avatar{display:inline-flex;align-items:center;justify-content:center;background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface);border-radius:4px;overflow:hidden;font-weight:600}.pfx-avatar.shape-rounded{border-radius:8px}.pfx-avatar.shape-circle{border-radius:999px}.pfx-avatar--initials{text-transform:uppercase;font-size:12px}.pfx-cell-compose{display:inline-flex;align-items:center;gap:6px}.pfx-cell-compose.dir-col{flex-direction:column;align-items:stretch}.pfx-cell-compose.align-start{justify-content:flex-start}.pfx-cell-compose.align-center{justify-content:center}.pfx-cell-compose.align-end{justify-content:flex-end}.pfx-cell-compose.wrap{flex-wrap:wrap}.pfx-cell-compose.ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.px-scroll-viewport{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}.px-scroll-viewport.scroll-none{overflow-x:visible}.px-scroll-viewport.scroll-auto ::ng-deep .mat-mdc-table{width:max-content;min-width:100%}.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-header-cell,.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-cell{white-space:normal;text-overflow:initial}.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-table{width:100%}:host ::ng-deep .mat-mdc-header-row{position:sticky;top:0;z-index:1;background:var(--p-table-header-bg);color:var(--p-table-header-fg);box-shadow:var(--p-table-header-shadow, 0 1px 0 var(--p-table-border-color));border-bottom:1px solid var(--p-table-border-color)}:host ::ng-deep .mat-mdc-header-cell,:host ::ng-deep .mat-sort-header-content,:host ::ng-deep .mat-mdc-header-row .mat-icon{color:var(--p-table-header-fg)!important;font-weight:600}:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow,:host ::ng-deep .mat-mdc-header-cell:hover .mat-sort-header-arrow{color:var(--p-table-header-fg)!important}:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-indicator,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-stem,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer-left,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer-right{border-color:var(--p-table-header-fg)!important;background:var(--p-table-header-fg)!important}:host ::ng-deep .mat-mdc-header-cell{padding:var(--p-header-padding, 12px 16px)!important;font-size:var(--p-header-font-size, inherit);font-weight:var(--p-header-font-weight, 600);letter-spacing:var(--p-header-letter-spacing, normal);text-transform:var(--p-header-text-transform, none);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-container{display:flex;align-items:center;width:100%;gap:4px;cursor:inherit}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable{-webkit-user-select:none;user-select:none;cursor:grab;padding-left:0!important}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable.cdk-drag-dragging{cursor:grabbing}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-content{display:inline-flex;align-items:center;gap:4px;flex:1 1 auto;min-width:0}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-header-label{display:inline-flex;align-items:center;gap:4px;flex:1 1 auto;min-width:0}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-header-label-text{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle{-webkit-appearance:none;appearance:none;border:0;background:transparent;color:var(--p-table-drag-handle-color);width:var(--p-table-drag-handle-size);min-width:var(--p-table-drag-handle-size);flex:0 0 var(--p-table-drag-handle-size);height:var(--p-table-drag-handle-size);padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:0;cursor:inherit;pointer-events:none;touch-action:none;opacity:var(--p-table-drag-handle-base-opacity, .42);transform:none;order:-1;margin-inline-end:0;transition:opacity var(--p-table-drag-handle-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1)),color var(--p-table-drag-handle-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:hover .praxis-column-drag-handle,:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:focus-within .praxis-column-drag-handle{opacity:var(--p-table-drag-handle-visible-opacity, .72);color:var(--p-table-drag-handle-hover-color, var(--p-table-drag-handle-color))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle:active{opacity:var(--p-table-drag-handle-active-opacity, 1);cursor:grabbing}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle .mat-icon{font-size:14px;width:14px;height:14px;line-height:14px;transition:transform .18s var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:hover .praxis-column-drag-handle .mat-icon{transform:none}:host ::ng-deep .pfx-column-drag-indicator .cdk-drop-list-dragging .mat-mdc-header-cell:not(.cdk-drag-placeholder){transition:transform var(--p-table-reorder-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-indicator .mat-mdc-header-cell.cdk-drag-animating{transition:transform var(--p-table-reorder-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}.pfx-column-drag-preview{box-sizing:border-box;display:flex;align-items:center;border-radius:10px;border:1px solid var(--p-table-border-color);background:linear-gradient(135deg,var(--p-table-header-bg) 0%,var(--p-table-row-hover-bg) 100%);color:var(--p-table-header-fg);box-shadow:var(--p-table-drag-preview-shadow);transform:scale(var(--p-table-drag-preview-scale, 1.01));pointer-events:none;z-index:1000}.pfx-column-drag-preview .praxis-column-drag-handle,.pfx-column-drag-preview .mat-sort-header-arrow,.pfx-column-drag-preview .mat-sort-header-indicator,.pfx-column-drag-preview .mat-sort-header-stem,.pfx-column-drag-preview .mat-sort-header-pointer,.pfx-column-drag-preview .mat-sort-header-pointer-left,.pfx-column-drag-preview .mat-sort-header-pointer-right{display:none!important}.pfx-column-drag-preview .mat-sort-header-container{display:flex;align-items:center;width:100%;min-height:100%;padding-right:0!important}.pfx-column-drag-preview .mat-sort-header-content,.pfx-column-drag-preview .praxis-header-label{display:inline-flex;align-items:center;min-width:0;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .pfx-column-drag-indicator .cdk-drag-placeholder{opacity:1;border:1px dashed var(--p-table-border-color);background:var(--p-table-row-hover-bg)}:host ::ng-deep .pfx-column-drag-indicator .cdk-drag-placeholder *{opacity:0}:host ::ng-deep .pfx-column-drag-indicator .mat-mdc-header-cell.cdk-drag-dragging{opacity:.58}@media(prefers-reduced-motion:reduce){:host ::ng-deep .pfx-column-drag-indicator .cdk-drop-list-dragging .mat-mdc-header-cell:not(.cdk-drag-placeholder){transition:none}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle,:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle .mat-icon,.pfx-column-drag-preview{transition:none;transform:none}.praxis-column-reorder-status{animation:none}.pfx-expansion-detail-panel{animation:none!important;transition:none!important;transform:none!important}:host ::ng-deep .mat-mdc-row{transition:none}:host ::ng-deep .mat-mdc-table{transition:none}}.praxis-actions-header{text-align:right}.praxis-actions-header.align-start{text-align:left}.praxis-actions-header.align-center{text-align:center}.praxis-actions-header.align-end{text-align:right}.praxis-actions-header .praxis-actions-header__content{display:inline-flex;align-items:center;gap:var(--p-actions-header-gap, 6px);color:var(--p-actions-header-color, inherit)}.praxis-actions-header .praxis-actions-header__content .mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}:host ::ng-deep .mat-mdc-header-cell .mat-sort-header-container{padding-right:20px}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-container{padding-right:12px}@media(pointer:coarse){:host{--p-table-drag-handle-size: 18px;--p-table-drag-handle-base-opacity: .56;--p-table-drag-handle-visible-opacity: .92}}:host ::ng-deep .mat-mdc-cell{color:var(--p-table-text-color);font-size:var(--p-cell-font-size, inherit);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .mat-mdc-cell .pfx-cell-content,:host ::ng-deep .mat-cell .pfx-cell-content{display:inline-flex;align-items:center;gap:6px;width:100%;min-width:0;overflow:hidden}:host ::ng-deep .mat-mdc-row:hover{background:var(--p-table-row-hover-bg)}:host ::ng-deep .mat-mdc-row{transition:background-color var(--p-table-hover-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1)),box-shadow var(--p-table-selection-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .mat-mdc-row:nth-child(2n){background:var(--p-table-row-even-bg)}:host ::ng-deep .mat-mdc-row:nth-child(2n):hover{background:var(--p-table-row-hover-bg)}:host ::ng-deep .mat-mdc-row.pfx-row-selected,:host ::ng-deep .mat-mdc-row.pfx-row-selected:hover{background:var(--p-table-row-selected-bg)}:host.row-borders ::ng-deep .mat-mdc-row .mat-mdc-cell{border-bottom:1px solid var(--p-table-border-color)}:host.row-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell{border-bottom:none}:host.col-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell,:host.col-borders ::ng-deep .mat-mdc-row .mat-mdc-cell{border-right:1px solid var(--p-table-border-color)}:host.col-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell:last-child,:host.col-borders ::ng-deep .mat-mdc-row .mat-mdc-cell:last-child{border-right:none}.ptable-error{display:flex;align-items:center;gap:12px;padding:12px;margin:8px 0;border:1px solid var(--md-sys-color-error);border-radius:8px}.ptable-error__content{flex:1}.ptable-error__title{font-weight:600}.ptable-info-banner{display:flex;gap:12px;align-items:center;padding:8px 12px;margin:8px 0;border-radius:8px;border:1px solid var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.ptable-info-banner .text{flex:1;font-weight:600}.ptable-info-banner .actions{display:flex;gap:8px}.pfx-cell-image{display:inline-block;vertical-align:middle;background:var(--md-sys-color-surface-variant);border:1px solid var(--md-sys-color-outline-variant)}.pfx-cell-image.shape-rounded{border-radius:8px}.pfx-cell-image.shape-circle{border-radius:9999px}.pfx-badge{display:inline-flex;align-items:center;gap:6px;line-height:1;padding:4px 8px;border-radius:9999px;font-size:12px;font-weight:600;border:1px solid transparent}.pfx-badge .pfx-badge-icon{font-size:16px;width:16px;height:16px}.pfx-badge--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-badge--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-badge--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-badge--outlined{background:transparent;border-color:var(--md-sys-color-outline-variant);color:inherit}.pfx-badge--soft-primary{background:var(--p-table-badge-soft-primary-bg);color:var(--p-table-badge-soft-primary-fg)}.pfx-badge--soft-accent{background:var(--p-table-badge-soft-accent-bg);color:var(--p-table-badge-soft-accent-fg)}.pfx-badge--soft-warn{background:var(--p-table-badge-soft-warn-bg);color:var(--p-table-badge-soft-warn-fg)}.row--success,.row--success td,td.row--success{background-color:var(--p-table-state-success-bg)!important;color:var(--p-table-state-success-fg)!important}.row--warning,.row--warning td,td.row--warning{background-color:var(--p-table-state-warning-bg)!important;color:var(--p-table-state-warning-fg)!important}.row--danger,.row--danger td,td.row--danger{background-color:var(--p-table-state-danger-bg)!important;color:var(--p-table-state-danger-fg)!important}.row--highlight,.row--highlight td,td.row--highlight{background-color:var(--p-table-state-highlight-bg)!important;color:var(--p-table-state-highlight-fg)!important;font-weight:600}.row--muted,.row--muted td,td.row--muted{opacity:.7;filter:saturate(.6)}\n"] }]
42065
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i3$1.SettingsPanelService }, { type: i1.GenericCrudService }, { type: TableDefaultsProvider }, { type: FilterConfigService }, { type: DataFormattingService }, { type: i6$3.PraxisDialog }, { type: i2$1.MatSnackBar }, { type: undefined, decorators: [{
42302
+ ], template: "@if (shouldShowEmptyState()) {\n <praxis-empty-state-card\n icon=\"link\"\n [title]=\"'Conecte a tabela \u00E0 fonte de dados'\"\n [description]=\"'Informe a rota do recurso da API para carregar colunas e dados automaticamente.'\"\n [primaryAction]=\"{ label: 'Conectar \u00E0 fonte de dados', icon: 'bolt', action: openQuickConnect.bind(this) }\"\n ></praxis-empty-state-card>\n}\n\n<!-- Error State with Quick Connect CTA -->\n@if (isRemoteMode() && (schemaError || dataError)) {\n<div class=\"ptable-error\" role=\"alert\" aria-live=\"assertive\">\n <mat-icon color=\"warn\" aria-hidden=\"true\">error</mat-icon>\n <div class=\"ptable-error__content\">\n <div class=\"ptable-error__title\">Erro</div>\n <div>{{ errorMessage || 'Ocorreu um erro ao carregar a tabela.' }}</div>\n </div>\n <button mat-flat-button color=\"primary\" (click)=\"openQuickConnect()\">\n <mat-icon>bolt</mat-icon>\n Conectar a recurso\n </button>\n @if (!schemaError) { <button mat-stroked-button (click)=\"retryData()\">Tentar novamente</button> }\n @if (schemaError) { <button mat-stroked-button (click)=\"reloadSchema()\">Recarregar colunas</button> }\n </div>\n}\n\n<!-- Inline banner for schema change (only in edit mode) -->\n@if (shouldShowOutdatedInline()) {\n<div class=\"ptable-info-banner\" role=\"status\" aria-live=\"polite\">\n <div class=\"text\">O schema do servidor mudou. Reconciliar agora?</div>\n <div class=\"actions\">\n <button mat-stroked-button color=\"primary\" (click)=\"onReconcileRequested()\">\n <mat-icon>sync</mat-icon>\n Reconciliar\n </button>\n <button mat-button (click)=\"onSnoozeOutdated()\">Lembrar depois</button>\n <button mat-button (click)=\"onIgnoreOutdated()\">Ignorar</button>\n </div>\n </div>\n}\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError && toolbarV2) {\n <div class=\"praxis-table-header\" [class.edit-mode]=\"enableCustomization\" [class.stacked]=\"showToolbar\">\n @if (showToolbar && shouldShowToolbarTopPlacement()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n [showActionsGroup]=\"shouldShowToolbarActionsTop()\"\n [showMobileActions]=\"shouldShowToolbarActionsTop()\"\n (toolbarAction)=\"onToolbarAction($event)\"\n (reset)=\"onResetPreferences()\"\n >\n @if (shouldRenderAdvancedFilter()) {\n <praxis-filter\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n \n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (requestSearch)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n }\n <ng-content select=\"[advancedFilter]\" />\n <ng-content select=\"[toolbar]\" />\n \n <!-- AI Assistant in Toolbar -->\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\" end-actions></praxis-ai-assistant>\n }\n }\n\n @if (enableCustomization) {\n <button end-actions mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </praxis-table-toolbar>\n }\n @if (!showToolbar && enableCustomization) {\n <div class=\"ptable-header-actions\">\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\"></praxis-ai-assistant>\n }\n }\n <button mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\" (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n @if (isRemoteMode()) {\n <button mat-icon-button (click)=\"disconnect()\" aria-label=\"Desconectar\" matTooltip=\"Desconectar da fonte de dados\">\n <mat-icon>link_off</mat-icon>\n </button>\n }\n </div>\n }\n </div>\n} @else {\n @if (shouldRenderDataSurface() && !schemaError && !dataError) {\n @if (showToolbar && shouldShowToolbarTopPlacement()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n [showActionsGroup]=\"shouldShowToolbarActionsTop()\"\n [showMobileActions]=\"shouldShowToolbarActionsTop()\"\n (toolbarAction)=\"onToolbarAction($event)\"\n (reset)=\"onResetPreferences()\"\n >\n @if (shouldRenderAdvancedFilter()) {\n <praxis-filter\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n \n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (requestSearch)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n }\n <ng-content select=\"[advancedFilter]\" />\n <ng-content select=\"[toolbar]\" />\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant [adapter]=\"aiAdapter\" end-actions></praxis-ai-assistant>\n }\n }\n @if (enableCustomization) {\n <button end-actions mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </praxis-table-toolbar>\n }\n @if (!showToolbar && enableCustomization) {\n <div class=\"ptable-header-actions\">\n <button mat-icon-button color=\"primary\" data-role=\"table-settings\" data-testid=\"table-settings-trigger\" (click)=\"openTableSettings()\" aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\" matBadgeSize=\"small\" matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\">\n <mat-icon>settings</mat-icon>\n </button>\n </div>\n }\n }\n}\n<div class=\"px-scroll-viewport\"\n cdkScrollable\n [class.scroll-auto]=\"horizontalScroll === 'auto'\"\n [class.scroll-wrap]=\"horizontalScroll === 'wrap'\"\n [class.scroll-none]=\"horizontalScroll === 'none'\">\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError) {\n<div class=\"praxis-visually-hidden-status\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ columnReorderStatusMessage }}\n</div>\n@if (columnReorderVisualStatusMessage) {\n <div class=\"praxis-column-reorder-status\" role=\"note\">\n {{ columnReorderVisualStatusMessage }}\n </div>\n}\n<table\n mat-table\n data-testid=\"table-column-drag-drop-list\"\n [dataSource]=\"dataSource\"\n [multiTemplateDataRows]=\"isRowExpansionRuntimeEnabled()\"\n cdkDropList\n [cdkDropListDisabled]=\"!isColumnDraggingEnabled()\"\n [cdkDropListData]=\"visibleDataColumnsForDrag\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onColumnDrop($event)\"\n matSort\n (matSortChange)=\"onSortChange($event)\"\n [matSortDisabled]=\"!getSortingEnabled()\"\n [ngClass]=\"getTableElevationClassName()\"\n [class.table-stack-top]=\"showToolbar\"\n [class.pfx-column-drag-enabled]=\"isColumnDraggingEnabled()\"\n [class.pfx-column-drag-indicator]=\"isColumnDragIndicatorEnabled()\"\n>\n @if (config.behavior?.selection?.enabled) {\n <ng-container\n matColumnDef=\"_select\"\n >\n <th mat-header-cell *matHeaderCellDef>\n @if (canSelectAll()) {\n <mat-checkbox\n (change)=\"masterToggle()\"\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n ></mat-checkbox>\n }\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n [checked]=\"selection.isSelected(row)\"\n ></mat-checkbox>\n </td>\n </ng-container>\n }\n @if (isRowExpansionRuntimeEnabled()) {\n <ng-container matColumnDef=\"_expander\">\n <th mat-header-cell *matHeaderCellDef class=\"pfx-expansion-col-header\">\n <span class=\"praxis-visually-hidden-status\">Expandir detalhes da linha</span>\n </th>\n <td mat-cell *matCellDef=\"let row; let i = index\" class=\"pfx-expansion-col-cell\">\n <button\n mat-icon-button\n class=\"pfx-expansion-toggle\"\n [disabled]=\"!isRowExpandable(row, i) || !isExpansionIconTriggerEnabled()\"\n [attr.aria-expanded]=\"isRowExpanded(row, i) ? 'true' : 'false'\"\n [attr.aria-controls]=\"getRowExpansionDetailId(row, i)\"\n [attr.aria-label]=\"getRowExpansionToggleAriaLabel(row, i)\"\n (click)=\"onExpansionToggleFromIcon(row, i, $event)\"\n (keydown)=\"onExpansionToggleKeydown($event, row, i)\"\n >\n <mat-icon [praxisIcon]=\"isRowExpanded(row, i)\n ? getExpansionExpandedIcon()\n : getExpansionCollapsedIcon()\"></mat-icon>\n </button>\n </td>\n </ng-container>\n }\n @for (column of visibleColumns; track column.field) {\n <ng-container\n [matColumnDef]=\"column.field\"\n [sticky]=\"column.sticky === true || column.sticky === 'start'\"\n [stickyEnd]=\"column.sticky === 'end'\"\n >\n <th\n mat-header-cell\n *matHeaderCellDef\n mat-sort-header\n cdkDrag\n [cdkDragData]=\"column\"\n cdkDragLockAxis=\"x\"\n cdkDragPreviewClass=\"pfx-column-drag-preview\"\n (cdkDragStarted)=\"onColumnDragStarted(column)\"\n (cdkDragEnded)=\"onColumnDragEnded($event, column)\"\n (keydown)=\"onColumnDragHandleKeydown($event, column)\"\n [cdkDragDisabled]=\"!isColumnDraggingEnabled() || !isColumnDraggable(column)\"\n [class.praxis-header-draggable]=\"isColumnDraggingEnabled() && isColumnDraggable(column)\"\n [disabled]=\"!getSortingEnabled() || column.sortable === false\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnHeaderAttrStyle(column)\"\n [attr.aria-label]=\"isColumnDraggingEnabled() && isColumnDraggable(column) ? getColumnDragHandleAriaLabel(column) : null\"\n >\n <span class=\"praxis-header-label\" data-testid=\"column-header-label\">\n @if (isColumnDraggingEnabled() && isColumnDraggable(column)) {\n <span\n class=\"praxis-column-drag-handle\"\n data-testid=\"column-drag-handle\"\n [attr.data-column-field]=\"column.field\"\n aria-hidden=\"true\"\n >\n <mat-icon [praxisIcon]=\"'drag_indicator'\"></mat-icon>\n </span>\n }\n <span class=\"praxis-header-label-text\">{{ column.header }}</span>\n </span>\n </th>\n <td\n mat-cell\n *matCellDef=\"let element\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnCellAttrStyle(column)\"\n [ngClass]=\"getCellClasses(element, column)\"\n [ngStyle]=\"getCellNgStyle(element, column)\"\n >\n <div\n class=\"pfx-cell-content\"\n [ngClass]=\"getCellContentClasses(element, column)\"\n [ngStyle]=\"getCellContentNgStyle(element, column)\"\n >\n <ng-container [ngSwitch]=\"getEffectiveRendererType(element, column)\">\n <!-- Icon renderer -->\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon\n [color]=\"getIconColor(element, column) || null\"\n [ngStyle]=\"getIconStyle(element, column)\"\n [attr.aria-label]=\"getIconAriaLabel(element, column) || null\"\n >{{ getIconName(element, column) }}</mat-icon\n >\n </ng-container>\n\n <!-- Image renderer -->\n <ng-container *ngSwitchCase=\"'image'\">\n <img\n class=\"pfx-cell-image\"\n [src]=\"getImageSrc(element, column)\"\n [attr.alt]=\"getImageAlt(element, column) || ''\"\n [attr.loading]=\"getImageLazy(element, column) ? 'lazy' : null\"\n [style.width.px]=\"getImageWidth(element, column)\"\n [style.height.px]=\"getImageHeight(element, column)\"\n [class.shape-rounded]=\"getImageShape(element, column) === 'rounded'\"\n [class.shape-circle]=\"getImageShape(element, column) === 'circle'\"\n [style.object-fit]=\"getImageFit(element, column)\"\n />\n </ng-container>\n\n <!-- Badge renderer -->\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(element, column)\">\n @if (getBadgeIcon(element, column); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }\n <span class=\"pfx-badge-text\">{{ getBadgeText(element, column) }}</span>\n </span>\n </ng-container>\n\n <!-- Link renderer -->\n <ng-container *ngSwitchCase=\"'link'\">\n <a\n class=\"pfx-link\"\n [attr.href]=\"getLinkHref(element, column) || null\"\n [attr.target]=\"getLinkTarget(element, column) || null\"\n [attr.rel]=\"getLinkRel(element, column) || null\"\n (click)=\"$event.stopPropagation()\"\n >{{ getLinkText(element, column) }}</a\n >\n </ng-container>\n\n <!-- Button renderer -->\n <ng-container *ngSwitchCase=\"'button'\">\n <ng-container [ngSwitch]=\"getButtonVariant(element, column)\">\n <button\n *ngSwitchCase=\"'outlined'\"\n mat-stroked-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n <button\n *ngSwitchCase=\"'text'\"\n mat-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n <button\n *ngSwitchDefault\n mat-flat-button\n [color]=\"getButtonColor(element, column) || null\"\n [disabled]=\"isButtonDisabled(element, column)\"\n [attr.aria-label]=\"getButtonAriaLabel(element, column) || getButtonLabel(element, column)\"\n (click)=\"onButtonClick(element, column, $event)\"\n >\n @if (getButtonIcon(element, column); as bi) { <mat-icon>{{ bi }}</mat-icon> }\n {{ getButtonLabel(element, column) }}\n </button>\n </ng-container>\n </ng-container>\n\n <!-- Chip renderer -->\n <ng-container *ngSwitchCase=\"'chip'\">\n <span class=\"pfx-chip\" [ngClass]=\"getChipClasses(element, column)\">\n @if (getChipIcon(element, column); as ci) { <mat-icon class=\"pfx-chip-icon\">{{ ci }}</mat-icon> }\n <span class=\"pfx-chip-text\">{{ getChipText(element, column) }}</span>\n </span>\n </ng-container>\n\n <!-- Progress renderer -->\n <ng-container *ngSwitchCase=\"'progress'\">\n <div class=\"pfx-progress\">\n <div class=\"pfx-progress-bar\" [style.width.%]=\"getProgressWidthPercentStyle(element, column)\" [style.background]=\"getProgressBackgroundStyle(element, column)\"></div>\n @if (getProgressShowLabel(element, column)) { <div class=\"pfx-progress-label\">{{ getProgressValue(element, column) }}%</div> }\n </div>\n </ng-container>\n\n <!-- Avatar renderer -->\n <ng-container *ngSwitchCase=\"'avatar'\">\n @if (getAvatarSrc(element, column); as asrc) {\n <img class=\"pfx-avatar\" [src]=\"asrc\" [attr.alt]=\"getAvatarAlt(element, column) || ''\" [ngStyle]=\"getAvatarStyle(element, column)\" [class.shape-rounded]=\"getAvatarShape(element, column) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, column) === 'circle'\" loading=\"lazy\" />\n } @else {\n <span class=\"pfx-avatar pfx-avatar--initials\" [ngStyle]=\"getAvatarStyle(element, column)\" [class.shape-rounded]=\"getAvatarShape(element, column) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, column) === 'circle'\">{{ getAvatarInitials(element, column) }}</span>\n }\n </ng-container>\n\n <!-- Toggle renderer -->\n <ng-container *ngSwitchCase=\"'toggle'\">\n <mat-slide-toggle\n [checked]=\"getToggleState(element, column)\"\n [disabled]=\"isToggleDisabled(element, column)\"\n [attr.aria-label]=\"getToggleAriaLabel(element, column) || 'Alternar'\"\n (change)=\"onToggleChange(element, column, $event)\"\n (click)=\"$event.stopPropagation()\"\n ></mat-slide-toggle>\n </ng-container>\n\n <!-- Menu renderer -->\n <ng-container *ngSwitchCase=\"'menu'\">\n <button mat-icon-button [matMenuTriggerFor]=\"menuRef\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getMenuAriaLabel(element, column) || 'Menu'\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menuRef=\"matMenu\">\n <button mat-menu-item *ngFor=\"let it of getMenuItems(element, column)\" (click)=\"onMenuItemClick(it, element, $event)\" [disabled]=\"!it.__visible\" >\n @if (it.icon) { <mat-icon>{{ it.icon }}</mat-icon> }\n <span>{{ it.label }}</span>\n </button>\n </mat-menu>\n </ng-container>\n\n <!-- Rating renderer -->\n <ng-container *ngSwitchCase=\"'rating'\">\n <praxis-table-rating\n class=\"pfx-rating-cell\"\n [itemsCount]=\"getRatingMax(element, column)\"\n [value]=\"getRatingValue(element, column)\"\n [size]=\"getRatingSize(element, column)\"\n [ratingColor]=\"getRatingColor(element, column)\"\n [outlineColor]=\"getRatingOutlineColor(element, column)\"\n [ariaLabel]=\"getRatingAriaLabel(element, column) || column.header\">\n </praxis-table-rating>\n </ng-container>\n\n <!-- HTML renderer (sanitizado) -->\n <ng-container *ngSwitchCase=\"'html'\">\n <span [innerHTML]=\"getSafeHtml(element, column)\"></span>\n </ng-container>\n\n <!-- Compose renderer -->\n <ng-container *ngSwitchCase=\"'compose'\">\n <span class=\"pfx-cell-compose\" [ngClass]=\"getComposeClasses(element, column)\" [ngStyle]=\"getComposeGapStyle(element, column)\">\n <ng-container *ngFor=\"let it of getComposeItems(element, column)\">\n <ng-container [ngSwitch]=\"getItemEffectiveType(element, column, it)\">\n <!-- Reuse helpers by projecting item as faux column -->\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon [color]=\"getIconColor(element, asItemColumn(column, it)) || null\" [ngStyle]=\"getIconStyle(element, asItemColumn(column, it))\" [attr.aria-label]=\"getIconAriaLabel(element, asItemColumn(column, it)) || null\">{{ getIconName(element, asItemColumn(column, it)) }}</mat-icon>\n </ng-container>\n <ng-container *ngSwitchCase=\"'image'\">\n <img class=\"pfx-cell-image\" [src]=\"getImageSrc(element, asItemColumn(column, it))\" [attr.alt]=\"getImageAlt(element, asItemColumn(column, it)) || ''\" [attr.loading]=\"getImageLazy(element, asItemColumn(column, it)) ? 'lazy' : null\" [style.width.px]=\"getImageWidth(element, asItemColumn(column, it))\" [style.height.px]=\"getImageHeight(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getImageShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getImageShape(element, asItemColumn(column, it)) === 'circle'\" [style.object-fit]=\"getImageFit(element, asItemColumn(column, it))\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(element, asItemColumn(column, it))\">@if (getBadgeIcon(element, asItemColumn(column, it)); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }<span class=\"pfx-badge-text\">{{ getBadgeText(element, asItemColumn(column, it)) }}</span></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'link'\">\n <a class=\"pfx-link\" [attr.href]=\"getLinkHref(element, asItemColumn(column, it)) || null\" [attr.target]=\"getLinkTarget(element, asItemColumn(column, it)) || null\" [attr.rel]=\"getLinkRel(element, asItemColumn(column, it)) || null\" (click)=\"$event.stopPropagation()\">{{ getLinkText(element, asItemColumn(column, it)) }}</a>\n </ng-container>\n <ng-container *ngSwitchCase=\"'button'\">\n <ng-container [ngSwitch]=\"getButtonVariant(element, asItemColumn(column, it))\">\n <button *ngSwitchCase=\"'outlined'\" mat-stroked-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n <button *ngSwitchCase=\"'text'\" mat-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n <button *ngSwitchDefault mat-flat-button [color]=\"getButtonColor(element, asItemColumn(column, it)) || null\" [disabled]=\"isButtonDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getButtonAriaLabel(element, asItemColumn(column, it)) || getButtonLabel(element, asItemColumn(column, it))\" (click)=\"onButtonClick(element, asItemColumn(column, it), $event)\">@if (getButtonIcon(element, asItemColumn(column, it)); as bi) { <mat-icon>{{ bi }}</mat-icon> }{{ getButtonLabel(element, asItemColumn(column, it)) }}</button>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'chip'\">\n <span class=\"pfx-chip\" [ngClass]=\"getChipClasses(element, asItemColumn(column, it))\">@if (getChipIcon(element, asItemColumn(column, it)); as ci) { <mat-icon class=\"pfx-chip-icon\">{{ ci }}</mat-icon> }<span class=\"pfx-chip-text\">{{ getChipText(element, asItemColumn(column, it)) }}</span></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'progress'\">\n <div class=\"pfx-progress\"><div class=\"pfx-progress-bar\" [style.width.%]=\"getProgressWidthPercentStyle(element, asItemColumn(column, it))\" [style.background]=\"getProgressBackgroundStyle(element, asItemColumn(column, it))\"></div>@if (getProgressShowLabel(element, asItemColumn(column, it))) { <div class=\"pfx-progress-label\">{{ getProgressValue(element, asItemColumn(column, it)) }}%</div> }</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'avatar'\">\n @if (getAvatarSrc(element, asItemColumn(column, it)); as asrc) {\n <img class=\"pfx-avatar\" [src]=\"asrc\" [attr.alt]=\"getAvatarAlt(element, asItemColumn(column, it)) || ''\" [ngStyle]=\"getAvatarStyle(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getAvatarShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, asItemColumn(column, it)) === 'circle'\" loading=\"lazy\" />\n } @else {\n <span class=\"pfx-avatar pfx-avatar--initials\" [ngStyle]=\"getAvatarStyle(element, asItemColumn(column, it))\" [class.shape-rounded]=\"getAvatarShape(element, asItemColumn(column, it)) === 'rounded'\" [class.shape-circle]=\"getAvatarShape(element, asItemColumn(column, it)) === 'circle'\">{{ getAvatarInitials(element, asItemColumn(column, it)) }}</span>\n }\n </ng-container>\n <ng-container *ngSwitchCase=\"'toggle'\">\n <mat-slide-toggle [checked]=\"getToggleState(element, asItemColumn(column, it))\" [disabled]=\"isToggleDisabled(element, asItemColumn(column, it))\" [attr.aria-label]=\"getToggleAriaLabel(element, asItemColumn(column, it)) || 'Alternar'\" (change)=\"onToggleChange(element, asItemColumn(column, it), $event)\" (click)=\"$event.stopPropagation()\"></mat-slide-toggle>\n </ng-container>\n <ng-container *ngSwitchCase=\"'menu'\">\n <button mat-icon-button [matMenuTriggerFor]=\"menuRef\" (click)=\"$event.stopPropagation()\" [attr.aria-label]=\"getMenuAriaLabel(element, asItemColumn(column, it)) || 'Menu'\"><mat-icon>more_vert</mat-icon></button>\n <mat-menu #menuRef=\"matMenu\">\n <button mat-menu-item *ngFor=\"let mi of getMenuItems(element, asItemColumn(column, it))\" (click)=\"onMenuItemClick(mi, element, $event)\" [disabled]=\"!mi.__visible\">\n @if (mi.icon) { <mat-icon>{{ mi.icon }}</mat-icon> }\n <span>{{ mi.label }}</span>\n </button>\n </mat-menu>\n </ng-container>\n <ng-container *ngSwitchCase=\"'rating'\">\n <praxis-table-rating\n class=\"pfx-rating-cell\"\n [itemsCount]=\"getRatingMax(element, asItemColumn(column, it))\"\n [value]=\"getRatingValue(element, asItemColumn(column, it))\"\n [size]=\"getRatingSize(element, asItemColumn(column, it))\"\n [ratingColor]=\"getRatingColor(element, asItemColumn(column, it))\"\n [outlineColor]=\"getRatingOutlineColor(element, asItemColumn(column, it))\"\n [ariaLabel]=\"getRatingAriaLabel(element, asItemColumn(column, it)) || column.header\">\n </praxis-table-rating>\n </ng-container>\n <ng-container *ngSwitchCase=\"'html'\">\n <span [innerHTML]=\"getSafeHtml(element, asItemColumn(column, it))\"></span>\n </ng-container>\n <!-- Value item: render base cell text alongside visuals -->\n <ng-container *ngSwitchCase=\"'value'\">\n <span class=\"pfx-cell-value\">{{ getComposeItemValue(element, column, it) }}</span>\n </ng-container>\n </ng-container>\n </ng-container>\n </span>\n </ng-container>\n\n <!-- Default text rendering -->\n <ng-container *ngSwitchDefault>\n {{ getCellValue(element, column) }}\n </ng-container>\n </ng-container>\n </div>\n </td>\n </ng-container>\n }\n @if (config.actions?.row?.enabled) {\n <ng-container matColumnDef=\"_actions\" [sticky]=\"config.actions?.row?.sticky === true || config.actions?.row?.sticky === 'start'\" [stickyEnd]=\"config.actions?.row?.sticky === 'end'\">\n <th mat-header-cell *matHeaderCellDef #actionsHeaderCell [style.width]=\"getRowActionsWidthStyle()\" class=\"praxis-actions-header\" [class.align-start]=\"getActionsHeaderAlign() === 'start'\" [class.align-center]=\"getActionsHeaderAlign() === 'center'\" [class.align-end]=\"getActionsHeaderAlign() === 'end'\">\n <div class=\"praxis-actions-header__content\" [matTooltip]=\"getActionsHeaderTooltip() || ''\" [matTooltipDisabled]=\"!getActionsHeaderTooltip()\">\n @if (getActionsHeaderIcon(); as hi) { <mat-icon [praxisIcon]=\"hi\"></mat-icon> }\n @if (getActionsHeaderLabel(); as hl) { <span class=\"label\">{{ hl }}</span> }\n </div>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"praxis-actions-cell\"\n [class.dense]=\"dense\"\n [style.width]=\"getRowActionsWidthStyle()\"\n >\n <div class=\"praxis-actions-cell__content\">\n <!-- A\u00E7\u00F5es inline -->\n <!-- Inline actions: icons mode -->\n @if (config.actions?.row?.display === 'icons' || !config.actions?.row?.display) {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button\n mat-icon-button\n class=\"praxis-icon-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [matTooltip]=\"a.label || getActionId(a)\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"praxis-tooltip\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\"\n >\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n </button>\n </ng-container>\n }\n\n <!-- Inline actions: buttons mode (show label + icon) -->\n @if (config.actions?.row?.display === 'buttons') {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button\n mat-flat-button\n class=\"praxis-row-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\"\n >\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n }\n\n <!-- Menu de overflow -->\n @if (hasOverflowRowActions(row)) {\n <button\n mat-icon-button\n class=\"praxis-icon-btn praxis-more-btn\"\n [matMenuTriggerFor]=\"rowMoreMenu\"\n [color]=\"getRowMenuButtonColor() || null\"\n aria-label=\"Mais a\u00E7\u00F5es\"\n >\n <mat-icon [praxisIcon]=\"getRowMenuIcon()\"></mat-icon>\n </button>\n }\n <mat-menu #rowMoreMenu=\"matMenu\" xPosition=\"before\">\n <ng-container\n *ngFor=\"let a of getOverflowRowActions(row); trackBy: trackAction\"\n >\n <button\n mat-menu-item\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [disabled]=\"isActionDisabled(a, row)\"\n >\n <mat-icon [color]=\"a.color || null\" [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n </mat-menu>\n </div>\n </td>\n </ng-container>\n }\n\n <tr\n mat-header-row\n *matHeaderRowDef=\"displayedColumns\"\n ></tr>\n @if (!isVirtualized()) {\n <tr\n mat-row\n *matRowDef=\"let row; let i = index; columns: displayedColumns\"\n [class.pfx-row-selected]=\"selection.isSelected(row)\"\n [class.pfx-row-expanded]=\"isRowExpansionRuntimeEnabled() && isRowExpanded(row, i)\"\n [attr.aria-selected]=\"config.behavior?.selection?.enabled ? (selection.isSelected(row) ? 'true' : 'false') : null\"\n [attr.aria-expanded]=\"isRowExpansionRuntimeEnabled() ? (isRowExpanded(row, i) ? 'true' : 'false') : null\"\n [ngClass]=\"getRowClasses(row)\"\n [ngStyle]=\"getRowNgStyle(row)\"\n [matTooltip]=\"getRowTooltip(row) || null\"\n [matTooltipDisabled]=\"!getRowTooltip(row)\"\n [matTooltipPosition]=\"getRowTooltipPosition(row)\"\n [matTooltipShowDelay]=\"getRowTooltipShowDelay(row)\"\n (click)=\"onRowClicked(row, i, $event)\"\n (dblclick)=\"onRowDoubleClicked(row, i)\"\n ></tr>\n @if (isRowExpansionRuntimeEnabled()) {\n <ng-container matColumnDef=\"_detail\">\n <td\n mat-cell\n *matCellDef=\"let row; let i = index\"\n class=\"pfx-expansion-detail-cell\"\n [attr.colspan]=\"displayedColumns.length\"\n >\n <section\n class=\"pfx-expansion-detail-panel\"\n [ngClass]=\"getExpansionMotionPresetClass()\"\n [ngStyle]=\"getExpansionMotionStyle()\"\n [attr.id]=\"getRowExpansionDetailId(row, i)\"\n role=\"region\"\n [attr.aria-label]=\"getRowExpansionRegionAriaLabel(row, i)\"\n [attr.aria-busy]=\"getExpansionDetailViewState(row, i).status === 'loading' ? 'true' : 'false'\"\n >\n @let detailState = getExpansionDetailViewState(row, i);\n @if (detailState.status === 'loading') {\n <div class=\"pfx-expansion-detail-message\" role=\"status\" aria-live=\"polite\">\n Carregando detail schema...\n </div>\n } @else if (detailState.status !== 'ready') {\n <div\n class=\"pfx-expansion-detail-message pfx-expansion-detail-message--error\"\n role=\"alert\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n >\n {{ detailState.message || 'Detail indispon\u00EDvel para esta linha.' }}\n </div>\n } @else {\n @if (getExpansionDetailLayout(detailState.schema) === 'tabs') {\n @let detailTabs = getExpansionDetailTabs(detailState.schema);\n @if (detailTabs.length) {\n <div class=\"pfx-expansion-detail-tabs\" role=\"tablist\" aria-label=\"Se\u00E7\u00F5es do detail\">\n @for (tab of detailTabs; track $index; let tabIndex = $index) {\n <button\n type=\"button\"\n class=\"pfx-expansion-detail-tab-btn\"\n role=\"tab\"\n [attr.id]=\"getExpansionDetailTabId(row, i, tab, tabIndex)\"\n [attr.aria-controls]=\"getExpansionDetailPanelId(row, i, tab, tabIndex)\"\n [attr.aria-selected]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs) ? 'true' : 'false'\"\n [attr.tabindex]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs) ? '0' : '-1'\"\n [class.is-active]=\"isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs)\"\n (click)=\"onExpansionDetailTabSelect(row, i, tab, tabIndex, $event)\"\n (keydown)=\"onExpansionDetailTabKeydown($event, row, i, tabIndex, detailTabs)\"\n >\n {{ getExpansionDetailNodeTitle(tab, 'Tab') }}\n </button>\n }\n </div>\n @for (tab of detailTabs; track $index; let tabIndex = $index) {\n @if (isExpansionDetailTabActive(row, i, tab, tabIndex, detailTabs)) {\n <div\n class=\"pfx-expansion-detail-tab-panel\"\n role=\"tabpanel\"\n [attr.id]=\"getExpansionDetailPanelId(row, i, tab, tabIndex)\"\n [attr.aria-labelledby]=\"getExpansionDetailTabId(row, i, tab, tabIndex)\"\n >\n @for (childNode of getExpansionDetailNodeChildren(tab); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: childNode, row: row, index: i }\n \"\n ></ng-container>\n }\n </div>\n }\n }\n } @else {\n <div class=\"pfx-expansion-detail-message\">\n Schema em layout tabs sem abas v\u00E1lidas.\n </div>\n }\n } @else {\n <div class=\"pfx-expansion-detail-stack\">\n @for (node of getExpansionDetailItems(detailState.schema); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: node, row: row, index: i }\n \"\n ></ng-container>\n }\n </div>\n }\n }\n\n <ng-template #expansionDetailNodeTemplate let-node let-row=\"row\" let-index=\"index\">\n @switch (getExpansionDetailNodeType(node)) {\n @case ('card') {\n <article class=\"pfx-expansion-node pfx-expansion-node-card\">\n <header class=\"pfx-expansion-node-card__header\">\n <h5 class=\"pfx-expansion-node-card__title\">\n {{ getExpansionDetailNodeTitle(node, 'Card') }}\n </h5>\n @if (node?.subtitle) {\n <p class=\"pfx-expansion-node-card__subtitle\">{{ node?.subtitle }}</p>\n }\n </header>\n @for (childNode of getExpansionDetailNodeChildren(node); track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n expansionDetailNodeTemplate;\n context: { $implicit: childNode, row: row, index: index }\n \"\n ></ng-container>\n }\n </article>\n }\n @case ('value') {\n <div class=\"pfx-expansion-node pfx-expansion-node-value\">\n <span class=\"pfx-expansion-node-value__label\">\n {{ getExpansionDetailNodeTitle(node, 'Valor') }}\n </span>\n <strong class=\"pfx-expansion-node-value__content\">\n {{ getExpansionDetailValue(row, node) }}\n </strong>\n </div>\n }\n @case ('list') {\n <section class=\"pfx-expansion-node pfx-expansion-node-list\">\n <h6 class=\"pfx-expansion-node-list__title\">\n {{ getExpansionDetailNodeTitle(node, 'Lista') }}\n </h6>\n @let listItems = getExpansionDetailListItems(row, node);\n @if (listItems.length) {\n <ul>\n @for (entry of listItems; track $index) {\n <li>{{ entry }}</li>\n }\n </ul>\n } @else {\n <p class=\"pfx-expansion-node-placeholder\">Sem itens.</p>\n }\n </section>\n }\n @case ('richText') {\n <div\n class=\"pfx-expansion-node pfx-expansion-node-richtext\"\n [innerHTML]=\"getExpansionDetailRichText(node)\"\n ></div>\n }\n @case ('formRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Formul\u00E1rio referenciado: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('tableRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Tabela referenciada: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('chartRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Gr\u00E1fico referenciado: <code>{{ node?.schemaId || node?.id || 'sem-id' }}</code>\n </div>\n }\n @case ('templateRef') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Template referenciado: <code>{{ node?.id || node?.templateId || 'sem-id' }}</code>\n </div>\n }\n @case ('action') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n A\u00E7\u00E3o declarada: <code>{{ node?.id || node?.actionId || 'sem-id' }}</code>\n </div>\n }\n @case ('tab') {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Node <code>tab</code> fora de contexto de tabs.\n </div>\n }\n @default {\n <div class=\"pfx-expansion-node pfx-expansion-node-placeholder\">\n Node n\u00E3o suportado: <code>{{ getExpansionDetailNodeType(node) }}</code>\n </div>\n }\n }\n </ng-template>\n </section>\n </td>\n </ng-container>\n <tr\n mat-row\n *matRowDef=\"let row; columns: expansionDetailRowColumns; when: isExpansionDetailRow\"\n class=\"pfx-expansion-detail-row\"\n ></tr>\n }\n }\n</table>\n}\n\n<!-- Virtual rows path (header preserved above) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && isVirtualized()) {\n <cdk-virtual-scroll-viewport\n class=\"ptable-viewport\"\n [itemSize]=\"getVirtItemHeight()\"\n [minBufferPx]=\"getVirtBufferSize() * getVirtItemHeight()\"\n [maxBufferPx]=\"getVirtBufferSize() * getVirtItemHeight() * 2\"\n [style.minHeight]=\"getVirtMinHeightHostStyle()\"\n >\n <table\n class=\"mat-mdc-table\"\n [ngClass]=\"getTableElevationClassName()\"\n [style.width]=\"getVirtualTableWidthStyle()\"\n >\n <tbody>\n <tr class=\"mat-mdc-row\"\n *cdkVirtualFor=\"let row of dataSource.data; let i = index; trackBy: trackByRow\"\n [class.pfx-row-selected]=\"selection.isSelected(row)\"\n [attr.aria-selected]=\"config.behavior?.selection?.enabled ? (selection.isSelected(row) ? 'true' : 'false') : null\"\n [ngClass]=\"getRowClasses(row)\"\n [ngStyle]=\"getRowNgStyle(row)\"\n [matTooltip]=\"getRowTooltip(row) || null\"\n [matTooltipDisabled]=\"!getRowTooltip(row)\"\n [matTooltipPosition]=\"getRowTooltipPosition(row)\"\n [matTooltipShowDelay]=\"getRowTooltipShowDelay(row)\"\n (click)=\"onRowClicked(row, i, $event)\"\n (dblclick)=\"onRowDoubleClicked(row, i)\">\n <!-- Selection column -->\n @if (config.behavior?.selection?.enabled) { <td class=\"mat-mdc-cell\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td> }\n <!-- Data columns -->\n @for (column of visibleColumns; track column.field) {\n <td class=\"mat-mdc-cell\"\n [style.text-align]=\"getColumnTextAlignStyle(column)\"\n [style.width]=\"getColumnWidthStyle(column)\"\n [attr.style]=\"getColumnCellAttrStyle(column)\"\n [ngClass]=\"getCellClasses(row, column)\"\n [ngStyle]=\"getCellNgStyle(row, column)\">\n <div\n class=\"pfx-cell-content\"\n [ngClass]=\"getCellContentClasses(row, column)\"\n [ngStyle]=\"getCellContentNgStyle(row, column)\"\n >\n <ng-container [ngSwitch]=\"getEffectiveRendererType(row, column)\">\n <ng-container *ngSwitchCase=\"'icon'\">\n <mat-icon [color]=\"getIconColor(row, column) || null\"\n [ngStyle]=\"getIconStyle(row, column)\"\n [attr.aria-label]=\"getIconAriaLabel(row, column) || null\">\n {{ getIconName(row, column) }}\n </mat-icon>\n </ng-container>\n <ng-container *ngSwitchCase=\"'image'\">\n <img class=\"pfx-cell-image\"\n [src]=\"getImageSrc(row, column)\"\n [attr.alt]=\"getImageAlt(row, column) || ''\"\n [attr.loading]=\"getImageLazy(row, column) ? 'lazy' : null\"\n [style.width.px]=\"getImageWidth(row, column)\"\n [style.height.px]=\"getImageHeight(row, column)\"\n [class.shape-rounded]=\"getImageShape(row, column) === 'rounded'\"\n [class.shape-circle]=\"getImageShape(row, column) === 'circle'\"\n [style.object-fit]=\"getImageFit(row, column)\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'badge'\">\n <span class=\"pfx-badge\" [ngClass]=\"getBadgeClasses(row, column)\">\n @if (getBadgeIcon(row, column); as bi) { <mat-icon class=\"pfx-badge-icon\">{{ bi }}</mat-icon> }\n <span class=\"pfx-badge-text\">{{ getBadgeText(row, column) }}</span>\n </span>\n </ng-container>\n <ng-container *ngSwitchDefault>\n {{ getCellValue(row, column) }}\n </ng-container>\n </ng-container>\n </div>\n </td>\n }\n\n <!-- Actions column -->\n @if (config.actions?.row?.enabled) {\n <td class=\"mat-mdc-cell praxis-actions-cell\" [class.dense]=\"dense\" [style.width]=\"getRowActionsWidthStyle()\">\n <div class=\"praxis-actions-cell__content\">\n @if (config.actions?.row?.display === 'icons' || !config.actions?.row?.display) {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button mat-icon-button class=\"praxis-icon-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [matTooltip]=\"a.label || getActionId(a)\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"praxis-tooltip\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\">\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n </button>\n </ng-container>\n }\n @if (config.actions?.row?.display === 'buttons') {\n <ng-container *ngFor=\"let a of getInlineRowActions(row); trackBy: trackAction\">\n <button mat-flat-button class=\"praxis-row-btn\"\n [disabled]=\"isActionDisabled(a, row)\"\n (click)=\"onRowAction(getActionId(a), row, $event)\"\n [attr.aria-label]=\"a.label || getActionId(a)\"\n [color]=\"a.color || null\">\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n }\n @if (hasOverflowRowActions(row)) {\n <button mat-icon-button class=\"praxis-icon-btn praxis-more-btn\"\n [matMenuTriggerFor]=\"rowMoreMenuV\"\n [color]=\"getRowMenuButtonColor() || null\"\n aria-label=\"Mais a\u00E7\u00F5es\">\n <mat-icon [praxisIcon]=\"getRowMenuIcon()\"></mat-icon>\n </button>\n }\n <mat-menu #rowMoreMenuV=\"matMenu\" xPosition=\"before\">\n <ng-container *ngFor=\"let a of getOverflowRowActions(row); trackBy: trackAction\">\n <button mat-menu-item (click)=\"onRowAction(getActionId(a), row, $event)\" [disabled]=\"isActionDisabled(a, row)\">\n <mat-icon [color]=\"a.color || null\" [praxisIcon]=\"a.icon\"></mat-icon>\n <span>{{ a.label || getActionId(a) }}</span>\n </button>\n </ng-container>\n </mat-menu>\n </div>\n </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n}\n\n</div>\n@if (\n shouldRenderDataSurface()\n && !schemaError\n && !dataError\n && shouldRenderFloatingBulkActions()\n && getFloatingBulkActions().length\n && !shouldHideFloatingBulkActions()\n) {\n <div [class]=\"'praxis-floating-bulk-actions ' + getFloatingBulkPositionClass()\">\n @for (action of getFloatingBulkActions(); track getActionId(action)) {\n <button\n mat-mini-fab\n [color]=\"action.color || 'primary'\"\n [disabled]=\"isFloatingBulkActionDisabled(action)\"\n (click)=\"onToolbarAction({ action: getActionId(action), actionConfig: action })\"\n [attr.aria-label]=\"action.label || getActionId(action)\"\n [matTooltip]=\"action.label || getActionId(action)\"\n matTooltipPosition=\"left\"\n >\n <mat-icon [praxisIcon]=\"action.icon || 'done_all'\"></mat-icon>\n </button>\n }\n </div>\n}\n<!-- Barra de a\u00E7\u00F5es no rodap\u00E9 (opcional) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && showToolbar && shouldRenderFooterToolbar()) {\n <praxis-table-toolbar\n [config]=\"config\"\n [backgroundColor]=\"getToolbarActionsBackgroundColor()\"\n [style.--pfx-filter-h]=\"getToolbarLayoutHeightHostStyle()\"\n [class.footer-flat]=\"hasBottomPaginator()\"\n class=\"praxis-toolbar-footer\"\n placement=\"footer\"\n [showMain]=\"shouldShowFooterToolbarMain()\"\n [showEndActions]=\"shouldShowFooterToolbarEndActions()\"\n [showReset]=\"shouldShowFooterToolbarReset()\"\n [showActionsGroup]=\"shouldShowToolbarActionsBottom()\"\n [showMobileActions]=\"shouldShowToolbarActionsBottom()\"\n [dslContext]=\"getToolbarDslContext()\"\n [dslFunctionRegistry]=\"dslFunctionRegistry\"\n (toolbarAction)=\"onToolbarAction($event)\"\n >\n <praxis-filter\n *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\"\n advancedFilter\n [resourcePath]=\"getAdvancedFilterResourcePath()\"\n [filterId]=\"tableId\"\n [formId]=\"tableId\"\n [persistenceKey]=\"getAdvancedFilterPersistenceKey()\"\n [fieldMetadata]=\"getAdvancedFilterFieldMetadata()\"\n [enableCustomization]=\"enableCustomization\"\n [alwaysVisibleFields]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFields\"\n [alwaysVisibleFieldMetadataOverrides]=\"config.behavior?.filtering?.advancedFilters?.settings?.alwaysVisibleFieldMetadataOverrides ?? {}\"\n [selectedFieldIds]=\"config.behavior?.filtering?.advancedFilters?.settings?.selectedFieldIds ?? []\"\n [allowSaveTags]=\"config.behavior?.filtering?.advancedFilters?.settings?.allowSaveTags\"\n [changeDebounceMs]=\"config.behavior?.filtering?.advancedFilters?.settings?.changeDebounceMs ?? 300\"\n [i18n]=\"getFilterI18n()\"\n [mode]=\"'filter'\"\n [showFilterSettings]=\"enableCustomization\"\n (change)=\"onAdvancedFilterChange($event)\"\n (requestSearch)=\"onAdvancedFilterSubmit($event)\"\n (clear)=\"onAdvancedFilterClear()\"\n ></praxis-filter>\n <ng-container *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\">\n <ng-content select=\"[advancedFilter]\"></ng-content>\n </ng-container>\n <ng-container *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()\">\n <ng-content select=\"[toolbar]\"></ng-content>\n </ng-container>\n @if (shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter()) {\n @defer (on idle) {\n @if (aiAdapter) {\n <praxis-ai-assistant\n [adapter]=\"aiAdapter\"\n end-actions\n ></praxis-ai-assistant>\n }\n }\n }\n <button\n *ngIf=\"shouldShowFooterToolbarMain() && shouldRenderAdvancedFilter() && enableCustomization\"\n end-actions\n mat-icon-button\n color=\"primary\"\n data-role=\"table-settings\"\n data-testid=\"table-settings-trigger\"\n (click)=\"openTableSettings()\"\n aria-label=\"Configura\u00E7\u00F5es\"\n [matBadge]=\"schemaOutdated ? '!' : ''\"\n [matBadgeHidden]=\"!schemaOutdated\"\n matBadgeColor=\"warn\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n [matTooltip]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : 'Configura\u00E7\u00F5es'\"\n matTooltipPosition=\"below\"\n >\n <mat-icon>settings</mat-icon>\n </button>\n </praxis-table-toolbar>\n}\n<!-- Paginadores (top/bottom) -->\n@if (shouldRenderDataSurface() && !schemaError && !dataError && getPaginationEnabled() && (config.behavior?.pagination?.position === 'top' || config.behavior?.pagination?.position === 'both')) {\n <mat-paginator\n [length]=\"getPaginationLength()\"\n [pageSize]=\"getPaginationPageSize()\"\n [pageSizeOptions]=\"getPaginationPageSizeOptions()\"\n [showFirstLastButtons]=\"getPaginationShowFirstLast()\"\n (page)=\"onPageChange($event)\"\n [class.compact]=\"config.behavior?.pagination?.style === 'compact'\"\n >\n </mat-paginator>\n}\n\n@if (shouldRenderDataSurface() && !schemaError && !dataError && getPaginationEnabled() && (config.behavior?.pagination?.position === 'bottom' || config.behavior?.pagination?.position === 'both' || !config.behavior?.pagination?.position)) {\n <mat-paginator\n [length]=\"getPaginationLength()\"\n [pageSize]=\"getPaginationPageSize()\"\n [pageSizeOptions]=\"getPaginationPageSizeOptions()\"\n [showFirstLastButtons]=\"getPaginationShowFirstLast()\"\n (page)=\"onPageChange($event)\"\n [class.compact]=\"config.behavior?.pagination?.style === 'compact'\"\n [class.footer-stack]=\"shouldShowToolbarActionsBottom()\"\n >\n </mat-paginator>\n}\n", styles: ["@charset \"UTF-8\";table{width:100%}.praxis-visually-hidden-status{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.praxis-column-reorder-status{margin:8px 0;padding:10px 12px;border-radius:8px;border:1px solid var(--p-table-border-color);background:var(--p-table-row-hover-bg);color:var(--p-table-header-fg);font-size:12px;line-height:1.4;box-shadow:0 4px 12px #00000014;animation:pfx-column-reorder-status-in var(--p-table-drag-status-enter-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}@keyframes pfx-column-reorder-status-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.praxis-actions-cell{height:100%;padding-inline:12px;white-space:nowrap}.pfx-expansion-col-header,.pfx-expansion-col-cell{width:52px;min-width:52px;text-align:center}.pfx-expansion-toggle:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pfx-expansion-detail-row{background:var(--md-sys-color-surface-container-low)}.pfx-expansion-detail-cell{padding:0!important;border-bottom:1px solid var(--p-table-border-color)}.pfx-expansion-detail-panel{padding:12px 16px;border-left:3px solid var(--md-sys-color-primary)}.pfx-expansion-detail-panel.pfx-expansion-motion-none{animation:none;transition:none}.pfx-expansion-detail-panel.pfx-expansion-motion-subtle-slide{animation:pfx-expansion-subtle-slide-in var(--pfx-expansion-motion-duration, .16s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1))}.pfx-expansion-detail-panel.pfx-expansion-motion-accordion{animation:pfx-expansion-accordion-in var(--pfx-expansion-motion-duration, .18s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1));transform-origin:top center}.pfx-expansion-detail-panel.pfx-expansion-motion-fade-scale{animation:pfx-expansion-fade-scale-in var(--pfx-expansion-motion-duration, .16s) var(--pfx-expansion-motion-easing, cubic-bezier(.2, 0, 0, 1));transform-origin:top center}@keyframes pfx-expansion-subtle-slide-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes pfx-expansion-accordion-in{0%{opacity:0;transform:scaleY(.96)}to{opacity:1;transform:scaleY(1)}}@keyframes pfx-expansion-fade-scale-in{0%{opacity:0;transform:translateY(-2px) scale(.985)}to{opacity:1;transform:translateY(0) scale(1)}}.pfx-expansion-detail-schema{margin:0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px;line-height:1.4;white-space:pre-wrap;word-break:break-word;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-detail-message{font-size:13px;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-detail-message--error{color:var(--md-sys-color-error)}.pfx-expansion-detail-stack{display:grid;gap:10px}.pfx-expansion-detail-tabs{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px}.pfx-expansion-detail-tab-btn{border:1px solid var(--p-table-border-color);background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface);border-radius:999px;padding:6px 12px;font-size:12px;line-height:1.2;cursor:pointer}.pfx-expansion-detail-tab-btn.is-active{border-color:var(--md-sys-color-primary);color:var(--md-sys-color-primary);font-weight:600}.pfx-expansion-detail-tab-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pfx-expansion-detail-tab-panel{display:grid;gap:10px}.pfx-expansion-node{border:1px solid var(--p-table-border-color);border-radius:8px;padding:10px 12px;background:var(--md-sys-color-surface)}.pfx-expansion-node-card__header{margin-bottom:8px}.pfx-expansion-node-card__title{margin:0;font-size:14px;line-height:1.3}.pfx-expansion-node-card__subtitle{margin:4px 0 0;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.pfx-expansion-node-value{display:flex;align-items:baseline;gap:8px}.pfx-expansion-node-value__label{color:var(--md-sys-color-on-surface-variant);font-size:12px}.pfx-expansion-node-value__content{font-size:14px}.pfx-expansion-node-list__title{margin:0 0 6px;font-size:13px}.pfx-expansion-node-list ul{margin:0;padding-left:18px}.pfx-expansion-node-richtext :where(p,ul,ol,h1,h2,h3,h4,h5,h6){margin-top:0;margin-bottom:8px}.pfx-expansion-node-placeholder{font-size:12px;color:var(--md-sys-color-on-surface-variant)}:host.density-compact{--p-header-padding: 8px 12px;--p-cell-padding: 8px 12px;--p-actions-btn-size: 32px;--p-actions-icon-size: 18px}:host.density-comfortable{--p-header-padding: 12px 16px;--p-cell-padding: 12px 16px;--p-actions-btn-size: 40px;--p-actions-icon-size: 22px}:host.density-spacious{--p-header-padding: 16px 20px;--p-cell-padding: 16px 20px;--p-actions-btn-size: 44px;--p-actions-icon-size: 24px}:host.density-compact ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 8px 12px)}:host.density-comfortable ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 12px 16px)}:host.density-spacious ::ng-deep .mat-mdc-cell{padding:var(--p-cell-padding, 16px 20px)}:host.density-compact .praxis-actions-cell{padding-inline:8px}:host.density-spacious .praxis-actions-cell{padding-inline:16px}.praxis-actions-cell__content{display:flex;align-items:center;justify-content:flex-end;gap:8px;width:100%}.praxis-actions-cell.dense .praxis-actions-cell__content{gap:6px}.praxis-icon-btn{width:var(--p-actions-btn-size, 40px);height:var(--p-actions-btn-size, 40px);border:0;background:transparent;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:9999px;cursor:pointer;--mat-icon-button-state-layer-size: var(--p-actions-btn-size, 40px)}.praxis-icon-btn:hover{background:var(--md-sys-color-surface-variant)}.praxis-icon-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.praxis-icon-btn mat-icon,.praxis-icon-btn .mat-icon{font-size:var(--p-actions-icon-size, 22px);width:var(--p-actions-icon-size, 22px);height:var(--p-actions-icon-size, 22px);line-height:var(--p-actions-icon-size, 22px)}.praxis-more-btn{width:var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));height:var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));--mat-icon-button-state-layer-size: var(--p-actions-more-btn-size, var(--p-actions-btn-size, 40px));background-image:var(--p-actions-more-btn-gradient, none);background-size:100% 100%;background-repeat:no-repeat}.praxis-more-btn mat-icon,.praxis-more-btn .mat-icon{font-size:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));width:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));height:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));line-height:var(--p-actions-more-icon-size, var(--p-actions-icon-size, 22px));color:var(--p-actions-more-icon-color);background-image:var(--p-actions-more-icon-gradient, none);-webkit-background-clip:text;background-clip:text}.praxis-icon-btn.destructive mat-icon{color:var(--md-sys-color-error)}.mat-mdc-tooltip.praxis-tooltip{margin-top:-8px;margin-bottom:8px}.spacer{flex:1 1 auto}.praxis-table-header{display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;margin:16px 0 12px;width:100%;clear:both;position:relative}.praxis-table-header.stacked{margin:0}.praxis-table-header>praxis-table-toolbar{flex:1 0 100%}.praxis-floating-bulk-actions{position:fixed;z-index:1001;display:inline-flex;align-items:center;gap:8px;padding:8px;border-radius:999px;background:var(--md-sys-color-surface-container-highest);box-shadow:0 8px 20px #00000029}.praxis-floating-bulk-actions.pos-bottom-right{right:20px;bottom:20px}.praxis-floating-bulk-actions.pos-bottom-left{left:20px;bottom:20px}.praxis-floating-bulk-actions.pos-top-right{right:20px;top:20px}.praxis-floating-bulk-actions.pos-top-left{left:20px;top:20px}@media(max-width:768px){.praxis-floating-bulk-actions{gap:6px;padding:6px}.praxis-floating-bulk-actions.pos-bottom-right{right:12px;left:auto;bottom:12px}.praxis-floating-bulk-actions.pos-bottom-left{left:12px;right:auto;bottom:12px}.praxis-floating-bulk-actions.pos-top-right{right:12px;left:auto;top:12px}.praxis-floating-bulk-actions.pos-top-left{left:12px;right:auto;top:12px}}:host{display:block;width:100%;min-width:0;max-width:100%;--pfx-toolbar-pad-y: 6px;--pfx-toolbar-pad-x: 12px;--p-table-bg: var(--md-sys-color-surface-container-highest);--p-table-text-color: var(--md-sys-color-on-surface);--p-table-header-bg: var(--md-sys-color-surface-container-highest);--p-table-header-fg: var(--md-sys-color-on-surface);--p-table-border-color: var(--md-sys-color-outline-variant);--p-table-row-even-bg: var(--md-sys-color-surface-container);--p-table-row-hover-bg: var(--md-sys-color-surface-container-high);--p-table-row-selected-bg: var(--md-sys-color-primary-container);--p-table-badge-soft-primary-bg: var(--md-sys-color-primary-container);--p-table-badge-soft-primary-fg: var(--md-sys-color-on-primary-container);--p-table-badge-soft-accent-bg: var(--md-sys-color-secondary-container);--p-table-badge-soft-accent-fg: var(--md-sys-color-on-secondary-container);--p-table-badge-soft-warn-bg: var(--md-sys-color-error-container);--p-table-badge-soft-warn-fg: var(--md-sys-color-on-error-container);--p-table-state-success-bg: var(--md-sys-color-tertiary-container);--p-table-state-success-fg: var(--md-sys-color-on-tertiary-container);--p-table-state-warning-bg: var(--md-sys-color-secondary-container);--p-table-state-warning-fg: var(--md-sys-color-on-secondary-container);--p-table-state-danger-bg: var(--md-sys-color-error-container);--p-table-state-danger-fg: var(--md-sys-color-on-error-container);--p-table-state-highlight-bg: var(--md-sys-color-primary-container);--p-table-state-highlight-fg: var(--md-sys-color-on-primary-container);--p-table-drag-handle-size: 14px;--p-table-drag-handle-color: var(--md-sys-color-on-surface-variant);--p-table-drag-handle-hover-color: var(--md-sys-color-on-surface);--p-table-drag-handle-base-opacity: 0;--p-table-drag-handle-visible-opacity: .72;--p-table-drag-handle-active-opacity: 1;--p-table-drag-handle-transition-duration: .16s;--p-table-reorder-transition-duration: .16s;--p-table-drag-preview-scale: 1.01;--p-table-drag-status-enter-duration: .18s;--p-table-drag-preview-shadow: 0 14px 32px rgba(0, 0, 0, .28), 0 0 0 1px var(--p-table-border-color)}:host ::ng-deep .mat-mdc-table{background:var(--p-table-bg);color:var(--p-table-text-color);border-radius:12px 12px 0 0;width:100%;box-shadow:var(--p-table-surface-shadow);transition:box-shadow var(--p-table-selection-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .mat-mdc-table:hover{box-shadow:var(--p-table-surface-shadow-hover, var(--p-table-surface-shadow))}:host ::ng-deep .mat-mdc-table.table-stack-top{border-top-left-radius:0;border-top-right-radius:0}:host ::ng-deep .praxis-toolbar-footer{border:0 solid var(--p-table-border-color);border-top:0;border-radius:0;background:var(--p-table-bg)}:host ::ng-deep .mat-mdc-paginator.footer-stack{border-top-left-radius:0;border-top-right-radius:0;border-top:0}:host ::ng-deep .mat-mdc-paginator.footer-stack .mat-mdc-paginator-container{padding:8px 12px}:host [data-role=table-settings].mat-mdc-icon-button{--mdc-icon-button-icon-color: var(--md-sys-color-primary);color:var(--md-sys-color-primary)}.pfx-link{color:var(--md-sys-color-primary);text-decoration:underline;cursor:pointer}.pfx-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:10px;font-size:12px;line-height:1;border:1px solid transparent}.pfx-chip-icon{font-size:14px;width:14px;height:14px}.pfx-chip--outlined{background:transparent;border-color:var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}.pfx-chip--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-chip--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-chip--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-chip--soft-primary{background:var(--p-table-badge-soft-primary-bg);color:var(--p-table-badge-soft-primary-fg)}.pfx-chip--soft-accent{background:var(--p-table-badge-soft-accent-bg);color:var(--p-table-badge-soft-accent-fg)}.pfx-chip--soft-warn{background:var(--p-table-badge-soft-warn-bg);color:var(--p-table-badge-soft-warn-fg)}.pfx-progress{position:relative;width:100%;max-width:140px;height:8px;background:var(--md-sys-color-surface-container-highest);border-radius:4px;overflow:hidden;display:inline-block;vertical-align:middle}.pfx-progress-bar{height:100%;background:var(--md-sys-color-primary);transition:width .2s ease}.pfx-progress-label{margin-left:8px;font-size:12px;opacity:.8;display:inline-block;vertical-align:middle}.pfx-avatar{display:inline-flex;align-items:center;justify-content:center;background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface);border-radius:4px;overflow:hidden;font-weight:600}.pfx-avatar.shape-rounded{border-radius:8px}.pfx-avatar.shape-circle{border-radius:999px}.pfx-avatar--initials{text-transform:uppercase;font-size:12px}.pfx-cell-compose{display:inline-flex;align-items:center;gap:6px}.pfx-cell-compose.dir-col{flex-direction:column;align-items:stretch}.pfx-cell-compose.align-start{justify-content:flex-start}.pfx-cell-compose.align-center{justify-content:center}.pfx-cell-compose.align-end{justify-content:flex-end}.pfx-cell-compose.wrap{flex-wrap:wrap}.pfx-cell-compose.ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.px-scroll-viewport{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}.px-scroll-viewport.scroll-none{overflow-x:visible}.px-scroll-viewport.scroll-auto ::ng-deep .mat-mdc-table{width:max-content;min-width:100%}.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-header-cell,.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-cell{white-space:normal;text-overflow:initial}.px-scroll-viewport.scroll-wrap ::ng-deep .mat-mdc-table{width:100%}:host ::ng-deep .mat-mdc-header-row{position:sticky;top:0;z-index:1;background:var(--p-table-header-bg);color:var(--p-table-header-fg);box-shadow:var(--p-table-header-shadow, 0 1px 0 var(--p-table-border-color));border-bottom:1px solid var(--p-table-border-color)}:host ::ng-deep .mat-mdc-header-cell,:host ::ng-deep .mat-sort-header-content,:host ::ng-deep .mat-mdc-header-row .mat-icon{color:var(--p-table-header-fg)!important;font-weight:600}:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow,:host ::ng-deep .mat-mdc-header-cell:hover .mat-sort-header-arrow{color:var(--p-table-header-fg)!important}:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-indicator,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-stem,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer-left,:host ::ng-deep .mat-mdc-header-cell.mat-sort-header-sorted .mat-sort-header-arrow .mat-sort-header-pointer-right{border-color:var(--p-table-header-fg)!important;background:var(--p-table-header-fg)!important}:host ::ng-deep .mat-mdc-header-cell{padding:var(--p-header-padding, 12px 16px)!important;font-size:var(--p-header-font-size, inherit);font-weight:var(--p-header-font-weight, 600);letter-spacing:var(--p-header-letter-spacing, normal);text-transform:var(--p-header-text-transform, none);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-container{display:flex;align-items:center;width:100%;gap:4px;cursor:inherit}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable{-webkit-user-select:none;user-select:none;cursor:grab;padding-left:0!important}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable.cdk-drag-dragging{cursor:grabbing}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-content{display:inline-flex;align-items:center;gap:4px;flex:1 1 auto;min-width:0}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-header-label{display:inline-flex;align-items:center;gap:4px;flex:1 1 auto;min-width:0}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-header-label-text{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle{-webkit-appearance:none;appearance:none;border:0;background:transparent;color:var(--p-table-drag-handle-color);width:var(--p-table-drag-handle-size);min-width:var(--p-table-drag-handle-size);flex:0 0 var(--p-table-drag-handle-size);height:var(--p-table-drag-handle-size);padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:0;cursor:inherit;pointer-events:none;touch-action:none;opacity:var(--p-table-drag-handle-base-opacity, .42);transform:none;order:-1;margin-inline-end:0;transition:opacity var(--p-table-drag-handle-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1)),color var(--p-table-drag-handle-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:hover .praxis-column-drag-handle,:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:focus-within .praxis-column-drag-handle{opacity:var(--p-table-drag-handle-visible-opacity, .72);color:var(--p-table-drag-handle-hover-color, var(--p-table-drag-handle-color))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle:active{opacity:var(--p-table-drag-handle-active-opacity, 1);cursor:grabbing}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle .mat-icon{font-size:14px;width:14px;height:14px;line-height:14px;transition:transform .18s var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable:hover .praxis-column-drag-handle .mat-icon{transform:none}:host ::ng-deep .pfx-column-drag-indicator .cdk-drop-list-dragging .mat-mdc-header-cell:not(.cdk-drag-placeholder){transition:transform var(--p-table-reorder-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .pfx-column-drag-indicator .mat-mdc-header-cell.cdk-drag-animating{transition:transform var(--p-table-reorder-transition-duration, .16s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}.pfx-column-drag-preview{box-sizing:border-box;display:flex;align-items:center;border-radius:10px;border:1px solid var(--p-table-border-color);background:linear-gradient(135deg,var(--p-table-header-bg) 0%,var(--p-table-row-hover-bg) 100%);color:var(--p-table-header-fg);box-shadow:var(--p-table-drag-preview-shadow);transform:scale(var(--p-table-drag-preview-scale, 1.01));pointer-events:none;z-index:1000}.pfx-column-drag-preview .praxis-column-drag-handle,.pfx-column-drag-preview .mat-sort-header-arrow,.pfx-column-drag-preview .mat-sort-header-indicator,.pfx-column-drag-preview .mat-sort-header-stem,.pfx-column-drag-preview .mat-sort-header-pointer,.pfx-column-drag-preview .mat-sort-header-pointer-left,.pfx-column-drag-preview .mat-sort-header-pointer-right{display:none!important}.pfx-column-drag-preview .mat-sort-header-container{display:flex;align-items:center;width:100%;min-height:100%;padding-right:0!important}.pfx-column-drag-preview .mat-sort-header-content,.pfx-column-drag-preview .praxis-header-label{display:inline-flex;align-items:center;min-width:0;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .pfx-column-drag-indicator .cdk-drag-placeholder{opacity:1;border:1px dashed var(--p-table-border-color);background:var(--p-table-row-hover-bg)}:host ::ng-deep .pfx-column-drag-indicator .cdk-drag-placeholder *{opacity:0}:host ::ng-deep .pfx-column-drag-indicator .mat-mdc-header-cell.cdk-drag-dragging{opacity:.58}@media(prefers-reduced-motion:reduce){:host ::ng-deep .pfx-column-drag-indicator .cdk-drop-list-dragging .mat-mdc-header-cell:not(.cdk-drag-placeholder){transition:none}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle,:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell .praxis-column-drag-handle .mat-icon,.pfx-column-drag-preview{transition:none;transform:none}.praxis-column-reorder-status{animation:none}.pfx-expansion-detail-panel{animation:none!important;transition:none!important;transform:none!important}:host ::ng-deep .mat-mdc-row{transition:none}:host ::ng-deep .mat-mdc-table{transition:none}}.praxis-actions-header{text-align:right}.praxis-actions-header.align-start{text-align:left}.praxis-actions-header.align-center{text-align:center}.praxis-actions-header.align-end{text-align:right}.praxis-actions-header .praxis-actions-header__content{display:inline-flex;align-items:center;gap:var(--p-actions-header-gap, 6px);color:var(--p-actions-header-color, inherit)}.praxis-actions-header .praxis-actions-header__content .mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}:host ::ng-deep .mat-mdc-header-cell .mat-sort-header-container{padding-right:20px}:host ::ng-deep .pfx-column-drag-enabled .mat-mdc-header-cell.praxis-header-draggable .mat-sort-header-container{padding-right:12px}@media(pointer:coarse){:host{--p-table-drag-handle-size: 18px;--p-table-drag-handle-base-opacity: .56;--p-table-drag-handle-visible-opacity: .92}}:host ::ng-deep .mat-mdc-cell{color:var(--p-table-text-color);font-size:var(--p-cell-font-size, inherit);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .mat-mdc-cell .pfx-cell-content,:host ::ng-deep .mat-cell .pfx-cell-content{display:inline-flex;align-items:center;gap:6px;width:100%;min-width:0;overflow:hidden}:host ::ng-deep .mat-mdc-row:hover{background:var(--p-table-row-hover-bg)}:host ::ng-deep .mat-mdc-row{transition:background-color var(--p-table-hover-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1)),box-shadow var(--p-table-selection-transition-duration, .18s) var(--p-table-motion-easing, cubic-bezier(0, 0, .2, 1))}:host ::ng-deep .mat-mdc-row:nth-child(2n){background:var(--p-table-row-even-bg)}:host ::ng-deep .mat-mdc-row:nth-child(2n):hover{background:var(--p-table-row-hover-bg)}:host ::ng-deep .mat-mdc-row.pfx-row-selected,:host ::ng-deep .mat-mdc-row.pfx-row-selected:hover{background:var(--p-table-row-selected-bg)}:host.row-borders ::ng-deep .mat-mdc-row .mat-mdc-cell{border-bottom:1px solid var(--p-table-border-color)}:host.row-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell{border-bottom:none}:host.col-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell,:host.col-borders ::ng-deep .mat-mdc-row .mat-mdc-cell{border-right:1px solid var(--p-table-border-color)}:host.col-borders ::ng-deep .mat-mdc-header-row .mat-mdc-header-cell:last-child,:host.col-borders ::ng-deep .mat-mdc-row .mat-mdc-cell:last-child{border-right:none}.ptable-error{display:flex;align-items:center;gap:12px;padding:12px;margin:8px 0;border:1px solid var(--md-sys-color-error);border-radius:8px}.ptable-error__content{flex:1}.ptable-error__title{font-weight:600}.ptable-info-banner{display:flex;gap:12px;align-items:center;padding:8px 12px;margin:8px 0;border-radius:8px;border:1px solid var(--md-sys-color-primary);background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.ptable-info-banner .text{flex:1;font-weight:600}.ptable-info-banner .actions{display:flex;gap:8px}.pfx-cell-image{display:inline-block;vertical-align:middle;background:var(--md-sys-color-surface-variant);border:1px solid var(--md-sys-color-outline-variant)}.pfx-cell-image.shape-rounded{border-radius:8px}.pfx-cell-image.shape-circle{border-radius:9999px}.pfx-badge{display:inline-flex;align-items:center;gap:6px;line-height:1;padding:4px 8px;border-radius:9999px;font-size:12px;font-weight:600;border:1px solid transparent}.pfx-badge .pfx-badge-icon{font-size:16px;width:16px;height:16px}.pfx-badge--filled-primary{background:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pfx-badge--filled-accent{background:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pfx-badge--filled-warn{background:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pfx-badge--outlined{background:transparent;border-color:var(--md-sys-color-outline-variant);color:inherit}.pfx-badge--soft-primary{background:var(--p-table-badge-soft-primary-bg);color:var(--p-table-badge-soft-primary-fg)}.pfx-badge--soft-accent{background:var(--p-table-badge-soft-accent-bg);color:var(--p-table-badge-soft-accent-fg)}.pfx-badge--soft-warn{background:var(--p-table-badge-soft-warn-bg);color:var(--p-table-badge-soft-warn-fg)}.row--success,.row--success td,td.row--success{background-color:var(--p-table-state-success-bg)!important;color:var(--p-table-state-success-fg)!important}.row--warning,.row--warning td,td.row--warning{background-color:var(--p-table-state-warning-bg)!important;color:var(--p-table-state-warning-fg)!important}.row--danger,.row--danger td,td.row--danger{background-color:var(--p-table-state-danger-bg)!important;color:var(--p-table-state-danger-fg)!important}.row--highlight,.row--highlight td,td.row--highlight{background-color:var(--p-table-state-highlight-bg)!important;color:var(--p-table-state-highlight-fg)!important;font-weight:600}.row--muted,.row--muted td,td.row--muted{opacity:.7;filter:saturate(.6)}\n"] }]
42303
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i3$1.SettingsPanelService }, { type: i1.GenericCrudService }, { type: TableDefaultsProvider }, { type: FilterConfigService }, { type: DataFormattingService }, { type: i6$3.PraxisDialog }, { type: i2$2.MatSnackBar }, { type: undefined, decorators: [{
42066
42304
  type: Inject,
42067
42305
  args: [ASYNC_CONFIG_STORAGE]
42068
42306
  }] }, { type: undefined, decorators: [{