@praxisui/table 1.0.0-beta.40 → 1.0.0-beta.41

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.
@@ -32,7 +32,7 @@ import * as i13 from '@angular/cdk/drag-drop';
32
32
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
33
33
  import { Subject, debounceTime, takeUntil, of, firstValueFrom, BehaviorSubject, take as take$1 } from 'rxjs';
34
34
  import * as i1 from '@praxisui/core';
35
- import { LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, PraxisIconDirective, isTableConfigV2, GLOBAL_ACTION_SPEC_CATALOG, getGlobalActionUiSchema, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_VALUES, FieldControlType, INLINE_FILTER_ALIAS_TOKENS, normalizeControlTypeToken, ASYNC_CONFIG_STORAGE, resolveControlTypeAlias, mapFieldDefinitionsToMetadata, GenericCrudService, TableConfigService, createDefaultTableConfig, fillUndefined, GlobalConfigService, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, buildSchemaId, fetchWithETag, ResourceQuickConnectComponent, PRAXIS_LOADING_CTX, CONNECTION_STORAGE, PRAXIS_LOADING_RENDERER, EmptyStateCardComponent, ComponentMetadataRegistry } from '@praxisui/core';
35
+ import { LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, PraxisIconDirective, isTableConfigV2, GLOBAL_ACTION_SPEC_CATALOG, getGlobalActionUiSchema, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_VALUES, FieldControlType, INLINE_FILTER_ALIAS_TOKENS, normalizeControlTypeToken, ASYNC_CONFIG_STORAGE, resolveControlTypeAlias, mapFieldDefinitionsToMetadata, GenericCrudService, TableConfigService, createDefaultTableConfig, fillUndefined, GlobalConfigService, buildSchemaId, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, fetchWithETag, ResourceQuickConnectComponent, PRAXIS_LOADING_CTX, CONNECTION_STORAGE, PRAXIS_LOADING_RENDERER, EmptyStateCardComponent, ComponentMetadataRegistry } from '@praxisui/core';
36
36
  import * as i2 from '@angular/material/toolbar';
37
37
  import { MatToolbarModule } from '@angular/material/toolbar';
38
38
  import { FunctionRegistry, DslParser, DslValidator, ValidationSeverity, ValidationIssueType } from '@praxisui/specification';
@@ -1143,7 +1143,7 @@ function getActionId(action) {
1143
1143
 
1144
1144
  const TOOLBAR_SHORTCUT_HANDLED_FLAG = '__praxisTableToolbarShortcutHandled__';
1145
1145
  const BLOCKED_PATH_SEGMENTS$1 = new Set(['__proto__', 'prototype', 'constructor']);
1146
- function normalizeCorporateLoggerEnvironment$1(candidate) {
1146
+ function normalizeCorporateLoggerEnvironment$2(candidate) {
1147
1147
  const value = String(candidate || '')
1148
1148
  .trim()
1149
1149
  .toLowerCase();
@@ -1165,7 +1165,7 @@ function normalizeCorporateLoggerEnvironment$1(candidate) {
1165
1165
  return 'prod';
1166
1166
  }
1167
1167
  function createPraxisTableToolbarFallbackLogger(environment) {
1168
- return new LoggerService(createCorporateLoggerConfig(normalizeCorporateLoggerEnvironment$1(environment)), [new ConsoleLoggerSink()]);
1168
+ return new LoggerService(createCorporateLoggerConfig(normalizeCorporateLoggerEnvironment$2(environment)), [new ConsoleLoggerSink()]);
1169
1169
  }
1170
1170
  class PraxisTableToolbar {
1171
1171
  hostRef;
@@ -1277,7 +1277,7 @@ class PraxisTableToolbar {
1277
1277
  getLogger() {
1278
1278
  if (this.logger)
1279
1279
  return this.logger;
1280
- const runtimeEnvironment = normalizeCorporateLoggerEnvironment$1(this.resolveRuntimeEnvironment());
1280
+ const runtimeEnvironment = normalizeCorporateLoggerEnvironment$2(this.resolveRuntimeEnvironment());
1281
1281
  if (!this.fallbackLogger
1282
1282
  || this.fallbackLoggerEnvironment !== runtimeEnvironment) {
1283
1283
  this.fallbackLogger = createPraxisTableToolbarFallbackLogger(runtimeEnvironment);
@@ -20257,6 +20257,7 @@ class FilterSettingsComponent {
20257
20257
  try {
20258
20258
  this.storage.clearConfig('filter-config:' + key).pipe(take(1)).subscribe();
20259
20259
  this.storage.clearConfig(`filter-dto:${key}`).pipe(take(1)).subscribe();
20260
+ void this.clearPersistedSchemaStateByConfigKey(key);
20260
20261
  this.reset(); // Reset form to initial/default values
20261
20262
  this.form.markAsPristine();
20262
20263
  this.snackBar.open('Preferências do filtro redefinidas', undefined, {
@@ -20354,6 +20355,62 @@ class FilterSettingsComponent {
20354
20355
  tagsKey() {
20355
20356
  return this.configKey ? `filter-tags:${this.configKey}` : null;
20356
20357
  }
20358
+ schemaMetaScopeKey(configKey) {
20359
+ return `filter-schema-meta:${configKey}`;
20360
+ }
20361
+ schemaMetaIndexKey(configKey) {
20362
+ return `${this.schemaMetaScopeKey(configKey)}:index`;
20363
+ }
20364
+ schemaMetaKeyForSchemaId(configKey, schemaId) {
20365
+ return `${this.schemaMetaScopeKey(configKey)}:schema:${schemaId}`;
20366
+ }
20367
+ filterSchemaIgnoreKey(configKey, serverHash) {
20368
+ return `filter-schema-ignore:${configKey}:${serverHash}`;
20369
+ }
20370
+ filterSchemaSnoozeKey(configKey, serverHash) {
20371
+ return `filter-schema-snooze:${configKey}:${serverHash}`;
20372
+ }
20373
+ filterSchemaNotifiedKey(configKey, serverHash) {
20374
+ return `filter-schema-notified:${configKey}:${serverHash}`;
20375
+ }
20376
+ async clearPersistedSchemaStateByConfigKey(configKey) {
20377
+ const scopeKey = this.schemaMetaScopeKey(configKey);
20378
+ const indexKey = this.schemaMetaIndexKey(configKey);
20379
+ const schemaIds = await firstValueFrom(this.storage.loadConfig(indexKey).pipe(take(1)))
20380
+ .then((raw) => Array.from(new Set((Array.isArray(raw) ? raw : [])
20381
+ .map((item) => String(item || '').trim())
20382
+ .filter((item) => !!item))))
20383
+ .catch(() => []);
20384
+ const hashes = new Set();
20385
+ const legacyMeta = await firstValueFrom(this.storage.loadConfig(scopeKey).pipe(take(1))).catch(() => null);
20386
+ const legacyHash = String(legacyMeta?.serverHash || '').trim();
20387
+ if (legacyHash)
20388
+ hashes.add(legacyHash);
20389
+ for (const schemaId of schemaIds) {
20390
+ const key = this.schemaMetaKeyForSchemaId(configKey, schemaId);
20391
+ const meta = await firstValueFrom(this.storage.loadConfig(key).pipe(take(1))).catch(() => null);
20392
+ const hash = String(meta?.serverHash || '').trim();
20393
+ if (hash)
20394
+ hashes.add(hash);
20395
+ this.storage.clearConfig(key).pipe(take(1)).subscribe();
20396
+ }
20397
+ this.storage.clearConfig(indexKey).pipe(take(1)).subscribe();
20398
+ this.storage.clearConfig(scopeKey).pipe(take(1)).subscribe();
20399
+ hashes.forEach((hash) => {
20400
+ this.storage
20401
+ .clearConfig(this.filterSchemaIgnoreKey(configKey, hash))
20402
+ .pipe(take(1))
20403
+ .subscribe();
20404
+ this.storage
20405
+ .clearConfig(this.filterSchemaSnoozeKey(configKey, hash))
20406
+ .pipe(take(1))
20407
+ .subscribe();
20408
+ this.storage
20409
+ .clearConfig(this.filterSchemaNotifiedKey(configKey, hash))
20410
+ .pipe(take(1))
20411
+ .subscribe();
20412
+ });
20413
+ }
20357
20414
  async loadTags() {
20358
20415
  const key = this.tagsKey();
20359
20416
  if (!key) {
@@ -27616,6 +27673,8 @@ const DEFAULT_I18N = {
27616
27673
  retry: 'Tentar novamente',
27617
27674
  errorLoadingFilters: 'Erro ao carregar filtros.',
27618
27675
  settings: 'Configurações',
27676
+ settingsAriaLabel: 'Abrir configurações do filtro',
27677
+ tagActionsAriaLabel: 'Ações do atalho',
27619
27678
  save: 'Salvar',
27620
27679
  cancel: 'Cancelar',
27621
27680
  shortcutsLabel: 'Atalhos',
@@ -27667,6 +27726,28 @@ const FILTER_CONTROL_TYPE_SYNONYMS = new Set([
27667
27726
  ...INLINE_FILTER_ALIAS_TOKENS,
27668
27727
  ]);
27669
27728
  const INLINE_COMPACT_CONTROL_TYPE_TOKENS = new Set(INLINE_FILTER_CONTROL_TYPE_VALUES.map((controlType) => normalizeControlTypeToken(controlType)));
27729
+ function normalizeCorporateLoggerEnvironment$1(candidate) {
27730
+ const value = String(candidate || '')
27731
+ .trim()
27732
+ .toLowerCase();
27733
+ if (!value)
27734
+ return 'prod';
27735
+ if (value === 'dev' || value === 'development' || value === 'local')
27736
+ return 'dev';
27737
+ if (value === 'qa' || value === 'test' || value === 'testing')
27738
+ return 'qa';
27739
+ if (value === 'hml'
27740
+ || value === 'homolog'
27741
+ || value === 'homologacao'
27742
+ || value === 'stage'
27743
+ || value === 'staging') {
27744
+ return 'hml';
27745
+ }
27746
+ return 'prod';
27747
+ }
27748
+ function createPraxisFilterFallbackLogger(environment) {
27749
+ return new LoggerService(createCorporateLoggerConfig(normalizeCorporateLoggerEnvironment$1(environment)), [new ConsoleLoggerSink()]);
27750
+ }
27670
27751
  /**
27671
27752
  * Componente de filtro dinâmico para tabelas.
27672
27753
  *
@@ -27694,6 +27775,7 @@ class PraxisFilter {
27694
27775
  schemaNormalizer;
27695
27776
  componentKeys;
27696
27777
  route;
27778
+ logger;
27697
27779
  resourcePath;
27698
27780
  /**
27699
27781
  * Optional static metadata for offline/showcase usage.
@@ -27815,6 +27897,7 @@ class PraxisFilter {
27815
27897
  i18nLabels = DEFAULT_I18N;
27816
27898
  configKey = null;
27817
27899
  lastSchemaMeta;
27900
+ schemaLoadVersion = 0;
27818
27901
  // Outdated state and persistence helpers
27819
27902
  schemaOutdated = false;
27820
27903
  anchorRef;
@@ -27833,6 +27916,8 @@ class PraxisFilter {
27833
27916
  addItems = [];
27834
27917
  addItemsUpdateQueued = false;
27835
27918
  applySchemaQueued = false;
27919
+ fallbackLogger;
27920
+ fallbackLoggerEnvironment = null;
27836
27921
  // Lifecycle control
27837
27922
  isViewInitialized = false;
27838
27923
  // Debug trackers
@@ -27927,6 +28012,17 @@ class PraxisFilter {
27927
28012
  const key = this.resolveConfigKey();
27928
28013
  return key ? `filter-schema-meta:${key}` : null;
27929
28014
  }
28015
+ filterSchemaMetaIndexKey() {
28016
+ const key = this.filterSchemaMetaKey();
28017
+ return key ? `${key}:index` : null;
28018
+ }
28019
+ filterSchemaMetaKeyForSchemaId(schemaId) {
28020
+ const scopeKey = this.filterSchemaMetaKey();
28021
+ const id = String(schemaId || '').trim();
28022
+ if (!scopeKey || !id)
28023
+ return null;
28024
+ return `${scopeKey}:schema:${id}`;
28025
+ }
27930
28026
  filterSchemaIgnoreKey(serverHash) {
27931
28027
  const key = this.resolveConfigKey();
27932
28028
  return key ? `filter-schema-ignore:${key}:${serverHash}` : null;
@@ -27939,7 +28035,7 @@ class PraxisFilter {
27939
28035
  const key = this.resolveConfigKey();
27940
28036
  return key ? `filter-schema-notified:${key}:${serverHash}` : null;
27941
28037
  }
27942
- constructor(crud, configStorage, destroyRef, filterConfig, settingsPanel, snackBar, dialog, cdr, ngZone, dynamicForm, schemaNormalizer, componentKeys, route) {
28038
+ constructor(crud, configStorage, destroyRef, filterConfig, settingsPanel, snackBar, dialog, cdr, ngZone, dynamicForm, schemaNormalizer, componentKeys, route, logger) {
27943
28039
  this.crud = crud;
27944
28040
  this.configStorage = configStorage;
27945
28041
  this.destroyRef = destroyRef;
@@ -27953,8 +28049,53 @@ class PraxisFilter {
27953
28049
  this.schemaNormalizer = schemaNormalizer;
27954
28050
  this.componentKeys = componentKeys;
27955
28051
  this.route = route;
28052
+ this.logger = logger;
27956
28053
  }
27957
28054
  global = inject(GlobalConfigService);
28055
+ resolveRuntimeEnvironment() {
28056
+ const globalAny = this.global;
28057
+ let globalAppEnvironment;
28058
+ let globalEnvironment;
28059
+ try {
28060
+ globalAppEnvironment = globalAny?.get?.('app.environment');
28061
+ globalEnvironment = globalAny?.get?.('environment');
28062
+ }
28063
+ catch {
28064
+ // ignore config access failures
28065
+ }
28066
+ const candidates = [
28067
+ globalAppEnvironment,
28068
+ globalEnvironment,
28069
+ globalThis?.process?.env?.NODE_ENV,
28070
+ ];
28071
+ for (const candidate of candidates) {
28072
+ if (typeof candidate === 'string' && candidate.trim()) {
28073
+ return candidate.trim().toLowerCase();
28074
+ }
28075
+ }
28076
+ return 'prod';
28077
+ }
28078
+ getLogger() {
28079
+ if (this.logger)
28080
+ return this.logger;
28081
+ const runtimeEnvironment = normalizeCorporateLoggerEnvironment$1(this.resolveRuntimeEnvironment());
28082
+ if (!this.fallbackLogger
28083
+ || this.fallbackLoggerEnvironment !== runtimeEnvironment) {
28084
+ this.fallbackLogger = createPraxisFilterFallbackLogger(runtimeEnvironment);
28085
+ this.fallbackLoggerEnvironment = runtimeEnvironment;
28086
+ }
28087
+ return this.fallbackLogger;
28088
+ }
28089
+ buildFilterLogOptions(data, actionId) {
28090
+ return {
28091
+ context: {
28092
+ lib: 'praxis-table',
28093
+ component: 'PraxisFilter',
28094
+ ...(actionId ? { actionId } : {}),
28095
+ },
28096
+ ...(data !== undefined ? { data } : {}),
28097
+ };
28098
+ }
27958
28099
  isFilterDebugEnabled() {
27959
28100
  try {
27960
28101
  const explicitFlag = typeof window !== 'undefined' ? window.DEBUG_PTABLE : undefined;
@@ -27971,18 +28112,12 @@ class PraxisFilter {
27971
28112
  logFilterDebug(message, payload) {
27972
28113
  if (!this.isFilterDebugEnabled())
27973
28114
  return;
27974
- if (payload === undefined)
27975
- console.debug(message);
27976
- else
27977
- console.debug(message, payload);
28115
+ this.getLogger().debug(message, this.buildFilterLogOptions(payload, 'filter.debug'));
27978
28116
  }
27979
28117
  logFilterWarn(message, payload) {
27980
28118
  if (!this.isFilterDebugEnabled())
27981
28119
  return;
27982
- if (payload === undefined)
27983
- console.warn(message);
27984
- else
27985
- console.warn(message, payload);
28120
+ this.getLogger().warn(message, this.buildFilterLogOptions(payload, 'filter.warn'));
27986
28121
  }
27987
28122
  // Optional injection (adapter provided by host app)
27988
28123
  filterDrawerAdapter = (() => {
@@ -28283,12 +28418,20 @@ class PraxisFilter {
28283
28418
  }
28284
28419
  }
28285
28420
  ngOnChanges(changes) {
28421
+ const schemaIdentityChanged = (changes['resourcePath'] && !changes['resourcePath'].firstChange) ||
28422
+ (changes['filterId'] && !changes['filterId'].firstChange) ||
28423
+ (changes['formId'] && !changes['formId'].firstChange) ||
28424
+ (changes['persistenceKey'] && !changes['persistenceKey'].firstChange) ||
28425
+ (changes['componentInstanceId'] && !changes['componentInstanceId'].firstChange);
28286
28426
  if (changes['resourcePath'] ||
28287
28427
  changes['filterId'] ||
28288
28428
  changes['formId'] ||
28289
28429
  changes['persistenceKey'] ||
28290
28430
  changes['componentInstanceId']) {
28291
28431
  this.resolveConfigKey();
28432
+ if (schemaIdentityChanged) {
28433
+ this.resetSchemaStateForContextChange();
28434
+ }
28292
28435
  }
28293
28436
  if (changes['resourcePath'] && !changes['resourcePath'].firstChange) {
28294
28437
  this.logFilterDebug('[PFILTER] ngOnChanges: resourcePath changed', {
@@ -28615,7 +28758,7 @@ class PraxisFilter {
28615
28758
  this.snackBar.open(message, 'Fechar', { duration: 3000 });
28616
28759
  }
28617
28760
  catch (err) {
28618
- console.error('PFILTER:config:save:error', err);
28761
+ this.getLogger().error('PFILTER:config:save:error', this.buildFilterLogOptions({ error: err }, 'config.save'));
28619
28762
  this.snackBar.open('Erro ao salvar configurações', 'Fechar', {
28620
28763
  duration: 3000,
28621
28764
  });
@@ -28691,7 +28834,7 @@ class PraxisFilter {
28691
28834
  });
28692
28835
  }
28693
28836
  catch (err) {
28694
- console.error('PFILTER:openSettings:error', err);
28837
+ this.getLogger().error('PFILTER:openSettings:error', this.buildFilterLogOptions({ error: err }, 'settings.open'));
28695
28838
  this.snackBar.open('Erro ao abrir configurações', 'Fechar', {
28696
28839
  duration: 3000,
28697
28840
  });
@@ -28853,6 +28996,211 @@ class PraxisFilter {
28853
28996
  const locale = (typeof navigator !== 'undefined' && navigator.language) ? navigator.language : undefined;
28854
28997
  return { path, operation, schemaType, includeInternalSchemas: true, tenant, locale, baseUrl, apiOrigin };
28855
28998
  }
28999
+ toSchemaIdContext(ctx) {
29000
+ return {
29001
+ path: ctx.path,
29002
+ operation: ctx.operation,
29003
+ schemaType: ctx.schemaType,
29004
+ includeInternalSchemas: ctx.includeInternalSchemas,
29005
+ tenant: ctx.tenant,
29006
+ locale: ctx.locale,
29007
+ apiOrigin: ctx.apiOrigin,
29008
+ };
29009
+ }
29010
+ resetSchemaStateForContextChange() {
29011
+ this.schemaLoadVersion += 1;
29012
+ this.setSchemaLoading(false);
29013
+ this.lastSchemaMeta = undefined;
29014
+ this.schemaOutdated = false;
29015
+ this.schemaError = false;
29016
+ this.schemaMetas = undefined;
29017
+ this.advancedConfig = undefined;
29018
+ this.advancedForm = undefined;
29019
+ this.schemaStatusChange.emit({ outdated: false, formId: this.formId });
29020
+ }
29021
+ clearSchemaMetaPersistence(options) {
29022
+ try {
29023
+ const keys = new Set();
29024
+ const legacyScopeKey = this.getSchemaMetaKey();
29025
+ if (legacyScopeKey)
29026
+ keys.add(legacyScopeKey);
29027
+ if (options?.context) {
29028
+ const contextualKey = this.getSchemaMetaKeyForContext(options.context);
29029
+ if (contextualKey)
29030
+ keys.add(contextualKey);
29031
+ }
29032
+ if (options?.includeAllScoped) {
29033
+ const indexKey = this.filterSchemaMetaIndexKey();
29034
+ if (indexKey) {
29035
+ this.configStorage
29036
+ .loadConfig(indexKey)
29037
+ .pipe(take(1))
29038
+ .subscribe({
29039
+ next: (storedIds) => {
29040
+ const ids = Array.isArray(storedIds) ? storedIds : [];
29041
+ ids.forEach((schemaId) => {
29042
+ const key = this.filterSchemaMetaKeyForSchemaId(schemaId);
29043
+ if (key)
29044
+ this.clearConfigStorageKey(key);
29045
+ });
29046
+ this.clearConfigStorageKey(indexKey);
29047
+ },
29048
+ error: () => {
29049
+ this.clearConfigStorageKey(indexKey);
29050
+ },
29051
+ });
29052
+ }
29053
+ }
29054
+ keys.forEach((key) => this.clearConfigStorageKey(key));
29055
+ }
29056
+ catch {
29057
+ // no-op: schema metadata cleanup is best effort
29058
+ }
29059
+ }
29060
+ clearConfigStorageKey(key) {
29061
+ if (!key)
29062
+ return;
29063
+ try {
29064
+ this.configStorage.clearConfig(key).pipe(take(1)).subscribe();
29065
+ }
29066
+ catch {
29067
+ // ignore storage clear failures
29068
+ }
29069
+ }
29070
+ loadStoredSchemaMeta(key) {
29071
+ if (!key)
29072
+ return Promise.resolve(undefined);
29073
+ return firstValueFrom(this.configStorage.loadConfig(key))
29074
+ .then((value) => value ?? undefined)
29075
+ .catch(() => undefined);
29076
+ }
29077
+ rememberSchemaMetaContext(schemaId) {
29078
+ const id = String(schemaId || '').trim();
29079
+ if (!id)
29080
+ return;
29081
+ const indexKey = this.filterSchemaMetaIndexKey();
29082
+ if (!indexKey)
29083
+ return;
29084
+ try {
29085
+ this.configStorage
29086
+ .loadConfig(indexKey)
29087
+ .pipe(take(1))
29088
+ .subscribe((stored) => {
29089
+ const unique = new Set((Array.isArray(stored) ? stored : [])
29090
+ .map((item) => String(item || '').trim())
29091
+ .filter((item) => !!item));
29092
+ unique.add(id);
29093
+ this.configStorage
29094
+ .saveConfig(indexKey, Array.from(unique))
29095
+ .pipe(take(1))
29096
+ .subscribe();
29097
+ });
29098
+ }
29099
+ catch {
29100
+ // ignore index update failures
29101
+ }
29102
+ }
29103
+ getSchemaMetaKeyForContext(context) {
29104
+ try {
29105
+ return this.filterSchemaMetaKeyForSchemaId(buildSchemaId(context));
29106
+ }
29107
+ catch {
29108
+ return this.getSchemaMetaKey();
29109
+ }
29110
+ }
29111
+ isStoredSchemaMetaForContext(storedMeta, schemaId, context) {
29112
+ if (!storedMeta || typeof storedMeta !== 'object')
29113
+ return false;
29114
+ const storedSchemaId = String(storedMeta.schemaId || '').trim();
29115
+ const storedContext = storedMeta.schemaContext;
29116
+ if (!storedSchemaId && !storedContext)
29117
+ return false;
29118
+ if (storedSchemaId && storedSchemaId !== schemaId)
29119
+ return false;
29120
+ if (storedContext && !this.isSameSchemaContext(storedContext, context))
29121
+ return false;
29122
+ return true;
29123
+ }
29124
+ isSameSchemaContext(left, right) {
29125
+ if (!left || !right)
29126
+ return false;
29127
+ return (left.path === right.path &&
29128
+ left.operation === right.operation &&
29129
+ left.schemaType === right.schemaType &&
29130
+ left.includeInternalSchemas === right.includeInternalSchemas &&
29131
+ left.tenant === right.tenant &&
29132
+ left.locale === right.locale &&
29133
+ left.apiOrigin === right.apiOrigin);
29134
+ }
29135
+ resolveLocalSchemaHashForContext(context) {
29136
+ const localHash = String(this.lastSchemaMeta?.serverHash || '').trim();
29137
+ if (!localHash)
29138
+ return undefined;
29139
+ if (!this.isSameSchemaContext(this.lastSchemaMeta?.context, context)) {
29140
+ return undefined;
29141
+ }
29142
+ return localHash;
29143
+ }
29144
+ persistSchemaMeta(schemaId, context, serverHash) {
29145
+ try {
29146
+ const key = this.filterSchemaMetaKeyForSchemaId(schemaId) || this.getSchemaMetaKey();
29147
+ if (!key)
29148
+ return;
29149
+ const nowIso = new Date().toISOString();
29150
+ this.configStorage
29151
+ .loadConfig(key)
29152
+ .pipe(take(1))
29153
+ .subscribe((prev) => {
29154
+ const next = {
29155
+ ...(prev || {}),
29156
+ schemaId,
29157
+ schemaContext: context,
29158
+ lastVerifiedAt: nowIso,
29159
+ };
29160
+ if (serverHash)
29161
+ next.serverHash = serverHash;
29162
+ this.configStorage.saveConfig(key, next).pipe(take(1)).subscribe();
29163
+ });
29164
+ this.rememberSchemaMetaContext(schemaId);
29165
+ }
29166
+ catch {
29167
+ // no-op: schema metadata persistence is best effort
29168
+ }
29169
+ }
29170
+ syncSchemaMeta(ctx, serverHash) {
29171
+ const context = this.toSchemaIdContext(ctx);
29172
+ const schemaId = buildSchemaId(context);
29173
+ this.lastSchemaMeta = { schemaId, serverHash, context };
29174
+ this.metaChanged.emit({ schemaId, serverHash, context });
29175
+ this.persistSchemaMeta(schemaId, context, serverHash);
29176
+ }
29177
+ resolveFallbackSchemaHash() {
29178
+ try {
29179
+ const hash = String(this.crud?.getLastSchemaInfo?.()?.schemaHash || '').trim();
29180
+ if (hash)
29181
+ return hash;
29182
+ }
29183
+ catch {
29184
+ // ignore and try local fallback
29185
+ }
29186
+ const currentContext = this.toSchemaIdContext(this.buildFilteredSchemaContext());
29187
+ return this.resolveLocalSchemaHashForContext(currentContext);
29188
+ }
29189
+ isExplicitlyFilterable(definition) {
29190
+ if (!definition || typeof definition !== 'object')
29191
+ return false;
29192
+ if (definition.filterable === true)
29193
+ return true;
29194
+ const filterControlTypeToken = normalizeControlTypeToken(definition.filterControlType || '');
29195
+ if (filterControlTypeToken)
29196
+ return true;
29197
+ const controlTypeToken = normalizeControlTypeToken(definition.controlType || '');
29198
+ return controlTypeToken.startsWith('filter');
29199
+ }
29200
+ pickSafeGenericFallbackDefs(definitions) {
29201
+ const source = Array.isArray(definitions) ? definitions : [];
29202
+ return source.filter((definition) => this.isExplicitlyFilterable(definition));
29203
+ }
28856
29204
  async loadSchemaViaClient() {
28857
29205
  const ctx = this.buildFilteredSchemaContext();
28858
29206
  try {
@@ -28863,36 +29211,76 @@ class PraxisFilter {
28863
29211
  const adapter = disableCache
28864
29212
  ? new MemoryCacheAdapter()
28865
29213
  : new LocalStorageCacheAdapter({ ttlMs: 30 * 60 * 1000, maxEntries: 200 });
28866
- const client = new SchemaMetadataClient(adapter);
28867
- const entry = await client.getSchema({
28868
- baseUrl: ctx.baseUrl,
28869
- path: ctx.path,
28870
- operation: ctx.operation,
28871
- schemaType: ctx.schemaType,
28872
- includeInternalSchemas: ctx.includeInternalSchemas,
28873
- tenant: ctx.tenant,
28874
- locale: ctx.locale,
28875
- });
28876
- const defs = this.schemaNormalizer.normalizeSchema(entry.schema);
28877
- const metas = mapFieldDefinitionsToMetadata(defs);
28878
- this.logFilterWarn('[PFILTER] loadSchemaViaClient: metas', {
28879
- count: metas.length,
28880
- names: metas.map((m) => m.name),
28881
- });
28882
- const schemaId = buildSchemaId(ctx);
28883
- this.lastSchemaMeta = { schemaId, serverHash: entry.schemaHash, context: ctx };
28884
- // Emit metadata to host
28885
- this.metaChanged.emit({ schemaId, serverHash: entry.schemaHash, context: ctx });
28886
- // Persist minimal meta for future verify-only calls
28887
29214
  try {
28888
- const nowIso = new Date().toISOString();
28889
- const metaKey = this.getSchemaMetaKey();
28890
- if (metaKey) {
28891
- this.configStorage.saveConfig(metaKey, { serverHash: entry.schemaHash, lastVerifiedAt: nowIso }).pipe(take(1)).subscribe();
29215
+ const client = new SchemaMetadataClient(adapter);
29216
+ const entry = await client.getSchema({
29217
+ baseUrl: ctx.baseUrl,
29218
+ path: ctx.path,
29219
+ operation: ctx.operation,
29220
+ schemaType: ctx.schemaType,
29221
+ includeInternalSchemas: ctx.includeInternalSchemas,
29222
+ tenant: ctx.tenant,
29223
+ locale: ctx.locale,
29224
+ });
29225
+ const defs = this.schemaNormalizer.normalizeSchema(entry.schema);
29226
+ const metas = mapFieldDefinitionsToMetadata(defs);
29227
+ this.logFilterWarn('[PFILTER] loadSchemaViaClient: metas', {
29228
+ count: metas.length,
29229
+ names: metas.map((m) => m.name),
29230
+ });
29231
+ this.syncSchemaMeta(ctx, entry.schemaHash);
29232
+ return metas;
29233
+ }
29234
+ catch (schemaClientError) {
29235
+ // Runtime hardening: if /schemas/filtered returns HTML/redirect or invalid JSON,
29236
+ // fallback to CRUD HttpClient path before failing the filter experience.
29237
+ this.logFilterWarn('[PFILTER] loadSchemaViaClient: metadata client failed, trying CRUD fallback', {
29238
+ message: schemaClientError instanceof Error ? schemaClientError.message : String(schemaClientError),
29239
+ path: ctx.path,
29240
+ baseUrl: ctx.baseUrl,
29241
+ });
29242
+ return this.loadSchemaViaCrudFallback(ctx, schemaClientError);
29243
+ }
29244
+ }
29245
+ async loadSchemaViaCrudFallback(ctx, primaryError) {
29246
+ try {
29247
+ const filteredDefs = await firstValueFrom(this.crud.getFilteredSchema({
29248
+ path: ctx.path,
29249
+ operation: ctx.operation,
29250
+ schemaType: ctx.schemaType,
29251
+ includeInternalSchemas: ctx.includeInternalSchemas,
29252
+ }));
29253
+ const metas = mapFieldDefinitionsToMetadata(filteredDefs);
29254
+ this.syncSchemaMeta(ctx, this.resolveFallbackSchemaHash());
29255
+ this.logFilterWarn('[PFILTER] loadSchemaViaCrudFallback: using getFilteredSchema', {
29256
+ count: metas.length,
29257
+ hasSchemaHash: !!this.lastSchemaMeta?.serverHash,
29258
+ });
29259
+ return metas;
29260
+ }
29261
+ catch (filteredError) {
29262
+ try {
29263
+ const genericDefs = await firstValueFrom(this.crud.getSchema());
29264
+ const safeFallbackDefs = this.pickSafeGenericFallbackDefs(genericDefs);
29265
+ if (!safeFallbackDefs.length) {
29266
+ const unsafeFallback = new Error('PFILTER:schema:generic-fallback-unsafe');
29267
+ unsafeFallback.cause = genericDefs;
29268
+ throw unsafeFallback;
29269
+ }
29270
+ const metas = mapFieldDefinitionsToMetadata(safeFallbackDefs);
29271
+ this.syncSchemaMeta(ctx, this.resolveFallbackSchemaHash());
29272
+ this.logFilterWarn('[PFILTER] loadSchemaViaCrudFallback: using getSchema', {
29273
+ count: metas.length,
29274
+ originalCount: Array.isArray(genericDefs) ? genericDefs.length : 0,
29275
+ });
29276
+ return metas;
29277
+ }
29278
+ catch (genericError) {
29279
+ const error = new Error('PFILTER:schema:load:fallback-failed');
29280
+ error.cause = { primaryError, filteredError, genericError };
29281
+ throw error;
28892
29282
  }
28893
29283
  }
28894
- catch { }
28895
- return metas;
28896
29284
  }
28897
29285
  loadSchema() {
28898
29286
  this.logFilterWarn('[PFILTER] loadSchema: start');
@@ -28910,15 +29298,53 @@ class PraxisFilter {
28910
29298
  this.logFilterWarn('[PFILTER] loadSchema: already loading - skip');
28911
29299
  return;
28912
29300
  }
29301
+ // Avoid opening stale advanced config while a new schema context is being loaded.
29302
+ const requestContext = (() => {
29303
+ try {
29304
+ return this.toSchemaIdContext(this.buildFilteredSchemaContext());
29305
+ }
29306
+ catch {
29307
+ return undefined;
29308
+ }
29309
+ })();
29310
+ const requestVersion = ++this.schemaLoadVersion;
29311
+ this.advancedConfig = undefined;
29312
+ this.advancedForm = undefined;
28913
29313
  this.setSchemaLoading(true);
28914
29314
  this.schemaError = false;
28915
29315
  // Use SchemaMetadataClient with ETag/304 + schemaId context
28916
29316
  this.loadSchemaViaClient()
28917
29317
  .then((metas) => {
29318
+ if (requestVersion !== this.schemaLoadVersion)
29319
+ return;
29320
+ if (requestContext &&
29321
+ !this.isSameSchemaContext(requestContext, (() => {
29322
+ try {
29323
+ return this.toSchemaIdContext(this.buildFilteredSchemaContext());
29324
+ }
29325
+ catch {
29326
+ return undefined;
29327
+ }
29328
+ })())) {
29329
+ return;
29330
+ }
28918
29331
  if (this.schemaError)
28919
29332
  return;
28920
29333
  setTimeout(() => {
28921
29334
  this.ngZone.run(() => {
29335
+ if (requestVersion !== this.schemaLoadVersion)
29336
+ return;
29337
+ if (requestContext &&
29338
+ !this.isSameSchemaContext(requestContext, (() => {
29339
+ try {
29340
+ return this.toSchemaIdContext(this.buildFilteredSchemaContext());
29341
+ }
29342
+ catch {
29343
+ return undefined;
29344
+ }
29345
+ })())) {
29346
+ return;
29347
+ }
28922
29348
  this.setSchemaLoading(false);
28923
29349
  this.schemaMetas = metas;
28924
29350
  this.logFilterDebug('[PFILTER] loadSchema: metas received', {
@@ -28930,15 +29356,37 @@ class PraxisFilter {
28930
29356
  });
28931
29357
  })
28932
29358
  .catch((err) => {
28933
- console.error('PFILTER:schema:load:error', err);
29359
+ this.getLogger().error('PFILTER:schema:load:error', this.buildFilterLogOptions({ error: err }, 'schema.load'));
28934
29360
  setTimeout(() => {
28935
29361
  this.ngZone.run(() => {
29362
+ if (requestVersion !== this.schemaLoadVersion)
29363
+ return;
29364
+ if (requestContext &&
29365
+ !this.isSameSchemaContext(requestContext, (() => {
29366
+ try {
29367
+ return this.toSchemaIdContext(this.buildFilteredSchemaContext());
29368
+ }
29369
+ catch {
29370
+ return undefined;
29371
+ }
29372
+ })())) {
29373
+ return;
29374
+ }
28936
29375
  this.setSchemaLoading(false);
28937
29376
  this.schemaError = true;
28938
29377
  });
28939
29378
  });
28940
29379
  });
28941
29380
  }
29381
+ retrySchemaLoad() {
29382
+ if (this.usesProvidedFieldMetadata()) {
29383
+ this.applyProvidedFieldMetadata();
29384
+ return;
29385
+ }
29386
+ this.schemaMetas = undefined;
29387
+ this.schemaError = false;
29388
+ this.loadSchema();
29389
+ }
28942
29390
  applySchemaMetas() {
28943
29391
  if (this.applySchemaQueued)
28944
29392
  return;
@@ -29863,6 +30311,14 @@ class PraxisFilter {
29863
30311
  const plural = count > 1 ? 's' : '';
29864
30312
  return `${this.i18nLabels.advanced}, ${count} filtro${plural} ativo${plural}`;
29865
30313
  }
30314
+ getSettingsAriaLabel() {
30315
+ return this.i18nLabels.settingsAriaLabel || this.i18nLabels.settings || 'Configurações';
30316
+ }
30317
+ getTagActionsAriaLabel(tag) {
30318
+ const base = this.i18nLabels.tagActionsAriaLabel || 'Ações do atalho';
30319
+ const tagLabel = String(tag?.label || '').trim();
30320
+ return tagLabel ? `${base}: ${tagLabel}` : base;
30321
+ }
29866
30322
  // =============================
29867
30323
  // Schema verification (ETag) + persistence helpers
29868
30324
  // =============================
@@ -29966,59 +30422,57 @@ class PraxisFilter {
29966
30422
  try {
29967
30423
  if (this.usesProvidedFieldMetadata())
29968
30424
  return;
29969
- const metaKey = this.getSchemaMetaKey();
29970
- if (!this.resourcePath || !metaKey)
30425
+ if (!this.resourcePath)
30426
+ return;
30427
+ const currentCtx = this.buildFilteredSchemaContext();
30428
+ const currentSchemaContext = this.toSchemaIdContext(currentCtx);
30429
+ const currentSchemaId = buildSchemaId(currentSchemaContext);
30430
+ const scopedMetaKey = this.getSchemaMetaKeyForContext(currentSchemaContext) || this.getSchemaMetaKey();
30431
+ if (!scopedMetaKey)
29971
30432
  return;
29972
30433
  // Build request to /schemas/filtered for filter (path=/.../filter, operation=post, schemaType=request)
29973
- const baseUrl = this.crud.getSchemasFilteredBaseUrl();
29974
- const basePath = (this.crud.schemaUrl() || '').replace(/\/+$/, '').replace(/\/schemas$/, '');
29975
- let path = basePath ? `${basePath}/filter` : `/${(this.resourcePath || '').replace(/^\/+|\/+$/g, '')}/filter`;
29976
- const u = new URL(baseUrl);
29977
- u.searchParams.set('path', path);
29978
- u.searchParams.set('operation', 'post');
29979
- u.searchParams.set('schemaType', 'request');
29980
- u.searchParams.set('includeInternalSchemas', 'true');
30434
+ const u = new URL(currentCtx.baseUrl);
30435
+ u.searchParams.set('path', currentCtx.path);
30436
+ u.searchParams.set('operation', String(currentCtx.operation || 'post'));
30437
+ u.searchParams.set('schemaType', String(currentCtx.schemaType || 'request'));
30438
+ u.searchParams.set('includeInternalSchemas', currentCtx.includeInternalSchemas ? 'true' : 'false');
29981
30439
  // Load previously persisted meta (serverHash)
29982
- const persistedMeta = await (async () => {
29983
- if (!metaKey)
29984
- return undefined;
29985
- try {
29986
- return await firstValueFrom(this.configStorage.loadConfig(metaKey));
29987
- }
29988
- catch {
29989
- return undefined;
29990
- }
29991
- })();
29992
- const previousHash = persistedMeta?.serverHash || this.lastSchemaMeta?.serverHash;
29993
- const hasPersistedMeta = persistedMeta != null;
29994
- const hasLocalMeta = !!this.lastSchemaMeta?.serverHash;
29995
- const shouldPersistMeta = hasPersistedMeta || !hasLocalMeta;
30440
+ const scopedMeta = await this.loadStoredSchemaMeta(scopedMetaKey);
30441
+ const legacyScopeKey = this.getSchemaMetaKey();
30442
+ const legacyMeta = legacyScopeKey && legacyScopeKey !== scopedMetaKey
30443
+ ? await this.loadStoredSchemaMeta(legacyScopeKey)
30444
+ : undefined;
30445
+ const persistedMeta = this.isStoredSchemaMetaForContext(scopedMeta, currentSchemaId, currentSchemaContext)
30446
+ ? scopedMeta
30447
+ : this.isStoredSchemaMetaForContext(legacyMeta, currentSchemaId, currentSchemaContext)
30448
+ ? legacyMeta
30449
+ : undefined;
30450
+ const persistedHash = String(persistedMeta?.serverHash || '').trim() || undefined;
30451
+ const previousHash = persistedHash ||
30452
+ this.resolveLocalSchemaHashForContext(currentSchemaContext);
29996
30453
  // If we have no prior hash and no in-memory schema, skip verification to avoid an extra full GET.
29997
30454
  // The initial loadSchema() will fetch the body and persist the hash.
29998
30455
  if (!previousHash && !this.schemaMetas?.length) {
29999
30456
  return;
30000
30457
  }
30001
- const tenant = (() => { try {
30002
- return this.global.getTenant();
30003
- }
30004
- catch {
30005
- return undefined;
30006
- } })();
30007
- const locale = (() => { try {
30008
- return (typeof navigator !== 'undefined' && navigator.language) ? navigator.language : undefined;
30009
- }
30010
- catch {
30011
- return undefined;
30012
- } })();
30458
+ const tenant = currentCtx.tenant;
30459
+ const locale = currentCtx.locale;
30013
30460
  const res = await fetchWithETag({ url: u.toString(), schemaHash: previousHash, tenant, locale });
30014
30461
  const nowIso = new Date().toISOString();
30015
30462
  const metaToSave = { ...(persistedMeta || {}) };
30463
+ metaToSave.schemaId = currentSchemaId;
30464
+ metaToSave.schemaContext = currentSchemaContext;
30016
30465
  metaToSave.lastVerifiedAt = nowIso;
30466
+ if (!metaToSave.serverHash && previousHash) {
30467
+ metaToSave.serverHash = previousHash;
30468
+ }
30017
30469
  if (res.status === 304) {
30018
30470
  try {
30019
- const key = this.getSchemaMetaKey();
30020
- if (shouldPersistMeta && key)
30021
- this.configStorage.saveConfig(key, metaToSave).pipe(take(1)).subscribe();
30471
+ this.configStorage
30472
+ .saveConfig(scopedMetaKey, metaToSave)
30473
+ .pipe(take(1))
30474
+ .subscribe();
30475
+ this.rememberSchemaMetaContext(currentSchemaId);
30022
30476
  }
30023
30477
  catch { }
30024
30478
  if (this.schemaOutdated)
@@ -30030,9 +30484,11 @@ class PraxisFilter {
30030
30484
  const newHash = res.schemaHash;
30031
30485
  metaToSave.serverHash = newHash;
30032
30486
  try {
30033
- const key = this.getSchemaMetaKey();
30034
- if (shouldPersistMeta && key)
30035
- this.configStorage.saveConfig(key, metaToSave).pipe(take(1)).subscribe();
30487
+ this.configStorage
30488
+ .saveConfig(scopedMetaKey, metaToSave)
30489
+ .pipe(take(1))
30490
+ .subscribe();
30491
+ this.rememberSchemaMetaContext(currentSchemaId);
30036
30492
  }
30037
30493
  catch { }
30038
30494
  // Only mark outdated when there was a previous base (hash or schemaMetas) and we are in edit mode
@@ -30057,10 +30513,11 @@ class PraxisFilter {
30057
30513
  return;
30058
30514
  if (this._resolvedPrefs.notifyIfOutdated === 'none')
30059
30515
  return;
30060
- const metaKey = this.getSchemaMetaKey();
30516
+ const currentSchemaContext = this.toSchemaIdContext(this.buildFilteredSchemaContext());
30517
+ const metaKey = this.getSchemaMetaKeyForContext(currentSchemaContext);
30061
30518
  if (!metaKey)
30062
30519
  return;
30063
- const serverHash = (await firstValueFrom(this.configStorage.loadConfig(metaKey)) || {})?.serverHash;
30520
+ const serverHash = (await this.loadStoredSchemaMeta(metaKey) || {})?.serverHash;
30064
30521
  if (!serverHash || !this.schemaOutdated)
30065
30522
  return;
30066
30523
  if (await this.isOutdatedIgnored(serverHash))
@@ -30130,7 +30587,7 @@ class PraxisFilter {
30130
30587
  this.submit.emit({ ...this.dto });
30131
30588
  }
30132
30589
  catch (err) {
30133
- console.error('PFILTER:applyTag:error', err);
30590
+ this.getLogger().error('PFILTER:applyTag:error', this.buildFilterLogOptions({ error: err }, 'tag.apply'));
30134
30591
  }
30135
30592
  }
30136
30593
  // =============================
@@ -30200,6 +30657,8 @@ class PraxisFilter {
30200
30657
  this.applyProvidedFieldMetadata();
30201
30658
  return !!this.advancedConfig;
30202
30659
  }
30660
+ if (this.schemaError)
30661
+ return false;
30203
30662
  if (!this.schemaLoading)
30204
30663
  this.loadSchema();
30205
30664
  const startedAt = Date.now();
@@ -30209,13 +30668,35 @@ class PraxisFilter {
30209
30668
  }
30210
30669
  await new Promise((resolve) => setTimeout(resolve, 50));
30211
30670
  }
30212
- return !!this.advancedConfig || this.schemaError || !this.schemaLoading;
30671
+ return !!this.advancedConfig;
30672
+ }
30673
+ focusSchemaRetryButton() {
30674
+ setTimeout(() => {
30675
+ try {
30676
+ const host = this.advancedButton?.nativeElement?.closest('.praxis-filter-bar')?.parentElement;
30677
+ const retry = host?.querySelector('.schema-error-retry');
30678
+ retry?.focus?.();
30679
+ }
30680
+ catch {
30681
+ // ignore focus errors
30682
+ }
30683
+ });
30684
+ }
30685
+ showAdvancedUnavailableFeedback() {
30686
+ const hasSchemaError = !!this.schemaError && !this.advancedConfig;
30687
+ if (hasSchemaError) {
30688
+ this.focusSchemaRetryButton();
30689
+ return;
30690
+ }
30691
+ const message = this.i18nLabels.noData || 'Nenhum filtro avançado disponível.';
30692
+ const action = this.i18nLabels.cancel || 'Fechar';
30693
+ this.snackBar.open(message, action, { duration: 3200 });
30213
30694
  }
30214
30695
  async openAdvancedModal() {
30215
30696
  this.captureLastActiveElement();
30216
30697
  const ready = await this.ensureAdvancedConfigReady();
30217
- if (!ready && !this.advancedConfig) {
30218
- this.snackBar.open(this.i18nLabels.errorLoadingFilters || 'Erro ao carregar filtros.', this.i18nLabels.retry || 'Tentar novamente', { duration: 3200 });
30698
+ if (!ready || !this.advancedConfig) {
30699
+ this.showAdvancedUnavailableFeedback();
30219
30700
  return;
30220
30701
  }
30221
30702
  this.advancedOpen = true;
@@ -30259,8 +30740,8 @@ class PraxisFilter {
30259
30740
  return;
30260
30741
  }
30261
30742
  const ready = await this.ensureAdvancedConfigReady();
30262
- if (!ready && !this.advancedConfig) {
30263
- this.snackBar.open(this.i18nLabels.errorLoadingFilters || 'Erro ao carregar filtros.', this.i18nLabels.retry || 'Tentar novamente', { duration: 3200 });
30743
+ if (!ready || !this.advancedConfig) {
30744
+ this.showAdvancedUnavailableFeedback();
30264
30745
  return;
30265
30746
  }
30266
30747
  this.advancedOpen = true;
@@ -30285,7 +30766,7 @@ class PraxisFilter {
30285
30766
  }
30286
30767
  catch (error) {
30287
30768
  this.closeAdvanced();
30288
- console.error('PFILTER:drawer:open:error', error);
30769
+ this.getLogger().error('PFILTER:drawer:open:error', this.buildFilterLogOptions({ error }, 'drawer.open'));
30289
30770
  }
30290
30771
  }
30291
30772
  toggleAdvanced() {
@@ -30310,10 +30791,12 @@ class PraxisFilter {
30310
30791
  if (!this.usesProvidedFieldMetadata())
30311
30792
  return;
30312
30793
  const source = (this.fieldMetadata || []);
30794
+ this.schemaLoadVersion += 1;
30313
30795
  this.schemaError = false;
30314
30796
  this.setSchemaLoading(false);
30315
30797
  this.schemaMetas = source.map((meta) => ({ ...meta }));
30316
30798
  this.lastSchemaMeta = undefined;
30799
+ this.clearSchemaMetaPersistence();
30317
30800
  this.applySchemaMetas();
30318
30801
  }
30319
30802
  saveConfig() {
@@ -30540,8 +31023,8 @@ class PraxisFilter {
30540
31023
  // no-op
30541
31024
  }
30542
31025
  }
30543
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", 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 }], target: i0.ɵɵFactoryTarget.Component });
30544
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", 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", editModeEnabled: "editModeEnabled", 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\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--query\">\n <button mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\" type=\"button\"\n (click)=\"onSubmit()\" [attr.aria-label]=\"i18nLabels.apply\">\n <mat-icon [praxisIcon]=\"'search'\"></mat-icon>\n </button>\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 [attr.aria-controls]=\"advancedPanelId\">\n <mat-icon [praxisIcon]=\"'filter_alt'\"></mat-icon>\n </button>\n </div>\n\n <div class=\"action-cluster action-cluster--manage\">\n <mat-select #addSelect multiple panelClass=\"praxis-add-select-panel\" panelWidth=\"min(340px, calc(100vw - 24px))\" [value]=\"selectedFieldIds\"\n [aria-label]=\"getAddAriaLabel()\" (openedChange)=\"onAddOpened($event)\"\n (selectionChange)=\"onAddSelectionChange(addSelect.value)\">\n <mat-select-trigger>\n <span class=\"add-trigger\" [matBadge]=\"selectedFieldIds.length || 0\"\n [matBadgeHidden]=\"!(selectedFieldIds.length)\" matBadgeSize=\"small\" matBadgeColor=\"primary\"\n [matBadgeOverlap]=\"false\">\n <mat-icon>add</mat-icon>\n <span class=\"add-trigger-label\">{{ getAddTriggerLabel() }}</span>\n </span>\n </mat-select-trigger>\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]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : i18nLabels.settings\"\n matTooltipPosition=\"below\">\n <mat-icon [praxisIcon]=\"'settings'\"></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()\" aria-label=\"tag actions\">\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}.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--query{border-color:var(--md-sys-color-outline-variant);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}.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{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 0 auto!important}:host ::ng-deep .compact-fields>.pfx-field-shell,:host ::ng-deep .compact-fields>praxis-field-shell{flex:0 0 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=filter-date-range-inline] .mat-mdc-form-field{width:var(--pdx-inline-date-range-shell-width, auto)!important;max-width:none!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=filter-select-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-select-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-searchable-select-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-searchable-select-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-multiselect-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-multiselect-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-input-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-input-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-toggle-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-toggle-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-range-inline]{justify-self:start}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=filter-range-inline]{max-width:min(340px,100%)}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-range-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-range-inline] .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}.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}: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 .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.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: i14$1.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i15$3.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: i5$1.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: i5$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i5$1.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: i12.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$2.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: "directive", type: i5$2.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i5$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }] });
31026
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", 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 });
31027
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", 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", editModeEnabled: "editModeEnabled", 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--query\">\n <button mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\" type=\"button\"\n (click)=\"onSubmit()\" [attr.aria-label]=\"i18nLabels.apply\">\n <mat-icon [praxisIcon]=\"'search'\"></mat-icon>\n </button>\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 [attr.aria-controls]=\"advancedPanelId\">\n <mat-icon [praxisIcon]=\"'filter_alt'\"></mat-icon>\n </button>\n </div>\n\n <div class=\"action-cluster action-cluster--manage\">\n <mat-select #addSelect multiple panelClass=\"praxis-add-select-panel\" panelWidth=\"min(340px, calc(100vw - 24px))\" [value]=\"selectedFieldIds\"\n [aria-label]=\"getAddAriaLabel()\" (openedChange)=\"onAddOpened($event)\"\n (selectionChange)=\"onAddSelectionChange(addSelect.value)\">\n <mat-select-trigger>\n <span class=\"add-trigger\" [matBadge]=\"selectedFieldIds.length || 0\"\n [matBadgeHidden]=\"!(selectedFieldIds.length)\" matBadgeSize=\"small\" matBadgeColor=\"primary\"\n [matBadgeOverlap]=\"false\">\n <mat-icon>add</mat-icon>\n <span class=\"add-trigger-label\">{{ getAddTriggerLabel() }}</span>\n </span>\n </mat-select-trigger>\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]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : i18nLabels.settings\"\n matTooltipPosition=\"below\" [attr.aria-label]=\"getSettingsAriaLabel()\">\n <mat-icon [praxisIcon]=\"'settings'\"></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--query{border-color:var(--md-sys-color-outline-variant);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}.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{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 0 auto!important}:host ::ng-deep .compact-fields>.pfx-field-shell,:host ::ng-deep .compact-fields>praxis-field-shell{flex:0 0 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=filter-date-range-inline] .mat-mdc-form-field{width:var(--pdx-inline-date-range-shell-width, auto)!important;max-width:none!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=filter-select-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-select-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-searchable-select-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-searchable-select-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-multiselect-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-multiselect-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-input-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-input-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-toggle-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-toggle-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-range-inline]{justify-self:start}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=filter-range-inline]{max-width:min(340px,100%)}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-range-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-range-inline] .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}.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}: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 .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: i14$1.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i15$3.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: i5$1.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: i5$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i5$1.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: i12.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$2.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: "directive", type: i5$2.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i5$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }] });
30545
31028
  }
30546
31029
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisFilter, decorators: [{
30547
31030
  type: Component,
@@ -30569,12 +31052,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
30569
31052
  '[style.--pfx-always-min]': 'alwaysMinWidth + "px"',
30570
31053
  '[style.--pfx-always-cols-md]': 'alwaysColsMd',
30571
31054
  '[style.--pfx-always-cols-lg]': 'alwaysColsLg',
30572
- }, template: "<mat-progress-bar *ngIf=\"saving\" mode=\"indeterminate\"></mat-progress-bar>\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--query\">\n <button mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\" type=\"button\"\n (click)=\"onSubmit()\" [attr.aria-label]=\"i18nLabels.apply\">\n <mat-icon [praxisIcon]=\"'search'\"></mat-icon>\n </button>\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 [attr.aria-controls]=\"advancedPanelId\">\n <mat-icon [praxisIcon]=\"'filter_alt'\"></mat-icon>\n </button>\n </div>\n\n <div class=\"action-cluster action-cluster--manage\">\n <mat-select #addSelect multiple panelClass=\"praxis-add-select-panel\" panelWidth=\"min(340px, calc(100vw - 24px))\" [value]=\"selectedFieldIds\"\n [aria-label]=\"getAddAriaLabel()\" (openedChange)=\"onAddOpened($event)\"\n (selectionChange)=\"onAddSelectionChange(addSelect.value)\">\n <mat-select-trigger>\n <span class=\"add-trigger\" [matBadge]=\"selectedFieldIds.length || 0\"\n [matBadgeHidden]=\"!(selectedFieldIds.length)\" matBadgeSize=\"small\" matBadgeColor=\"primary\"\n [matBadgeOverlap]=\"false\">\n <mat-icon>add</mat-icon>\n <span class=\"add-trigger-label\">{{ getAddTriggerLabel() }}</span>\n </span>\n </mat-select-trigger>\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]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : i18nLabels.settings\"\n matTooltipPosition=\"below\">\n <mat-icon [praxisIcon]=\"'settings'\"></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()\" aria-label=\"tag actions\">\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}.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--query{border-color:var(--md-sys-color-outline-variant);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}.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{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 0 auto!important}:host ::ng-deep .compact-fields>.pfx-field-shell,:host ::ng-deep .compact-fields>praxis-field-shell{flex:0 0 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=filter-date-range-inline] .mat-mdc-form-field{width:var(--pdx-inline-date-range-shell-width, auto)!important;max-width:none!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=filter-select-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-select-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-searchable-select-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-searchable-select-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-multiselect-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-multiselect-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-input-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-input-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-toggle-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-toggle-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-range-inline]{justify-self:start}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=filter-range-inline]{max-width:min(340px,100%)}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-range-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-range-inline] .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}.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}: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 .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"] }]
31055
+ }, 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--query\">\n <button mat-icon-button class=\"cluster-btn\" [color]=\"actionsButtonColor==='basic'? null : actionsButtonColor\" type=\"button\"\n (click)=\"onSubmit()\" [attr.aria-label]=\"i18nLabels.apply\">\n <mat-icon [praxisIcon]=\"'search'\"></mat-icon>\n </button>\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 [attr.aria-controls]=\"advancedPanelId\">\n <mat-icon [praxisIcon]=\"'filter_alt'\"></mat-icon>\n </button>\n </div>\n\n <div class=\"action-cluster action-cluster--manage\">\n <mat-select #addSelect multiple panelClass=\"praxis-add-select-panel\" panelWidth=\"min(340px, calc(100vw - 24px))\" [value]=\"selectedFieldIds\"\n [aria-label]=\"getAddAriaLabel()\" (openedChange)=\"onAddOpened($event)\"\n (selectionChange)=\"onAddSelectionChange(addSelect.value)\">\n <mat-select-trigger>\n <span class=\"add-trigger\" [matBadge]=\"selectedFieldIds.length || 0\"\n [matBadgeHidden]=\"!(selectedFieldIds.length)\" matBadgeSize=\"small\" matBadgeColor=\"primary\"\n [matBadgeOverlap]=\"false\">\n <mat-icon>add</mat-icon>\n <span class=\"add-trigger-label\">{{ getAddTriggerLabel() }}</span>\n </span>\n </mat-select-trigger>\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]=\"schemaOutdated ? 'Schema do servidor mudou \u2014 Reconciliar' : i18nLabels.settings\"\n matTooltipPosition=\"below\" [attr.aria-label]=\"getSettingsAriaLabel()\">\n <mat-icon [praxisIcon]=\"'settings'\"></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--query{border-color:var(--md-sys-color-outline-variant);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}.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{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 0 auto!important}:host ::ng-deep .compact-fields>.pfx-field-shell,:host ::ng-deep .compact-fields>praxis-field-shell{flex:0 0 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=filter-date-range-inline] .mat-mdc-form-field{width:var(--pdx-inline-date-range-shell-width, auto)!important;max-width:none!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=filter-select-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-select-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-searchable-select-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-searchable-select-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-multiselect-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-multiselect-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-input-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-input-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-toggle-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-toggle-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-range-inline]{justify-self:start}:host ::ng-deep .compact-fields .pfx-field-shell[data-control-type=filter-range-inline]{max-width:min(340px,100%)}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-inline] .mat-mdc-form-field{width:auto;min-width:0;max-width:100%}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-range-inline]{justify-self:start}:host ::ng-deep .fields-grid .pfx-field-shell[data-control-type=filter-date-range-inline] .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}.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}: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 .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"] }]
30573
31056
  }], ctorParameters: () => [{ type: i1.GenericCrudService }, { type: undefined, decorators: [{
30574
31057
  type: Inject,
30575
31058
  args: [ASYNC_CONFIG_STORAGE]
30576
31059
  }] }, { 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: [{
30577
31060
  type: Optional
31061
+ }] }, { type: i1.LoggerService, decorators: [{
31062
+ type: Optional
30578
31063
  }] }], propDecorators: { resourcePath: [{
30579
31064
  type: Input,
30580
31065
  args: [{ required: true }]