@praxisui/crud 10.0.0-rc.13 → 10.0.0-rc.15

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.
@@ -6,36 +6,36 @@ import { Router, ActivatedRoute, RouterLink } from '@angular/router';
6
6
  import { MatSnackBar } from '@angular/material/snack-bar';
7
7
  import { firstValueFrom, BehaviorSubject, Subscription } from 'rxjs';
8
8
  import { take, filter } from 'rxjs/operators';
9
- import * as i2$2 from '@praxisui/core';
9
+ import * as i2$1 from '@praxisui/core';
10
10
  import { PraxisBulkClientService, generateBulkIdempotencyKey, API_URL, SafeExpressionEvaluator, buildApiUrl, ASYNC_CONFIG_STORAGE, GlobalConfigService, CrudOperationResolutionService, LoggerService, SurfaceNavigationError, fillUndefined, SETTINGS_PANEL_DATA, PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, createDefaultTableConfig, PraxisWidgetEventBus, EnterpriseRuntimeContextService, GLOBAL_SURFACE_SERVICE, SurfaceOutletRegistryService, ComponentKeyService, ResourceDiscoveryService, ResourceActionOpenAdapterService, ResourceSurfaceOpenAdapterService, normalizeSurfaceOperationContext, translateUnavailableWorkflowMessage, isSurfaceNavigationError, translateSurfaceNavigationRejected, normalizeUnknownError, EmptyStateCardComponent, RESOURCE_DISCOVERY_I18N_CONFIG, SURFACE_DRAWER_REF, SURFACE_DRAWER_CONTENT_DATA, PraxisIconButtonComponent, PraxisResourceIdentityComponent, GenericCrudService, ComponentMetadataRegistry } from '@praxisui/core';
11
11
  export { createDynamicRecord, extractRecordId, isDynamicDataRecord, resolveDataField } from '@praxisui/core';
12
- import * as i1$1 from '@angular/common';
12
+ import * as i1 from '@angular/common';
13
13
  import { CommonModule } from '@angular/common';
14
- import * as i2 from '@angular/material/button';
14
+ import * as i3 from '@angular/material/button';
15
15
  import { MatButtonModule } from '@angular/material/button';
16
- import * as i1$2 from '@angular/material/dialog';
16
+ import * as i1$1 from '@angular/material/dialog';
17
17
  import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
18
18
  export { MAT_DIALOG_DATA as DIALOG_DATA } from '@angular/material/dialog';
19
- import * as i2$1 from '@angular/material/icon';
19
+ import * as i4 from '@angular/material/icon';
20
20
  import { MatIconModule } from '@angular/material/icon';
21
- import * as i3 from '@angular/material/progress-spinner';
21
+ import * as i4$1 from '@angular/material/progress-spinner';
22
22
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
23
- import * as i1 from '@angular/forms';
23
+ import * as i2 from '@angular/forms';
24
24
  import { FormsModule } from '@angular/forms';
25
25
  import { PraxisDynamicForm } from '@praxisui/dynamic-form';
26
- import * as i5 from '@angular/material/select';
26
+ import * as i6 from '@angular/material/select';
27
27
  import { MatSelectModule } from '@angular/material/select';
28
- import * as i6 from '@angular/material/input';
28
+ import * as i7 from '@angular/material/input';
29
29
  import { MatInputModule } from '@angular/material/input';
30
30
  import { MatFormFieldModule } from '@angular/material/form-field';
31
31
  import { SettingsPanelService } from '@praxisui/settings-panel';
32
32
  import { PraxisTableInlineAuthoringEditorComponent, PraxisTable, PraxisScopeBarComponent } from '@praxisui/table';
33
33
  import { ConfirmDialogComponent } from '@praxisui/dynamic-fields';
34
- import * as i4 from '@angular/material/tooltip';
34
+ import * as i4$2 from '@angular/material/tooltip';
35
35
  import { MatTooltipModule } from '@angular/material/tooltip';
36
36
  import * as i3$1 from '@angular/material/card';
37
37
  import { MatCardModule } from '@angular/material/card';
38
- import * as i4$1 from '@angular/material/expansion';
38
+ import * as i4$3 from '@angular/material/expansion';
39
39
  import { MatExpansionModule } from '@angular/material/expansion';
40
40
  import * as i8 from '@angular/material/slide-toggle';
41
41
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
@@ -104,6 +104,15 @@ class PraxisBulkOperationDialogComponent {
104
104
  this.action.requestSchemaUrl ||
105
105
  null);
106
106
  }
107
+ getParametersFormId() {
108
+ const resourcePart = String(this.data.resourceKey || this.data.resourcePath || 'resource')
109
+ .trim()
110
+ .replace(/[^a-zA-Z0-9_-]+/g, '-');
111
+ const actionPart = String(this.action.id || 'action')
112
+ .trim()
113
+ .replace(/[^a-zA-Z0-9_-]+/g, '-');
114
+ return `bulk-params-${resourcePart}-${actionPart}`;
115
+ }
107
116
  onParametersChange(event) {
108
117
  const raw = event?.formData ?? event?.value ?? event;
109
118
  if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
@@ -146,12 +155,79 @@ class PraxisBulkOperationDialogComponent {
146
155
  diag?.category === 'UNEXPECTED_SANITIZED' ||
147
156
  diag?.severity === 'ERROR');
148
157
  }
158
+ getRejectedTotal() {
159
+ const totals = this.execution()?.totals;
160
+ if (!totals)
161
+ return 0;
162
+ return ((totals['denied'] ?? 0) +
163
+ (totals['invalid'] ?? 0) +
164
+ (totals['conflict'] ?? 0) +
165
+ (totals['notProcessed'] ?? 0) +
166
+ (totals['unknown'] ?? 0));
167
+ }
168
+ getExecutionAlertClass() {
169
+ const status = this.execution()?.status;
170
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
171
+ return 'praxis-bulk-dialog__alert--error';
172
+ }
173
+ if (status === 'CANCELLED' || status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
174
+ return 'praxis-bulk-dialog__alert--warning';
175
+ }
176
+ return 'praxis-bulk-dialog__alert--success';
177
+ }
178
+ getExecutionAlertIcon() {
179
+ const status = this.execution()?.status;
180
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
181
+ return 'report_problem';
182
+ }
183
+ if (status === 'CANCELLED') {
184
+ return 'cancel_schedule_send';
185
+ }
186
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
187
+ return 'warning_amber';
188
+ }
189
+ return 'verified';
190
+ }
191
+ getExecutionAlertTitle() {
192
+ const status = this.execution()?.status;
193
+ if (status === 'RECONCILIATION_REQUIRED') {
194
+ return 'Reconciliação necessária';
195
+ }
196
+ if (status === 'STOPPED') {
197
+ return 'Execução interrompida por restrição de lote';
198
+ }
199
+ if (status === 'CANCELLED') {
200
+ return 'Execução cancelada pelo operador';
201
+ }
202
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
203
+ return 'Operação concluída com restrições parciais';
204
+ }
205
+ return 'Operação concluída com êxito!';
206
+ }
207
+ getExecutionAlertMessage() {
208
+ const status = this.execution()?.status;
209
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
210
+ return 'A operação não pôde ser concluída integralmente. Consulte os diagnósticos de governança abaixo.';
211
+ }
212
+ if (status === 'CANCELLED') {
213
+ return 'O processamento do lote foi interrompido. Verifique o resultado por registro abaixo.';
214
+ }
215
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
216
+ return 'Os registros elegíveis foram efetivados; itens com restrição ou conflito foram preservados conforme o diagnóstico abaixo.';
217
+ }
218
+ return 'Transação homologada e registrada na auditoria corporativa.';
219
+ }
149
220
  onEvaluate() {
150
221
  const bulkContract = this.action.execution?.bulk;
151
222
  if (!bulkContract) {
152
223
  this.errorMessage.set('Contrato de operação em lote não encontrado na ação.');
153
224
  return;
154
225
  }
226
+ const maxTargets = bulkContract.limits?.maxTargets;
227
+ if (typeof maxTargets === 'number' && maxTargets > 0 && this.targets.length > maxTargets) {
228
+ this.errorMessage.set(`A seleção atual (${this.targets.length} itens) excede o limite máximo permitido pelo contrato (${maxTargets} itens por lote).`);
229
+ return;
230
+ }
155
231
  this.confirmationIdempotencyKey = undefined;
156
232
  this.step.set('EVALUATING');
157
233
  this.errorMessage.set(null);
@@ -407,7 +483,7 @@ class PraxisBulkOperationDialogComponent {
407
483
  <div class="praxis-bulk-dialog__section">
408
484
  <h3 class="praxis-bulk-dialog__section-title">Parâmetros da Operação</h3>
409
485
  <praxis-dynamic-form
410
- [formId]="'bulk-params-form'"
486
+ [formId]="getParametersFormId()"
411
487
  [schemaUrl]="parametersSchemaUrl()!"
412
488
  [initialValue]="parametersValue()"
413
489
  [resourcePath]="data.resourcePath"
@@ -565,29 +641,48 @@ class PraxisBulkOperationDialogComponent {
565
641
  <!-- Passo 3: Resultado da Execução Concluída -->
566
642
  @if (step() === 'RESULT' && execution()) {
567
643
  <div class="praxis-bulk-dialog__section">
568
- <div class="praxis-bulk-dialog__alert praxis-bulk-dialog__alert--success">
569
- <mat-icon>verified</mat-icon>
644
+ <div class="praxis-bulk-dialog__alert" [ngClass]="getExecutionAlertClass()">
645
+ <mat-icon>{{ getExecutionAlertIcon() }}</mat-icon>
570
646
  <div class="alert-content">
571
- <strong>Operação concluída com êxito!</strong>
572
- <p>Transação homologada e registrada na auditoria corporativa.</p>
647
+ <strong>{{ getExecutionAlertTitle() }}</strong>
648
+ <p>{{ getExecutionAlertMessage() }}</p>
573
649
  </div>
574
650
  </div>
575
651
 
576
652
  <div class="praxis-bulk-dialog__totals-grid">
577
653
  <div class="praxis-bulk-dialog__total-card total-card--executable">
578
654
  <span class="total-label">Efetivados</span>
579
- <span class="total-value">{{ execution()?.totals?.confirmed }}</span>
655
+ <span class="total-value">{{ execution()?.totals?.confirmed ?? 0 }}</span>
580
656
  </div>
581
657
  <div class="praxis-bulk-dialog__total-card">
582
658
  <span class="total-label">Preservados</span>
583
- <span class="total-value">{{ execution()?.totals?.unchanged }}</span>
659
+ <span class="total-value">{{ execution()?.totals?.unchanged ?? 0 }}</span>
584
660
  </div>
585
- <div class="praxis-bulk-dialog__total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
661
+ <div class="praxis-bulk-dialog__total-card" [class.total-card--blocked]="getRejectedTotal() > 0">
586
662
  <span class="total-label">Rejeitados</span>
587
- <span class="total-value">{{ execution()?.totals?.denied }}</span>
663
+ <span class="total-value">{{ getRejectedTotal() }}</span>
588
664
  </div>
589
665
  </div>
590
666
 
667
+ @if (execution()?.diagnostics?.length) {
668
+ <div class="praxis-bulk-dialog__diagnostics">
669
+ <h4 class="diagnostics-title">Diagnósticos de Execução ({{ execution()?.diagnostics?.length }})</h4>
670
+ <div class="diagnostics-list">
671
+ @for (diag of execution()?.diagnostics; track $index) {
672
+ <div class="diagnostic-item" [class.diagnostic-item--error]="isDiagnosticError(diag)">
673
+ <mat-icon>{{ isDiagnosticError(diag) ? 'cancel' : 'info' }}</mat-icon>
674
+ <div class="diagnostic-text">
675
+ @if (diag.target != null) {
676
+ <span class="diagnostic-target">Item {{ diag.target }}:</span>
677
+ }
678
+ <span>{{ diag.message }}</span>
679
+ </div>
680
+ </div>
681
+ }
682
+ </div>
683
+ </div>
684
+ }
685
+
591
686
  @if (executionItems().length > 0) {
592
687
  <div class="praxis-bulk-dialog__diagnostics">
593
688
  <h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
@@ -660,7 +755,7 @@ class PraxisBulkOperationDialogComponent {
660
755
  }
661
756
  </div>
662
757
  </div>
663
- `, isInline: true, styles: [".cdk-global-overlay-wrapper:has(.praxis-bulk-dialog-panel){display:flex!important;justify-content:center!important;align-items:center!important;padding:24px!important;box-sizing:border-box!important}.cdk-overlay-pane.praxis-bulk-dialog-panel{--mat-dialog-container-color: var(--card, var(--praxis-color-surface, #1e293b)) !important;--mdc-dialog-container-color: var(--card, var(--praxis-color-surface, #1e293b)) !important;--mat-dialog-container-shape: 16px;position:relative!important;inset:auto!important;margin:auto!important;display:flex!important;justify-content:center!important;align-items:center!important}.cdk-overlay-pane.praxis-bulk-dialog-panel .mat-mdc-dialog-surface{border-radius:16px;border:1px solid var(--border, var(--praxis-border-subtle, rgba(148, 163, 184, .2)));box-shadow:0 24px 64px #0000008c;background-color:var(--card, var(--praxis-color-surface, #1e293b))!important;color:var(--foreground, #f8fafc)!important;overflow:hidden;width:100%}.praxis-bulk-dialog{display:flex;flex-direction:column;max-height:85vh;width:100%;min-width:600px;max-width:680px;margin:0 auto;color:var(--foreground, var(--praxis-text-primary, #f8fafc));background:transparent;box-sizing:border-box}.praxis-bulk-dialog__header{display:flex;justify-content:space-between;align-items:flex-start;padding:22px 26px 18px;border-bottom:1px solid var(--border, rgba(148, 163, 184, .15))}.praxis-bulk-dialog__title-group{display:flex;align-items:flex-start;gap:14px}.praxis-bulk-dialog__header-icon{color:var(--primary, var(--praxis-primary, #0284c7));font-size:28px;width:28px;height:28px;margin-top:2px}.praxis-bulk-dialog__title{font-size:1.25rem;font-weight:600;margin:0;line-height:1.3;color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__subtitle{font-size:.875rem;color:var(--muted-foreground, rgba(148, 163, 184, .85));margin:4px 0 0;line-height:1.45}.praxis-bulk-dialog__content{padding:22px 26px;overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:20px}.praxis-bulk-dialog__targets-badge{display:inline-flex;align-items:center;gap:10px;padding:10px 16px;background:color-mix(in srgb,var(--foreground, #f8fafc) 6%,var(--card, #1e293b));border:1px solid var(--border, rgba(148, 163, 184, .2));border-radius:10px;font-size:.875rem;color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__targets-badge mat-icon{font-size:18px;width:18px;height:18px;color:var(--primary, var(--praxis-primary, #0284c7))}.praxis-bulk-dialog__section{display:flex;flex-direction:column;gap:20px}.praxis-bulk-dialog__section-title{font-size:1rem;font-weight:600;margin:0;color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__totals-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:4px 0 12px}.praxis-bulk-dialog__total-card{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:104px;padding:20px 22px;background:color-mix(in srgb,var(--foreground, #f8fafc) 6%,var(--card, #1e293b));border:1px solid var(--border, rgba(148, 163, 184, .2));border-radius:14px;transition:background .2s ease,border-color .2s ease;box-sizing:border-box;gap:8px}.praxis-bulk-dialog__total-card .total-label{font-size:.8125rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted-foreground, rgba(148, 163, 184, .85));font-weight:600;margin-bottom:2px}.praxis-bulk-dialog__total-card .total-value{font-size:2rem;font-weight:700;color:var(--foreground, #f8fafc);line-height:1;margin:0;letter-spacing:-.02em}.total-card--executable{border-color:color-mix(in srgb,var(--praxis-success, #10b981) 50%,transparent)!important;background:color-mix(in srgb,var(--praxis-success, #10b981) 16%,var(--card, #1e293b))!important}.total-card--executable .total-value{color:var(--praxis-success, #10b981)}.total-card--blocked{border-color:color-mix(in srgb,var(--praxis-error, #ef4444) 50%,transparent)!important;background:color-mix(in srgb,var(--praxis-error, #ef4444) 16%,var(--card, #1e293b))!important}.total-card--blocked .total-value{color:var(--praxis-error, #ef4444)}.praxis-bulk-dialog__alert{display:flex;align-items:flex-start;gap:14px;padding:18px 22px;border-radius:12px;font-size:.875rem;line-height:1.5}.praxis-bulk-dialog__alert mat-icon{font-size:22px;width:22px;height:22px;flex-shrink:0;margin-top:1px}.praxis-bulk-dialog__alert .alert-content{display:flex;flex-direction:column;gap:4px}.praxis-bulk-dialog__alert .alert-content strong{font-size:.9375rem;font-weight:600;color:inherit}.praxis-bulk-dialog__alert .alert-content p{margin:0;font-size:.8125rem;opacity:.9}.praxis-bulk-dialog__alert--error{background:color-mix(in srgb,var(--praxis-error, #ef4444) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-error, #ef4444) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__alert--error mat-icon{color:var(--praxis-error, #ef4444)}.praxis-bulk-dialog__alert--warning{background:color-mix(in srgb,var(--praxis-warning, #d97706) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-warning, #d97706) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__alert--warning mat-icon{color:var(--praxis-warning, #d97706)}.praxis-bulk-dialog__alert--success{background:color-mix(in srgb,var(--praxis-success, #10b981) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-success, #10b981) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__alert--success mat-icon{color:var(--praxis-success, #10b981)}.praxis-bulk-dialog__notice-box{display:flex;align-items:center;gap:12px;padding:16px 20px;background:color-mix(in srgb,var(--praxis-info, #0284c7) 14%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-info, #0284c7) 40%,transparent);border-radius:10px;color:var(--foreground, #f8fafc);font-size:.875rem}.praxis-bulk-dialog__notice-box mat-icon{color:var(--praxis-info, #0284c7)}.praxis-bulk-dialog__diagnostics{margin-top:12px;border:1px solid var(--border, rgba(148, 163, 184, .2));border-radius:10px;padding:14px 18px;background:color-mix(in srgb,var(--foreground, #f8fafc) 4%,var(--card, #1e293b))}.diagnostics-title{font-size:.875rem;font-weight:600;margin:0 0 8px;color:var(--praxis-text-primary, var(--foreground, inherit))}.diagnostics-list{display:flex;flex-direction:column;gap:6px;max-height:160px;overflow-y:auto}.diagnostic-item{display:flex;align-items:center;gap:8px;font-size:.8125rem;color:var(--praxis-text-muted, var(--muted-foreground, inherit))}.diagnostic-item mat-icon{font-size:16px;width:16px;height:16px;color:var(--praxis-primary, var(--primary, var(--md-sys-color-primary, #0284c7)))}.diagnostic-item--error{color:var(--praxis-error, #dc2626)}.diagnostic-item--error mat-icon{color:var(--praxis-error, #dc2626)}.diagnostic-target{font-weight:600;margin-right:4px;color:var(--praxis-text-primary, var(--foreground, inherit))}.praxis-bulk-dialog__loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;gap:16px;color:var(--praxis-text-muted, var(--muted-foreground, inherit));font-size:.9375rem}.praxis-bulk-dialog__actions{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding:16px 24px 20px;border-top:1px solid var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "emptyState", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "submitResourceVersionTargetResourceKey", "submitResourceVersionTargetIdField", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "layoutMode", "formLayout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "presentation", "presentationPreset", "sectionDefaultAppearance", "sectionDivider", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "payloadPreviewChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange", "reactiveDeterminationExecuted", "reactiveDeterminationPendingChange", "tabChange", "tabSelected"] }], encapsulation: i0.ViewEncapsulation.None });
758
+ `, isInline: true, styles: [".cdk-global-overlay-wrapper:has(.praxis-bulk-dialog-panel){display:flex!important;justify-content:center!important;align-items:center!important;padding:24px!important;box-sizing:border-box!important}.cdk-overlay-pane.praxis-bulk-dialog-panel{--mat-dialog-container-color: var(--card, var(--praxis-color-surface, #1e293b)) !important;--mdc-dialog-container-color: var(--card, var(--praxis-color-surface, #1e293b)) !important;--mat-dialog-container-shape: 16px;position:relative!important;inset:auto!important;margin:auto!important;display:flex!important;justify-content:center!important;align-items:center!important}.cdk-overlay-pane.praxis-bulk-dialog-panel .mat-mdc-dialog-surface{border-radius:16px;border:1px solid var(--border, var(--praxis-border-subtle, rgba(148, 163, 184, .2)));box-shadow:0 24px 64px #0000008c;background-color:var(--card, var(--praxis-color-surface, #1e293b))!important;color:var(--foreground, #f8fafc)!important;overflow:hidden;width:100%}.praxis-bulk-dialog{display:flex;flex-direction:column;max-height:85vh;width:100%;min-width:600px;max-width:680px;margin:0 auto;color:var(--foreground, var(--praxis-text-primary, #f8fafc));background:transparent;box-sizing:border-box}.praxis-bulk-dialog__header{display:flex;justify-content:space-between;align-items:flex-start;padding:22px 26px 18px;border-bottom:1px solid var(--border, rgba(148, 163, 184, .15))}.praxis-bulk-dialog__title-group{display:flex;align-items:flex-start;gap:14px}.praxis-bulk-dialog__header-icon{color:var(--primary, var(--praxis-primary, #0284c7));font-size:28px;width:28px;height:28px;margin-top:2px}.praxis-bulk-dialog__title{font-size:1.25rem;font-weight:600;margin:0;line-height:1.3;color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__subtitle{font-size:.875rem;color:var(--muted-foreground, rgba(148, 163, 184, .85));margin:4px 0 0;line-height:1.45}.praxis-bulk-dialog__content{padding:22px 26px;overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:20px}.praxis-bulk-dialog__targets-badge{display:inline-flex;align-items:center;gap:10px;padding:10px 16px;background:color-mix(in srgb,var(--foreground, #f8fafc) 6%,var(--card, #1e293b));border:1px solid var(--border, rgba(148, 163, 184, .2));border-radius:10px;font-size:.875rem;color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__targets-badge mat-icon{font-size:18px;width:18px;height:18px;color:var(--primary, var(--praxis-primary, #0284c7))}.praxis-bulk-dialog__section{display:flex;flex-direction:column;gap:20px}.praxis-bulk-dialog__section-title{font-size:1rem;font-weight:600;margin:0;color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__totals-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:4px 0 12px}.praxis-bulk-dialog__total-card{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:104px;padding:20px 22px;background:color-mix(in srgb,var(--foreground, #f8fafc) 6%,var(--card, #1e293b));border:1px solid var(--border, rgba(148, 163, 184, .2));border-radius:14px;transition:background .2s ease,border-color .2s ease;box-sizing:border-box;gap:8px}.praxis-bulk-dialog__total-card .total-label{font-size:.8125rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted-foreground, rgba(148, 163, 184, .85));font-weight:600;margin-bottom:2px}.praxis-bulk-dialog__total-card .total-value{font-size:2rem;font-weight:700;color:var(--foreground, #f8fafc);line-height:1;margin:0;letter-spacing:-.02em}.total-card--executable{border-color:color-mix(in srgb,var(--praxis-success, #10b981) 50%,transparent)!important;background:color-mix(in srgb,var(--praxis-success, #10b981) 16%,var(--card, #1e293b))!important}.total-card--executable .total-value{color:var(--praxis-success, #10b981)}.total-card--blocked{border-color:color-mix(in srgb,var(--praxis-error, #ef4444) 50%,transparent)!important;background:color-mix(in srgb,var(--praxis-error, #ef4444) 16%,var(--card, #1e293b))!important}.total-card--blocked .total-value{color:var(--praxis-error, #ef4444)}.praxis-bulk-dialog__alert{display:flex;align-items:flex-start;gap:14px;padding:18px 22px;border-radius:12px;font-size:.875rem;line-height:1.5}.praxis-bulk-dialog__alert mat-icon{font-size:22px;width:22px;height:22px;flex-shrink:0;margin-top:1px}.praxis-bulk-dialog__alert .alert-content{display:flex;flex-direction:column;gap:4px}.praxis-bulk-dialog__alert .alert-content strong{font-size:.9375rem;font-weight:600;color:inherit}.praxis-bulk-dialog__alert .alert-content p{margin:0;font-size:.8125rem;opacity:.9}.praxis-bulk-dialog__alert--error{background:color-mix(in srgb,var(--praxis-error, #ef4444) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-error, #ef4444) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__alert--error mat-icon{color:var(--praxis-error, #ef4444)}.praxis-bulk-dialog__alert--warning{background:color-mix(in srgb,var(--praxis-warning, #d97706) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-warning, #d97706) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__alert--warning mat-icon{color:var(--praxis-warning, #d97706)}.praxis-bulk-dialog__alert--success{background:color-mix(in srgb,var(--praxis-success, #10b981) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-success, #10b981) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-dialog__alert--success mat-icon{color:var(--praxis-success, #10b981)}.praxis-bulk-dialog__notice-box{display:flex;align-items:center;gap:12px;padding:16px 20px;background:color-mix(in srgb,var(--praxis-info, #0284c7) 14%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-info, #0284c7) 40%,transparent);border-radius:10px;color:var(--foreground, #f8fafc);font-size:.875rem}.praxis-bulk-dialog__notice-box mat-icon{color:var(--praxis-info, #0284c7)}.praxis-bulk-dialog__diagnostics{margin-top:12px;border:1px solid var(--border, rgba(148, 163, 184, .2));border-radius:10px;padding:14px 18px;background:color-mix(in srgb,var(--foreground, #f8fafc) 4%,var(--card, #1e293b))}.diagnostics-title{font-size:.875rem;font-weight:600;margin:0 0 8px;color:var(--praxis-text-primary, var(--foreground, inherit))}.diagnostics-list{display:flex;flex-direction:column;gap:6px;max-height:160px;overflow-y:auto}.diagnostic-item{display:flex;align-items:center;gap:8px;font-size:.8125rem;color:var(--praxis-text-muted, var(--muted-foreground, inherit))}.diagnostic-item mat-icon{font-size:16px;width:16px;height:16px;color:var(--praxis-primary, var(--primary, var(--md-sys-color-primary, #0284c7)))}.diagnostic-item--error{color:var(--praxis-error, #dc2626)}.diagnostic-item--error mat-icon{color:var(--praxis-error, #dc2626)}.diagnostic-target{font-weight:600;margin-right:4px;color:var(--praxis-text-primary, var(--foreground, inherit))}.praxis-bulk-dialog__loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;gap:16px;color:var(--praxis-text-muted, var(--muted-foreground, inherit));font-size:.9375rem}.praxis-bulk-dialog__actions{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding:16px 24px 20px;border-top:1px solid var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i4$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "emptyState", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "submitResourceVersionTargetResourceKey", "submitResourceVersionTargetIdField", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "layoutMode", "formLayout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "presentation", "presentationPreset", "sectionDefaultAppearance", "sectionDivider", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "payloadPreviewChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange", "reactiveDeterminationExecuted", "reactiveDeterminationPendingChange", "tabChange", "tabSelected"] }], encapsulation: i0.ViewEncapsulation.None });
664
759
  }
665
760
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisBulkOperationDialogComponent, decorators: [{
666
761
  type: Component,
@@ -705,7 +800,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
705
800
  <div class="praxis-bulk-dialog__section">
706
801
  <h3 class="praxis-bulk-dialog__section-title">Parâmetros da Operação</h3>
707
802
  <praxis-dynamic-form
708
- [formId]="'bulk-params-form'"
803
+ [formId]="getParametersFormId()"
709
804
  [schemaUrl]="parametersSchemaUrl()!"
710
805
  [initialValue]="parametersValue()"
711
806
  [resourcePath]="data.resourcePath"
@@ -863,29 +958,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
863
958
  <!-- Passo 3: Resultado da Execução Concluída -->
864
959
  @if (step() === 'RESULT' && execution()) {
865
960
  <div class="praxis-bulk-dialog__section">
866
- <div class="praxis-bulk-dialog__alert praxis-bulk-dialog__alert--success">
867
- <mat-icon>verified</mat-icon>
961
+ <div class="praxis-bulk-dialog__alert" [ngClass]="getExecutionAlertClass()">
962
+ <mat-icon>{{ getExecutionAlertIcon() }}</mat-icon>
868
963
  <div class="alert-content">
869
- <strong>Operação concluída com êxito!</strong>
870
- <p>Transação homologada e registrada na auditoria corporativa.</p>
964
+ <strong>{{ getExecutionAlertTitle() }}</strong>
965
+ <p>{{ getExecutionAlertMessage() }}</p>
871
966
  </div>
872
967
  </div>
873
968
 
874
969
  <div class="praxis-bulk-dialog__totals-grid">
875
970
  <div class="praxis-bulk-dialog__total-card total-card--executable">
876
971
  <span class="total-label">Efetivados</span>
877
- <span class="total-value">{{ execution()?.totals?.confirmed }}</span>
972
+ <span class="total-value">{{ execution()?.totals?.confirmed ?? 0 }}</span>
878
973
  </div>
879
974
  <div class="praxis-bulk-dialog__total-card">
880
975
  <span class="total-label">Preservados</span>
881
- <span class="total-value">{{ execution()?.totals?.unchanged }}</span>
976
+ <span class="total-value">{{ execution()?.totals?.unchanged ?? 0 }}</span>
882
977
  </div>
883
- <div class="praxis-bulk-dialog__total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
978
+ <div class="praxis-bulk-dialog__total-card" [class.total-card--blocked]="getRejectedTotal() > 0">
884
979
  <span class="total-label">Rejeitados</span>
885
- <span class="total-value">{{ execution()?.totals?.denied }}</span>
980
+ <span class="total-value">{{ getRejectedTotal() }}</span>
886
981
  </div>
887
982
  </div>
888
983
 
984
+ @if (execution()?.diagnostics?.length) {
985
+ <div class="praxis-bulk-dialog__diagnostics">
986
+ <h4 class="diagnostics-title">Diagnósticos de Execução ({{ execution()?.diagnostics?.length }})</h4>
987
+ <div class="diagnostics-list">
988
+ @for (diag of execution()?.diagnostics; track $index) {
989
+ <div class="diagnostic-item" [class.diagnostic-item--error]="isDiagnosticError(diag)">
990
+ <mat-icon>{{ isDiagnosticError(diag) ? 'cancel' : 'info' }}</mat-icon>
991
+ <div class="diagnostic-text">
992
+ @if (diag.target != null) {
993
+ <span class="diagnostic-target">Item {{ diag.target }}:</span>
994
+ }
995
+ <span>{{ diag.message }}</span>
996
+ </div>
997
+ </div>
998
+ }
999
+ </div>
1000
+ </div>
1001
+ }
1002
+
889
1003
  @if (executionItems().length > 0) {
890
1004
  <div class="praxis-bulk-dialog__diagnostics">
891
1005
  <h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
@@ -1234,7 +1348,74 @@ class PraxisBulkEditDialogComponent {
1234
1348
  diag?.category === 'UNEXPECTED_SANITIZED' ||
1235
1349
  diag?.severity === 'ERROR');
1236
1350
  }
1351
+ getRejectedTotal() {
1352
+ const totals = this.execution()?.totals;
1353
+ if (!totals)
1354
+ return 0;
1355
+ return ((totals['denied'] ?? 0) +
1356
+ (totals['invalid'] ?? 0) +
1357
+ (totals['conflict'] ?? 0) +
1358
+ (totals['notProcessed'] ?? 0) +
1359
+ (totals['unknown'] ?? 0));
1360
+ }
1361
+ getExecutionAlertClass() {
1362
+ const status = this.execution()?.status;
1363
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
1364
+ return 'praxis-bulk-edit-dialog__alert--error';
1365
+ }
1366
+ if (status === 'CANCELLED' || status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
1367
+ return 'praxis-bulk-edit-dialog__alert--warning';
1368
+ }
1369
+ return 'praxis-bulk-edit-dialog__alert--success';
1370
+ }
1371
+ getExecutionAlertIcon() {
1372
+ const status = this.execution()?.status;
1373
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
1374
+ return 'report_problem';
1375
+ }
1376
+ if (status === 'CANCELLED') {
1377
+ return 'cancel_schedule_send';
1378
+ }
1379
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
1380
+ return 'warning_amber';
1381
+ }
1382
+ return 'verified';
1383
+ }
1384
+ getExecutionAlertTitle() {
1385
+ const status = this.execution()?.status;
1386
+ if (status === 'RECONCILIATION_REQUIRED') {
1387
+ return 'Reconciliação necessária';
1388
+ }
1389
+ if (status === 'STOPPED') {
1390
+ return 'Execução interrompida por restrição de lote';
1391
+ }
1392
+ if (status === 'CANCELLED') {
1393
+ return 'Execução cancelada pelo operador';
1394
+ }
1395
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
1396
+ return 'Atualização concluída com restrições parciais';
1397
+ }
1398
+ return 'Atualização concluída com êxito!';
1399
+ }
1400
+ getExecutionAlertMessage() {
1401
+ const status = this.execution()?.status;
1402
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
1403
+ return 'A atualização não pôde ser concluída integralmente. Consulte os diagnósticos de governança abaixo.';
1404
+ }
1405
+ if (status === 'CANCELLED') {
1406
+ return 'O processamento do lote foi interrompido. Verifique o resultado por registro abaixo.';
1407
+ }
1408
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
1409
+ return 'Os registros elegíveis foram efetivados; itens com restrição ou conflito foram preservados conforme o diagnóstico abaixo.';
1410
+ }
1411
+ return 'Transação homologada e registrada na auditoria corporativa.';
1412
+ }
1237
1413
  onEvaluate() {
1414
+ const maxTargets = this.contract?.limits?.maxTargets;
1415
+ if (typeof maxTargets === 'number' && maxTargets > 0 && this.targets.length > maxTargets) {
1416
+ this.errorMessage.set(`A seleção atual (${this.targets.length} registros) excede o limite máximo permitido pelo contrato (${maxTargets} registros por lote).`);
1417
+ return;
1418
+ }
1238
1419
  for (const r of this.fieldRows()) {
1239
1420
  if (!r.field)
1240
1421
  continue;
@@ -1775,29 +1956,46 @@ class PraxisBulkEditDialogComponent {
1775
1956
  <!-- Resultado -->
1776
1957
  @if (step() === 'RESULT' && execution()) {
1777
1958
  <div class="praxis-bulk-edit-dialog__section">
1778
- <div class="praxis-bulk-edit-dialog__alert praxis-bulk-edit-dialog__alert--success">
1779
- <mat-icon>verified</mat-icon>
1959
+ <div class="praxis-bulk-edit-dialog__alert" [ngClass]="getExecutionAlertClass()">
1960
+ <mat-icon>{{ getExecutionAlertIcon() }}</mat-icon>
1780
1961
  <div class="alert-content">
1781
- <strong>Atualização concluída com êxito!</strong>
1782
- <p>Transação homologada e registrada na auditoria corporativa.</p>
1962
+ <strong>{{ getExecutionAlertTitle() }}</strong>
1963
+ <p>{{ getExecutionAlertMessage() }}</p>
1783
1964
  </div>
1784
1965
  </div>
1785
1966
 
1786
1967
  <div class="praxis-bulk-edit-dialog__totals-grid">
1787
1968
  <div class="total-card total-card--executable">
1788
1969
  <span class="total-label">Efetivados</span>
1789
- <span class="total-value">{{ execution()?.totals?.confirmed }}</span>
1970
+ <span class="total-value">{{ execution()?.totals?.confirmed ?? 0 }}</span>
1790
1971
  </div>
1791
1972
  <div class="total-card">
1792
1973
  <span class="total-label">Preservados</span>
1793
- <span class="total-value">{{ execution()?.totals?.unchanged }}</span>
1974
+ <span class="total-value">{{ execution()?.totals?.unchanged ?? 0 }}</span>
1794
1975
  </div>
1795
- <div class="total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
1976
+ <div class="total-card" [class.total-card--blocked]="getRejectedTotal() > 0">
1796
1977
  <span class="total-label">Rejeitados</span>
1797
- <span class="total-value">{{ execution()?.totals?.denied }}</span>
1978
+ <span class="total-value">{{ getRejectedTotal() }}</span>
1798
1979
  </div>
1799
1980
  </div>
1800
1981
 
1982
+ @if (execution()?.diagnostics?.length) {
1983
+ <div class="praxis-bulk-edit-dialog__diagnostics">
1984
+ <h4 class="diagnostics-title">Diagnósticos de Execução ({{ execution()?.diagnostics?.length }})</h4>
1985
+ @for (diag of execution()?.diagnostics; track $index) {
1986
+ <div class="diagnostic-item" [class.diagnostic-item--error]="isDiagnosticError(diag)">
1987
+ <mat-icon>{{ isDiagnosticError(diag) ? 'cancel' : 'info' }}</mat-icon>
1988
+ <div class="diagnostic-content">
1989
+ @if (diag.target != null) {
1990
+ <span class="diagnostic-target">Registro #{{ diag.target }}:</span>
1991
+ }
1992
+ <span class="diagnostic-message">{{ diag.message }}</span>
1993
+ </div>
1994
+ </div>
1995
+ }
1996
+ </div>
1997
+ }
1998
+
1801
1999
  @if (executionItems().length > 0) {
1802
2000
  <div class="praxis-bulk-edit-dialog__diagnostics">
1803
2001
  <h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
@@ -1868,7 +2066,7 @@ class PraxisBulkEditDialogComponent {
1868
2066
  }
1869
2067
  </div>
1870
2068
  </div>
1871
- `, isInline: true, styles: [".cdk-global-overlay-wrapper:has(.praxis-bulk-dialog-panel){display:flex!important;justify-content:center!important;align-items:center!important;padding:24px!important;box-sizing:border-box!important}.cdk-overlay-pane.praxis-bulk-dialog-panel{--mat-dialog-container-color: var(--card, var(--praxis-color-surface, #1e293b)) !important;--mdc-dialog-container-color: var(--card, var(--praxis-color-surface, #1e293b)) !important;--mat-dialog-container-shape: 16px;position:relative!important;inset:auto!important;margin:auto!important;display:flex!important;justify-content:center!important;align-items:center!important}.cdk-overlay-pane.praxis-bulk-dialog-panel .mat-mdc-dialog-surface{border-radius:16px;border:1px solid var(--border, var(--praxis-border-subtle, rgba(148, 163, 184, .2)));box-shadow:0 24px 64px #0000008c;background-color:var(--card, var(--praxis-color-surface, #1e293b))!important;color:var(--foreground, #f8fafc)!important;overflow:hidden;width:100%}.praxis-bulk-edit-dialog{display:flex;flex-direction:column;max-height:85vh;width:100%;min-width:600px;max-width:680px;margin:0 auto;color:var(--foreground, var(--praxis-text-primary, #f8fafc));background:transparent;box-sizing:border-box}.praxis-bulk-edit-dialog__header{display:flex;justify-content:space-between;align-items:flex-start;padding:22px 26px 18px;border-bottom:1px solid var(--border, rgba(148, 163, 184, .15))}.praxis-bulk-edit-dialog__title-group{display:flex;align-items:flex-start;gap:14px}.praxis-bulk-edit-dialog__header-icon{color:var(--primary, var(--praxis-primary, #0284c7));font-size:28px;width:28px;height:28px;margin-top:2px}.praxis-bulk-edit-dialog__title{font-size:1.25rem;font-weight:600;margin:0;line-height:1.3;color:var(--foreground, #f8fafc)}.praxis-bulk-edit-dialog__subtitle{font-size:.875rem;color:var(--muted-foreground, rgba(148, 163, 184, .85));margin:4px 0 0;line-height:1.45}.praxis-bulk-edit-dialog__content{padding:22px 26px;overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:20px}.praxis-bulk-edit-dialog__targets-badge{display:inline-flex;align-items:center;gap:10px;padding:10px 16px;background:color-mix(in srgb,var(--foreground, #f8fafc) 6%,var(--card, #1e293b));border:1px solid var(--border, rgba(148, 163, 184, .2));border-radius:10px;font-size:.875rem;color:var(--foreground, #f8fafc)}.praxis-bulk-edit-dialog__targets-badge mat-icon{font-size:18px;width:18px;height:18px;color:var(--primary, var(--praxis-primary, #0284c7))}.section-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.section-title{font-size:1rem;font-weight:600;margin:0;color:var(--praxis-text-primary, var(--foreground, var(--md-sys-color-on-surface, inherit)))}.praxis-bulk-edit-dialog__empty-box{display:flex;flex-direction:column;align-items:center;padding:32px 16px;background:color-mix(in srgb,var(--praxis-text-primary, var(--foreground, currentColor)) 2%,transparent);border:1px dashed var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .25))));border-radius:8px;color:var(--praxis-text-muted, var(--muted-foreground, var(--md-sys-color-on-surface-variant, inherit)));gap:8px}.praxis-bulk-edit-dialog__empty-box mat-icon{font-size:32px;width:32px;height:32px;color:var(--praxis-text-muted, var(--muted-foreground, inherit))}.field-rows-container{display:flex;flex-direction:column;gap:12px}.field-row{display:flex;align-items:center;gap:12px}.field-select{flex:1.3}.field-tech-name{font-size:.75rem;color:var(--praxis-text-muted, var(--muted-foreground, inherit));margin-left:6px;opacity:.75}.operator-select{flex:.9}.value-input{flex:1.4}.clear-notice{flex:1.4;display:flex;align-items:center;gap:8px;font-size:.8125rem;color:var(--praxis-warning, #d97706);background:color-mix(in srgb,var(--praxis-warning, #d97706) 12%,transparent);border:1px solid color-mix(in srgb,var(--praxis-warning, #d97706) 30%,transparent);padding:8px 12px;border-radius:6px}.clear-notice mat-icon{font-size:16px;width:16px;height:16px}.praxis-bulk-edit-dialog__section{display:flex;flex-direction:column;gap:20px}.praxis-bulk-edit-dialog__totals-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:4px 0 12px}.total-card{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:104px;padding:20px 22px;background:color-mix(in srgb,var(--foreground, #f8fafc) 6%,var(--card, #1e293b));border:1px solid var(--border, rgba(148, 163, 184, .2));border-radius:14px;transition:background .2s ease,border-color .2s ease;box-sizing:border-box;gap:8px}.total-card .total-label{font-size:.8125rem;text-transform:uppercase;letter-spacing:.05em;font-weight:600;color:var(--muted-foreground, rgba(148, 163, 184, .85));margin-bottom:2px}.total-card .total-value{font-size:2rem;font-weight:700;color:var(--foreground, #f8fafc);line-height:1;margin:0;letter-spacing:-.02em}.total-card--executable{border-color:color-mix(in srgb,var(--praxis-success, #10b981) 50%,transparent)!important;background:color-mix(in srgb,var(--praxis-success, #10b981) 16%,var(--card, #1e293b))!important}.total-card--executable .total-value{color:var(--praxis-success, #10b981)}.total-card--blocked{border-color:color-mix(in srgb,var(--praxis-error, #ef4444) 50%,transparent)!important;background:color-mix(in srgb,var(--praxis-error, #ef4444) 16%,var(--card, #1e293b))!important}.total-card--blocked .total-value{color:var(--praxis-error, #ef4444)}.praxis-bulk-edit-dialog__alert{display:flex;align-items:flex-start;gap:14px;padding:18px 22px;border-radius:12px;font-size:.875rem;line-height:1.5}.praxis-bulk-edit-dialog__alert mat-icon{font-size:22px;width:22px;height:22px;flex-shrink:0;margin-top:1px}.praxis-bulk-edit-dialog__alert .alert-content{display:flex;flex-direction:column;gap:4px}.praxis-bulk-edit-dialog__alert .alert-content strong{font-size:.9375rem;font-weight:600;color:inherit}.praxis-bulk-edit-dialog__alert .alert-content p{margin:0;font-size:.8125rem;opacity:.9}.praxis-bulk-edit-dialog__alert--error{background:color-mix(in srgb,var(--praxis-error, #ef4444) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-error, #ef4444) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-edit-dialog__alert--error mat-icon{color:var(--praxis-error, #ef4444)}.praxis-bulk-edit-dialog__alert--warning{background:color-mix(in srgb,var(--praxis-warning, #d97706) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-warning, #d97706) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-edit-dialog__alert--warning mat-icon{color:var(--praxis-warning, #d97706)}.praxis-bulk-edit-dialog__alert--success{background:color-mix(in srgb,var(--praxis-success, #10b981) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-success, #10b981) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-edit-dialog__alert--success mat-icon{color:var(--praxis-success, #10b981)}.praxis-bulk-edit-dialog__diagnostics{margin-top:12px;padding:12px 16px;background:color-mix(in srgb,var(--praxis-text-primary, var(--foreground, currentColor)) 3%,transparent);border:1px solid var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))));border-radius:8px;display:flex;flex-direction:column;gap:8px}.diagnostics-title{font-size:.875rem;font-weight:600;margin:0 0 4px;color:var(--praxis-text-primary, var(--foreground, inherit))}.diagnostic-item{display:flex;align-items:flex-start;gap:8px;font-size:.8125rem;color:var(--praxis-text-muted, var(--muted-foreground, inherit))}.diagnostic-item mat-icon{font-size:16px;width:16px;height:16px;margin-top:2px;flex-shrink:0;color:var(--praxis-primary, var(--primary, var(--md-sys-color-primary, #0284c7)))}.diagnostic-item--error{color:var(--praxis-error, #ef4444)}.diagnostic-item--error mat-icon{color:var(--praxis-error, #ef4444)}.diagnostic-content{display:flex;flex-wrap:wrap;gap:4px}.diagnostic-target{font-weight:600;color:var(--praxis-text-primary, var(--foreground, inherit))}.praxis-bulk-edit-dialog__loading{display:flex;flex-direction:column;align-items:center;padding:40px;gap:16px;color:var(--praxis-text-muted, var(--muted-foreground, inherit))}.praxis-bulk-edit-dialog__actions{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding:18px 24px 22px;border-top:1px solid var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.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: MatFormFieldModule }], encapsulation: i0.ViewEncapsulation.None });
2069
+ `, isInline: true, styles: [".cdk-global-overlay-wrapper:has(.praxis-bulk-dialog-panel){display:flex!important;justify-content:center!important;align-items:center!important;padding:24px!important;box-sizing:border-box!important}.cdk-overlay-pane.praxis-bulk-dialog-panel{--mat-dialog-container-color: var(--card, var(--praxis-color-surface, #1e293b)) !important;--mdc-dialog-container-color: var(--card, var(--praxis-color-surface, #1e293b)) !important;--mat-dialog-container-shape: 16px;position:relative!important;inset:auto!important;margin:auto!important;display:flex!important;justify-content:center!important;align-items:center!important}.cdk-overlay-pane.praxis-bulk-dialog-panel .mat-mdc-dialog-surface{border-radius:16px;border:1px solid var(--border, var(--praxis-border-subtle, rgba(148, 163, 184, .2)));box-shadow:0 24px 64px #0000008c;background-color:var(--card, var(--praxis-color-surface, #1e293b))!important;color:var(--foreground, #f8fafc)!important;overflow:hidden;width:100%}.praxis-bulk-edit-dialog{display:flex;flex-direction:column;max-height:85vh;width:100%;min-width:600px;max-width:680px;margin:0 auto;color:var(--foreground, var(--praxis-text-primary, #f8fafc));background:transparent;box-sizing:border-box}.praxis-bulk-edit-dialog__header{display:flex;justify-content:space-between;align-items:flex-start;padding:22px 26px 18px;border-bottom:1px solid var(--border, rgba(148, 163, 184, .15))}.praxis-bulk-edit-dialog__title-group{display:flex;align-items:flex-start;gap:14px}.praxis-bulk-edit-dialog__header-icon{color:var(--primary, var(--praxis-primary, #0284c7));font-size:28px;width:28px;height:28px;margin-top:2px}.praxis-bulk-edit-dialog__title{font-size:1.25rem;font-weight:600;margin:0;line-height:1.3;color:var(--foreground, #f8fafc)}.praxis-bulk-edit-dialog__subtitle{font-size:.875rem;color:var(--muted-foreground, rgba(148, 163, 184, .85));margin:4px 0 0;line-height:1.45}.praxis-bulk-edit-dialog__content{padding:22px 26px;overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:20px}.praxis-bulk-edit-dialog__targets-badge{display:inline-flex;align-items:center;gap:10px;padding:10px 16px;background:color-mix(in srgb,var(--foreground, #f8fafc) 6%,var(--card, #1e293b));border:1px solid var(--border, rgba(148, 163, 184, .2));border-radius:10px;font-size:.875rem;color:var(--foreground, #f8fafc)}.praxis-bulk-edit-dialog__targets-badge mat-icon{font-size:18px;width:18px;height:18px;color:var(--primary, var(--praxis-primary, #0284c7))}.section-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.section-title{font-size:1rem;font-weight:600;margin:0;color:var(--praxis-text-primary, var(--foreground, var(--md-sys-color-on-surface, inherit)))}.praxis-bulk-edit-dialog__empty-box{display:flex;flex-direction:column;align-items:center;padding:32px 16px;background:color-mix(in srgb,var(--praxis-text-primary, var(--foreground, currentColor)) 2%,transparent);border:1px dashed var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .25))));border-radius:8px;color:var(--praxis-text-muted, var(--muted-foreground, var(--md-sys-color-on-surface-variant, inherit)));gap:8px}.praxis-bulk-edit-dialog__empty-box mat-icon{font-size:32px;width:32px;height:32px;color:var(--praxis-text-muted, var(--muted-foreground, inherit))}.field-rows-container{display:flex;flex-direction:column;gap:12px}.field-row{display:flex;align-items:center;gap:12px}.field-select{flex:1.3}.field-tech-name{font-size:.75rem;color:var(--praxis-text-muted, var(--muted-foreground, inherit));margin-left:6px;opacity:.75}.operator-select{flex:.9}.value-input{flex:1.4}.clear-notice{flex:1.4;display:flex;align-items:center;gap:8px;font-size:.8125rem;color:var(--praxis-warning, #d97706);background:color-mix(in srgb,var(--praxis-warning, #d97706) 12%,transparent);border:1px solid color-mix(in srgb,var(--praxis-warning, #d97706) 30%,transparent);padding:8px 12px;border-radius:6px}.clear-notice mat-icon{font-size:16px;width:16px;height:16px}.praxis-bulk-edit-dialog__section{display:flex;flex-direction:column;gap:20px}.praxis-bulk-edit-dialog__totals-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:4px 0 12px}.total-card{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:104px;padding:20px 22px;background:color-mix(in srgb,var(--foreground, #f8fafc) 6%,var(--card, #1e293b));border:1px solid var(--border, rgba(148, 163, 184, .2));border-radius:14px;transition:background .2s ease,border-color .2s ease;box-sizing:border-box;gap:8px}.total-card .total-label{font-size:.8125rem;text-transform:uppercase;letter-spacing:.05em;font-weight:600;color:var(--muted-foreground, rgba(148, 163, 184, .85));margin-bottom:2px}.total-card .total-value{font-size:2rem;font-weight:700;color:var(--foreground, #f8fafc);line-height:1;margin:0;letter-spacing:-.02em}.total-card--executable{border-color:color-mix(in srgb,var(--praxis-success, #10b981) 50%,transparent)!important;background:color-mix(in srgb,var(--praxis-success, #10b981) 16%,var(--card, #1e293b))!important}.total-card--executable .total-value{color:var(--praxis-success, #10b981)}.total-card--blocked{border-color:color-mix(in srgb,var(--praxis-error, #ef4444) 50%,transparent)!important;background:color-mix(in srgb,var(--praxis-error, #ef4444) 16%,var(--card, #1e293b))!important}.total-card--blocked .total-value{color:var(--praxis-error, #ef4444)}.praxis-bulk-edit-dialog__alert{display:flex;align-items:flex-start;gap:14px;padding:18px 22px;border-radius:12px;font-size:.875rem;line-height:1.5}.praxis-bulk-edit-dialog__alert mat-icon{font-size:22px;width:22px;height:22px;flex-shrink:0;margin-top:1px}.praxis-bulk-edit-dialog__alert .alert-content{display:flex;flex-direction:column;gap:4px}.praxis-bulk-edit-dialog__alert .alert-content strong{font-size:.9375rem;font-weight:600;color:inherit}.praxis-bulk-edit-dialog__alert .alert-content p{margin:0;font-size:.8125rem;opacity:.9}.praxis-bulk-edit-dialog__alert--error{background:color-mix(in srgb,var(--praxis-error, #ef4444) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-error, #ef4444) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-edit-dialog__alert--error mat-icon{color:var(--praxis-error, #ef4444)}.praxis-bulk-edit-dialog__alert--warning{background:color-mix(in srgb,var(--praxis-warning, #d97706) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-warning, #d97706) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-edit-dialog__alert--warning mat-icon{color:var(--praxis-warning, #d97706)}.praxis-bulk-edit-dialog__alert--success{background:color-mix(in srgb,var(--praxis-success, #10b981) 16%,var(--card, #1e293b));border:1px solid color-mix(in srgb,var(--praxis-success, #10b981) 45%,transparent);color:var(--foreground, #f8fafc)}.praxis-bulk-edit-dialog__alert--success mat-icon{color:var(--praxis-success, #10b981)}.praxis-bulk-edit-dialog__diagnostics{margin-top:12px;padding:12px 16px;background:color-mix(in srgb,var(--praxis-text-primary, var(--foreground, currentColor)) 3%,transparent);border:1px solid var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))));border-radius:8px;display:flex;flex-direction:column;gap:8px}.diagnostics-title{font-size:.875rem;font-weight:600;margin:0 0 4px;color:var(--praxis-text-primary, var(--foreground, inherit))}.diagnostic-item{display:flex;align-items:flex-start;gap:8px;font-size:.8125rem;color:var(--praxis-text-muted, var(--muted-foreground, inherit))}.diagnostic-item mat-icon{font-size:16px;width:16px;height:16px;margin-top:2px;flex-shrink:0;color:var(--praxis-primary, var(--primary, var(--md-sys-color-primary, #0284c7)))}.diagnostic-item--error{color:var(--praxis-error, #ef4444)}.diagnostic-item--error mat-icon{color:var(--praxis-error, #ef4444)}.diagnostic-content{display:flex;flex-wrap:wrap;gap:4px}.diagnostic-target{font-weight:600;color:var(--praxis-text-primary, var(--foreground, inherit))}.praxis-bulk-edit-dialog__loading{display:flex;flex-direction:column;align-items:center;padding:40px;gap:16px;color:var(--praxis-text-muted, var(--muted-foreground, inherit))}.praxis-bulk-edit-dialog__actions{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding:18px 24px 22px;border-top:1px solid var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i4$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatSelectModule }, { 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: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatFormFieldModule }], encapsulation: i0.ViewEncapsulation.None });
1872
2070
  }
1873
2071
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisBulkEditDialogComponent, decorators: [{
1874
2072
  type: Component,
@@ -2148,29 +2346,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2148
2346
  <!-- Resultado -->
2149
2347
  @if (step() === 'RESULT' && execution()) {
2150
2348
  <div class="praxis-bulk-edit-dialog__section">
2151
- <div class="praxis-bulk-edit-dialog__alert praxis-bulk-edit-dialog__alert--success">
2152
- <mat-icon>verified</mat-icon>
2349
+ <div class="praxis-bulk-edit-dialog__alert" [ngClass]="getExecutionAlertClass()">
2350
+ <mat-icon>{{ getExecutionAlertIcon() }}</mat-icon>
2153
2351
  <div class="alert-content">
2154
- <strong>Atualização concluída com êxito!</strong>
2155
- <p>Transação homologada e registrada na auditoria corporativa.</p>
2352
+ <strong>{{ getExecutionAlertTitle() }}</strong>
2353
+ <p>{{ getExecutionAlertMessage() }}</p>
2156
2354
  </div>
2157
2355
  </div>
2158
2356
 
2159
2357
  <div class="praxis-bulk-edit-dialog__totals-grid">
2160
2358
  <div class="total-card total-card--executable">
2161
2359
  <span class="total-label">Efetivados</span>
2162
- <span class="total-value">{{ execution()?.totals?.confirmed }}</span>
2360
+ <span class="total-value">{{ execution()?.totals?.confirmed ?? 0 }}</span>
2163
2361
  </div>
2164
2362
  <div class="total-card">
2165
2363
  <span class="total-label">Preservados</span>
2166
- <span class="total-value">{{ execution()?.totals?.unchanged }}</span>
2364
+ <span class="total-value">{{ execution()?.totals?.unchanged ?? 0 }}</span>
2167
2365
  </div>
2168
- <div class="total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
2366
+ <div class="total-card" [class.total-card--blocked]="getRejectedTotal() > 0">
2169
2367
  <span class="total-label">Rejeitados</span>
2170
- <span class="total-value">{{ execution()?.totals?.denied }}</span>
2368
+ <span class="total-value">{{ getRejectedTotal() }}</span>
2171
2369
  </div>
2172
2370
  </div>
2173
2371
 
2372
+ @if (execution()?.diagnostics?.length) {
2373
+ <div class="praxis-bulk-edit-dialog__diagnostics">
2374
+ <h4 class="diagnostics-title">Diagnósticos de Execução ({{ execution()?.diagnostics?.length }})</h4>
2375
+ @for (diag of execution()?.diagnostics; track $index) {
2376
+ <div class="diagnostic-item" [class.diagnostic-item--error]="isDiagnosticError(diag)">
2377
+ <mat-icon>{{ isDiagnosticError(diag) ? 'cancel' : 'info' }}</mat-icon>
2378
+ <div class="diagnostic-content">
2379
+ @if (diag.target != null) {
2380
+ <span class="diagnostic-target">Registro #{{ diag.target }}:</span>
2381
+ }
2382
+ <span class="diagnostic-message">{{ diag.message }}</span>
2383
+ </div>
2384
+ </div>
2385
+ }
2386
+ </div>
2387
+ }
2388
+
2174
2389
  @if (executionItems().length > 0) {
2175
2390
  <div class="praxis-bulk-edit-dialog__diagnostics">
2176
2391
  <h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
@@ -2559,7 +2774,7 @@ class PraxisKpiBandComponent {
2559
2774
  </ng-template>
2560
2775
  </div>
2561
2776
  </div>
2562
- `, isInline: true, styles: [".praxis-kpi-band{display:flex;flex-direction:column;gap:.75rem;margin-bottom:1.25rem;width:100%;box-sizing:border-box}.praxis-kpi-band-header{display:flex;align-items:center;justify-content:space-between;gap:1rem}.praxis-kpi-band-title{margin:0;font-size:1rem;font-weight:600;color:var(--praxis-text-primary, #0f172a)}.praxis-kpi-band-subtitle{margin:.125rem 0 0;font-size:.8125rem;color:var(--praxis-text-muted, #64748b)}.praxis-kpi-band-grid{display:grid;grid-template-columns:repeat(var(--praxis-kpi-columns, auto-fit),minmax(200px,1fr));gap:var(--praxis-kpi-gap, 1rem);width:100%}.praxis-kpi-card{display:flex;flex-direction:column;justify-content:space-between;padding:1rem 1.25rem;border-radius:.75rem;background:var(--praxis-surface-card, #ffffff);border:1px solid var(--praxis-border-subtle, #e2e8f0);box-shadow:0 1px 3px #0000000a;transition:transform .15s ease,box-shadow .15s ease,border-color .15s ease;position:relative;overflow:hidden;min-height:5.5rem;box-sizing:border-box}.praxis-kpi-card.interactive{cursor:pointer}.praxis-kpi-card.interactive:hover{transform:translateY(-2px);box-shadow:0 4px 12px #00000014}.praxis-kpi-card.interactive:focus-visible{outline:2px solid var(--praxis-primary, #0284c7);outline-offset:2px}.praxis-kpi-card-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.praxis-kpi-card-label{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--praxis-text-muted, #64748b)}.praxis-kpi-card-icon{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:.5rem}.praxis-kpi-card-icon mat-icon{font-size:1.25rem;width:1.25rem;height:1.25rem}.praxis-kpi-card-value{font-size:1.625rem;font-weight:700;line-height:1.2;letter-spacing:-.02em;font-feature-settings:\"tnum\" on,\"lnum\" on;color:var(--praxis-text-primary, #0f172a)}.praxis-kpi-card-caption{font-size:.75rem;color:var(--praxis-text-muted, #64748b);margin-top:.375rem}.praxis-kpi-card-footnote{font-size:.7rem;color:var(--praxis-text-secondary, #94a3b8);margin-top:.25rem}.tone-info{border-left:4px solid var(--praxis-info, #0284c7)}.tone-info .praxis-kpi-card-icon{background:color-mix(in srgb,var(--praxis-info, #0284c7) 14%,transparent);color:var(--praxis-info, #0284c7)}.tone-success{border-left:4px solid var(--praxis-success, #059669)}.tone-success .praxis-kpi-card-icon{background:color-mix(in srgb,var(--praxis-success, #059669) 14%,transparent);color:var(--praxis-success, #059669)}.tone-warning{border-left:4px solid var(--praxis-warning, #d97706)}.tone-warning .praxis-kpi-card-icon{background:color-mix(in srgb,var(--praxis-warning, #d97706) 14%,transparent);color:var(--praxis-warning, #d97706)}.tone-error,.tone-danger{border-left:4px solid var(--praxis-error, #dc2626)}.tone-error .praxis-kpi-card-icon,.tone-danger .praxis-kpi-card-icon{background:color-mix(in srgb,var(--praxis-error, #dc2626) 14%,transparent);color:var(--praxis-error, #dc2626)}.tone-neutral{border-left:4px solid var(--praxis-neutral, #94a3b8)}.tone-neutral .praxis-kpi-card-icon{background:color-mix(in srgb,var(--praxis-neutral, #94a3b8) 14%,transparent);color:var(--praxis-text-secondary, #64748b)}.praxis-kpi-card-skeleton{pointer-events:none}.praxis-kpi-skeleton-line{background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-text-secondary, #94a3b8) 12%,transparent) 25%,color-mix(in srgb,var(--praxis-text-secondary, #94a3b8) 22%,transparent),color-mix(in srgb,var(--praxis-text-secondary, #94a3b8) 12%,transparent) 75%);background-size:200% 100%;animation:praxis-shimmer 1.5s infinite;border-radius:.25rem}.praxis-kpi-skeleton-line.label{width:40%;height:.75rem;margin-bottom:.75rem}.praxis-kpi-skeleton-line.value{width:65%;height:1.5rem;margin-bottom:.5rem}.praxis-kpi-skeleton-line.caption{width:50%;height:.65rem}@keyframes praxis-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2777
+ `, isInline: true, styles: [".praxis-kpi-band{display:flex;flex-direction:column;gap:.75rem;margin-bottom:1.25rem;width:100%;box-sizing:border-box}.praxis-kpi-band-header{display:flex;align-items:center;justify-content:space-between;gap:1rem}.praxis-kpi-band-title{margin:0;font-size:1rem;font-weight:600;color:var(--praxis-text-primary, #0f172a)}.praxis-kpi-band-subtitle{margin:.125rem 0 0;font-size:.8125rem;color:var(--praxis-text-muted, #64748b)}.praxis-kpi-band-grid{display:grid;grid-template-columns:repeat(var(--praxis-kpi-columns, auto-fit),minmax(200px,1fr));gap:var(--praxis-kpi-gap, 1rem);width:100%}.praxis-kpi-card{display:flex;flex-direction:column;justify-content:space-between;padding:1rem 1.25rem;border-radius:.75rem;background:var(--praxis-surface-card, #ffffff);border:1px solid var(--praxis-border-subtle, #e2e8f0);box-shadow:0 1px 3px #0000000a;transition:transform .15s ease,box-shadow .15s ease,border-color .15s ease;position:relative;overflow:hidden;min-height:5.5rem;box-sizing:border-box}.praxis-kpi-card.interactive{cursor:pointer}.praxis-kpi-card.interactive:hover{transform:translateY(-2px);box-shadow:0 4px 12px #00000014}.praxis-kpi-card.interactive:focus-visible{outline:2px solid var(--praxis-primary, #0284c7);outline-offset:2px}.praxis-kpi-card-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.praxis-kpi-card-label{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--praxis-text-muted, #64748b)}.praxis-kpi-card-icon{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:.5rem}.praxis-kpi-card-icon mat-icon{font-size:1.25rem;width:1.25rem;height:1.25rem}.praxis-kpi-card-value{font-size:1.625rem;font-weight:700;line-height:1.2;letter-spacing:-.02em;font-feature-settings:\"tnum\" on,\"lnum\" on;color:var(--praxis-text-primary, #0f172a)}.praxis-kpi-card-caption{font-size:.75rem;color:var(--praxis-text-muted, #64748b);margin-top:.375rem}.praxis-kpi-card-footnote{font-size:.7rem;color:var(--praxis-text-secondary, #94a3b8);margin-top:.25rem}.tone-info{border-left:4px solid var(--praxis-info, #0284c7)}.tone-info .praxis-kpi-card-icon{background:color-mix(in srgb,var(--praxis-info, #0284c7) 14%,transparent);color:var(--praxis-info, #0284c7)}.tone-success{border-left:4px solid var(--praxis-success, #059669)}.tone-success .praxis-kpi-card-icon{background:color-mix(in srgb,var(--praxis-success, #059669) 14%,transparent);color:var(--praxis-success, #059669)}.tone-warning{border-left:4px solid var(--praxis-warning, #d97706)}.tone-warning .praxis-kpi-card-icon{background:color-mix(in srgb,var(--praxis-warning, #d97706) 14%,transparent);color:var(--praxis-warning, #d97706)}.tone-error,.tone-danger{border-left:4px solid var(--praxis-error, #dc2626)}.tone-error .praxis-kpi-card-icon,.tone-danger .praxis-kpi-card-icon{background:color-mix(in srgb,var(--praxis-error, #dc2626) 14%,transparent);color:var(--praxis-error, #dc2626)}.tone-neutral{border-left:4px solid var(--praxis-neutral, #94a3b8)}.tone-neutral .praxis-kpi-card-icon{background:color-mix(in srgb,var(--praxis-neutral, #94a3b8) 14%,transparent);color:var(--praxis-text-secondary, #64748b)}.praxis-kpi-card-skeleton{pointer-events:none}.praxis-kpi-skeleton-line{background:linear-gradient(90deg,color-mix(in srgb,var(--praxis-text-secondary, #94a3b8) 12%,transparent) 25%,color-mix(in srgb,var(--praxis-text-secondary, #94a3b8) 22%,transparent),color-mix(in srgb,var(--praxis-text-secondary, #94a3b8) 12%,transparent) 75%);background-size:200% 100%;animation:praxis-shimmer 1.5s infinite;border-radius:.25rem}.praxis-kpi-skeleton-line.label{width:40%;height:.75rem;margin-bottom:.75rem}.praxis-kpi-skeleton-line.value{width:65%;height:1.5rem;margin-bottom:.5rem}.praxis-kpi-skeleton-line.caption{width:50%;height:.65rem}@keyframes praxis-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: MatTooltipModule }, { kind: "directive", type: i4$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2563
2778
  }
2564
2779
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisKpiBandComponent, decorators: [{
2565
2780
  type: Component,
@@ -2665,13 +2880,13 @@ class DialogService {
2665
2880
  const component = await loader();
2666
2881
  return this.zone.run(() => this.matDialog.open(component, config));
2667
2882
  }
2668
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DialogService, deps: [{ token: i1$2.MatDialog }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
2883
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DialogService, deps: [{ token: i1$1.MatDialog }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
2669
2884
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DialogService, providedIn: 'root' });
2670
2885
  }
2671
2886
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DialogService, decorators: [{
2672
2887
  type: Injectable,
2673
2888
  args: [{ providedIn: 'root' }]
2674
- }], ctorParameters: () => [{ type: i1$2.MatDialog }, { type: i0.NgZone }] });
2889
+ }], ctorParameters: () => [{ type: i1$1.MatDialog }, { type: i0.NgZone }] });
2675
2890
 
2676
2891
  function getCrudDrawerAdapterToken() {
2677
2892
  const registryKey = '__PAX_CRUD_DRAWER_ADAPTER_TOKEN__';
@@ -5901,7 +6116,7 @@ class CrudMetadataEditorComponent {
5901
6116
  </mat-tab>
5902
6117
  </mat-tab-group>
5903
6118
  </section>
5904
- `, isInline: true, styles: [":host{display:block;min-width:0;color:var(--md-sys-color-on-surface,#1a1b20)}.editor-shell{display:grid;gap:16px}.editor-header{display:flex;justify-content:space-between;gap:16px;align-items:start}.editor-overview,.editor-health-map{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.editor-health-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-health-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-health-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus{display:flex;gap:12px;align-items:start;padding:14px 16px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-focus--success{background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.editor-focus-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent);white-space:nowrap}.editor-focus-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-focus-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus-copy{display:grid;gap:4px}.editor-focus-copy p{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-tabs{display:flex;flex-direction:column;min-width:0}.editor-tabs .mat-mdc-tab{min-width:118px}.editor-tabs ::ng-deep .mdc-tab__content{gap:8px}.editor-tabs ::ng-deep .mat-mdc-tab-body-wrapper,.editor-tabs ::ng-deep .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.editor-tabs ::ng-deep .mat-mdc-tab-body-content{overflow:hidden}.tab-status-dot{width:8px;height:8px;border-radius:999px;background:var(--md-sys-color-primary,#1263b4);flex:0 0 auto}.tab-status-dot--warn{background:var(--md-sys-color-tertiary,#7d5700)}.tab-status-dot--error{background:var(--md-sys-color-error,#b3261e)}.tab-content{display:grid;gap:14px;min-width:0;padding:12px 2px 4px;box-sizing:border-box}.editor-overview-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-overview-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-overview-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-overview-label{font-size:12px;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-overview-value{line-height:1.3;overflow-wrap:anywhere}.editor-overview-note{margin:0;font-size:12px;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-header h2,.editor-card h3{margin:0}.editor-header p{margin:6px 0 0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-chip{padding:6px 10px;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary,#1263b4) 12%,transparent);font-size:12px}.editor-card{display:grid;gap:14px;padding:16px;border-radius:20px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline,#c5c7ce) 70%,transparent)}.editor-section-header{display:flex;justify-content:space-between;gap:12px;align-items:start}.editor-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-grid--compact{grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.editor-toggles{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-actions,.action-grid{display:grid;gap:14px}.action-summary-strip{display:flex;flex-wrap:wrap;gap:8px}.action-summary-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.action-summary-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.action-summary-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.action-group{display:grid;gap:10px;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 88%,transparent)}.action-group--advanced{background:color-mix(in srgb,var(--md-sys-color-surface-container,#f5f7fb) 90%,transparent)}.action-group__header{display:grid;gap:4px}.action-subgroup{display:grid;gap:10px;padding:10px;border-radius:14px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low,#fafbfd) 92%,transparent)}.action-subgroup__header{display:grid;gap:4px}.action-param-list{display:grid;gap:12px}.action-param-row{display:grid;gap:8px}.action-advanced-panel{border:1px solid color-mix(in srgb,var(--md-sys-color-outline,#c5c7ce) 65%,transparent);border-radius:16px}.editor-section-note{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.diagnostics-groups{display:grid;gap:12px}.diagnostics-group{display:grid;gap:10px;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.diagnostics{display:grid;gap:8px;margin:0;padding-left:18px}.diagnostics .error{color:var(--md-sys-color-error,#b3261e)}pre{margin:0;overflow:auto;max-height:320px;padding:12px;border-radius:14px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i4$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i4$1.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i8.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i9.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i9.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i9.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisTableInlineAuthoringEditorComponent, selector: "praxis-table-inline-authoring-editor", inputs: ["config", "readonly"], outputs: ["configChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6119
+ `, isInline: true, styles: [":host{display:block;min-width:0;color:var(--md-sys-color-on-surface,#1a1b20)}.editor-shell{display:grid;gap:16px}.editor-header{display:flex;justify-content:space-between;gap:16px;align-items:start}.editor-overview,.editor-health-map{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.editor-health-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-health-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-health-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus{display:flex;gap:12px;align-items:start;padding:14px 16px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-focus--success{background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.editor-focus-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent);white-space:nowrap}.editor-focus-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-focus-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus-copy{display:grid;gap:4px}.editor-focus-copy p{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-tabs{display:flex;flex-direction:column;min-width:0}.editor-tabs .mat-mdc-tab{min-width:118px}.editor-tabs ::ng-deep .mdc-tab__content{gap:8px}.editor-tabs ::ng-deep .mat-mdc-tab-body-wrapper,.editor-tabs ::ng-deep .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.editor-tabs ::ng-deep .mat-mdc-tab-body-content{overflow:hidden}.tab-status-dot{width:8px;height:8px;border-radius:999px;background:var(--md-sys-color-primary,#1263b4);flex:0 0 auto}.tab-status-dot--warn{background:var(--md-sys-color-tertiary,#7d5700)}.tab-status-dot--error{background:var(--md-sys-color-error,#b3261e)}.tab-content{display:grid;gap:14px;min-width:0;padding:12px 2px 4px;box-sizing:border-box}.editor-overview-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-overview-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-overview-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-overview-label{font-size:12px;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-overview-value{line-height:1.3;overflow-wrap:anywhere}.editor-overview-note{margin:0;font-size:12px;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-header h2,.editor-card h3{margin:0}.editor-header p{margin:6px 0 0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-chip{padding:6px 10px;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary,#1263b4) 12%,transparent);font-size:12px}.editor-card{display:grid;gap:14px;padding:16px;border-radius:20px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline,#c5c7ce) 70%,transparent)}.editor-section-header{display:flex;justify-content:space-between;gap:12px;align-items:start}.editor-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-grid--compact{grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.editor-toggles{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-actions,.action-grid{display:grid;gap:14px}.action-summary-strip{display:flex;flex-wrap:wrap;gap:8px}.action-summary-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.action-summary-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.action-summary-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.action-group{display:grid;gap:10px;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 88%,transparent)}.action-group--advanced{background:color-mix(in srgb,var(--md-sys-color-surface-container,#f5f7fb) 90%,transparent)}.action-group__header{display:grid;gap:4px}.action-subgroup{display:grid;gap:10px;padding:10px;border-radius:14px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low,#fafbfd) 92%,transparent)}.action-subgroup__header{display:grid;gap:4px}.action-param-list{display:grid;gap:12px}.action-param-row{display:grid;gap:8px}.action-advanced-panel{border:1px solid color-mix(in srgb,var(--md-sys-color-outline,#c5c7ce) 65%,transparent);border-radius:16px}.editor-section-note{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.diagnostics-groups{display:grid;gap:12px}.diagnostics-group{display:grid;gap:10px;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.diagnostics{display:grid;gap:8px;margin:0;padding-left:18px}.diagnostics .error{color:var(--md-sys-color-error,#b3261e)}pre{margin:0;overflow:auto;max-height:320px;padding:12px;border-radius:14px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4$3.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4$3.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i4$3.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i4$3.MatExpansionPanelDescription, selector: "mat-panel-description" }, { 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: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i8.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i9.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i9.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i9.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisTableInlineAuthoringEditorComponent, selector: "praxis-table-inline-authoring-editor", inputs: ["config", "readonly"], outputs: ["configChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5905
6120
  }
5906
6121
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CrudMetadataEditorComponent, decorators: [{
5907
6122
  type: Component,
@@ -6856,9 +7071,16 @@ class PraxisCrudComponent {
6856
7071
  const bulkContract = resolvedBulk.contract;
6857
7072
  const discoveredCatalogAction = resolvedBulk.catalogAction;
6858
7073
  if (bulkContract) {
7074
+ const selectedCount = Array.isArray(rawTargets) && rawTargets.length > 0 ? rawTargets.length : rows.length;
7075
+ const maxTargets = bulkContract.limits?.maxTargets;
7076
+ if (typeof maxTargets === 'number' && maxTargets > 0 && selectedCount > maxTargets) {
7077
+ this.snack.open(`A seleção atual (${selectedCount} itens) excede o limite máximo permitido (${maxTargets} itens por lote).`, undefined, { duration: 4000 });
7078
+ return;
7079
+ }
7080
+ const requiresResourceVersion = discoveredCatalogAction?.execution?.preconditions?.resourceVersion !== 'NONE';
6859
7081
  const targets = Array.isArray(rawTargets) && rawTargets.length > 0
6860
7082
  ? rawTargets
6861
- : await this.resolveBulkTargetsFromRows(rows);
7083
+ : await this.resolveBulkTargetsFromRows(rows, requiresResourceVersion);
6862
7084
  if (!targets.length) {
6863
7085
  this.snack.open('Nenhum registro selecionado para a operação em lote.', undefined, { duration: 3000 });
6864
7086
  return;
@@ -6894,7 +7116,7 @@ class PraxisCrudComponent {
6894
7116
  .pipe(takeUntilDestroyed(this.destroyRef))
6895
7117
  .subscribe((res) => {
6896
7118
  if (res?.success) {
6897
- this.refreshTable();
7119
+ this.handleBulkExecutionCompleted(discoveredCatalogAction?.execution?.refresh);
6898
7120
  this.snack.open('Atualização em lote concluída com sucesso.', undefined, { duration: 3000 });
6899
7121
  }
6900
7122
  });
@@ -6934,7 +7156,7 @@ class PraxisCrudComponent {
6934
7156
  .pipe(takeUntilDestroyed(this.destroyRef))
6935
7157
  .subscribe((res) => {
6936
7158
  if (res?.success) {
6937
- this.refreshTable();
7159
+ this.handleBulkExecutionCompleted(discoveredCatalogAction?.execution?.refresh);
6938
7160
  this.snack.open('Operação em lote executada com sucesso.', undefined, { duration: 3000 });
6939
7161
  }
6940
7162
  });
@@ -6947,39 +7169,64 @@ class PraxisCrudComponent {
6947
7169
  }
6948
7170
  await this.onAction(action, row ?? undefined, event);
6949
7171
  }
6950
- async resolveBulkTargetsFromRows(rows) {
7172
+ handleBulkExecutionCompleted(refreshPolicy) {
7173
+ try {
7174
+ this.table?.clearSelection?.();
7175
+ this.table?.selection?.clear?.();
7176
+ }
7177
+ catch {
7178
+ // Best-effort table selection cleanup
7179
+ }
7180
+ if (refreshPolicy?.collection !== false) {
7181
+ this.refreshTable();
7182
+ }
7183
+ if (refreshPolicy?.capabilities && this.tableCollectionLinks) {
7184
+ this.collectionCapabilitiesResolvedHref = null;
7185
+ this.onCollectionLinksChange(this.tableCollectionLinks);
7186
+ }
7187
+ }
7188
+ async resolveBulkTargetsFromRows(rows, fetchSelfWhenVersionMissing = true) {
6951
7189
  const options = this.buildDiscoveryOptions();
6952
- return Promise.all(rows.map(async (r) => {
6953
- const id = this.resolveRowResourceId(r);
6954
- let expectedVersion = (r?.resourceVersion != null ? String(r.resourceVersion).trim() : null) ||
6955
- (r?.version != null ? String(r.version).trim() : null) ||
6956
- (r?._etag != null ? String(r._etag).trim() : null) ||
6957
- (r?.etag != null ? String(r.etag).trim() : null) ||
6958
- (r?.eTag != null ? String(r.eTag).trim() : null) ||
6959
- undefined;
6960
- if (!expectedVersion && r?._links?.self) {
6961
- try {
6962
- const selfHref = this.getResourceDiscovery().resolveLinkHref(r._links, 'self', options);
6963
- if (selfHref) {
6964
- const resp = await firstValueFrom(this.http.get(selfHref, { observe: 'response' }));
6965
- const etagHeader = resp.headers?.get('ETag');
6966
- const bodyVersion = resp.body?.data?.resourceVersion ??
6967
- resp.body?.resourceVersion ??
6968
- resp.body?.data?.version;
6969
- if (etagHeader && etagHeader.trim()) {
6970
- expectedVersion = etagHeader.trim();
6971
- }
6972
- else if (bodyVersion != null && String(bodyVersion).trim()) {
6973
- expectedVersion = String(bodyVersion).trim();
7190
+ const results = new Array(rows.length);
7191
+ const concurrency = 4;
7192
+ for (let offset = 0; offset < rows.length; offset += concurrency) {
7193
+ const slice = rows.slice(offset, offset + concurrency);
7194
+ await Promise.all(slice.map(async (r, idx) => {
7195
+ const id = this.resolveRowResourceId(r);
7196
+ let expectedVersion = (r?.resourceVersion != null ? String(r.resourceVersion).trim() : null) ||
7197
+ (r?.version != null ? String(r.version).trim() : null) ||
7198
+ (r?._etag != null ? String(r._etag).trim() : null) ||
7199
+ (r?.etag != null ? String(r.etag).trim() : null) ||
7200
+ (r?.eTag != null ? String(r.eTag).trim() : null) ||
7201
+ undefined;
7202
+ if (fetchSelfWhenVersionMissing && !expectedVersion && r?._links?.self) {
7203
+ try {
7204
+ const selfHref = this.getResourceDiscovery().resolveLinkHref(r._links, 'self', options);
7205
+ if (selfHref) {
7206
+ const resp = await firstValueFrom(this.http.get(selfHref, { observe: 'response' }));
7207
+ const etagHeader = resp.headers?.get('ETag');
7208
+ const bodyVersion = resp.body?.data?.resourceVersion ??
7209
+ resp.body?.resourceVersion ??
7210
+ resp.body?.data?.version;
7211
+ if (etagHeader && etagHeader.trim()) {
7212
+ expectedVersion = etagHeader.trim();
7213
+ }
7214
+ else if (bodyVersion != null && String(bodyVersion).trim()) {
7215
+ expectedVersion = String(bodyVersion).trim();
7216
+ }
6974
7217
  }
6975
7218
  }
7219
+ catch {
7220
+ // Non-blocking fallback when self endpoint is unreachable or unmocked
7221
+ }
6976
7222
  }
6977
- catch {
6978
- // Non-blocking fallback when self endpoint is unreachable or unmocked
6979
- }
6980
- }
6981
- return { id: id, ...(expectedVersion ? { expectedVersion } : {}) };
6982
- }));
7223
+ results[offset + idx] = {
7224
+ id: id,
7225
+ ...(expectedVersion ? { expectedVersion } : {}),
7226
+ };
7227
+ }));
7228
+ }
7229
+ return results;
6983
7230
  }
6984
7231
  resolveSyncBulkExecutionContractForAction(action, normalizedAction, configAction, crudAction, tableBulkAction) {
6985
7232
  const direct = configAction?.execution?.bulk ||
@@ -8322,6 +8569,35 @@ class PraxisCrudComponent {
8322
8569
  toolbar.filters.enabled = true;
8323
8570
  changed = true;
8324
8571
  }
8572
+ const existingAdvancedFilters = cfg.behavior?.filtering?.advancedFilters;
8573
+ const hasConfiguredFilterFields = (existingAdvancedFilters?.settings?.alwaysVisibleFields?.length ?? 0) > 0 ||
8574
+ (existingAdvancedFilters?.settings?.selectedFieldIds?.length ?? 0) > 0;
8575
+ if (hasConfiguredFilterFields &&
8576
+ cfg.behavior?.filtering?.enabled !== false &&
8577
+ existingAdvancedFilters?.enabled !== false) {
8578
+ const filtering = cfg.behavior.filtering;
8579
+ if (filtering.enabled !== true) {
8580
+ filtering.enabled = true;
8581
+ changed = true;
8582
+ }
8583
+ if (existingAdvancedFilters.enabled !== true) {
8584
+ existingAdvancedFilters.enabled = true;
8585
+ changed = true;
8586
+ }
8587
+ const toolbar = ensureToolbar();
8588
+ if (toolbar.visible === undefined) {
8589
+ toolbar.visible = true;
8590
+ changed = true;
8591
+ }
8592
+ if (!toolbar.filters) {
8593
+ toolbar.filters = { enabled: true, showAdvancedButton: true };
8594
+ changed = true;
8595
+ }
8596
+ else if (toolbar.filters.enabled === undefined) {
8597
+ toolbar.filters.enabled = true;
8598
+ changed = true;
8599
+ }
8600
+ }
8325
8601
  const effectiveResourcePath = meta?.resource?.schemaPath?.trim() || this.resolveResourcePath(meta);
8326
8602
  if (effectiveResourcePath && cfg.behavior?.filtering?.advancedFilters) {
8327
8603
  const advancedFilters = cfg.behavior.filtering.advancedFilters;
@@ -8816,13 +9092,17 @@ class PraxisCrudComponent {
8816
9092
  for (const action of (capabilities.actions || [])
8817
9093
  .filter((a) => a.scope === 'COLLECTION' && a.execution?.bulk)
8818
9094
  .sort((left, right) => (left.order ?? 0) - (right.order ?? 0))) {
9095
+ const available = this.isCatalogActionAvailable(capabilities, action.id);
8819
9096
  items.push({
8820
9097
  id: action.id,
8821
9098
  label: action.title || action.id,
8822
9099
  icon: action.icon || (action.execution?.bulk?.mode === 'UNIFORM_UPDATE' ? 'edit_note' : 'playlist_add_check'),
8823
9100
  action: action.id,
8824
9101
  requiresSelection: true,
8825
- disabled: !this.isCatalogActionAvailable(capabilities, action.id),
9102
+ disabled: !available,
9103
+ tooltip: !available
9104
+ ? translateUnavailableWorkflowMessage(this.i18n, capabilities.operations?.[action.id]?.availability || action.availability) || action.description
9105
+ : action.description,
8826
9106
  execution: { bulk: action.execution.bulk },
8827
9107
  });
8828
9108
  }
@@ -8830,15 +9110,19 @@ class PraxisCrudComponent {
8830
9110
  if (op?.supported &&
8831
9111
  op?.scope === 'COLLECTION' &&
8832
9112
  op?.bulk?.mode === 'UNIFORM_UPDATE' &&
8833
- op.availability?.allowed !== false &&
8834
9113
  !items.some((item) => String(item['action'] || item['id']).toLowerCase() === opKey.toLowerCase())) {
8835
9114
  const isAtomic = op.bulk.atomicity === 'ATOMIC' || op.bulk.atomicity === 'ALL_OR_NONE';
9115
+ const available = op.availability?.allowed !== false;
8836
9116
  items.push({
8837
9117
  id: op.id || opKey,
8838
9118
  label: isAtomic ? 'Editar Selecionados (Atômico)' : 'Editar Selecionados',
8839
9119
  icon: 'edit_note',
8840
9120
  action: op.id || opKey,
8841
9121
  requiresSelection: true,
9122
+ disabled: !available,
9123
+ tooltip: !available
9124
+ ? translateUnavailableWorkflowMessage(this.i18n, op.availability)
9125
+ : undefined,
8842
9126
  execution: { bulk: op.bulk },
8843
9127
  });
8844
9128
  }
@@ -9813,7 +10097,7 @@ class DynamicFormDialogHostComponent {
9813
10097
  : { top: offset };
9814
10098
  return { ...horizontal, ...vertical };
9815
10099
  }
9816
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicFormDialogHostComponent, deps: [{ token: MatDialogRef, optional: true }, { token: MAT_DIALOG_DATA, optional: true }, { token: DialogService }, { token: i2$2.GenericCrudService }, { token: ASYNC_CONFIG_STORAGE }, { token: SURFACE_DRAWER_REF, optional: true }, { token: SURFACE_DRAWER_CONTENT_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
10100
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicFormDialogHostComponent, deps: [{ token: MatDialogRef, optional: true }, { token: MAT_DIALOG_DATA, optional: true }, { token: DialogService }, { token: i2$1.GenericCrudService }, { token: ASYNC_CONFIG_STORAGE }, { token: SURFACE_DRAWER_REF, optional: true }, { token: SURFACE_DRAWER_CONTENT_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
9817
10101
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: DynamicFormDialogHostComponent, isStandalone: true, selector: "praxis-dynamic-form-dialog-host", outputs: { reactiveDeterminationExecuted: "reactiveDeterminationExecuted", reactiveDeterminationPendingChange: "reactiveDeterminationPendingChange", reactiveDeterminationStabilityChange: "reactiveDeterminationStabilityChange" }, host: { properties: { "attr.data-density": "modal.density || \"default\"", "attr.data-presentation": "presentation", "class.praxis-drawer": "presentation === \"drawer\"", "class.praxis-surface-frame": "isSurfaceFrame" }, classAttribute: "praxis-dialog" }, providers: [
9818
10102
  {
9819
10103
  provide: GenericCrudService,
@@ -9921,7 +10205,7 @@ class DynamicFormDialogHostComponent {
9921
10205
  (reactiveDeterminationPendingChange)="onReactiveDeterminationPendingChange($event)"
9922
10206
  ></praxis-dynamic-form>
9923
10207
  </mat-dialog-content>
9924
- `, isInline: true, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);min-height:var(--dlg-header-h);padding:10px var(--dlg-pad);margin:0;background:var(--md-sys-color-surface-container-high);border-bottom:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-title{margin:0;font:inherit;font-weight:600;color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-heading{display:grid;min-width:0;gap:2px}praxis-dynamic-form-dialog-host .dialog-title-icon{display:inline-grid;flex:0 0 auto;width:36px;height:36px;place-items:center;border-radius:10px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}praxis-dynamic-form-dialog-host .dialog-title-icon mat-icon{width:22px;height:22px;font-size:22px}praxis-dynamic-form-dialog-host .dialog-subtitle{display:-webkit-box;overflow:hidden;color:var(--md-sys-color-on-surface-variant);font-size:.82rem;font-weight:400;line-height:1.35;-webkit-box-orient:vertical;-webkit-line-clamp:2}praxis-dynamic-form-dialog-host .spacer{flex:1}praxis-dynamic-form-dialog-host .dialog-content{flex:1 1 auto;overflow:auto;padding:var(--dlg-pad);max-height:calc(100svh - var(--dlg-header-h) - 32px)}praxis-dynamic-form-dialog-host .crud-operation-context{position:sticky;top:0;z-index:1;display:grid;gap:.75rem;margin-block-end:var(--dlg-pad);padding-block:.5rem .75rem;background:var(--pfx-form-surface, var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant)}praxis-dynamic-form-dialog-host .crud-resource-identity{display:grid;gap:.25rem;min-width:0}praxis-dynamic-form-dialog-host .crud-resource-identity__label{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-label-medium, 500 .75rem/1rem inherit)}praxis-dynamic-form-dialog-host.praxis-drawer{--dlg-header-h: 72px;width:100%;min-width:0;max-width:100vw;height:100dvh;background:var(--pfx-form-surface, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-header{background:color-mix(in srgb,var(--md-sys-color-surface-container-high, var(--md-sys-color-surface)),transparent 4%)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content{display:flex;flex-direction:column;max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form{display:block;flex:1 1 auto;min-height:0}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form{min-height:100%}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:auto;padding-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}praxis-dynamic-form-dialog-host.praxis-surface-frame .dialog-content{max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button:hover{color:var(--md-sys-color-primary)}praxis-dynamic-form-dialog-host .dialog-footer{position:sticky;bottom:0;z-index:1;padding:var(--dlg-pad)}.pfx-blur-backdrop{background-color:var(--pfx-backdrop, rgba(15, 23, 42, .42))!important;backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%)}.pfx-transparent-backdrop{background-color:transparent!important}.cdk-overlay-pane.pfx-dialog-pane{overflow:hidden;transition:width .2s ease,height .2s ease,margin .2s ease}.cdk-overlay-pane.pfx-dialog-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane .mdc-dialog__surface{display:flex;flex-direction:column;width:100%;min-width:0;height:100%;max-height:inherit;overflow:hidden;background:var(--pfx-form-surface, var(--md-sys-color-surface))!important;border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant))!important}.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mdc-dialog__surface{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.cdk-overlay-pane.pfx-drawer-pane{margin:0!important;border-radius:0!important;box-shadow:var(--md-sys-elevation-level3, 0 24px 80px rgba(15, 23, 42, .28)),0 0 0 1px color-mix(in srgb,var(--md-sys-color-outline, #64748b) 24%,transparent)}.cdk-overlay-pane.pfx-drawer-pane.pfx-drawer-maximized{margin:var(--pfx-drawer-edge-gap, 8px)!important}.cdk-overlay-pane.pfx-drawer-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-drawer-pane .mdc-dialog__surface{min-width:0!important;border-radius:0!important}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisResourceIdentityComponent, selector: "praxis-resource-identity", inputs: ["identity", "emptyTitle", "density", "showMetadataLabels", "showKey", "showKeyLabel", "ariaLabel"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "emptyState", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "submitResourceVersionTargetResourceKey", "submitResourceVersionTargetIdField", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "layoutMode", "formLayout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "presentation", "presentationPreset", "sectionDefaultAppearance", "sectionDivider", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "payloadPreviewChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange", "reactiveDeterminationExecuted", "reactiveDeterminationPendingChange", "tabChange", "tabSelected"] }], encapsulation: i0.ViewEncapsulation.None });
10208
+ `, isInline: true, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);min-height:var(--dlg-header-h);padding:10px var(--dlg-pad);margin:0;background:var(--md-sys-color-surface-container-high);border-bottom:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-title{margin:0;font:inherit;font-weight:600;color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-heading{display:grid;min-width:0;gap:2px}praxis-dynamic-form-dialog-host .dialog-title-icon{display:inline-grid;flex:0 0 auto;width:36px;height:36px;place-items:center;border-radius:10px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}praxis-dynamic-form-dialog-host .dialog-title-icon mat-icon{width:22px;height:22px;font-size:22px}praxis-dynamic-form-dialog-host .dialog-subtitle{display:-webkit-box;overflow:hidden;color:var(--md-sys-color-on-surface-variant);font-size:.82rem;font-weight:400;line-height:1.35;-webkit-box-orient:vertical;-webkit-line-clamp:2}praxis-dynamic-form-dialog-host .spacer{flex:1}praxis-dynamic-form-dialog-host .dialog-content{flex:1 1 auto;overflow:auto;padding:var(--dlg-pad);max-height:calc(100svh - var(--dlg-header-h) - 32px)}praxis-dynamic-form-dialog-host .crud-operation-context{position:sticky;top:0;z-index:1;display:grid;gap:.75rem;margin-block-end:var(--dlg-pad);padding-block:.5rem .75rem;background:var(--pfx-form-surface, var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant)}praxis-dynamic-form-dialog-host .crud-resource-identity{display:grid;gap:.25rem;min-width:0}praxis-dynamic-form-dialog-host .crud-resource-identity__label{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-label-medium, 500 .75rem/1rem inherit)}praxis-dynamic-form-dialog-host.praxis-drawer{--dlg-header-h: 72px;width:100%;min-width:0;max-width:100vw;height:100dvh;background:var(--pfx-form-surface, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-header{background:color-mix(in srgb,var(--md-sys-color-surface-container-high, var(--md-sys-color-surface)),transparent 4%)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content{display:flex;flex-direction:column;max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form{display:block;flex:1 1 auto;min-height:0}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form{min-height:100%}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:auto;padding-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}praxis-dynamic-form-dialog-host.praxis-surface-frame .dialog-content{max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button:hover{color:var(--md-sys-color-primary)}praxis-dynamic-form-dialog-host .dialog-footer{position:sticky;bottom:0;z-index:1;padding:var(--dlg-pad)}.pfx-blur-backdrop{background-color:var(--pfx-backdrop, rgba(15, 23, 42, .42))!important;backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%)}.pfx-transparent-backdrop{background-color:transparent!important}.cdk-overlay-pane.pfx-dialog-pane{overflow:hidden;transition:width .2s ease,height .2s ease,margin .2s ease}.cdk-overlay-pane.pfx-dialog-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane .mdc-dialog__surface{display:flex;flex-direction:column;width:100%;min-width:0;height:100%;max-height:inherit;overflow:hidden;background:var(--pfx-form-surface, var(--md-sys-color-surface))!important;border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant))!important}.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mdc-dialog__surface{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.cdk-overlay-pane.pfx-drawer-pane{margin:0!important;border-radius:0!important;box-shadow:var(--md-sys-elevation-level3, 0 24px 80px rgba(15, 23, 42, .28)),0 0 0 1px color-mix(in srgb,var(--md-sys-color-outline, #64748b) 24%,transparent)}.cdk-overlay-pane.pfx-drawer-pane.pfx-drawer-maximized{margin:var(--pfx-drawer-edge-gap, 8px)!important}.cdk-overlay-pane.pfx-drawer-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-drawer-pane .mdc-dialog__surface{min-width:0!important;border-radius:0!important}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisResourceIdentityComponent, selector: "praxis-resource-identity", inputs: ["identity", "emptyTitle", "density", "showMetadataLabels", "showKey", "showKeyLabel", "ariaLabel"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "emptyState", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "submitResourceVersionTargetResourceKey", "submitResourceVersionTargetIdField", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "layoutMode", "formLayout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "presentation", "presentationPreset", "sectionDefaultAppearance", "sectionDivider", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "payloadPreviewChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange", "reactiveDeterminationExecuted", "reactiveDeterminationPendingChange", "tabChange", "tabSelected"] }], encapsulation: i0.ViewEncapsulation.None });
9925
10209
  }
9926
10210
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicFormDialogHostComponent, decorators: [{
9927
10211
  type: Component,
@@ -10056,7 +10340,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
10056
10340
  }, {
10057
10341
  type: Inject,
10058
10342
  args: [MAT_DIALOG_DATA]
10059
- }] }, { type: DialogService }, { type: i2$2.GenericCrudService }, { type: undefined, decorators: [{
10343
+ }] }, { type: DialogService }, { type: i2$1.GenericCrudService }, { type: undefined, decorators: [{
10060
10344
  type: Inject,
10061
10345
  args: [ASYNC_CONFIG_STORAGE]
10062
10346
  }] }, { type: undefined, decorators: [{
@@ -10856,7 +11140,7 @@ class CrudPageHeaderComponent {
10856
11140
  <ng-content></ng-content>
10857
11141
  </div>
10858
11142
  </header>
10859
- `, isInline: true, styles: [".crud-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 0;background:var(--md-sys-color-surface)}.crud-header.sticky{position:sticky;top:0;z-index:10;-webkit-backdrop-filter:saturate(110%);backdrop-filter:saturate(110%)}.crud-header.with-divider{border-bottom:1px solid var(--md-sys-color-outline-variant)}.left{display:flex;align-items:center;gap:8px;min-width:0}.right{display:flex;align-items:center;gap:8px}.title{margin:0;font-weight:600;color:var(--md-sys-color-on-surface, currentColor);font:var(--mdc-typography-title-large, 600 20px/28px system-ui);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.back-btn{display:inline-flex;align-items:center;gap:6px;text-decoration:none}.back-btn .mat-mdc-button{padding-left:0}.back-btn mat-icon{color:var(--md-sys-color-on-surface-variant, currentColor)}.back-btn .label{color:var(--md-sys-color-on-surface-variant, currentColor)}.back-btn.ghost{border-radius:20px;padding:4px 8px}.back-btn.ghost:hover{background:var(--md-sys-color-primary-container)}.back-btn.tonal{border-radius:20px;padding:4px 10px;background:var(--md-sys-color-surface-container);box-shadow:inset 0 0 0 1px var(--md-sys-color-outline-variant)}.back-btn.tonal:hover{background:var(--md-sys-color-primary-container)}.back-btn.outlined{border-radius:20px;padding:4px 10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface)}.back-btn.outlined:hover{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container)}@media(max-width:599px){.label.hide-on-narrow{display:none}}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
11143
+ `, isInline: true, styles: [".crud-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 0;background:var(--md-sys-color-surface)}.crud-header.sticky{position:sticky;top:0;z-index:10;-webkit-backdrop-filter:saturate(110%);backdrop-filter:saturate(110%)}.crud-header.with-divider{border-bottom:1px solid var(--md-sys-color-outline-variant)}.left{display:flex;align-items:center;gap:8px;min-width:0}.right{display:flex;align-items:center;gap:8px}.title{margin:0;font-weight:600;color:var(--md-sys-color-on-surface, currentColor);font:var(--mdc-typography-title-large, 600 20px/28px system-ui);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.back-btn{display:inline-flex;align-items:center;gap:6px;text-decoration:none}.back-btn .mat-mdc-button{padding-left:0}.back-btn mat-icon{color:var(--md-sys-color-on-surface-variant, currentColor)}.back-btn .label{color:var(--md-sys-color-on-surface-variant, currentColor)}.back-btn.ghost{border-radius:20px;padding:4px 8px}.back-btn.ghost:hover{background:var(--md-sys-color-primary-container)}.back-btn.tonal{border-radius:20px;padding:4px 10px;background:var(--md-sys-color-surface-container);box-shadow:inset 0 0 0 1px var(--md-sys-color-outline-variant)}.back-btn.tonal:hover{background:var(--md-sys-color-primary-container)}.back-btn.outlined{border-radius:20px;padding:4px 10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface)}.back-btn.outlined:hover{border-color:var(--md-sys-color-primary);background:var(--md-sys-color-primary-container)}@media(max-width:599px){.label.hide-on-narrow{display:none}}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { 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: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
10860
11144
  }
10861
11145
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CrudPageHeaderComponent, decorators: [{
10862
11146
  type: Component,
@@ -11568,7 +11852,7 @@ class PraxisResourcePage {
11568
11852
  const fromRoute = this.routeScopeBarSignal();
11569
11853
  if (fromRoute)
11570
11854
  return fromRoute;
11571
- // Auto-promoção declarativa a partir de metadata.table.toolbar.filters.quickFilters
11855
+ // Auto-promoção declarativa a partir de metadata.table.toolbar.filters.quickFilters ou metadata.filterBar.quickFilters
11572
11856
  const metaSource = this.metadata || this.routeMetadataSignal();
11573
11857
  let meta = null;
11574
11858
  if (typeof metaSource === 'string' && metaSource.trim().startsWith('{')) {
@@ -11580,7 +11864,10 @@ class PraxisResourcePage {
11580
11864
  else if (metaSource && typeof metaSource === 'object') {
11581
11865
  meta = metaSource;
11582
11866
  }
11583
- const quickFilters = meta?.table?.toolbar?.filters?.quickFilters;
11867
+ const quickFilters = meta?.table?.toolbar?.filters?.quickFilters ??
11868
+ (Array.isArray(meta?.filterBar?.quickFilters)
11869
+ ? meta.filterBar.quickFilters
11870
+ : undefined);
11584
11871
  if (Array.isArray(quickFilters) && quickFilters.length > 0) {
11585
11872
  return {
11586
11873
  items: quickFilters.map((qf) => ({
@@ -11591,6 +11878,7 @@ class PraxisResourcePage {
11591
11878
  tone: qf.tone,
11592
11879
  badge: qf.badge,
11593
11880
  count: qf.count,
11881
+ isDefault: qf.isDefault,
11594
11882
  })),
11595
11883
  leadLabel: 'Filtro:',
11596
11884
  leadIcon: 'tune',
@@ -11647,13 +11935,19 @@ class PraxisResourcePage {
11647
11935
  }
11648
11936
  // Se o ScopeBar estiver ativo no cabeçalho (seja manual ou auto-promovido),
11649
11937
  // suprimir os botões redundantes de quickFilters na toolbar interna da tabela
11650
- if (this.effectiveScopeBar() && base.table?.toolbar?.filters) {
11938
+ if (this.effectiveScopeBar() &&
11939
+ (base.table?.toolbar?.filters || Array.isArray(base.filterBar?.quickFilters))) {
11940
+ const existingFilters = base.table?.toolbar?.filters;
11651
11941
  base.table = {
11652
- ...base.table,
11942
+ ...(base.table || { columns: [] }),
11653
11943
  toolbar: {
11654
- ...base.table.toolbar,
11944
+ ...(base.table?.toolbar || {}),
11655
11945
  filters: {
11656
- ...base.table.toolbar.filters,
11946
+ enabled: existingFilters?.enabled ?? true,
11947
+ showAdvancedButton: existingFilters?.showAdvancedButton ??
11948
+ base.filterBar?.showAdvanced ??
11949
+ true,
11950
+ ...(existingFilters || {}),
11657
11951
  showQuickFilters: false,
11658
11952
  },
11659
11953
  },
@@ -11780,10 +12074,10 @@ class PraxisResourcePage {
11780
12074
  }
11781
12075
  handleKpiCardClick(event) {
11782
12076
  const cardFilter = event.card.filter;
11783
- if (cardFilter && typeof cardFilter === 'object') {
12077
+ if (cardFilter !== undefined && cardFilter !== null) {
11784
12078
  const sb = this.effectiveScopeBar();
11785
12079
  if (sb && sb.items) {
11786
- const matched = sb.items.find((item) => JSON.stringify(item.filter) === JSON.stringify(cardFilter));
12080
+ const matched = sb.items.find((item) => this.areScopeFiltersEqual(item.filter, cardFilter));
11787
12081
  if (matched) {
11788
12082
  this.onScopeChange(matched);
11789
12083
  }
@@ -11792,25 +12086,71 @@ class PraxisResourcePage {
11792
12086
  this.kpiCardClick.emit(event);
11793
12087
  }
11794
12088
  applyItemFilter(item) {
11795
- let filterObj = {};
11796
- if (item.filter && typeof item.filter === 'object') {
11797
- filterObj = item.filter;
12089
+ this.activeScopeFilter.set(this.normalizeScopeFilterExpression(item.filter));
12090
+ }
12091
+ normalizeScopeFilterExpression(filter) {
12092
+ if (filter && typeof filter === 'object' && !Array.isArray(filter)) {
12093
+ return { ...filter };
11798
12094
  }
11799
- else if (typeof item.filter === 'string') {
11800
- const trimmed = item.filter.trim();
11801
- if (trimmed.startsWith('{')) {
12095
+ if (typeof filter === 'string' && filter.trim().length > 0) {
12096
+ const trimmed = filter.trim();
12097
+ if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
11802
12098
  try {
11803
- filterObj = JSON.parse(trimmed);
12099
+ const parsed = JSON.parse(trimmed);
12100
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
12101
+ return parsed;
12102
+ }
11804
12103
  }
11805
12104
  catch {
11806
- filterObj = { query: trimmed };
12105
+ // fallback to key-value or query below
11807
12106
  }
11808
12107
  }
11809
- else if (trimmed) {
11810
- filterObj = { query: trimmed };
12108
+ if (trimmed.includes('=')) {
12109
+ const result = {};
12110
+ const pairs = trimmed.split('&');
12111
+ for (const pair of pairs) {
12112
+ const eqIdx = pair.indexOf('=');
12113
+ if (eqIdx > 0) {
12114
+ const key = pair.substring(0, eqIdx).trim();
12115
+ const rawVal = pair.substring(eqIdx + 1).trim();
12116
+ const isQuoted = (rawVal.startsWith("'") && rawVal.endsWith("'")) ||
12117
+ (rawVal.startsWith('"') && rawVal.endsWith('"'));
12118
+ const val = isQuoted ? rawVal.slice(1, -1) : rawVal;
12119
+ if (!isQuoted && val.toLowerCase() === 'true') {
12120
+ result[key] = true;
12121
+ }
12122
+ else if (!isQuoted && val.toLowerCase() === 'false') {
12123
+ result[key] = false;
12124
+ }
12125
+ else if (!isQuoted && /^-?\d+$/.test(val)) {
12126
+ result[key] = parseInt(val, 10);
12127
+ }
12128
+ else if (!isQuoted && /^-?\d+\.\d+$/.test(val)) {
12129
+ result[key] = parseFloat(val);
12130
+ }
12131
+ else {
12132
+ result[key] = val;
12133
+ }
12134
+ }
12135
+ }
12136
+ if (Object.keys(result).length > 0) {
12137
+ return result;
12138
+ }
11811
12139
  }
12140
+ return { query: trimmed };
12141
+ }
12142
+ return {};
12143
+ }
12144
+ areScopeFiltersEqual(a, b) {
12145
+ const normA = this.normalizeScopeFilterExpression(a);
12146
+ const normB = this.normalizeScopeFilterExpression(b);
12147
+ const keysA = Object.keys(normA).sort();
12148
+ const keysB = Object.keys(normB).sort();
12149
+ if (keysA.length === 0 || keysA.length !== keysB.length) {
12150
+ return false;
11812
12151
  }
11813
- this.activeScopeFilter.set(filterObj);
12152
+ return keysA.every((key, idx) => key === keysB[idx] &&
12153
+ JSON.stringify(normA[key]) === JSON.stringify(normB[key]));
11814
12154
  }
11815
12155
  extractRouteData(data) {
11816
12156
  if ('metadata' in data) {
@@ -11905,7 +12245,7 @@ class PraxisResourcePage {
11905
12245
  }
11906
12246
  }
11907
12247
  </div>
11908
- `, isInline: true, styles: [":host{display:block;width:100%;min-height:100%;box-sizing:border-box}.praxis-resource-page{width:100%;display:flex;flex-direction:column;gap:20px;padding:var(--praxis-page-padding, 24px);box-sizing:border-box;max-width:1540px;margin:0 auto}.praxis-resource-page__header{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap}.praxis-resource-page__header-main{min-width:0;display:flex;flex-direction:column}.praxis-resource-page__domain-badge{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:9999px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px;align-self:flex-start;background:var(--praxis-domain-badge-bg, rgba(255, 255, 255, .08));color:var(--praxis-domain-badge-color, inherit);border:1px solid var(--praxis-domain-badge-border, rgba(255, 255, 255, .1))}.praxis-resource-page__domain-badge.tone-primary,.praxis-resource-page__domain-badge.tone-info{background:color-mix(in srgb,var(--praxis-info, #0284c7) 14%,transparent);color:var(--praxis-info, #38bdf8);border-color:color-mix(in srgb,var(--praxis-info, #0284c7) 30%,transparent)}.praxis-resource-page__domain-badge.tone-success{background:color-mix(in srgb,var(--praxis-success, #059669) 14%,transparent);color:var(--praxis-success, #34d399);border-color:color-mix(in srgb,var(--praxis-success, #059669) 30%,transparent)}.praxis-resource-page__domain-badge.tone-warning{background:color-mix(in srgb,var(--praxis-warning, #d97706) 14%,transparent);color:var(--praxis-warning, #fbbf24);border-color:color-mix(in srgb,var(--praxis-warning, #d97706) 30%,transparent)}.praxis-resource-page__domain-badge.tone-danger,.praxis-resource-page__domain-badge.tone-error{background:color-mix(in srgb,var(--praxis-error, #dc2626) 14%,transparent);color:var(--praxis-error, #f87171);border-color:color-mix(in srgb,var(--praxis-error, #dc2626) 30%,transparent)}.praxis-resource-page__domain-badge span.material-symbols-outlined{font-size:14px}.praxis-resource-page__title{margin:0 0 6px;font-size:var(--praxis-page-title-size, 2rem);font-weight:800;letter-spacing:-.02em;color:var(--praxis-page-title-color, var(--foreground, inherit));line-height:1.2}.praxis-resource-page__subtitle{margin:0;font-size:var(--praxis-page-subtitle-size, .9rem);color:var(--muted-foreground, #94a3b8);max-width:800px;line-height:1.5}.praxis-resource-page__crud-surface{width:100%;border-radius:var(--praxis-surface-radius, 16px);overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PraxisCrudComponent, selector: "praxis-crud", inputs: ["metadata", "crudId", "resource", "componentInstanceId", "tableConfigPersistenceStrategy", "context", "enableCustomization", "showResourceIdentityKey", "authoringCapability", "filterCriteria", "filterTeleport", "disableAutoDrawer"], outputs: ["configureRequested", "afterOpen", "afterClose", "afterSave", "afterDelete", "reactiveDeterminationExecuted", "reactiveDeterminationPendingChange", "reactiveDeterminationStabilityChange", "error", "rowClick", "rowAction", "selectionChange", "resourceEvent", "tableRuntimeConfigChange", "drawerOpen", "drawerClose", "crudAuthoringDocumentApplied", "crudAuthoringDocumentSaved", "kpiCardClick"] }, { kind: "component", type: PraxisScopeBarComponent, selector: "praxis-scope-bar", inputs: ["items", "activeId", "showOmnibox", "omniboxPlaceholder", "omniboxValue", "omniboxDebounceMs", "leadIcon", "leadLabel", "showClearButton", "clearLabel", "target", "targetWidgetId", "scopeBarId", "searchField"], outputs: ["activeIdChange", "omniboxValueChange", "scopeChange", "searchChange", "filterCriteriaChange", "clear"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12248
+ `, isInline: true, styles: [":host{display:block;width:100%;min-height:100%;box-sizing:border-box}.praxis-resource-page{width:100%;display:flex;flex-direction:column;gap:20px;padding:var(--praxis-page-padding, 24px);box-sizing:border-box;max-width:1540px;margin:0 auto}.praxis-resource-page__header{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap}.praxis-resource-page__header-main{min-width:0;display:flex;flex-direction:column}.praxis-resource-page__domain-badge{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:9999px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px;align-self:flex-start;background:var(--praxis-domain-badge-bg, rgba(255, 255, 255, .08));color:var(--praxis-domain-badge-color, inherit);border:1px solid var(--praxis-domain-badge-border, rgba(255, 255, 255, .1))}.praxis-resource-page__domain-badge.tone-primary,.praxis-resource-page__domain-badge.tone-info{background:color-mix(in srgb,var(--praxis-info, #0284c7) 14%,transparent);color:var(--praxis-info, #38bdf8);border-color:color-mix(in srgb,var(--praxis-info, #0284c7) 30%,transparent)}.praxis-resource-page__domain-badge.tone-success{background:color-mix(in srgb,var(--praxis-success, #059669) 14%,transparent);color:var(--praxis-success, #34d399);border-color:color-mix(in srgb,var(--praxis-success, #059669) 30%,transparent)}.praxis-resource-page__domain-badge.tone-warning{background:color-mix(in srgb,var(--praxis-warning, #d97706) 14%,transparent);color:var(--praxis-warning, #fbbf24);border-color:color-mix(in srgb,var(--praxis-warning, #d97706) 30%,transparent)}.praxis-resource-page__domain-badge.tone-danger,.praxis-resource-page__domain-badge.tone-error{background:color-mix(in srgb,var(--praxis-error, #dc2626) 14%,transparent);color:var(--praxis-error, #f87171);border-color:color-mix(in srgb,var(--praxis-error, #dc2626) 30%,transparent)}.praxis-resource-page__domain-badge span.material-symbols-outlined{font-size:14px}.praxis-resource-page__title{margin:0 0 6px;font-size:var(--praxis-page-title-size, 2rem);font-weight:800;letter-spacing:-.02em;color:var(--praxis-page-title-color, var(--foreground, inherit));line-height:1.2}.praxis-resource-page__subtitle{margin:0;font-size:var(--praxis-page-subtitle-size, .9rem);color:var(--muted-foreground, #94a3b8);max-width:800px;line-height:1.5}.praxis-resource-page__crud-surface{width:100%;border-radius:var(--praxis-surface-radius, 16px);overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PraxisCrudComponent, selector: "praxis-crud", inputs: ["metadata", "crudId", "resource", "componentInstanceId", "tableConfigPersistenceStrategy", "context", "enableCustomization", "showResourceIdentityKey", "authoringCapability", "filterCriteria", "filterTeleport", "disableAutoDrawer"], outputs: ["configureRequested", "afterOpen", "afterClose", "afterSave", "afterDelete", "reactiveDeterminationExecuted", "reactiveDeterminationPendingChange", "reactiveDeterminationStabilityChange", "error", "rowClick", "rowAction", "selectionChange", "resourceEvent", "tableRuntimeConfigChange", "drawerOpen", "drawerClose", "crudAuthoringDocumentApplied", "crudAuthoringDocumentSaved", "kpiCardClick"] }, { kind: "component", type: PraxisScopeBarComponent, selector: "praxis-scope-bar", inputs: ["items", "activeId", "showOmnibox", "omniboxPlaceholder", "omniboxValue", "omniboxDebounceMs", "leadIcon", "leadLabel", "showClearButton", "clearLabel", "target", "targetWidgetId", "scopeBarId", "searchField"], outputs: ["activeIdChange", "omniboxValueChange", "scopeChange", "searchChange", "filterCriteriaChange", "clear"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11909
12249
  }
11910
12250
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisResourcePage, decorators: [{
11911
12251
  type: Component,