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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-10-14T09:51:43.880Z",
3
+ "generatedAt": "2026-10-14T11:31:33.532Z",
4
4
  "packageName": "@praxisui/crud",
5
- "packageVersion": "10.0.0-rc.13",
5
+ "packageVersion": "10.0.0-rc.14",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 2,
@@ -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';
@@ -146,12 +146,79 @@ class PraxisBulkOperationDialogComponent {
146
146
  diag?.category === 'UNEXPECTED_SANITIZED' ||
147
147
  diag?.severity === 'ERROR');
148
148
  }
149
+ getRejectedTotal() {
150
+ const totals = this.execution()?.totals;
151
+ if (!totals)
152
+ return 0;
153
+ return ((totals['denied'] ?? 0) +
154
+ (totals['invalid'] ?? 0) +
155
+ (totals['conflict'] ?? 0) +
156
+ (totals['notProcessed'] ?? 0) +
157
+ (totals['unknown'] ?? 0));
158
+ }
159
+ getExecutionAlertClass() {
160
+ const status = this.execution()?.status;
161
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
162
+ return 'praxis-bulk-dialog__alert--error';
163
+ }
164
+ if (status === 'CANCELLED' || status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
165
+ return 'praxis-bulk-dialog__alert--warning';
166
+ }
167
+ return 'praxis-bulk-dialog__alert--success';
168
+ }
169
+ getExecutionAlertIcon() {
170
+ const status = this.execution()?.status;
171
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
172
+ return 'report_problem';
173
+ }
174
+ if (status === 'CANCELLED') {
175
+ return 'cancel_schedule_send';
176
+ }
177
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
178
+ return 'warning_amber';
179
+ }
180
+ return 'verified';
181
+ }
182
+ getExecutionAlertTitle() {
183
+ const status = this.execution()?.status;
184
+ if (status === 'RECONCILIATION_REQUIRED') {
185
+ return 'Reconciliação necessária';
186
+ }
187
+ if (status === 'STOPPED') {
188
+ return 'Execução interrompida por restrição de lote';
189
+ }
190
+ if (status === 'CANCELLED') {
191
+ return 'Execução cancelada pelo operador';
192
+ }
193
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
194
+ return 'Operação concluída com restrições parciais';
195
+ }
196
+ return 'Operação concluída com êxito!';
197
+ }
198
+ getExecutionAlertMessage() {
199
+ const status = this.execution()?.status;
200
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
201
+ return 'A operação não pôde ser concluída integralmente. Consulte os diagnósticos de governança abaixo.';
202
+ }
203
+ if (status === 'CANCELLED') {
204
+ return 'O processamento do lote foi interrompido. Verifique o resultado por registro abaixo.';
205
+ }
206
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
207
+ return 'Os registros elegíveis foram efetivados; itens com restrição ou conflito foram preservados conforme o diagnóstico abaixo.';
208
+ }
209
+ return 'Transação homologada e registrada na auditoria corporativa.';
210
+ }
149
211
  onEvaluate() {
150
212
  const bulkContract = this.action.execution?.bulk;
151
213
  if (!bulkContract) {
152
214
  this.errorMessage.set('Contrato de operação em lote não encontrado na ação.');
153
215
  return;
154
216
  }
217
+ const maxTargets = bulkContract.limits?.maxTargets;
218
+ if (typeof maxTargets === 'number' && maxTargets > 0 && this.targets.length > maxTargets) {
219
+ this.errorMessage.set(`A seleção atual (${this.targets.length} itens) excede o limite máximo permitido pelo contrato (${maxTargets} itens por lote).`);
220
+ return;
221
+ }
155
222
  this.confirmationIdempotencyKey = undefined;
156
223
  this.step.set('EVALUATING');
157
224
  this.errorMessage.set(null);
@@ -565,29 +632,48 @@ class PraxisBulkOperationDialogComponent {
565
632
  <!-- Passo 3: Resultado da Execução Concluída -->
566
633
  @if (step() === 'RESULT' && execution()) {
567
634
  <div class="praxis-bulk-dialog__section">
568
- <div class="praxis-bulk-dialog__alert praxis-bulk-dialog__alert--success">
569
- <mat-icon>verified</mat-icon>
635
+ <div class="praxis-bulk-dialog__alert" [ngClass]="getExecutionAlertClass()">
636
+ <mat-icon>{{ getExecutionAlertIcon() }}</mat-icon>
570
637
  <div class="alert-content">
571
- <strong>Operação concluída com êxito!</strong>
572
- <p>Transação homologada e registrada na auditoria corporativa.</p>
638
+ <strong>{{ getExecutionAlertTitle() }}</strong>
639
+ <p>{{ getExecutionAlertMessage() }}</p>
573
640
  </div>
574
641
  </div>
575
642
 
576
643
  <div class="praxis-bulk-dialog__totals-grid">
577
644
  <div class="praxis-bulk-dialog__total-card total-card--executable">
578
645
  <span class="total-label">Efetivados</span>
579
- <span class="total-value">{{ execution()?.totals?.confirmed }}</span>
646
+ <span class="total-value">{{ execution()?.totals?.confirmed ?? 0 }}</span>
580
647
  </div>
581
648
  <div class="praxis-bulk-dialog__total-card">
582
649
  <span class="total-label">Preservados</span>
583
- <span class="total-value">{{ execution()?.totals?.unchanged }}</span>
650
+ <span class="total-value">{{ execution()?.totals?.unchanged ?? 0 }}</span>
584
651
  </div>
585
- <div class="praxis-bulk-dialog__total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
652
+ <div class="praxis-bulk-dialog__total-card" [class.total-card--blocked]="getRejectedTotal() > 0">
586
653
  <span class="total-label">Rejeitados</span>
587
- <span class="total-value">{{ execution()?.totals?.denied }}</span>
654
+ <span class="total-value">{{ getRejectedTotal() }}</span>
588
655
  </div>
589
656
  </div>
590
657
 
658
+ @if (execution()?.diagnostics?.length) {
659
+ <div class="praxis-bulk-dialog__diagnostics">
660
+ <h4 class="diagnostics-title">Diagnósticos de Execução ({{ execution()?.diagnostics?.length }})</h4>
661
+ <div class="diagnostics-list">
662
+ @for (diag of execution()?.diagnostics; track $index) {
663
+ <div class="diagnostic-item" [class.diagnostic-item--error]="isDiagnosticError(diag)">
664
+ <mat-icon>{{ isDiagnosticError(diag) ? 'cancel' : 'info' }}</mat-icon>
665
+ <div class="diagnostic-text">
666
+ @if (diag.target != null) {
667
+ <span class="diagnostic-target">Item {{ diag.target }}:</span>
668
+ }
669
+ <span>{{ diag.message }}</span>
670
+ </div>
671
+ </div>
672
+ }
673
+ </div>
674
+ </div>
675
+ }
676
+
591
677
  @if (executionItems().length > 0) {
592
678
  <div class="praxis-bulk-dialog__diagnostics">
593
679
  <h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
@@ -660,7 +746,7 @@ class PraxisBulkOperationDialogComponent {
660
746
  }
661
747
  </div>
662
748
  </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 });
749
+ `, 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
750
  }
665
751
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisBulkOperationDialogComponent, decorators: [{
666
752
  type: Component,
@@ -863,29 +949,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
863
949
  <!-- Passo 3: Resultado da Execução Concluída -->
864
950
  @if (step() === 'RESULT' && execution()) {
865
951
  <div class="praxis-bulk-dialog__section">
866
- <div class="praxis-bulk-dialog__alert praxis-bulk-dialog__alert--success">
867
- <mat-icon>verified</mat-icon>
952
+ <div class="praxis-bulk-dialog__alert" [ngClass]="getExecutionAlertClass()">
953
+ <mat-icon>{{ getExecutionAlertIcon() }}</mat-icon>
868
954
  <div class="alert-content">
869
- <strong>Operação concluída com êxito!</strong>
870
- <p>Transação homologada e registrada na auditoria corporativa.</p>
955
+ <strong>{{ getExecutionAlertTitle() }}</strong>
956
+ <p>{{ getExecutionAlertMessage() }}</p>
871
957
  </div>
872
958
  </div>
873
959
 
874
960
  <div class="praxis-bulk-dialog__totals-grid">
875
961
  <div class="praxis-bulk-dialog__total-card total-card--executable">
876
962
  <span class="total-label">Efetivados</span>
877
- <span class="total-value">{{ execution()?.totals?.confirmed }}</span>
963
+ <span class="total-value">{{ execution()?.totals?.confirmed ?? 0 }}</span>
878
964
  </div>
879
965
  <div class="praxis-bulk-dialog__total-card">
880
966
  <span class="total-label">Preservados</span>
881
- <span class="total-value">{{ execution()?.totals?.unchanged }}</span>
967
+ <span class="total-value">{{ execution()?.totals?.unchanged ?? 0 }}</span>
882
968
  </div>
883
- <div class="praxis-bulk-dialog__total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
969
+ <div class="praxis-bulk-dialog__total-card" [class.total-card--blocked]="getRejectedTotal() > 0">
884
970
  <span class="total-label">Rejeitados</span>
885
- <span class="total-value">{{ execution()?.totals?.denied }}</span>
971
+ <span class="total-value">{{ getRejectedTotal() }}</span>
886
972
  </div>
887
973
  </div>
888
974
 
975
+ @if (execution()?.diagnostics?.length) {
976
+ <div class="praxis-bulk-dialog__diagnostics">
977
+ <h4 class="diagnostics-title">Diagnósticos de Execução ({{ execution()?.diagnostics?.length }})</h4>
978
+ <div class="diagnostics-list">
979
+ @for (diag of execution()?.diagnostics; track $index) {
980
+ <div class="diagnostic-item" [class.diagnostic-item--error]="isDiagnosticError(diag)">
981
+ <mat-icon>{{ isDiagnosticError(diag) ? 'cancel' : 'info' }}</mat-icon>
982
+ <div class="diagnostic-text">
983
+ @if (diag.target != null) {
984
+ <span class="diagnostic-target">Item {{ diag.target }}:</span>
985
+ }
986
+ <span>{{ diag.message }}</span>
987
+ </div>
988
+ </div>
989
+ }
990
+ </div>
991
+ </div>
992
+ }
993
+
889
994
  @if (executionItems().length > 0) {
890
995
  <div class="praxis-bulk-dialog__diagnostics">
891
996
  <h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
@@ -1234,7 +1339,74 @@ class PraxisBulkEditDialogComponent {
1234
1339
  diag?.category === 'UNEXPECTED_SANITIZED' ||
1235
1340
  diag?.severity === 'ERROR');
1236
1341
  }
1342
+ getRejectedTotal() {
1343
+ const totals = this.execution()?.totals;
1344
+ if (!totals)
1345
+ return 0;
1346
+ return ((totals['denied'] ?? 0) +
1347
+ (totals['invalid'] ?? 0) +
1348
+ (totals['conflict'] ?? 0) +
1349
+ (totals['notProcessed'] ?? 0) +
1350
+ (totals['unknown'] ?? 0));
1351
+ }
1352
+ getExecutionAlertClass() {
1353
+ const status = this.execution()?.status;
1354
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
1355
+ return 'praxis-bulk-edit-dialog__alert--error';
1356
+ }
1357
+ if (status === 'CANCELLED' || status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
1358
+ return 'praxis-bulk-edit-dialog__alert--warning';
1359
+ }
1360
+ return 'praxis-bulk-edit-dialog__alert--success';
1361
+ }
1362
+ getExecutionAlertIcon() {
1363
+ const status = this.execution()?.status;
1364
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
1365
+ return 'report_problem';
1366
+ }
1367
+ if (status === 'CANCELLED') {
1368
+ return 'cancel_schedule_send';
1369
+ }
1370
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
1371
+ return 'warning_amber';
1372
+ }
1373
+ return 'verified';
1374
+ }
1375
+ getExecutionAlertTitle() {
1376
+ const status = this.execution()?.status;
1377
+ if (status === 'RECONCILIATION_REQUIRED') {
1378
+ return 'Reconciliação necessária';
1379
+ }
1380
+ if (status === 'STOPPED') {
1381
+ return 'Execução interrompida por restrição de lote';
1382
+ }
1383
+ if (status === 'CANCELLED') {
1384
+ return 'Execução cancelada pelo operador';
1385
+ }
1386
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
1387
+ return 'Atualização concluída com restrições parciais';
1388
+ }
1389
+ return 'Atualização concluída com êxito!';
1390
+ }
1391
+ getExecutionAlertMessage() {
1392
+ const status = this.execution()?.status;
1393
+ if (status === 'STOPPED' || status === 'RECONCILIATION_REQUIRED') {
1394
+ return 'A atualização não pôde ser concluída integralmente. Consulte os diagnósticos de governança abaixo.';
1395
+ }
1396
+ if (status === 'CANCELLED') {
1397
+ return 'O processamento do lote foi interrompido. Verifique o resultado por registro abaixo.';
1398
+ }
1399
+ if (status === 'COMPLETED_WITH_ERRORS' || this.getRejectedTotal() > 0) {
1400
+ return 'Os registros elegíveis foram efetivados; itens com restrição ou conflito foram preservados conforme o diagnóstico abaixo.';
1401
+ }
1402
+ return 'Transação homologada e registrada na auditoria corporativa.';
1403
+ }
1237
1404
  onEvaluate() {
1405
+ const maxTargets = this.contract?.limits?.maxTargets;
1406
+ if (typeof maxTargets === 'number' && maxTargets > 0 && this.targets.length > maxTargets) {
1407
+ this.errorMessage.set(`A seleção atual (${this.targets.length} registros) excede o limite máximo permitido pelo contrato (${maxTargets} registros por lote).`);
1408
+ return;
1409
+ }
1238
1410
  for (const r of this.fieldRows()) {
1239
1411
  if (!r.field)
1240
1412
  continue;
@@ -1775,29 +1947,46 @@ class PraxisBulkEditDialogComponent {
1775
1947
  <!-- Resultado -->
1776
1948
  @if (step() === 'RESULT' && execution()) {
1777
1949
  <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>
1950
+ <div class="praxis-bulk-edit-dialog__alert" [ngClass]="getExecutionAlertClass()">
1951
+ <mat-icon>{{ getExecutionAlertIcon() }}</mat-icon>
1780
1952
  <div class="alert-content">
1781
- <strong>Atualização concluída com êxito!</strong>
1782
- <p>Transação homologada e registrada na auditoria corporativa.</p>
1953
+ <strong>{{ getExecutionAlertTitle() }}</strong>
1954
+ <p>{{ getExecutionAlertMessage() }}</p>
1783
1955
  </div>
1784
1956
  </div>
1785
1957
 
1786
1958
  <div class="praxis-bulk-edit-dialog__totals-grid">
1787
1959
  <div class="total-card total-card--executable">
1788
1960
  <span class="total-label">Efetivados</span>
1789
- <span class="total-value">{{ execution()?.totals?.confirmed }}</span>
1961
+ <span class="total-value">{{ execution()?.totals?.confirmed ?? 0 }}</span>
1790
1962
  </div>
1791
1963
  <div class="total-card">
1792
1964
  <span class="total-label">Preservados</span>
1793
- <span class="total-value">{{ execution()?.totals?.unchanged }}</span>
1965
+ <span class="total-value">{{ execution()?.totals?.unchanged ?? 0 }}</span>
1794
1966
  </div>
1795
- <div class="total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
1967
+ <div class="total-card" [class.total-card--blocked]="getRejectedTotal() > 0">
1796
1968
  <span class="total-label">Rejeitados</span>
1797
- <span class="total-value">{{ execution()?.totals?.denied }}</span>
1969
+ <span class="total-value">{{ getRejectedTotal() }}</span>
1798
1970
  </div>
1799
1971
  </div>
1800
1972
 
1973
+ @if (execution()?.diagnostics?.length) {
1974
+ <div class="praxis-bulk-edit-dialog__diagnostics">
1975
+ <h4 class="diagnostics-title">Diagnósticos de Execução ({{ execution()?.diagnostics?.length }})</h4>
1976
+ @for (diag of execution()?.diagnostics; track $index) {
1977
+ <div class="diagnostic-item" [class.diagnostic-item--error]="isDiagnosticError(diag)">
1978
+ <mat-icon>{{ isDiagnosticError(diag) ? 'cancel' : 'info' }}</mat-icon>
1979
+ <div class="diagnostic-content">
1980
+ @if (diag.target != null) {
1981
+ <span class="diagnostic-target">Registro #{{ diag.target }}:</span>
1982
+ }
1983
+ <span class="diagnostic-message">{{ diag.message }}</span>
1984
+ </div>
1985
+ </div>
1986
+ }
1987
+ </div>
1988
+ }
1989
+
1801
1990
  @if (executionItems().length > 0) {
1802
1991
  <div class="praxis-bulk-edit-dialog__diagnostics">
1803
1992
  <h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
@@ -1868,7 +2057,7 @@ class PraxisBulkEditDialogComponent {
1868
2057
  }
1869
2058
  </div>
1870
2059
  </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 });
2060
+ `, 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
2061
  }
1873
2062
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisBulkEditDialogComponent, decorators: [{
1874
2063
  type: Component,
@@ -2148,29 +2337,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2148
2337
  <!-- Resultado -->
2149
2338
  @if (step() === 'RESULT' && execution()) {
2150
2339
  <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>
2340
+ <div class="praxis-bulk-edit-dialog__alert" [ngClass]="getExecutionAlertClass()">
2341
+ <mat-icon>{{ getExecutionAlertIcon() }}</mat-icon>
2153
2342
  <div class="alert-content">
2154
- <strong>Atualização concluída com êxito!</strong>
2155
- <p>Transação homologada e registrada na auditoria corporativa.</p>
2343
+ <strong>{{ getExecutionAlertTitle() }}</strong>
2344
+ <p>{{ getExecutionAlertMessage() }}</p>
2156
2345
  </div>
2157
2346
  </div>
2158
2347
 
2159
2348
  <div class="praxis-bulk-edit-dialog__totals-grid">
2160
2349
  <div class="total-card total-card--executable">
2161
2350
  <span class="total-label">Efetivados</span>
2162
- <span class="total-value">{{ execution()?.totals?.confirmed }}</span>
2351
+ <span class="total-value">{{ execution()?.totals?.confirmed ?? 0 }}</span>
2163
2352
  </div>
2164
2353
  <div class="total-card">
2165
2354
  <span class="total-label">Preservados</span>
2166
- <span class="total-value">{{ execution()?.totals?.unchanged }}</span>
2355
+ <span class="total-value">{{ execution()?.totals?.unchanged ?? 0 }}</span>
2167
2356
  </div>
2168
- <div class="total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
2357
+ <div class="total-card" [class.total-card--blocked]="getRejectedTotal() > 0">
2169
2358
  <span class="total-label">Rejeitados</span>
2170
- <span class="total-value">{{ execution()?.totals?.denied }}</span>
2359
+ <span class="total-value">{{ getRejectedTotal() }}</span>
2171
2360
  </div>
2172
2361
  </div>
2173
2362
 
2363
+ @if (execution()?.diagnostics?.length) {
2364
+ <div class="praxis-bulk-edit-dialog__diagnostics">
2365
+ <h4 class="diagnostics-title">Diagnósticos de Execução ({{ execution()?.diagnostics?.length }})</h4>
2366
+ @for (diag of execution()?.diagnostics; track $index) {
2367
+ <div class="diagnostic-item" [class.diagnostic-item--error]="isDiagnosticError(diag)">
2368
+ <mat-icon>{{ isDiagnosticError(diag) ? 'cancel' : 'info' }}</mat-icon>
2369
+ <div class="diagnostic-content">
2370
+ @if (diag.target != null) {
2371
+ <span class="diagnostic-target">Registro #{{ diag.target }}:</span>
2372
+ }
2373
+ <span class="diagnostic-message">{{ diag.message }}</span>
2374
+ </div>
2375
+ </div>
2376
+ }
2377
+ </div>
2378
+ }
2379
+
2174
2380
  @if (executionItems().length > 0) {
2175
2381
  <div class="praxis-bulk-edit-dialog__diagnostics">
2176
2382
  <h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
@@ -2559,7 +2765,7 @@ class PraxisKpiBandComponent {
2559
2765
  </ng-template>
2560
2766
  </div>
2561
2767
  </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 });
2768
+ `, 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
2769
  }
2564
2770
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisKpiBandComponent, decorators: [{
2565
2771
  type: Component,
@@ -2665,13 +2871,13 @@ class DialogService {
2665
2871
  const component = await loader();
2666
2872
  return this.zone.run(() => this.matDialog.open(component, config));
2667
2873
  }
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 });
2874
+ 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
2875
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DialogService, providedIn: 'root' });
2670
2876
  }
2671
2877
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DialogService, decorators: [{
2672
2878
  type: Injectable,
2673
2879
  args: [{ providedIn: 'root' }]
2674
- }], ctorParameters: () => [{ type: i1$2.MatDialog }, { type: i0.NgZone }] });
2880
+ }], ctorParameters: () => [{ type: i1$1.MatDialog }, { type: i0.NgZone }] });
2675
2881
 
2676
2882
  function getCrudDrawerAdapterToken() {
2677
2883
  const registryKey = '__PAX_CRUD_DRAWER_ADAPTER_TOKEN__';
@@ -5901,7 +6107,7 @@ class CrudMetadataEditorComponent {
5901
6107
  </mat-tab>
5902
6108
  </mat-tab-group>
5903
6109
  </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 });
6110
+ `, 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
6111
  }
5906
6112
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CrudMetadataEditorComponent, decorators: [{
5907
6113
  type: Component,
@@ -6856,9 +7062,16 @@ class PraxisCrudComponent {
6856
7062
  const bulkContract = resolvedBulk.contract;
6857
7063
  const discoveredCatalogAction = resolvedBulk.catalogAction;
6858
7064
  if (bulkContract) {
7065
+ const selectedCount = Array.isArray(rawTargets) && rawTargets.length > 0 ? rawTargets.length : rows.length;
7066
+ const maxTargets = bulkContract.limits?.maxTargets;
7067
+ if (typeof maxTargets === 'number' && maxTargets > 0 && selectedCount > maxTargets) {
7068
+ this.snack.open(`A seleção atual (${selectedCount} itens) excede o limite máximo permitido (${maxTargets} itens por lote).`, undefined, { duration: 4000 });
7069
+ return;
7070
+ }
7071
+ const requiresResourceVersion = discoveredCatalogAction?.execution?.preconditions?.resourceVersion !== 'NONE';
6859
7072
  const targets = Array.isArray(rawTargets) && rawTargets.length > 0
6860
7073
  ? rawTargets
6861
- : await this.resolveBulkTargetsFromRows(rows);
7074
+ : await this.resolveBulkTargetsFromRows(rows, requiresResourceVersion);
6862
7075
  if (!targets.length) {
6863
7076
  this.snack.open('Nenhum registro selecionado para a operação em lote.', undefined, { duration: 3000 });
6864
7077
  return;
@@ -6894,7 +7107,7 @@ class PraxisCrudComponent {
6894
7107
  .pipe(takeUntilDestroyed(this.destroyRef))
6895
7108
  .subscribe((res) => {
6896
7109
  if (res?.success) {
6897
- this.refreshTable();
7110
+ this.handleBulkExecutionCompleted(discoveredCatalogAction?.execution?.refresh);
6898
7111
  this.snack.open('Atualização em lote concluída com sucesso.', undefined, { duration: 3000 });
6899
7112
  }
6900
7113
  });
@@ -6934,7 +7147,7 @@ class PraxisCrudComponent {
6934
7147
  .pipe(takeUntilDestroyed(this.destroyRef))
6935
7148
  .subscribe((res) => {
6936
7149
  if (res?.success) {
6937
- this.refreshTable();
7150
+ this.handleBulkExecutionCompleted(discoveredCatalogAction?.execution?.refresh);
6938
7151
  this.snack.open('Operação em lote executada com sucesso.', undefined, { duration: 3000 });
6939
7152
  }
6940
7153
  });
@@ -6947,39 +7160,64 @@ class PraxisCrudComponent {
6947
7160
  }
6948
7161
  await this.onAction(action, row ?? undefined, event);
6949
7162
  }
6950
- async resolveBulkTargetsFromRows(rows) {
7163
+ handleBulkExecutionCompleted(refreshPolicy) {
7164
+ try {
7165
+ this.table?.clearSelection?.();
7166
+ this.table?.selection?.clear?.();
7167
+ }
7168
+ catch {
7169
+ // Best-effort table selection cleanup
7170
+ }
7171
+ if (refreshPolicy?.collection !== false) {
7172
+ this.refreshTable();
7173
+ }
7174
+ if (refreshPolicy?.capabilities && this.tableCollectionLinks) {
7175
+ this.collectionCapabilitiesResolvedHref = null;
7176
+ this.onCollectionLinksChange(this.tableCollectionLinks);
7177
+ }
7178
+ }
7179
+ async resolveBulkTargetsFromRows(rows, fetchSelfWhenVersionMissing = true) {
6951
7180
  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();
7181
+ const results = new Array(rows.length);
7182
+ const concurrency = 4;
7183
+ for (let offset = 0; offset < rows.length; offset += concurrency) {
7184
+ const slice = rows.slice(offset, offset + concurrency);
7185
+ await Promise.all(slice.map(async (r, idx) => {
7186
+ const id = this.resolveRowResourceId(r);
7187
+ let expectedVersion = (r?.resourceVersion != null ? String(r.resourceVersion).trim() : null) ||
7188
+ (r?.version != null ? String(r.version).trim() : null) ||
7189
+ (r?._etag != null ? String(r._etag).trim() : null) ||
7190
+ (r?.etag != null ? String(r.etag).trim() : null) ||
7191
+ (r?.eTag != null ? String(r.eTag).trim() : null) ||
7192
+ undefined;
7193
+ if (fetchSelfWhenVersionMissing && !expectedVersion && r?._links?.self) {
7194
+ try {
7195
+ const selfHref = this.getResourceDiscovery().resolveLinkHref(r._links, 'self', options);
7196
+ if (selfHref) {
7197
+ const resp = await firstValueFrom(this.http.get(selfHref, { observe: 'response' }));
7198
+ const etagHeader = resp.headers?.get('ETag');
7199
+ const bodyVersion = resp.body?.data?.resourceVersion ??
7200
+ resp.body?.resourceVersion ??
7201
+ resp.body?.data?.version;
7202
+ if (etagHeader && etagHeader.trim()) {
7203
+ expectedVersion = etagHeader.trim();
7204
+ }
7205
+ else if (bodyVersion != null && String(bodyVersion).trim()) {
7206
+ expectedVersion = String(bodyVersion).trim();
7207
+ }
6974
7208
  }
6975
7209
  }
7210
+ catch {
7211
+ // Non-blocking fallback when self endpoint is unreachable or unmocked
7212
+ }
6976
7213
  }
6977
- catch {
6978
- // Non-blocking fallback when self endpoint is unreachable or unmocked
6979
- }
6980
- }
6981
- return { id: id, ...(expectedVersion ? { expectedVersion } : {}) };
6982
- }));
7214
+ results[offset + idx] = {
7215
+ id: id,
7216
+ ...(expectedVersion ? { expectedVersion } : {}),
7217
+ };
7218
+ }));
7219
+ }
7220
+ return results;
6983
7221
  }
6984
7222
  resolveSyncBulkExecutionContractForAction(action, normalizedAction, configAction, crudAction, tableBulkAction) {
6985
7223
  const direct = configAction?.execution?.bulk ||
@@ -8816,13 +9054,17 @@ class PraxisCrudComponent {
8816
9054
  for (const action of (capabilities.actions || [])
8817
9055
  .filter((a) => a.scope === 'COLLECTION' && a.execution?.bulk)
8818
9056
  .sort((left, right) => (left.order ?? 0) - (right.order ?? 0))) {
9057
+ const available = this.isCatalogActionAvailable(capabilities, action.id);
8819
9058
  items.push({
8820
9059
  id: action.id,
8821
9060
  label: action.title || action.id,
8822
9061
  icon: action.icon || (action.execution?.bulk?.mode === 'UNIFORM_UPDATE' ? 'edit_note' : 'playlist_add_check'),
8823
9062
  action: action.id,
8824
9063
  requiresSelection: true,
8825
- disabled: !this.isCatalogActionAvailable(capabilities, action.id),
9064
+ disabled: !available,
9065
+ tooltip: !available
9066
+ ? translateUnavailableWorkflowMessage(this.i18n, capabilities.operations?.[action.id]?.availability || action.availability) || action.description
9067
+ : action.description,
8826
9068
  execution: { bulk: action.execution.bulk },
8827
9069
  });
8828
9070
  }
@@ -8830,15 +9072,19 @@ class PraxisCrudComponent {
8830
9072
  if (op?.supported &&
8831
9073
  op?.scope === 'COLLECTION' &&
8832
9074
  op?.bulk?.mode === 'UNIFORM_UPDATE' &&
8833
- op.availability?.allowed !== false &&
8834
9075
  !items.some((item) => String(item['action'] || item['id']).toLowerCase() === opKey.toLowerCase())) {
8835
9076
  const isAtomic = op.bulk.atomicity === 'ATOMIC' || op.bulk.atomicity === 'ALL_OR_NONE';
9077
+ const available = op.availability?.allowed !== false;
8836
9078
  items.push({
8837
9079
  id: op.id || opKey,
8838
9080
  label: isAtomic ? 'Editar Selecionados (Atômico)' : 'Editar Selecionados',
8839
9081
  icon: 'edit_note',
8840
9082
  action: op.id || opKey,
8841
9083
  requiresSelection: true,
9084
+ disabled: !available,
9085
+ tooltip: !available
9086
+ ? translateUnavailableWorkflowMessage(this.i18n, op.availability)
9087
+ : undefined,
8842
9088
  execution: { bulk: op.bulk },
8843
9089
  });
8844
9090
  }
@@ -9813,7 +10059,7 @@ class DynamicFormDialogHostComponent {
9813
10059
  : { top: offset };
9814
10060
  return { ...horizontal, ...vertical };
9815
10061
  }
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 });
10062
+ 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
10063
  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
10064
  {
9819
10065
  provide: GenericCrudService,
@@ -9921,7 +10167,7 @@ class DynamicFormDialogHostComponent {
9921
10167
  (reactiveDeterminationPendingChange)="onReactiveDeterminationPendingChange($event)"
9922
10168
  ></praxis-dynamic-form>
9923
10169
  </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 });
10170
+ `, 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
10171
  }
9926
10172
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicFormDialogHostComponent, decorators: [{
9927
10173
  type: Component,
@@ -10056,7 +10302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
10056
10302
  }, {
10057
10303
  type: Inject,
10058
10304
  args: [MAT_DIALOG_DATA]
10059
- }] }, { type: DialogService }, { type: i2$2.GenericCrudService }, { type: undefined, decorators: [{
10305
+ }] }, { type: DialogService }, { type: i2$1.GenericCrudService }, { type: undefined, decorators: [{
10060
10306
  type: Inject,
10061
10307
  args: [ASYNC_CONFIG_STORAGE]
10062
10308
  }] }, { type: undefined, decorators: [{
@@ -10856,7 +11102,7 @@ class CrudPageHeaderComponent {
10856
11102
  <ng-content></ng-content>
10857
11103
  </div>
10858
11104
  </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"] }] });
11105
+ `, 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
11106
  }
10861
11107
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CrudPageHeaderComponent, decorators: [{
10862
11108
  type: Component,
@@ -11905,7 +12151,7 @@ class PraxisResourcePage {
11905
12151
  }
11906
12152
  }
11907
12153
  </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 });
12154
+ `, 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
12155
  }
11910
12156
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisResourcePage, decorators: [{
11911
12157
  type: Component,
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "@praxisui/crud",
3
- "version": "10.0.0-rc.13",
3
+ "version": "10.0.0-rc.14",
4
4
  "description": "CRUD building blocks for Praxis UI: integrates dynamic forms and tables with unified configuration and services.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
- "@praxisui/dynamic-form": "^10.0.0-rc.13",
9
- "@praxisui/table": "^10.0.0-rc.13",
10
- "@praxisui/core": "^10.0.0-rc.13",
11
- "@praxisui/dynamic-fields": "^10.0.0-rc.13",
12
- "@praxisui/settings-panel": "^10.0.0-rc.13",
8
+ "@praxisui/dynamic-form": "^10.0.0-rc.14",
9
+ "@praxisui/table": "^10.0.0-rc.14",
10
+ "@praxisui/core": "^10.0.0-rc.14",
11
+ "@praxisui/dynamic-fields": "^10.0.0-rc.14",
12
+ "@praxisui/settings-panel": "^10.0.0-rc.14",
13
13
  "@angular/cdk": "^21.0.0",
14
14
  "@angular/forms": "^21.0.0",
15
15
  "@angular/material": "^21.0.0",
16
16
  "@angular/router": "^21.0.0",
17
- "@praxisui/ai": "^10.0.0-rc.13",
17
+ "@praxisui/ai": "^10.0.0-rc.14",
18
18
  "rxjs": "~7.8.0"
19
19
  },
20
20
  "dependencies": {
@@ -354,6 +354,7 @@ declare class PraxisCrudComponent implements OnChanges {
354
354
  onTableDrawerOpen(event: DrawerOpenEvent<DynamicDataRecord>): void;
355
355
  onTableDrawerClose(): void;
356
356
  onBulkAction(event: any): Promise<void>;
357
+ private handleBulkExecutionCompleted;
357
358
  private resolveBulkTargetsFromRows;
358
359
  private resolveSyncBulkExecutionContractForAction;
359
360
  private resolveAsyncDiscoveredBulkContractForAction;
@@ -1181,6 +1182,11 @@ declare class PraxisBulkOperationDialogComponent implements OnInit {
1181
1182
  isBlockedByAtomicity(): boolean;
1182
1183
  isConfirmDisabled(): boolean;
1183
1184
  isDiagnosticError(diag: any): boolean;
1185
+ getRejectedTotal(): number;
1186
+ getExecutionAlertClass(): string;
1187
+ getExecutionAlertIcon(): string;
1188
+ getExecutionAlertTitle(): string;
1189
+ getExecutionAlertMessage(): string;
1184
1190
  onEvaluate(): void;
1185
1191
  loadProposalResults(cursor?: string): void;
1186
1192
  onConfirm(): void;
@@ -1257,6 +1263,11 @@ declare class PraxisBulkEditDialogComponent {
1257
1263
  isBlockedByAtomicity(): boolean;
1258
1264
  isConfirmDisabled(): boolean;
1259
1265
  isDiagnosticError(diag: ResourceBulkProposalDiagnostic | any): boolean;
1266
+ getRejectedTotal(): number;
1267
+ getExecutionAlertClass(): string;
1268
+ getExecutionAlertIcon(): string;
1269
+ getExecutionAlertTitle(): string;
1270
+ getExecutionAlertMessage(): string;
1260
1271
  onEvaluate(): void;
1261
1272
  loadProposalResults(cursor?: string): void;
1262
1273
  onConfirm(): void;