@praxisui/crud 10.0.0-rc.11 → 10.0.0-rc.13
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.
- package/ai/component-registry.json +2 -2
- package/fesm2022/praxisui-crud.mjs +1115 -145
- package/package.json +7 -7
- package/types/praxisui-crud.d.ts +55 -10
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, DestroyRef, signal, Inject, ViewEncapsulation, Component, EventEmitter, ChangeDetectorRef, Output, Input, ChangeDetectionStrategy, Injectable, InjectionToken, input, computed, effect, output, Injector, booleanAttribute, ViewChild, Optional, ENVIRONMENT_INITIALIZER } from '@angular/core';
|
|
2
|
+
import { inject, DestroyRef, signal, HostListener, Inject, ViewEncapsulation, Component, EventEmitter, ChangeDetectorRef, Output, Input, ChangeDetectionStrategy, Injectable, InjectionToken, input, computed, effect, output, Injector, booleanAttribute, ViewChild, Optional, ENVIRONMENT_INITIALIZER } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { HttpClient } from '@angular/common/http';
|
|
5
5
|
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
|
|
@@ -7,7 +7,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
|
|
|
7
7
|
import { firstValueFrom, BehaviorSubject, Subscription } from 'rxjs';
|
|
8
8
|
import { take, filter } from 'rxjs/operators';
|
|
9
9
|
import * as i2$2 from '@praxisui/core';
|
|
10
|
-
import { PraxisBulkClientService, generateBulkIdempotencyKey, SafeExpressionEvaluator, 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';
|
|
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
12
|
import * as i1$1 from '@angular/common';
|
|
13
13
|
import { CommonModule } from '@angular/common';
|
|
@@ -52,6 +52,13 @@ class PraxisBulkOperationDialogComponent {
|
|
|
52
52
|
execution = signal(null, ...(ngDevMode ? [{ debugName: "execution" }] : /* istanbul ignore next */ []));
|
|
53
53
|
errorMessage = signal(null, ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
54
54
|
parametersValue = signal({}, ...(ngDevMode ? [{ debugName: "parametersValue" }] : /* istanbul ignore next */ []));
|
|
55
|
+
proposalItems = signal([], ...(ngDevMode ? [{ debugName: "proposalItems" }] : /* istanbul ignore next */ []));
|
|
56
|
+
proposalNextCursor = signal(null, ...(ngDevMode ? [{ debugName: "proposalNextCursor" }] : /* istanbul ignore next */ []));
|
|
57
|
+
loadingProposalResults = signal(false, ...(ngDevMode ? [{ debugName: "loadingProposalResults" }] : /* istanbul ignore next */ []));
|
|
58
|
+
executionItems = signal([], ...(ngDevMode ? [{ debugName: "executionItems" }] : /* istanbul ignore next */ []));
|
|
59
|
+
executionNextCursor = signal(null, ...(ngDevMode ? [{ debugName: "executionNextCursor" }] : /* istanbul ignore next */ []));
|
|
60
|
+
loadingExecutionResults = signal(false, ...(ngDevMode ? [{ debugName: "loadingExecutionResults" }] : /* istanbul ignore next */ []));
|
|
61
|
+
cancellingExecution = signal(false, ...(ngDevMode ? [{ debugName: "cancellingExecution" }] : /* istanbul ignore next */ []));
|
|
55
62
|
action;
|
|
56
63
|
targets;
|
|
57
64
|
confirmationIdempotencyKey;
|
|
@@ -80,22 +87,33 @@ class PraxisBulkOperationDialogComponent {
|
|
|
80
87
|
hasParametersSchema() {
|
|
81
88
|
const bulkContract = this.action.execution?.bulk;
|
|
82
89
|
const hasSchemaUrl = Boolean(bulkContract?.evaluationOperation?.requestSchema?.url || this.action.requestSchemaUrl);
|
|
83
|
-
if (hasSchemaUrl
|
|
84
|
-
|
|
85
|
-
return true;
|
|
90
|
+
if (!hasSchemaUrl) {
|
|
91
|
+
return false;
|
|
86
92
|
}
|
|
87
|
-
|
|
93
|
+
const descriptors = this.action.commandParameterDescriptors ||
|
|
94
|
+
bulkContract?.commandParameterDescriptors;
|
|
95
|
+
if (Array.isArray(descriptors)) {
|
|
96
|
+
return descriptors.length > 0;
|
|
97
|
+
}
|
|
98
|
+
return Boolean(typeof bulkContract?.parametersPointer === 'string' &&
|
|
99
|
+
bulkContract.parametersPointer.trim().length > 0);
|
|
88
100
|
}
|
|
89
101
|
parametersSchemaUrl() {
|
|
90
102
|
const bulkContract = this.action.execution?.bulk;
|
|
91
|
-
return (bulkContract?.evaluationOperation
|
|
103
|
+
return (bulkContract?.evaluationOperation?.requestSchema?.url ||
|
|
92
104
|
this.action.requestSchemaUrl ||
|
|
93
105
|
null);
|
|
94
106
|
}
|
|
95
107
|
onParametersChange(event) {
|
|
96
|
-
const
|
|
97
|
-
if (
|
|
98
|
-
|
|
108
|
+
const raw = event?.formData ?? event?.value ?? event;
|
|
109
|
+
if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
|
|
110
|
+
const unwrapped = raw.parameters &&
|
|
111
|
+
typeof raw.parameters === 'object' &&
|
|
112
|
+
!Array.isArray(raw.parameters) &&
|
|
113
|
+
Object.keys(raw).length === 1
|
|
114
|
+
? raw.parameters
|
|
115
|
+
: raw;
|
|
116
|
+
this.parametersValue.set(unwrapped);
|
|
99
117
|
}
|
|
100
118
|
}
|
|
101
119
|
isBlockedByAtomicity() {
|
|
@@ -103,7 +121,8 @@ class PraxisBulkOperationDialogComponent {
|
|
|
103
121
|
const bulkContract = this.action.execution?.bulk;
|
|
104
122
|
if (!prop || !bulkContract)
|
|
105
123
|
return false;
|
|
106
|
-
return bulkContract.atomicity === 'ATOMIC'
|
|
124
|
+
return ((bulkContract.atomicity === 'ATOMIC' || bulkContract.atomicity === 'ALL_OR_NONE') &&
|
|
125
|
+
prop.totals.blocked > 0);
|
|
107
126
|
}
|
|
108
127
|
isConfirmDisabled() {
|
|
109
128
|
const prop = this.proposal();
|
|
@@ -133,10 +152,14 @@ class PraxisBulkOperationDialogComponent {
|
|
|
133
152
|
this.errorMessage.set('Contrato de operação em lote não encontrado na ação.');
|
|
134
153
|
return;
|
|
135
154
|
}
|
|
155
|
+
this.confirmationIdempotencyKey = undefined;
|
|
136
156
|
this.step.set('EVALUATING');
|
|
137
157
|
this.errorMessage.set(null);
|
|
158
|
+
const executionMode = bulkContract.executionModes?.includes('SYNC')
|
|
159
|
+
? 'SYNC'
|
|
160
|
+
: (bulkContract.executionModes?.[0] ?? 'SYNC');
|
|
138
161
|
const request = {
|
|
139
|
-
executionMode
|
|
162
|
+
executionMode,
|
|
140
163
|
selection: {
|
|
141
164
|
mode: 'EXPLICIT',
|
|
142
165
|
targets: this.targets,
|
|
@@ -153,7 +176,15 @@ class PraxisBulkOperationDialogComponent {
|
|
|
153
176
|
.subscribe({
|
|
154
177
|
next: (proposal) => {
|
|
155
178
|
this.proposal.set(proposal);
|
|
179
|
+
const inlineItems = Array.isArray(proposal.items)
|
|
180
|
+
? proposal.items
|
|
181
|
+
: [];
|
|
182
|
+
this.proposalItems.set(inlineItems);
|
|
183
|
+
this.proposalNextCursor.set(null);
|
|
156
184
|
this.step.set('PREVIEW');
|
|
185
|
+
if (inlineItems.length === 0 && bulkContract.proposalResultsOperation) {
|
|
186
|
+
this.loadProposalResults();
|
|
187
|
+
}
|
|
157
188
|
},
|
|
158
189
|
error: (err) => {
|
|
159
190
|
this.errorMessage.set(err?.error?.message || err?.message || 'Falha ao avaliar proposta em lote.');
|
|
@@ -161,6 +192,38 @@ class PraxisBulkOperationDialogComponent {
|
|
|
161
192
|
},
|
|
162
193
|
});
|
|
163
194
|
}
|
|
195
|
+
loadProposalResults(cursor) {
|
|
196
|
+
const prop = this.proposal();
|
|
197
|
+
const bulkContract = this.action.execution?.bulk;
|
|
198
|
+
if (!prop ||
|
|
199
|
+
!bulkContract?.proposalResultsOperation ||
|
|
200
|
+
typeof this.bulkClient.getProposalResults !== 'function') {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
this.loadingProposalResults.set(true);
|
|
204
|
+
const requestOptions = {
|
|
205
|
+
endpointKey: this.data.endpointKey,
|
|
206
|
+
apiUrlEntry: this.data.apiUrlEntry,
|
|
207
|
+
};
|
|
208
|
+
this.bulkClient
|
|
209
|
+
.getProposalResults(bulkContract.proposalResultsOperation, prop.proposalId, 50, cursor, requestOptions)
|
|
210
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
211
|
+
.subscribe({
|
|
212
|
+
next: (page) => {
|
|
213
|
+
const newItems = Array.isArray(page?.items)
|
|
214
|
+
? page.items
|
|
215
|
+
: Array.isArray(page?.content)
|
|
216
|
+
? page.content
|
|
217
|
+
: [];
|
|
218
|
+
this.proposalItems.update((prev) => (cursor ? [...prev, ...newItems] : newItems));
|
|
219
|
+
this.proposalNextCursor.set(page?.nextCursor ?? page?.next ?? null);
|
|
220
|
+
this.loadingProposalResults.set(false);
|
|
221
|
+
},
|
|
222
|
+
error: () => {
|
|
223
|
+
this.loadingProposalResults.set(false);
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
164
227
|
onConfirm() {
|
|
165
228
|
const prop = this.proposal();
|
|
166
229
|
const bulkContract = this.action.execution?.bulk;
|
|
@@ -182,7 +245,25 @@ class PraxisBulkOperationDialogComponent {
|
|
|
182
245
|
.subscribe({
|
|
183
246
|
next: (execution) => {
|
|
184
247
|
this.execution.set(execution);
|
|
185
|
-
this.
|
|
248
|
+
const isTerminal = typeof this.bulkClient.isTerminalStatus === 'function'
|
|
249
|
+
? this.bulkClient.isTerminalStatus(execution.status)
|
|
250
|
+
: execution.status !== 'QUEUED' && execution.status !== 'RUNNING';
|
|
251
|
+
if (!isTerminal && bulkContract.executionOperation && typeof this.bulkClient.waitForExecution === 'function') {
|
|
252
|
+
this.bulkClient
|
|
253
|
+
.waitForExecution(bulkContract.executionOperation, execution.executionId, 1000, 60000, requestOptions)
|
|
254
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
255
|
+
.subscribe({
|
|
256
|
+
next: (finalExec) => {
|
|
257
|
+
this.finalizeExecution(finalExec);
|
|
258
|
+
},
|
|
259
|
+
error: (err) => {
|
|
260
|
+
this.errorMessage.set(err?.error?.message || err?.message || 'Falha ao acompanhar execução em lote.');
|
|
261
|
+
this.step.set('RESULT');
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
this.finalizeExecution(execution);
|
|
186
267
|
},
|
|
187
268
|
error: (err) => {
|
|
188
269
|
this.errorMessage.set(err?.error?.message || err?.message || 'Falha ao confirmar execução em lote.');
|
|
@@ -190,6 +271,89 @@ class PraxisBulkOperationDialogComponent {
|
|
|
190
271
|
},
|
|
191
272
|
});
|
|
192
273
|
}
|
|
274
|
+
finalizeExecution(exec) {
|
|
275
|
+
this.execution.set(exec);
|
|
276
|
+
const inlineItems = Array.isArray(exec.items)
|
|
277
|
+
? exec.items
|
|
278
|
+
: [];
|
|
279
|
+
this.executionItems.set(inlineItems);
|
|
280
|
+
this.executionNextCursor.set(null);
|
|
281
|
+
this.step.set('RESULT');
|
|
282
|
+
if (inlineItems.length === 0 && this.action.execution?.bulk?.resultsOperation) {
|
|
283
|
+
this.loadExecutionResults();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
loadExecutionResults(cursor) {
|
|
287
|
+
const exec = this.execution();
|
|
288
|
+
const bulkContract = this.action.execution?.bulk;
|
|
289
|
+
if (!exec ||
|
|
290
|
+
!bulkContract?.resultsOperation ||
|
|
291
|
+
typeof this.bulkClient.getExecutionResults !== 'function') {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
this.loadingExecutionResults.set(true);
|
|
295
|
+
const requestOptions = {
|
|
296
|
+
endpointKey: this.data.endpointKey,
|
|
297
|
+
apiUrlEntry: this.data.apiUrlEntry,
|
|
298
|
+
};
|
|
299
|
+
this.bulkClient
|
|
300
|
+
.getExecutionResults(bulkContract.resultsOperation, exec.executionId, 50, cursor, requestOptions)
|
|
301
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
302
|
+
.subscribe({
|
|
303
|
+
next: (page) => {
|
|
304
|
+
const newItems = Array.isArray(page?.items)
|
|
305
|
+
? page.items
|
|
306
|
+
: Array.isArray(page?.content)
|
|
307
|
+
? page.content
|
|
308
|
+
: [];
|
|
309
|
+
this.executionItems.update((prev) => (cursor ? [...prev, ...newItems] : newItems));
|
|
310
|
+
this.executionNextCursor.set(page?.nextCursor ?? page?.next ?? null);
|
|
311
|
+
this.loadingExecutionResults.set(false);
|
|
312
|
+
},
|
|
313
|
+
error: () => {
|
|
314
|
+
this.loadingExecutionResults.set(false);
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
canCancelExecution() {
|
|
319
|
+
const exec = this.execution();
|
|
320
|
+
const bulkContract = this.action.execution?.bulk;
|
|
321
|
+
if (this.step() !== 'CONFIRMING' || !exec || !bulkContract?.cancelOperation) {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
const isTerminal = typeof this.bulkClient.isTerminalStatus === 'function'
|
|
325
|
+
? this.bulkClient.isTerminalStatus(exec.status)
|
|
326
|
+
: exec.status !== 'QUEUED' && exec.status !== 'RUNNING';
|
|
327
|
+
return !isTerminal;
|
|
328
|
+
}
|
|
329
|
+
onCancelActiveExecution() {
|
|
330
|
+
const exec = this.execution();
|
|
331
|
+
const bulkContract = this.action.execution?.bulk;
|
|
332
|
+
if (!this.canCancelExecution() ||
|
|
333
|
+
!exec ||
|
|
334
|
+
!bulkContract?.cancelOperation ||
|
|
335
|
+
typeof this.bulkClient.cancel !== 'function') {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
this.cancellingExecution.set(true);
|
|
339
|
+
const requestOptions = {
|
|
340
|
+
endpointKey: this.data.endpointKey,
|
|
341
|
+
apiUrlEntry: this.data.apiUrlEntry,
|
|
342
|
+
};
|
|
343
|
+
this.bulkClient
|
|
344
|
+
.cancel(bulkContract.cancelOperation, exec.executionId, requestOptions)
|
|
345
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
346
|
+
.subscribe({
|
|
347
|
+
next: (cancelledExec) => {
|
|
348
|
+
this.cancellingExecution.set(false);
|
|
349
|
+
this.finalizeExecution(cancelledExec);
|
|
350
|
+
},
|
|
351
|
+
error: (err) => {
|
|
352
|
+
this.cancellingExecution.set(false);
|
|
353
|
+
this.errorMessage.set(err?.error?.message || err?.message || 'Falha ao solicitar cancelamento da execução em lote.');
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
}
|
|
193
357
|
onCloseSuccess() {
|
|
194
358
|
this.dialogRef.close({
|
|
195
359
|
success: true,
|
|
@@ -197,17 +361,27 @@ class PraxisBulkOperationDialogComponent {
|
|
|
197
361
|
});
|
|
198
362
|
}
|
|
199
363
|
onCancel() {
|
|
364
|
+
if (this.step() === 'RESULT') {
|
|
365
|
+
this.onCloseSuccess();
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
200
368
|
this.dialogRef.close({ success: false });
|
|
201
369
|
}
|
|
370
|
+
onEscape(event) {
|
|
371
|
+
if (this.step() !== 'CONFIRMING' && this.step() !== 'EVALUATING') {
|
|
372
|
+
event?.preventDefault();
|
|
373
|
+
this.onCancel();
|
|
374
|
+
}
|
|
375
|
+
}
|
|
202
376
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisBulkOperationDialogComponent, deps: [{ token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
203
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisBulkOperationDialogComponent, isStandalone: true, selector: "praxis-bulk-operation-dialog", ngImport: i0, template: `
|
|
204
|
-
<div class="praxis-bulk-dialog" role="dialog" aria-labelledby="praxis-bulk-dialog-title">
|
|
377
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisBulkOperationDialogComponent, isStandalone: true, selector: "praxis-bulk-operation-dialog", host: { listeners: { "keydown.escape": "onEscape($event)" } }, ngImport: i0, template: `
|
|
378
|
+
<div class="praxis-bulk-dialog" role="dialog" aria-labelledby="praxis-bulk-dialog-title" aria-describedby="praxis-bulk-dialog-subtitle">
|
|
205
379
|
<div class="praxis-bulk-dialog__header">
|
|
206
380
|
<div class="praxis-bulk-dialog__title-group">
|
|
207
381
|
<mat-icon class="praxis-bulk-dialog__header-icon">auto_awesome_motion</mat-icon>
|
|
208
382
|
<div>
|
|
209
383
|
<h2 id="praxis-bulk-dialog-title" class="praxis-bulk-dialog__title">{{ getActionTitle() }}</h2>
|
|
210
|
-
<p class="praxis-bulk-dialog__subtitle">
|
|
384
|
+
<p id="praxis-bulk-dialog-subtitle" class="praxis-bulk-dialog__subtitle">
|
|
211
385
|
{{ action.description || 'Execução de comando de domínio com avaliação prévia de regras de negócio e integridade.' }}
|
|
212
386
|
</p>
|
|
213
387
|
</div>
|
|
@@ -338,6 +512,34 @@ class PraxisBulkOperationDialogComponent {
|
|
|
338
512
|
</div>
|
|
339
513
|
</div>
|
|
340
514
|
}
|
|
515
|
+
|
|
516
|
+
<!-- Resultados Paginados da Proposta -->
|
|
517
|
+
@if (proposalItems().length > 0) {
|
|
518
|
+
<div class="praxis-bulk-dialog__diagnostics">
|
|
519
|
+
<h4 class="diagnostics-title">Avaliação por Registro ({{ proposalItems().length }})</h4>
|
|
520
|
+
<div class="diagnostics-list">
|
|
521
|
+
@for (item of proposalItems(); track item.id) {
|
|
522
|
+
<div class="diagnostic-item" [class.diagnostic-item--error]="item.decision === 'BLOCKED'">
|
|
523
|
+
<mat-icon>{{ item.decision === 'BLOCKED' ? 'cancel' : 'check_circle' }}</mat-icon>
|
|
524
|
+
<div class="diagnostic-text">
|
|
525
|
+
<span class="diagnostic-target">Item {{ item.id }}:</span>
|
|
526
|
+
<span>{{ item.decision === 'BLOCKED' ? (item.diagnostics?.[0]?.message || 'Bloqueado') : 'Elegível' }}</span>
|
|
527
|
+
</div>
|
|
528
|
+
</div>
|
|
529
|
+
}
|
|
530
|
+
</div>
|
|
531
|
+
@if (proposalNextCursor()) {
|
|
532
|
+
<button
|
|
533
|
+
mat-stroked-button
|
|
534
|
+
type="button"
|
|
535
|
+
(click)="loadProposalResults(proposalNextCursor()!)"
|
|
536
|
+
[disabled]="loadingProposalResults()"
|
|
537
|
+
>
|
|
538
|
+
{{ loadingProposalResults() ? 'Carregando...' : 'Carregar mais resultados' }}
|
|
539
|
+
</button>
|
|
540
|
+
}
|
|
541
|
+
</div>
|
|
542
|
+
}
|
|
341
543
|
</div>
|
|
342
544
|
}
|
|
343
545
|
|
|
@@ -346,6 +548,17 @@ class PraxisBulkOperationDialogComponent {
|
|
|
346
548
|
<div class="praxis-bulk-dialog__loading">
|
|
347
549
|
<mat-spinner diameter="40" />
|
|
348
550
|
<p>Executando alterações em lote com garantia de idempotência...</p>
|
|
551
|
+
@if (canCancelExecution()) {
|
|
552
|
+
<button
|
|
553
|
+
mat-stroked-button
|
|
554
|
+
color="warn"
|
|
555
|
+
type="button"
|
|
556
|
+
(click)="onCancelActiveExecution()"
|
|
557
|
+
[disabled]="cancellingExecution()"
|
|
558
|
+
>
|
|
559
|
+
{{ cancellingExecution() ? 'Cancelando...' : 'Cancelar Execução' }}
|
|
560
|
+
</button>
|
|
561
|
+
}
|
|
349
562
|
</div>
|
|
350
563
|
}
|
|
351
564
|
|
|
@@ -355,25 +568,52 @@ class PraxisBulkOperationDialogComponent {
|
|
|
355
568
|
<div class="praxis-bulk-dialog__alert praxis-bulk-dialog__alert--success">
|
|
356
569
|
<mat-icon>verified</mat-icon>
|
|
357
570
|
<div class="alert-content">
|
|
358
|
-
<strong>Operação concluída com
|
|
359
|
-
<p>
|
|
571
|
+
<strong>Operação concluída com êxito!</strong>
|
|
572
|
+
<p>Transação homologada e registrada na auditoria corporativa.</p>
|
|
360
573
|
</div>
|
|
361
574
|
</div>
|
|
362
575
|
|
|
363
576
|
<div class="praxis-bulk-dialog__totals-grid">
|
|
364
577
|
<div class="praxis-bulk-dialog__total-card total-card--executable">
|
|
365
|
-
<span class="total-label">
|
|
578
|
+
<span class="total-label">Efetivados</span>
|
|
366
579
|
<span class="total-value">{{ execution()?.totals?.confirmed }}</span>
|
|
367
580
|
</div>
|
|
368
581
|
<div class="praxis-bulk-dialog__total-card">
|
|
369
|
-
<span class="total-label">
|
|
582
|
+
<span class="total-label">Preservados</span>
|
|
370
583
|
<span class="total-value">{{ execution()?.totals?.unchanged }}</span>
|
|
371
584
|
</div>
|
|
372
585
|
<div class="praxis-bulk-dialog__total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
|
|
373
|
-
<span class="total-label">
|
|
586
|
+
<span class="total-label">Rejeitados</span>
|
|
374
587
|
<span class="total-value">{{ execution()?.totals?.denied }}</span>
|
|
375
588
|
</div>
|
|
376
589
|
</div>
|
|
590
|
+
|
|
591
|
+
@if (executionItems().length > 0) {
|
|
592
|
+
<div class="praxis-bulk-dialog__diagnostics">
|
|
593
|
+
<h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
|
|
594
|
+
<div class="diagnostics-list">
|
|
595
|
+
@for (item of executionItems(); track item.id) {
|
|
596
|
+
<div class="diagnostic-item" [class.diagnostic-item--error]="item.status !== 'CONFIRMED' && item.status !== 'UNCHANGED'">
|
|
597
|
+
<mat-icon>{{ item.status === 'CONFIRMED' || item.status === 'UNCHANGED' ? 'check_circle' : 'cancel' }}</mat-icon>
|
|
598
|
+
<div class="diagnostic-text">
|
|
599
|
+
<span class="diagnostic-target">Item {{ item.id }}:</span>
|
|
600
|
+
<span>{{ item.diagnostics?.[0]?.message || item.status }}</span>
|
|
601
|
+
</div>
|
|
602
|
+
</div>
|
|
603
|
+
}
|
|
604
|
+
</div>
|
|
605
|
+
@if (executionNextCursor()) {
|
|
606
|
+
<button
|
|
607
|
+
mat-stroked-button
|
|
608
|
+
type="button"
|
|
609
|
+
(click)="loadExecutionResults(executionNextCursor()!)"
|
|
610
|
+
[disabled]="loadingExecutionResults()"
|
|
611
|
+
>
|
|
612
|
+
{{ loadingExecutionResults() ? 'Carregando...' : 'Carregar mais resultados' }}
|
|
613
|
+
</button>
|
|
614
|
+
}
|
|
615
|
+
</div>
|
|
616
|
+
}
|
|
377
617
|
</div>
|
|
378
618
|
}
|
|
379
619
|
|
|
@@ -420,7 +660,7 @@ class PraxisBulkOperationDialogComponent {
|
|
|
420
660
|
}
|
|
421
661
|
</div>
|
|
422
662
|
</div>
|
|
423
|
-
`, isInline: true, styles: [".cdk-overlay-pane.praxis-bulk-dialog-panel{--mat-dialog-container-color: var(--praxis-surface-card, var(--card, var(--md-sys-color-surface-container, #1e293b)));--mat-dialog-container-shape: 16px;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(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))));box-shadow:var(--praxis-theme-elevation, 0 24px 64px rgba(0, 0, 0, .45));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(--praxis-text-primary, var(--foreground, var(--md-sys-color-on-surface, inherit)));background:transparent;box-sizing:border-box}.praxis-bulk-dialog__header{display:flex;justify-content:space-between;align-items:flex-start;padding:20px 24px 16px;border-bottom:1px solid var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))))}.praxis-bulk-dialog__title-group{display:flex;align-items:flex-start;gap:12px}.praxis-bulk-dialog__header-icon{color:var(--praxis-primary, var(--primary, var(--md-sys-color-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(--praxis-text-primary, var(--foreground, var(--md-sys-color-on-surface, inherit)))}.praxis-bulk-dialog__subtitle{font-size:.875rem;color:var(--praxis-text-muted, var(--muted-foreground, var(--md-sys-color-on-surface-variant, rgba(148, 163, 184, .8))));margin:4px 0 0}.praxis-bulk-dialog__content{padding:20px 24px;overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:16px}.praxis-bulk-dialog__targets-badge{display:inline-flex;align-items:center;gap:8px;padding:8px 14px;background:color-mix(in srgb,var(--praxis-text-primary, var(--foreground, currentColor)) 6%,transparent);border:1px solid color-mix(in srgb,var(--praxis-border-subtle, var(--border, currentColor)) 25%,transparent);border-radius:8px;font-size:.875rem;color:var(--praxis-text-primary, var(--foreground, inherit))}.praxis-bulk-dialog__targets-badge mat-icon{font-size:18px;width:18px;height:18px;color:var(--praxis-primary, var(--primary, var(--md-sys-color-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(--praxis-text-primary, var(--foreground, var(--md-sys-color-on-surface, inherit)))}.praxis-bulk-dialog__totals-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:0}.praxis-bulk-dialog__total-card{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:96px;padding:18px 20px;background:color-mix(in srgb,var(--praxis-text-primary, var(--foreground, currentColor)) 4%,transparent);border:1px solid var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .15))));border-radius:12px;transition:background .2s ease,border-color .2s ease;box-sizing:border-box}.praxis-bulk-dialog__total-card .total-label{font-size:.75rem;text-transform:uppercase;letter-spacing:.06em;color:var(--praxis-text-muted, var(--muted-foreground, var(--md-sys-color-on-surface-variant, rgba(148, 163, 184, .8))));font-weight:600;margin-bottom:6px}.praxis-bulk-dialog__total-card .total-value{font-size:1.875rem;font-weight:700;color:var(--praxis-text-primary, var(--foreground, var(--md-sys-color-on-surface, inherit)));line-height:1;margin:0}.total-card--executable{border-color:color-mix(in srgb,var(--praxis-success, #10b981) 50%,transparent);background:color-mix(in srgb,var(--praxis-success, #10b981) 12%,transparent)}.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);background:color-mix(in srgb,var(--praxis-error, #ef4444) 12%,transparent)}.total-card--blocked .total-value{color:var(--praxis-error, #ef4444)}.praxis-bulk-dialog__alert{display:flex;align-items:flex-start;gap:14px;padding:16px 20px;border-radius:12px;font-size:.875rem;line-height:1.45}.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:3px}.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) 12%,transparent);border:1px solid color-mix(in srgb,var(--praxis-error, #ef4444) 40%,transparent);color:var(--praxis-text-primary, var(--foreground, inherit))}.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) 12%,transparent);border:1px solid color-mix(in srgb,var(--praxis-warning, #d97706) 40%,transparent);color:var(--praxis-text-primary, var(--foreground, inherit))}.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) 12%,transparent);border:1px solid color-mix(in srgb,var(--praxis-success, #10b981) 40%,transparent);color:var(--praxis-text-primary, var(--foreground, inherit))}.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;background:color-mix(in srgb,var(--praxis-info, #0284c7) 12%,transparent);border:1px solid color-mix(in srgb,var(--praxis-info, #0284c7) 35%,transparent);border-radius:8px;color:var(--praxis-text-primary, var(--foreground, inherit));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(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))));border-radius:8px;padding:12px 16px;background:color-mix(in srgb,var(--praxis-text-primary, var(--foreground, currentColor)) 3%,transparent)}.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 });
|
|
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 });
|
|
424
664
|
}
|
|
425
665
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisBulkOperationDialogComponent, decorators: [{
|
|
426
666
|
type: Component,
|
|
@@ -433,13 +673,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
433
673
|
MatProgressSpinnerModule,
|
|
434
674
|
PraxisDynamicForm,
|
|
435
675
|
], template: `
|
|
436
|
-
<div class="praxis-bulk-dialog" role="dialog" aria-labelledby="praxis-bulk-dialog-title">
|
|
676
|
+
<div class="praxis-bulk-dialog" role="dialog" aria-labelledby="praxis-bulk-dialog-title" aria-describedby="praxis-bulk-dialog-subtitle">
|
|
437
677
|
<div class="praxis-bulk-dialog__header">
|
|
438
678
|
<div class="praxis-bulk-dialog__title-group">
|
|
439
679
|
<mat-icon class="praxis-bulk-dialog__header-icon">auto_awesome_motion</mat-icon>
|
|
440
680
|
<div>
|
|
441
681
|
<h2 id="praxis-bulk-dialog-title" class="praxis-bulk-dialog__title">{{ getActionTitle() }}</h2>
|
|
442
|
-
<p class="praxis-bulk-dialog__subtitle">
|
|
682
|
+
<p id="praxis-bulk-dialog-subtitle" class="praxis-bulk-dialog__subtitle">
|
|
443
683
|
{{ action.description || 'Execução de comando de domínio com avaliação prévia de regras de negócio e integridade.' }}
|
|
444
684
|
</p>
|
|
445
685
|
</div>
|
|
@@ -570,6 +810,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
570
810
|
</div>
|
|
571
811
|
</div>
|
|
572
812
|
}
|
|
813
|
+
|
|
814
|
+
<!-- Resultados Paginados da Proposta -->
|
|
815
|
+
@if (proposalItems().length > 0) {
|
|
816
|
+
<div class="praxis-bulk-dialog__diagnostics">
|
|
817
|
+
<h4 class="diagnostics-title">Avaliação por Registro ({{ proposalItems().length }})</h4>
|
|
818
|
+
<div class="diagnostics-list">
|
|
819
|
+
@for (item of proposalItems(); track item.id) {
|
|
820
|
+
<div class="diagnostic-item" [class.diagnostic-item--error]="item.decision === 'BLOCKED'">
|
|
821
|
+
<mat-icon>{{ item.decision === 'BLOCKED' ? 'cancel' : 'check_circle' }}</mat-icon>
|
|
822
|
+
<div class="diagnostic-text">
|
|
823
|
+
<span class="diagnostic-target">Item {{ item.id }}:</span>
|
|
824
|
+
<span>{{ item.decision === 'BLOCKED' ? (item.diagnostics?.[0]?.message || 'Bloqueado') : 'Elegível' }}</span>
|
|
825
|
+
</div>
|
|
826
|
+
</div>
|
|
827
|
+
}
|
|
828
|
+
</div>
|
|
829
|
+
@if (proposalNextCursor()) {
|
|
830
|
+
<button
|
|
831
|
+
mat-stroked-button
|
|
832
|
+
type="button"
|
|
833
|
+
(click)="loadProposalResults(proposalNextCursor()!)"
|
|
834
|
+
[disabled]="loadingProposalResults()"
|
|
835
|
+
>
|
|
836
|
+
{{ loadingProposalResults() ? 'Carregando...' : 'Carregar mais resultados' }}
|
|
837
|
+
</button>
|
|
838
|
+
}
|
|
839
|
+
</div>
|
|
840
|
+
}
|
|
573
841
|
</div>
|
|
574
842
|
}
|
|
575
843
|
|
|
@@ -578,6 +846,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
578
846
|
<div class="praxis-bulk-dialog__loading">
|
|
579
847
|
<mat-spinner diameter="40" />
|
|
580
848
|
<p>Executando alterações em lote com garantia de idempotência...</p>
|
|
849
|
+
@if (canCancelExecution()) {
|
|
850
|
+
<button
|
|
851
|
+
mat-stroked-button
|
|
852
|
+
color="warn"
|
|
853
|
+
type="button"
|
|
854
|
+
(click)="onCancelActiveExecution()"
|
|
855
|
+
[disabled]="cancellingExecution()"
|
|
856
|
+
>
|
|
857
|
+
{{ cancellingExecution() ? 'Cancelando...' : 'Cancelar Execução' }}
|
|
858
|
+
</button>
|
|
859
|
+
}
|
|
581
860
|
</div>
|
|
582
861
|
}
|
|
583
862
|
|
|
@@ -587,25 +866,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
587
866
|
<div class="praxis-bulk-dialog__alert praxis-bulk-dialog__alert--success">
|
|
588
867
|
<mat-icon>verified</mat-icon>
|
|
589
868
|
<div class="alert-content">
|
|
590
|
-
<strong>Operação concluída com
|
|
591
|
-
<p>
|
|
869
|
+
<strong>Operação concluída com êxito!</strong>
|
|
870
|
+
<p>Transação homologada e registrada na auditoria corporativa.</p>
|
|
592
871
|
</div>
|
|
593
872
|
</div>
|
|
594
873
|
|
|
595
874
|
<div class="praxis-bulk-dialog__totals-grid">
|
|
596
875
|
<div class="praxis-bulk-dialog__total-card total-card--executable">
|
|
597
|
-
<span class="total-label">
|
|
876
|
+
<span class="total-label">Efetivados</span>
|
|
598
877
|
<span class="total-value">{{ execution()?.totals?.confirmed }}</span>
|
|
599
878
|
</div>
|
|
600
879
|
<div class="praxis-bulk-dialog__total-card">
|
|
601
|
-
<span class="total-label">
|
|
880
|
+
<span class="total-label">Preservados</span>
|
|
602
881
|
<span class="total-value">{{ execution()?.totals?.unchanged }}</span>
|
|
603
882
|
</div>
|
|
604
883
|
<div class="praxis-bulk-dialog__total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
|
|
605
|
-
<span class="total-label">
|
|
884
|
+
<span class="total-label">Rejeitados</span>
|
|
606
885
|
<span class="total-value">{{ execution()?.totals?.denied }}</span>
|
|
607
886
|
</div>
|
|
608
887
|
</div>
|
|
888
|
+
|
|
889
|
+
@if (executionItems().length > 0) {
|
|
890
|
+
<div class="praxis-bulk-dialog__diagnostics">
|
|
891
|
+
<h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
|
|
892
|
+
<div class="diagnostics-list">
|
|
893
|
+
@for (item of executionItems(); track item.id) {
|
|
894
|
+
<div class="diagnostic-item" [class.diagnostic-item--error]="item.status !== 'CONFIRMED' && item.status !== 'UNCHANGED'">
|
|
895
|
+
<mat-icon>{{ item.status === 'CONFIRMED' || item.status === 'UNCHANGED' ? 'check_circle' : 'cancel' }}</mat-icon>
|
|
896
|
+
<div class="diagnostic-text">
|
|
897
|
+
<span class="diagnostic-target">Item {{ item.id }}:</span>
|
|
898
|
+
<span>{{ item.diagnostics?.[0]?.message || item.status }}</span>
|
|
899
|
+
</div>
|
|
900
|
+
</div>
|
|
901
|
+
}
|
|
902
|
+
</div>
|
|
903
|
+
@if (executionNextCursor()) {
|
|
904
|
+
<button
|
|
905
|
+
mat-stroked-button
|
|
906
|
+
type="button"
|
|
907
|
+
(click)="loadExecutionResults(executionNextCursor()!)"
|
|
908
|
+
[disabled]="loadingExecutionResults()"
|
|
909
|
+
>
|
|
910
|
+
{{ loadingExecutionResults() ? 'Carregando...' : 'Carregar mais resultados' }}
|
|
911
|
+
</button>
|
|
912
|
+
}
|
|
913
|
+
</div>
|
|
914
|
+
}
|
|
609
915
|
</div>
|
|
610
916
|
}
|
|
611
917
|
|
|
@@ -652,11 +958,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
652
958
|
}
|
|
653
959
|
</div>
|
|
654
960
|
</div>
|
|
655
|
-
`, styles: [".cdk-overlay-pane.praxis-bulk-dialog-panel{--mat-dialog-container-color: var(--praxis-surface
|
|
961
|
+
`, 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"] }]
|
|
656
962
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
657
963
|
type: Inject,
|
|
658
964
|
args: [MAT_DIALOG_DATA]
|
|
659
|
-
}] }]
|
|
965
|
+
}] }], propDecorators: { onEscape: [{
|
|
966
|
+
type: HostListener,
|
|
967
|
+
args: ['keydown.escape', ['$event']]
|
|
968
|
+
}] } });
|
|
660
969
|
|
|
661
970
|
class PraxisBulkEditDialogComponent {
|
|
662
971
|
data;
|
|
@@ -668,17 +977,25 @@ class PraxisBulkEditDialogComponent {
|
|
|
668
977
|
proposal = signal(null, ...(ngDevMode ? [{ debugName: "proposal" }] : /* istanbul ignore next */ []));
|
|
669
978
|
execution = signal(null, ...(ngDevMode ? [{ debugName: "execution" }] : /* istanbul ignore next */ []));
|
|
670
979
|
errorMessage = signal(null, ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
980
|
+
fetchedSchema = signal(null, ...(ngDevMode ? [{ debugName: "fetchedSchema" }] : /* istanbul ignore next */ []));
|
|
981
|
+
proposalItems = signal([], ...(ngDevMode ? [{ debugName: "proposalItems" }] : /* istanbul ignore next */ []));
|
|
982
|
+
proposalNextCursor = signal(null, ...(ngDevMode ? [{ debugName: "proposalNextCursor" }] : /* istanbul ignore next */ []));
|
|
983
|
+
loadingProposalResults = signal(false, ...(ngDevMode ? [{ debugName: "loadingProposalResults" }] : /* istanbul ignore next */ []));
|
|
984
|
+
executionItems = signal([], ...(ngDevMode ? [{ debugName: "executionItems" }] : /* istanbul ignore next */ []));
|
|
985
|
+
executionNextCursor = signal(null, ...(ngDevMode ? [{ debugName: "executionNextCursor" }] : /* istanbul ignore next */ []));
|
|
986
|
+
loadingExecutionResults = signal(false, ...(ngDevMode ? [{ debugName: "loadingExecutionResults" }] : /* istanbul ignore next */ []));
|
|
987
|
+
cancellingExecution = signal(false, ...(ngDevMode ? [{ debugName: "cancellingExecution" }] : /* istanbul ignore next */ []));
|
|
671
988
|
contract;
|
|
672
989
|
targets;
|
|
673
990
|
writableFields;
|
|
674
991
|
clearableFields;
|
|
675
992
|
confirmationIdempotencyKey = null;
|
|
676
993
|
get dialogTitle() {
|
|
677
|
-
return this.data.title || 'Atualização de
|
|
994
|
+
return this.data.title || 'Atualização de Registros em Massa';
|
|
678
995
|
}
|
|
679
996
|
get dialogSubtitle() {
|
|
680
997
|
return (this.data.subtitle ||
|
|
681
|
-
'
|
|
998
|
+
'Atualize os campos homologados de forma simultânea e consistente para todos os registros selecionados.');
|
|
682
999
|
}
|
|
683
1000
|
constructor(data) {
|
|
684
1001
|
this.data = data;
|
|
@@ -686,17 +1003,72 @@ class PraxisBulkEditDialogComponent {
|
|
|
686
1003
|
this.targets = data.targets || [];
|
|
687
1004
|
this.writableFields = data.bulkContract.editableFields?.writableFields || [];
|
|
688
1005
|
this.clearableFields = data.bulkContract.editableFields?.clearableFields || [];
|
|
1006
|
+
this.hydrateRemoteSchemaIfNeeded();
|
|
689
1007
|
if (this.writableFields.length > 0) {
|
|
690
1008
|
this.addFieldRow();
|
|
691
1009
|
}
|
|
692
1010
|
}
|
|
1011
|
+
hydrateRemoteSchemaIfNeeded() {
|
|
1012
|
+
if (this.data.schema?.properties) {
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
const schemaUrl = this.contract.editableFields?.requestSchema?.url ||
|
|
1016
|
+
this.contract.evaluationOperation?.requestSchema?.url;
|
|
1017
|
+
if (!schemaUrl || typeof this.bulkClient.fetchSchema !== 'function') {
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
this.bulkClient
|
|
1021
|
+
.fetchSchema(schemaUrl, {
|
|
1022
|
+
endpointKey: this.data.endpointKey,
|
|
1023
|
+
apiUrlEntry: this.data.apiUrlEntry,
|
|
1024
|
+
})
|
|
1025
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1026
|
+
.subscribe({
|
|
1027
|
+
next: (schema) => {
|
|
1028
|
+
if (schema && typeof schema === 'object') {
|
|
1029
|
+
this.fetchedSchema.set(schema);
|
|
1030
|
+
}
|
|
1031
|
+
},
|
|
1032
|
+
error: () => {
|
|
1033
|
+
// Non-blocking schema enrichment fallback
|
|
1034
|
+
},
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
getEffectiveSchemaProperty(fieldName) {
|
|
1038
|
+
const schema = this.data.schema || this.fetchedSchema();
|
|
1039
|
+
const rootProps = schema?.properties;
|
|
1040
|
+
if (rootProps?.[fieldName]) {
|
|
1041
|
+
return rootProps[fieldName];
|
|
1042
|
+
}
|
|
1043
|
+
const changesItemProps = rootProps?.changes?.items?.properties ||
|
|
1044
|
+
schema?.items?.properties;
|
|
1045
|
+
if (changesItemProps?.[fieldName]) {
|
|
1046
|
+
return changesItemProps[fieldName];
|
|
1047
|
+
}
|
|
1048
|
+
return undefined;
|
|
1049
|
+
}
|
|
1050
|
+
getFieldDescriptor(fieldName) {
|
|
1051
|
+
const descriptors = this.contract.editableFields?.fieldDescriptors ||
|
|
1052
|
+
this.contract.editableFields?.fields;
|
|
1053
|
+
if (!Array.isArray(descriptors)) {
|
|
1054
|
+
return undefined;
|
|
1055
|
+
}
|
|
1056
|
+
return descriptors.find((d) => (d?.name || d?.field || d?.property) === fieldName);
|
|
1057
|
+
}
|
|
693
1058
|
isFieldClearable(fieldName) {
|
|
1059
|
+
const descriptor = this.getFieldDescriptor(fieldName);
|
|
1060
|
+
if (descriptor && typeof descriptor['clearable'] === 'boolean') {
|
|
1061
|
+
return descriptor['clearable'];
|
|
1062
|
+
}
|
|
694
1063
|
return this.clearableFields.includes(fieldName);
|
|
695
1064
|
}
|
|
696
1065
|
hasAvailableFieldsToAdd() {
|
|
697
1066
|
const selectedFields = this.fieldRows().map((r) => r.field);
|
|
698
1067
|
return this.writableFields.some((f) => !selectedFields.includes(f));
|
|
699
1068
|
}
|
|
1069
|
+
isFieldSelectedInOtherRow(field, currentRow) {
|
|
1070
|
+
return this.fieldRows().some((r) => r !== currentRow && r.field === field);
|
|
1071
|
+
}
|
|
700
1072
|
addFieldRow() {
|
|
701
1073
|
const selectedFields = this.fieldRows().map((r) => r.field);
|
|
702
1074
|
const nextField = this.writableFields.find((f) => !selectedFields.includes(f)) || this.writableFields[0] || '';
|
|
@@ -715,12 +1087,18 @@ class PraxisBulkEditDialogComponent {
|
|
|
715
1087
|
getFieldLabel(fieldName) {
|
|
716
1088
|
if (!fieldName)
|
|
717
1089
|
return '';
|
|
1090
|
+
const descriptor = this.getFieldDescriptor(fieldName);
|
|
1091
|
+
if (descriptor?.['label'] || descriptor?.['title']) {
|
|
1092
|
+
return String(descriptor['label'] || descriptor['title']);
|
|
1093
|
+
}
|
|
718
1094
|
const col = this.data.columns?.find((c) => c.field === fieldName);
|
|
719
1095
|
if (col?.header)
|
|
720
1096
|
return col.header;
|
|
721
|
-
const prop = this.
|
|
722
|
-
if (prop?.
|
|
723
|
-
return prop.
|
|
1097
|
+
const prop = this.getEffectiveSchemaProperty(fieldName);
|
|
1098
|
+
if (prop?.['x-ui']?.label)
|
|
1099
|
+
return String(prop['x-ui'].label);
|
|
1100
|
+
if (prop?.['title'])
|
|
1101
|
+
return String(prop['title']);
|
|
724
1102
|
return fieldName
|
|
725
1103
|
.replace(/([A-Z])/g, ' $1')
|
|
726
1104
|
.replace(/^./, (str) => str.toUpperCase())
|
|
@@ -729,38 +1107,75 @@ class PraxisBulkEditDialogComponent {
|
|
|
729
1107
|
getFieldType(fieldName) {
|
|
730
1108
|
if (!fieldName)
|
|
731
1109
|
return 'string';
|
|
1110
|
+
const descriptor = this.getFieldDescriptor(fieldName);
|
|
1111
|
+
const descControl = String(descriptor?.['controlType'] || '').toLowerCase();
|
|
1112
|
+
const descType = String(descriptor?.['type'] || '').toLowerCase();
|
|
1113
|
+
const descFormat = String(descriptor?.['format'] || '').toLowerCase();
|
|
1114
|
+
if (Array.isArray(descriptor?.['options']) && descriptor['options'].length > 0)
|
|
1115
|
+
return 'enum';
|
|
1116
|
+
if (descControl === 'currency' || descType === 'currency' || descFormat.startsWith('currency'))
|
|
1117
|
+
return 'currency';
|
|
1118
|
+
if (descType === 'boolean' || descControl === 'checkbox' || descControl === 'toggle')
|
|
1119
|
+
return 'boolean';
|
|
1120
|
+
if (descType === 'date' || descFormat === 'date' || descFormat === 'date-time' || descControl === 'date')
|
|
1121
|
+
return 'date';
|
|
1122
|
+
if (descType === 'number' || descType === 'integer' || descType === 'decimal')
|
|
1123
|
+
return 'number';
|
|
732
1124
|
const col = this.data.columns?.find((c) => c.field === fieldName);
|
|
733
|
-
|
|
1125
|
+
const colFormat = String(col?.format || '').toLowerCase();
|
|
1126
|
+
if (col?.type === 'currency' || colFormat.startsWith('currency'))
|
|
734
1127
|
return 'currency';
|
|
735
1128
|
if (col?.type === 'number')
|
|
736
1129
|
return 'number';
|
|
737
|
-
if (col?.type === 'date')
|
|
1130
|
+
if (col?.type === 'date' || colFormat === 'date' || colFormat === 'date-time')
|
|
738
1131
|
return 'date';
|
|
739
1132
|
if (col?.type === 'boolean')
|
|
740
1133
|
return 'boolean';
|
|
741
|
-
|
|
742
|
-
|
|
1134
|
+
if (Array.isArray(col?.options) && col.options.length > 0)
|
|
1135
|
+
return 'enum';
|
|
1136
|
+
const prop = this.getEffectiveSchemaProperty(fieldName);
|
|
1137
|
+
const ui = prop?.['x-ui'] || {};
|
|
1138
|
+
const uiControl = String(ui.controlType || '').toLowerCase();
|
|
1139
|
+
const uiFormat = String(ui.format || prop?.['format'] || '').toLowerCase();
|
|
1140
|
+
if ((prop?.['enum'] && Array.isArray(prop['enum'])) ||
|
|
1141
|
+
(Array.isArray(ui.options) && ui.options.length > 0)) {
|
|
743
1142
|
return 'enum';
|
|
744
|
-
|
|
1143
|
+
}
|
|
1144
|
+
if (prop?.['type'] === 'boolean' || uiControl === 'checkbox' || uiControl === 'toggle') {
|
|
745
1145
|
return 'boolean';
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
1146
|
+
}
|
|
1147
|
+
if (prop?.['type'] === 'number' ||
|
|
1148
|
+
prop?.['type'] === 'integer' ||
|
|
1149
|
+
uiControl === 'currency' ||
|
|
1150
|
+
uiFormat.startsWith('currency')) {
|
|
1151
|
+
if (uiControl === 'currency' || uiFormat.startsWith('currency') || ui.type === 'currency') {
|
|
752
1152
|
return 'currency';
|
|
753
1153
|
}
|
|
754
1154
|
return 'number';
|
|
755
1155
|
}
|
|
756
|
-
if (
|
|
1156
|
+
if (uiFormat === 'date' || uiFormat === 'date-time' || uiControl === 'date' || uiControl === 'datepicker') {
|
|
757
1157
|
return 'date';
|
|
1158
|
+
}
|
|
758
1159
|
return 'string';
|
|
759
1160
|
}
|
|
760
1161
|
getFieldEnumOptions(fieldName) {
|
|
761
|
-
const
|
|
762
|
-
if (
|
|
763
|
-
return
|
|
1162
|
+
const descriptor = this.getFieldDescriptor(fieldName);
|
|
1163
|
+
if (Array.isArray(descriptor?.['options']) && descriptor['options'].length > 0) {
|
|
1164
|
+
return descriptor['options'].map((opt) => ({
|
|
1165
|
+
value: String(opt?.value ?? opt?.key ?? opt?.id ?? opt),
|
|
1166
|
+
label: String(opt?.label ?? opt?.title ?? opt?.value ?? opt?.key ?? opt),
|
|
1167
|
+
}));
|
|
1168
|
+
}
|
|
1169
|
+
const prop = this.getEffectiveSchemaProperty(fieldName);
|
|
1170
|
+
const uiOptions = prop?.['x-ui']?.options;
|
|
1171
|
+
if (Array.isArray(uiOptions) && uiOptions.length > 0) {
|
|
1172
|
+
return uiOptions.map((opt) => ({
|
|
1173
|
+
value: String(opt?.value ?? opt?.key ?? opt?.id ?? opt),
|
|
1174
|
+
label: String(opt?.label ?? opt?.title ?? opt?.value ?? opt?.key ?? opt),
|
|
1175
|
+
}));
|
|
1176
|
+
}
|
|
1177
|
+
if (prop?.['enum'] && Array.isArray(prop['enum'])) {
|
|
1178
|
+
return prop['enum'].map((val) => ({
|
|
764
1179
|
value: String(val),
|
|
765
1180
|
label: String(val),
|
|
766
1181
|
}));
|
|
@@ -779,21 +1194,23 @@ class PraxisBulkEditDialogComponent {
|
|
|
779
1194
|
row.operator = 'SET';
|
|
780
1195
|
}
|
|
781
1196
|
const type = this.getFieldType(row.field);
|
|
782
|
-
if (type === 'boolean'
|
|
1197
|
+
if (type === 'boolean') {
|
|
783
1198
|
row.value = 'true';
|
|
784
1199
|
}
|
|
785
1200
|
else if (type === 'enum') {
|
|
786
1201
|
const opts = this.getFieldEnumOptions(row.field);
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
1202
|
+
row.value = opts.length > 0 ? opts[0].value : '';
|
|
1203
|
+
}
|
|
1204
|
+
else {
|
|
1205
|
+
row.value = '';
|
|
790
1206
|
}
|
|
791
1207
|
}
|
|
792
1208
|
isBlockedByAtomicity() {
|
|
793
1209
|
const prop = this.proposal();
|
|
794
1210
|
if (!prop)
|
|
795
1211
|
return false;
|
|
796
|
-
return this.contract.atomicity === 'ATOMIC'
|
|
1212
|
+
return ((this.contract.atomicity === 'ATOMIC' || this.contract.atomicity === 'ALL_OR_NONE') &&
|
|
1213
|
+
prop.totals.blocked > 0);
|
|
797
1214
|
}
|
|
798
1215
|
isConfirmDisabled() {
|
|
799
1216
|
const prop = this.proposal();
|
|
@@ -818,21 +1235,49 @@ class PraxisBulkEditDialogComponent {
|
|
|
818
1235
|
diag?.severity === 'ERROR');
|
|
819
1236
|
}
|
|
820
1237
|
onEvaluate() {
|
|
821
|
-
const
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
1238
|
+
for (const r of this.fieldRows()) {
|
|
1239
|
+
if (!r.field)
|
|
1240
|
+
continue;
|
|
1241
|
+
if (r.operator === 'SET') {
|
|
1242
|
+
const valStr = String(r.value ?? '').trim();
|
|
1243
|
+
if (valStr === '') {
|
|
1244
|
+
this.errorMessage.set(`Por favor, informe um valor válido para o campo "${this.getFieldLabel(r.field)}".`);
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
const seen = new Set();
|
|
1250
|
+
const changes = [];
|
|
1251
|
+
for (const r of this.fieldRows()) {
|
|
1252
|
+
if (r.field && !seen.has(r.field)) {
|
|
1253
|
+
seen.add(r.field);
|
|
1254
|
+
if (r.operator === 'CLEAR') {
|
|
1255
|
+
changes.push({
|
|
1256
|
+
field: r.field,
|
|
1257
|
+
operator: 'CLEAR',
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
else {
|
|
1261
|
+
changes.push({
|
|
1262
|
+
field: r.field,
|
|
1263
|
+
operator: r.operator,
|
|
1264
|
+
value: this.parseFieldValue(r.value, r.field),
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
828
1269
|
if (changes.length === 0) {
|
|
829
1270
|
this.errorMessage.set('Selecione ao menos um campo para alterar.');
|
|
830
1271
|
return;
|
|
831
1272
|
}
|
|
1273
|
+
this.confirmationIdempotencyKey = null;
|
|
832
1274
|
this.step.set('EVALUATING');
|
|
833
1275
|
this.errorMessage.set(null);
|
|
1276
|
+
const executionMode = this.contract.executionModes?.includes('SYNC')
|
|
1277
|
+
? 'SYNC'
|
|
1278
|
+
: (this.contract.executionModes?.[0] ?? 'SYNC');
|
|
834
1279
|
const request = {
|
|
835
|
-
executionMode
|
|
1280
|
+
executionMode,
|
|
836
1281
|
selection: {
|
|
837
1282
|
mode: 'EXPLICIT',
|
|
838
1283
|
targets: this.targets,
|
|
@@ -849,7 +1294,15 @@ class PraxisBulkEditDialogComponent {
|
|
|
849
1294
|
.subscribe({
|
|
850
1295
|
next: (prop) => {
|
|
851
1296
|
this.proposal.set(prop);
|
|
1297
|
+
const inlineItems = Array.isArray(prop.items)
|
|
1298
|
+
? prop.items
|
|
1299
|
+
: [];
|
|
1300
|
+
this.proposalItems.set(inlineItems);
|
|
1301
|
+
this.proposalNextCursor.set(null);
|
|
852
1302
|
this.step.set('PREVIEW');
|
|
1303
|
+
if (inlineItems.length === 0 && this.contract.proposalResultsOperation) {
|
|
1304
|
+
this.loadProposalResults();
|
|
1305
|
+
}
|
|
853
1306
|
},
|
|
854
1307
|
error: (err) => {
|
|
855
1308
|
this.errorMessage.set(err?.error?.message || err?.message || 'Falha ao avaliar alterações em lote.');
|
|
@@ -857,6 +1310,37 @@ class PraxisBulkEditDialogComponent {
|
|
|
857
1310
|
},
|
|
858
1311
|
});
|
|
859
1312
|
}
|
|
1313
|
+
loadProposalResults(cursor) {
|
|
1314
|
+
const prop = this.proposal();
|
|
1315
|
+
if (!prop ||
|
|
1316
|
+
!this.contract?.proposalResultsOperation ||
|
|
1317
|
+
typeof this.bulkClient.getProposalResults !== 'function') {
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
this.loadingProposalResults.set(true);
|
|
1321
|
+
const requestOptions = {
|
|
1322
|
+
endpointKey: this.data.endpointKey,
|
|
1323
|
+
apiUrlEntry: this.data.apiUrlEntry,
|
|
1324
|
+
};
|
|
1325
|
+
this.bulkClient
|
|
1326
|
+
.getProposalResults(this.contract.proposalResultsOperation, prop.proposalId, 50, cursor, requestOptions)
|
|
1327
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1328
|
+
.subscribe({
|
|
1329
|
+
next: (page) => {
|
|
1330
|
+
const newItems = Array.isArray(page?.items)
|
|
1331
|
+
? page.items
|
|
1332
|
+
: Array.isArray(page?.content)
|
|
1333
|
+
? page.content
|
|
1334
|
+
: [];
|
|
1335
|
+
this.proposalItems.update((prev) => (cursor ? [...prev, ...newItems] : newItems));
|
|
1336
|
+
this.proposalNextCursor.set(page?.nextCursor ?? page?.next ?? null);
|
|
1337
|
+
this.loadingProposalResults.set(false);
|
|
1338
|
+
},
|
|
1339
|
+
error: () => {
|
|
1340
|
+
this.loadingProposalResults.set(false);
|
|
1341
|
+
},
|
|
1342
|
+
});
|
|
1343
|
+
}
|
|
860
1344
|
onConfirm() {
|
|
861
1345
|
const prop = this.proposal();
|
|
862
1346
|
if (!prop)
|
|
@@ -864,7 +1348,7 @@ class PraxisBulkEditDialogComponent {
|
|
|
864
1348
|
this.step.set('CONFIRMING');
|
|
865
1349
|
this.errorMessage.set(null);
|
|
866
1350
|
if (!this.confirmationIdempotencyKey) {
|
|
867
|
-
this.confirmationIdempotencyKey =
|
|
1351
|
+
this.confirmationIdempotencyKey = generateBulkIdempotencyKey();
|
|
868
1352
|
}
|
|
869
1353
|
const requestOptions = {
|
|
870
1354
|
endpointKey: this.data.endpointKey,
|
|
@@ -877,7 +1361,25 @@ class PraxisBulkEditDialogComponent {
|
|
|
877
1361
|
.subscribe({
|
|
878
1362
|
next: (exec) => {
|
|
879
1363
|
this.execution.set(exec);
|
|
880
|
-
this.
|
|
1364
|
+
const isTerminal = typeof this.bulkClient.isTerminalStatus === 'function'
|
|
1365
|
+
? this.bulkClient.isTerminalStatus(exec.status)
|
|
1366
|
+
: exec.status !== 'QUEUED' && exec.status !== 'RUNNING';
|
|
1367
|
+
if (!isTerminal && this.contract.executionOperation && typeof this.bulkClient.waitForExecution === 'function') {
|
|
1368
|
+
this.bulkClient
|
|
1369
|
+
.waitForExecution(this.contract.executionOperation, exec.executionId, 1000, 60000, requestOptions)
|
|
1370
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1371
|
+
.subscribe({
|
|
1372
|
+
next: (finalExec) => {
|
|
1373
|
+
this.finalizeExecution(finalExec);
|
|
1374
|
+
},
|
|
1375
|
+
error: (err) => {
|
|
1376
|
+
this.errorMessage.set(err?.error?.message || err?.message || 'Falha ao acompanhar execução em lote.');
|
|
1377
|
+
this.step.set('RESULT');
|
|
1378
|
+
},
|
|
1379
|
+
});
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
this.finalizeExecution(exec);
|
|
881
1383
|
},
|
|
882
1384
|
error: (err) => {
|
|
883
1385
|
this.errorMessage.set(err?.error?.message || err?.message || 'Falha ao confirmar alterações em lote.');
|
|
@@ -885,6 +1387,86 @@ class PraxisBulkEditDialogComponent {
|
|
|
885
1387
|
},
|
|
886
1388
|
});
|
|
887
1389
|
}
|
|
1390
|
+
finalizeExecution(exec) {
|
|
1391
|
+
this.execution.set(exec);
|
|
1392
|
+
const inlineItems = Array.isArray(exec.items)
|
|
1393
|
+
? exec.items
|
|
1394
|
+
: [];
|
|
1395
|
+
this.executionItems.set(inlineItems);
|
|
1396
|
+
this.executionNextCursor.set(null);
|
|
1397
|
+
this.step.set('RESULT');
|
|
1398
|
+
if (inlineItems.length === 0 && this.contract?.resultsOperation) {
|
|
1399
|
+
this.loadExecutionResults();
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
loadExecutionResults(cursor) {
|
|
1403
|
+
const exec = this.execution();
|
|
1404
|
+
if (!exec ||
|
|
1405
|
+
!this.contract?.resultsOperation ||
|
|
1406
|
+
typeof this.bulkClient.getExecutionResults !== 'function') {
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
this.loadingExecutionResults.set(true);
|
|
1410
|
+
const requestOptions = {
|
|
1411
|
+
endpointKey: this.data.endpointKey,
|
|
1412
|
+
apiUrlEntry: this.data.apiUrlEntry,
|
|
1413
|
+
};
|
|
1414
|
+
this.bulkClient
|
|
1415
|
+
.getExecutionResults(this.contract.resultsOperation, exec.executionId, 50, cursor, requestOptions)
|
|
1416
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1417
|
+
.subscribe({
|
|
1418
|
+
next: (page) => {
|
|
1419
|
+
const newItems = Array.isArray(page?.items)
|
|
1420
|
+
? page.items
|
|
1421
|
+
: Array.isArray(page?.content)
|
|
1422
|
+
? page.content
|
|
1423
|
+
: [];
|
|
1424
|
+
this.executionItems.update((prev) => (cursor ? [...prev, ...newItems] : newItems));
|
|
1425
|
+
this.executionNextCursor.set(page?.nextCursor ?? page?.next ?? null);
|
|
1426
|
+
this.loadingExecutionResults.set(false);
|
|
1427
|
+
},
|
|
1428
|
+
error: () => {
|
|
1429
|
+
this.loadingExecutionResults.set(false);
|
|
1430
|
+
},
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
canCancelExecution() {
|
|
1434
|
+
const exec = this.execution();
|
|
1435
|
+
if (this.step() !== 'CONFIRMING' || !exec || !this.contract?.cancelOperation) {
|
|
1436
|
+
return false;
|
|
1437
|
+
}
|
|
1438
|
+
const isTerminal = typeof this.bulkClient.isTerminalStatus === 'function'
|
|
1439
|
+
? this.bulkClient.isTerminalStatus(exec.status)
|
|
1440
|
+
: exec.status !== 'QUEUED' && exec.status !== 'RUNNING';
|
|
1441
|
+
return !isTerminal;
|
|
1442
|
+
}
|
|
1443
|
+
onCancelActiveExecution() {
|
|
1444
|
+
const exec = this.execution();
|
|
1445
|
+
if (!this.canCancelExecution() ||
|
|
1446
|
+
!exec ||
|
|
1447
|
+
!this.contract?.cancelOperation ||
|
|
1448
|
+
typeof this.bulkClient.cancel !== 'function') {
|
|
1449
|
+
return;
|
|
1450
|
+
}
|
|
1451
|
+
this.cancellingExecution.set(true);
|
|
1452
|
+
const requestOptions = {
|
|
1453
|
+
endpointKey: this.data.endpointKey,
|
|
1454
|
+
apiUrlEntry: this.data.apiUrlEntry,
|
|
1455
|
+
};
|
|
1456
|
+
this.bulkClient
|
|
1457
|
+
.cancel(this.contract.cancelOperation, exec.executionId, requestOptions)
|
|
1458
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1459
|
+
.subscribe({
|
|
1460
|
+
next: (cancelledExec) => {
|
|
1461
|
+
this.cancellingExecution.set(false);
|
|
1462
|
+
this.finalizeExecution(cancelledExec);
|
|
1463
|
+
},
|
|
1464
|
+
error: (err) => {
|
|
1465
|
+
this.cancellingExecution.set(false);
|
|
1466
|
+
this.errorMessage.set(err?.error?.message || err?.message || 'Falha ao solicitar cancelamento da execução em lote.');
|
|
1467
|
+
},
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
888
1470
|
onCloseSuccess() {
|
|
889
1471
|
this.dialogRef.close({
|
|
890
1472
|
success: true,
|
|
@@ -892,8 +1474,18 @@ class PraxisBulkEditDialogComponent {
|
|
|
892
1474
|
});
|
|
893
1475
|
}
|
|
894
1476
|
onCancel() {
|
|
1477
|
+
if (this.step() === 'RESULT') {
|
|
1478
|
+
this.onCloseSuccess();
|
|
1479
|
+
return;
|
|
1480
|
+
}
|
|
895
1481
|
this.dialogRef.close({ success: false });
|
|
896
1482
|
}
|
|
1483
|
+
onEscape(event) {
|
|
1484
|
+
if (this.step() !== 'CONFIRMING' && this.step() !== 'EVALUATING') {
|
|
1485
|
+
event?.preventDefault();
|
|
1486
|
+
this.onCancel();
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
897
1489
|
parseFieldValue(raw, fieldName) {
|
|
898
1490
|
if (fieldName) {
|
|
899
1491
|
const type = this.getFieldType(fieldName);
|
|
@@ -917,14 +1509,14 @@ class PraxisBulkEditDialogComponent {
|
|
|
917
1509
|
return trimmed;
|
|
918
1510
|
}
|
|
919
1511
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisBulkEditDialogComponent, deps: [{ token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
920
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisBulkEditDialogComponent, isStandalone: true, selector: "praxis-bulk-edit-dialog", ngImport: i0, template: `
|
|
921
|
-
<div class="praxis-bulk-edit-dialog" role="dialog" aria-labelledby="praxis-bulk-edit-dialog-title">
|
|
1512
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisBulkEditDialogComponent, isStandalone: true, selector: "praxis-bulk-edit-dialog", host: { listeners: { "keydown.escape": "onEscape($event)" } }, ngImport: i0, template: `
|
|
1513
|
+
<div class="praxis-bulk-edit-dialog" role="dialog" aria-labelledby="praxis-bulk-edit-dialog-title" aria-describedby="praxis-bulk-edit-dialog-subtitle">
|
|
922
1514
|
<div class="praxis-bulk-edit-dialog__header">
|
|
923
1515
|
<div class="praxis-bulk-edit-dialog__title-group">
|
|
924
1516
|
<mat-icon class="praxis-bulk-edit-dialog__header-icon">edit_note</mat-icon>
|
|
925
1517
|
<div>
|
|
926
1518
|
<h2 class="praxis-bulk-edit-dialog__title" id="praxis-bulk-edit-dialog-title">{{ dialogTitle }}</h2>
|
|
927
|
-
<p class="praxis-bulk-edit-dialog__subtitle">{{ dialogSubtitle }}</p>
|
|
1519
|
+
<p id="praxis-bulk-edit-dialog-subtitle" class="praxis-bulk-edit-dialog__subtitle">{{ dialogSubtitle }}</p>
|
|
928
1520
|
</div>
|
|
929
1521
|
</div>
|
|
930
1522
|
<button mat-icon-button (click)="onCancel()" [disabled]="step() === 'CONFIRMING'" aria-label="Fechar diálogo">
|
|
@@ -972,7 +1564,7 @@ class PraxisBulkEditDialogComponent {
|
|
|
972
1564
|
<mat-label>Campo</mat-label>
|
|
973
1565
|
<mat-select [(ngModel)]="row.field" (ngModelChange)="onFieldSelectionChange(row)">
|
|
974
1566
|
@for (field of writableFields; track field) {
|
|
975
|
-
<mat-option [value]="field">
|
|
1567
|
+
<mat-option [value]="field" [disabled]="isFieldSelectedInOtherRow(field, row)">
|
|
976
1568
|
{{ getFieldLabel(field) }}
|
|
977
1569
|
<span class="field-tech-name">({{ field }})</span>
|
|
978
1570
|
</mat-option>
|
|
@@ -983,7 +1575,7 @@ class PraxisBulkEditDialogComponent {
|
|
|
983
1575
|
<!-- Seleção do Operador: SET ou CLEAR -->
|
|
984
1576
|
<mat-form-field appearance="outline" class="operator-select">
|
|
985
1577
|
<mat-label>Operação</mat-label>
|
|
986
|
-
<mat-select [(ngModel)]="row.operator">
|
|
1578
|
+
<mat-select [(ngModel)]="row.operator" (ngModelChange)="errorMessage.set(null)">
|
|
987
1579
|
<mat-option value="SET">Definir Valor</mat-option>
|
|
988
1580
|
@if (isFieldClearable(row.field)) {
|
|
989
1581
|
<mat-option value="CLEAR">Limpar (CLEAR)</mat-option>
|
|
@@ -997,19 +1589,25 @@ class PraxisBulkEditDialogComponent {
|
|
|
997
1589
|
@case ('currency') {
|
|
998
1590
|
<mat-form-field appearance="outline" class="value-input">
|
|
999
1591
|
<mat-label>Novo Valor (R$)</mat-label>
|
|
1000
|
-
<input matInput type="number" step="0.01" [(ngModel)]="row.value" placeholder="0.00" />
|
|
1592
|
+
<input matInput type="number" step="0.01" [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)" placeholder="0.00" />
|
|
1001
1593
|
</mat-form-field>
|
|
1002
1594
|
}
|
|
1003
1595
|
@case ('number') {
|
|
1004
1596
|
<mat-form-field appearance="outline" class="value-input">
|
|
1005
1597
|
<mat-label>Novo Valor Numérico</mat-label>
|
|
1006
|
-
<input matInput type="number" [(ngModel)]="row.value" placeholder="0" />
|
|
1598
|
+
<input matInput type="number" [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)" placeholder="0" />
|
|
1599
|
+
</mat-form-field>
|
|
1600
|
+
}
|
|
1601
|
+
@case ('date') {
|
|
1602
|
+
<mat-form-field appearance="outline" class="value-input">
|
|
1603
|
+
<mat-label>Nova Data</mat-label>
|
|
1604
|
+
<input matInput type="date" [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)" />
|
|
1007
1605
|
</mat-form-field>
|
|
1008
1606
|
}
|
|
1009
1607
|
@case ('boolean') {
|
|
1010
1608
|
<mat-form-field appearance="outline" class="value-input">
|
|
1011
1609
|
<mat-label>Novo Valor</mat-label>
|
|
1012
|
-
<mat-select [(ngModel)]="row.value">
|
|
1610
|
+
<mat-select [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)">
|
|
1013
1611
|
<mat-option value="true">Sim (Verdadeiro)</mat-option>
|
|
1014
1612
|
<mat-option value="false">Não (Falso)</mat-option>
|
|
1015
1613
|
</mat-select>
|
|
@@ -1018,7 +1616,7 @@ class PraxisBulkEditDialogComponent {
|
|
|
1018
1616
|
@case ('enum') {
|
|
1019
1617
|
<mat-form-field appearance="outline" class="value-input">
|
|
1020
1618
|
<mat-label>Novo Valor</mat-label>
|
|
1021
|
-
<mat-select [(ngModel)]="row.value">
|
|
1619
|
+
<mat-select [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)">
|
|
1022
1620
|
@for (opt of getFieldEnumOptions(row.field); track opt.value) {
|
|
1023
1621
|
<mat-option [value]="opt.value">{{ opt.label }}</mat-option>
|
|
1024
1622
|
}
|
|
@@ -1028,7 +1626,7 @@ class PraxisBulkEditDialogComponent {
|
|
|
1028
1626
|
@default {
|
|
1029
1627
|
<mat-form-field appearance="outline" class="value-input">
|
|
1030
1628
|
<mat-label>Novo Valor</mat-label>
|
|
1031
|
-
<input matInput [(ngModel)]="row.value" placeholder="Digite o novo valor..." />
|
|
1629
|
+
<input matInput [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)" placeholder="Digite o novo valor..." />
|
|
1032
1630
|
</mat-form-field>
|
|
1033
1631
|
}
|
|
1034
1632
|
}
|
|
@@ -1125,6 +1723,33 @@ class PraxisBulkEditDialogComponent {
|
|
|
1125
1723
|
}
|
|
1126
1724
|
</div>
|
|
1127
1725
|
}
|
|
1726
|
+
|
|
1727
|
+
@if (proposalItems().length > 0) {
|
|
1728
|
+
<div class="praxis-bulk-edit-dialog__diagnostics">
|
|
1729
|
+
<h4 class="diagnostics-title">Avaliação por Registro ({{ proposalItems().length }})</h4>
|
|
1730
|
+
@for (item of proposalItems(); track item.id) {
|
|
1731
|
+
<div class="diagnostic-item" [class.diagnostic-item--error]="item.decision === 'BLOCKED'">
|
|
1732
|
+
<mat-icon>{{ item.decision === 'BLOCKED' ? 'cancel' : 'check_circle' }}</mat-icon>
|
|
1733
|
+
<div class="diagnostic-content">
|
|
1734
|
+
<span class="diagnostic-target">Registro #{{ item.id }}:</span>
|
|
1735
|
+
<span class="diagnostic-message">
|
|
1736
|
+
{{ item.decision === 'BLOCKED' ? (item.diagnostics?.[0]?.message || 'Bloqueado') : 'Elegível' }}
|
|
1737
|
+
</span>
|
|
1738
|
+
</div>
|
|
1739
|
+
</div>
|
|
1740
|
+
}
|
|
1741
|
+
@if (proposalNextCursor()) {
|
|
1742
|
+
<button
|
|
1743
|
+
mat-stroked-button
|
|
1744
|
+
type="button"
|
|
1745
|
+
(click)="loadProposalResults(proposalNextCursor()!)"
|
|
1746
|
+
[disabled]="loadingProposalResults()"
|
|
1747
|
+
>
|
|
1748
|
+
{{ loadingProposalResults() ? 'Carregando...' : 'Carregar mais resultados' }}
|
|
1749
|
+
</button>
|
|
1750
|
+
}
|
|
1751
|
+
</div>
|
|
1752
|
+
}
|
|
1128
1753
|
</div>
|
|
1129
1754
|
}
|
|
1130
1755
|
|
|
@@ -1133,6 +1758,17 @@ class PraxisBulkEditDialogComponent {
|
|
|
1133
1758
|
<div class="praxis-bulk-edit-dialog__loading">
|
|
1134
1759
|
<mat-spinner diameter="40" />
|
|
1135
1760
|
<p>Gravando atualizações em lote com garantia de idempotência...</p>
|
|
1761
|
+
@if (canCancelExecution()) {
|
|
1762
|
+
<button
|
|
1763
|
+
mat-stroked-button
|
|
1764
|
+
color="warn"
|
|
1765
|
+
type="button"
|
|
1766
|
+
(click)="onCancelActiveExecution()"
|
|
1767
|
+
[disabled]="cancellingExecution()"
|
|
1768
|
+
>
|
|
1769
|
+
{{ cancellingExecution() ? 'Cancelando...' : 'Cancelar Execução' }}
|
|
1770
|
+
</button>
|
|
1771
|
+
}
|
|
1136
1772
|
</div>
|
|
1137
1773
|
}
|
|
1138
1774
|
|
|
@@ -1142,25 +1778,50 @@ class PraxisBulkEditDialogComponent {
|
|
|
1142
1778
|
<div class="praxis-bulk-edit-dialog__alert praxis-bulk-edit-dialog__alert--success">
|
|
1143
1779
|
<mat-icon>verified</mat-icon>
|
|
1144
1780
|
<div class="alert-content">
|
|
1145
|
-
<strong>Atualização concluída com
|
|
1146
|
-
<p>
|
|
1781
|
+
<strong>Atualização concluída com êxito!</strong>
|
|
1782
|
+
<p>Transação homologada e registrada na auditoria corporativa.</p>
|
|
1147
1783
|
</div>
|
|
1148
1784
|
</div>
|
|
1149
1785
|
|
|
1150
1786
|
<div class="praxis-bulk-edit-dialog__totals-grid">
|
|
1151
1787
|
<div class="total-card total-card--executable">
|
|
1152
|
-
<span class="total-label">
|
|
1788
|
+
<span class="total-label">Efetivados</span>
|
|
1153
1789
|
<span class="total-value">{{ execution()?.totals?.confirmed }}</span>
|
|
1154
1790
|
</div>
|
|
1155
1791
|
<div class="total-card">
|
|
1156
|
-
<span class="total-label">
|
|
1792
|
+
<span class="total-label">Preservados</span>
|
|
1157
1793
|
<span class="total-value">{{ execution()?.totals?.unchanged }}</span>
|
|
1158
1794
|
</div>
|
|
1159
1795
|
<div class="total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
|
|
1160
|
-
<span class="total-label">
|
|
1796
|
+
<span class="total-label">Rejeitados</span>
|
|
1161
1797
|
<span class="total-value">{{ execution()?.totals?.denied }}</span>
|
|
1162
1798
|
</div>
|
|
1163
1799
|
</div>
|
|
1800
|
+
|
|
1801
|
+
@if (executionItems().length > 0) {
|
|
1802
|
+
<div class="praxis-bulk-edit-dialog__diagnostics">
|
|
1803
|
+
<h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
|
|
1804
|
+
@for (item of executionItems(); track item.id) {
|
|
1805
|
+
<div class="diagnostic-item" [class.diagnostic-item--error]="item.status !== 'CONFIRMED' && item.status !== 'UNCHANGED'">
|
|
1806
|
+
<mat-icon>{{ item.status === 'CONFIRMED' || item.status === 'UNCHANGED' ? 'check_circle' : 'cancel' }}</mat-icon>
|
|
1807
|
+
<div class="diagnostic-content">
|
|
1808
|
+
<span class="diagnostic-target">Registro #{{ item.id }}:</span>
|
|
1809
|
+
<span class="diagnostic-message">{{ item.diagnostics?.[0]?.message || item.status }}</span>
|
|
1810
|
+
</div>
|
|
1811
|
+
</div>
|
|
1812
|
+
}
|
|
1813
|
+
@if (executionNextCursor()) {
|
|
1814
|
+
<button
|
|
1815
|
+
mat-stroked-button
|
|
1816
|
+
type="button"
|
|
1817
|
+
(click)="loadExecutionResults(executionNextCursor()!)"
|
|
1818
|
+
[disabled]="loadingExecutionResults()"
|
|
1819
|
+
>
|
|
1820
|
+
{{ loadingExecutionResults() ? 'Carregando...' : 'Carregar mais resultados' }}
|
|
1821
|
+
</button>
|
|
1822
|
+
}
|
|
1823
|
+
</div>
|
|
1824
|
+
}
|
|
1164
1825
|
</div>
|
|
1165
1826
|
}
|
|
1166
1827
|
|
|
@@ -1207,7 +1868,7 @@ class PraxisBulkEditDialogComponent {
|
|
|
1207
1868
|
}
|
|
1208
1869
|
</div>
|
|
1209
1870
|
</div>
|
|
1210
|
-
`, isInline: true, styles: [".cdk-overlay-pane.praxis-bulk-dialog-panel{--mat-dialog-container-color: var(--praxis-surface-card, var(--card, var(--md-sys-color-surface-container, #1e293b)));--mat-dialog-container-shape: 16px;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(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))));box-shadow:var(--praxis-theme-elevation, 0 24px 64px rgba(0, 0, 0, .45));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(--praxis-text-primary, var(--foreground, var(--md-sys-color-on-surface, inherit)));background:transparent;box-sizing:border-box}.praxis-bulk-edit-dialog__header{display:flex;justify-content:space-between;align-items:flex-start;padding:20px 24px 16px;border-bottom:1px solid var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .2))))}.praxis-bulk-edit-dialog__title-group{display:flex;align-items:flex-start;gap:12px}.praxis-bulk-edit-dialog__header-icon{color:var(--praxis-primary, var(--primary, var(--md-sys-color-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;color:var(--praxis-text-primary, var(--foreground, var(--md-sys-color-on-surface, inherit)))}.praxis-bulk-edit-dialog__subtitle{font-size:.875rem;color:var(--praxis-text-muted, var(--muted-foreground, var(--md-sys-color-on-surface-variant, rgba(148, 163, 184, .8))));margin:4px 0 0}.praxis-bulk-edit-dialog__content{padding:20px 24px;overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:16px}.praxis-bulk-edit-dialog__targets-badge{display:inline-flex;align-items:center;gap:8px;padding:8px 14px;background:color-mix(in srgb,var(--praxis-text-primary, var(--foreground, currentColor)) 6%,transparent);border:1px solid color-mix(in srgb,var(--praxis-border-subtle, var(--border, currentColor)) 25%,transparent);border-radius:8px;font-size:.875rem;color:var(--praxis-text-primary, var(--foreground, inherit))}.praxis-bulk-edit-dialog__targets-badge mat-icon{font-size:18px;width:18px;height:18px;color:var(--praxis-primary, var(--primary, var(--md-sys-color-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:0}.total-card{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:96px;padding:18px 20px;background:color-mix(in srgb,var(--praxis-text-primary, var(--foreground, currentColor)) 4%,transparent);border:1px solid var(--praxis-border-subtle, var(--border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .15))));border-radius:12px;transition:background .2s ease,border-color .2s ease;box-sizing:border-box}.total-card .total-label{font-size:.75rem;text-transform:uppercase;letter-spacing:.06em;font-weight:600;color:var(--praxis-text-muted, var(--muted-foreground, var(--md-sys-color-on-surface-variant, rgba(148, 163, 184, .8))));margin-bottom:6px}.total-card .total-value{font-size:1.875rem;font-weight:700;color:var(--praxis-text-primary, var(--foreground, var(--md-sys-color-on-surface, inherit)));line-height:1;margin:0}.total-card--executable{border-color:color-mix(in srgb,var(--praxis-success, #10b981) 50%,transparent);background:color-mix(in srgb,var(--praxis-success, #10b981) 12%,transparent)}.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);background:color-mix(in srgb,var(--praxis-error, #ef4444) 12%,transparent)}.total-card--blocked .total-value{color:var(--praxis-error, #ef4444)}.praxis-bulk-edit-dialog__alert{display:flex;align-items:flex-start;gap:14px;padding:16px 20px;border-radius:12px;font-size:.875rem;line-height:1.45}.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:3px}.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) 12%,transparent);border:1px solid color-mix(in srgb,var(--praxis-error, #ef4444) 40%,transparent);color:var(--praxis-text-primary, var(--foreground, inherit))}.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) 12%,transparent);border:1px solid color-mix(in srgb,var(--praxis-warning, #d97706) 40%,transparent);color:var(--praxis-text-primary, var(--foreground, inherit))}.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) 12%,transparent);border:1px solid color-mix(in srgb,var(--praxis-success, #10b981) 40%,transparent);color:var(--praxis-text-primary, var(--foreground, inherit))}.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 });
|
|
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 });
|
|
1211
1872
|
}
|
|
1212
1873
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisBulkEditDialogComponent, decorators: [{
|
|
1213
1874
|
type: Component,
|
|
@@ -1222,13 +1883,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1222
1883
|
MatInputModule,
|
|
1223
1884
|
MatFormFieldModule,
|
|
1224
1885
|
], template: `
|
|
1225
|
-
<div class="praxis-bulk-edit-dialog" role="dialog" aria-labelledby="praxis-bulk-edit-dialog-title">
|
|
1886
|
+
<div class="praxis-bulk-edit-dialog" role="dialog" aria-labelledby="praxis-bulk-edit-dialog-title" aria-describedby="praxis-bulk-edit-dialog-subtitle">
|
|
1226
1887
|
<div class="praxis-bulk-edit-dialog__header">
|
|
1227
1888
|
<div class="praxis-bulk-edit-dialog__title-group">
|
|
1228
1889
|
<mat-icon class="praxis-bulk-edit-dialog__header-icon">edit_note</mat-icon>
|
|
1229
1890
|
<div>
|
|
1230
1891
|
<h2 class="praxis-bulk-edit-dialog__title" id="praxis-bulk-edit-dialog-title">{{ dialogTitle }}</h2>
|
|
1231
|
-
<p class="praxis-bulk-edit-dialog__subtitle">{{ dialogSubtitle }}</p>
|
|
1892
|
+
<p id="praxis-bulk-edit-dialog-subtitle" class="praxis-bulk-edit-dialog__subtitle">{{ dialogSubtitle }}</p>
|
|
1232
1893
|
</div>
|
|
1233
1894
|
</div>
|
|
1234
1895
|
<button mat-icon-button (click)="onCancel()" [disabled]="step() === 'CONFIRMING'" aria-label="Fechar diálogo">
|
|
@@ -1276,7 +1937,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1276
1937
|
<mat-label>Campo</mat-label>
|
|
1277
1938
|
<mat-select [(ngModel)]="row.field" (ngModelChange)="onFieldSelectionChange(row)">
|
|
1278
1939
|
@for (field of writableFields; track field) {
|
|
1279
|
-
<mat-option [value]="field">
|
|
1940
|
+
<mat-option [value]="field" [disabled]="isFieldSelectedInOtherRow(field, row)">
|
|
1280
1941
|
{{ getFieldLabel(field) }}
|
|
1281
1942
|
<span class="field-tech-name">({{ field }})</span>
|
|
1282
1943
|
</mat-option>
|
|
@@ -1287,7 +1948,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1287
1948
|
<!-- Seleção do Operador: SET ou CLEAR -->
|
|
1288
1949
|
<mat-form-field appearance="outline" class="operator-select">
|
|
1289
1950
|
<mat-label>Operação</mat-label>
|
|
1290
|
-
<mat-select [(ngModel)]="row.operator">
|
|
1951
|
+
<mat-select [(ngModel)]="row.operator" (ngModelChange)="errorMessage.set(null)">
|
|
1291
1952
|
<mat-option value="SET">Definir Valor</mat-option>
|
|
1292
1953
|
@if (isFieldClearable(row.field)) {
|
|
1293
1954
|
<mat-option value="CLEAR">Limpar (CLEAR)</mat-option>
|
|
@@ -1301,19 +1962,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1301
1962
|
@case ('currency') {
|
|
1302
1963
|
<mat-form-field appearance="outline" class="value-input">
|
|
1303
1964
|
<mat-label>Novo Valor (R$)</mat-label>
|
|
1304
|
-
<input matInput type="number" step="0.01" [(ngModel)]="row.value" placeholder="0.00" />
|
|
1965
|
+
<input matInput type="number" step="0.01" [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)" placeholder="0.00" />
|
|
1305
1966
|
</mat-form-field>
|
|
1306
1967
|
}
|
|
1307
1968
|
@case ('number') {
|
|
1308
1969
|
<mat-form-field appearance="outline" class="value-input">
|
|
1309
1970
|
<mat-label>Novo Valor Numérico</mat-label>
|
|
1310
|
-
<input matInput type="number" [(ngModel)]="row.value" placeholder="0" />
|
|
1971
|
+
<input matInput type="number" [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)" placeholder="0" />
|
|
1972
|
+
</mat-form-field>
|
|
1973
|
+
}
|
|
1974
|
+
@case ('date') {
|
|
1975
|
+
<mat-form-field appearance="outline" class="value-input">
|
|
1976
|
+
<mat-label>Nova Data</mat-label>
|
|
1977
|
+
<input matInput type="date" [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)" />
|
|
1311
1978
|
</mat-form-field>
|
|
1312
1979
|
}
|
|
1313
1980
|
@case ('boolean') {
|
|
1314
1981
|
<mat-form-field appearance="outline" class="value-input">
|
|
1315
1982
|
<mat-label>Novo Valor</mat-label>
|
|
1316
|
-
<mat-select [(ngModel)]="row.value">
|
|
1983
|
+
<mat-select [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)">
|
|
1317
1984
|
<mat-option value="true">Sim (Verdadeiro)</mat-option>
|
|
1318
1985
|
<mat-option value="false">Não (Falso)</mat-option>
|
|
1319
1986
|
</mat-select>
|
|
@@ -1322,7 +1989,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1322
1989
|
@case ('enum') {
|
|
1323
1990
|
<mat-form-field appearance="outline" class="value-input">
|
|
1324
1991
|
<mat-label>Novo Valor</mat-label>
|
|
1325
|
-
<mat-select [(ngModel)]="row.value">
|
|
1992
|
+
<mat-select [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)">
|
|
1326
1993
|
@for (opt of getFieldEnumOptions(row.field); track opt.value) {
|
|
1327
1994
|
<mat-option [value]="opt.value">{{ opt.label }}</mat-option>
|
|
1328
1995
|
}
|
|
@@ -1332,7 +1999,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1332
1999
|
@default {
|
|
1333
2000
|
<mat-form-field appearance="outline" class="value-input">
|
|
1334
2001
|
<mat-label>Novo Valor</mat-label>
|
|
1335
|
-
<input matInput [(ngModel)]="row.value" placeholder="Digite o novo valor..." />
|
|
2002
|
+
<input matInput [(ngModel)]="row.value" (ngModelChange)="errorMessage.set(null)" placeholder="Digite o novo valor..." />
|
|
1336
2003
|
</mat-form-field>
|
|
1337
2004
|
}
|
|
1338
2005
|
}
|
|
@@ -1429,6 +2096,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1429
2096
|
}
|
|
1430
2097
|
</div>
|
|
1431
2098
|
}
|
|
2099
|
+
|
|
2100
|
+
@if (proposalItems().length > 0) {
|
|
2101
|
+
<div class="praxis-bulk-edit-dialog__diagnostics">
|
|
2102
|
+
<h4 class="diagnostics-title">Avaliação por Registro ({{ proposalItems().length }})</h4>
|
|
2103
|
+
@for (item of proposalItems(); track item.id) {
|
|
2104
|
+
<div class="diagnostic-item" [class.diagnostic-item--error]="item.decision === 'BLOCKED'">
|
|
2105
|
+
<mat-icon>{{ item.decision === 'BLOCKED' ? 'cancel' : 'check_circle' }}</mat-icon>
|
|
2106
|
+
<div class="diagnostic-content">
|
|
2107
|
+
<span class="diagnostic-target">Registro #{{ item.id }}:</span>
|
|
2108
|
+
<span class="diagnostic-message">
|
|
2109
|
+
{{ item.decision === 'BLOCKED' ? (item.diagnostics?.[0]?.message || 'Bloqueado') : 'Elegível' }}
|
|
2110
|
+
</span>
|
|
2111
|
+
</div>
|
|
2112
|
+
</div>
|
|
2113
|
+
}
|
|
2114
|
+
@if (proposalNextCursor()) {
|
|
2115
|
+
<button
|
|
2116
|
+
mat-stroked-button
|
|
2117
|
+
type="button"
|
|
2118
|
+
(click)="loadProposalResults(proposalNextCursor()!)"
|
|
2119
|
+
[disabled]="loadingProposalResults()"
|
|
2120
|
+
>
|
|
2121
|
+
{{ loadingProposalResults() ? 'Carregando...' : 'Carregar mais resultados' }}
|
|
2122
|
+
</button>
|
|
2123
|
+
}
|
|
2124
|
+
</div>
|
|
2125
|
+
}
|
|
1432
2126
|
</div>
|
|
1433
2127
|
}
|
|
1434
2128
|
|
|
@@ -1437,6 +2131,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1437
2131
|
<div class="praxis-bulk-edit-dialog__loading">
|
|
1438
2132
|
<mat-spinner diameter="40" />
|
|
1439
2133
|
<p>Gravando atualizações em lote com garantia de idempotência...</p>
|
|
2134
|
+
@if (canCancelExecution()) {
|
|
2135
|
+
<button
|
|
2136
|
+
mat-stroked-button
|
|
2137
|
+
color="warn"
|
|
2138
|
+
type="button"
|
|
2139
|
+
(click)="onCancelActiveExecution()"
|
|
2140
|
+
[disabled]="cancellingExecution()"
|
|
2141
|
+
>
|
|
2142
|
+
{{ cancellingExecution() ? 'Cancelando...' : 'Cancelar Execução' }}
|
|
2143
|
+
</button>
|
|
2144
|
+
}
|
|
1440
2145
|
</div>
|
|
1441
2146
|
}
|
|
1442
2147
|
|
|
@@ -1446,25 +2151,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1446
2151
|
<div class="praxis-bulk-edit-dialog__alert praxis-bulk-edit-dialog__alert--success">
|
|
1447
2152
|
<mat-icon>verified</mat-icon>
|
|
1448
2153
|
<div class="alert-content">
|
|
1449
|
-
<strong>Atualização concluída com
|
|
1450
|
-
<p>
|
|
2154
|
+
<strong>Atualização concluída com êxito!</strong>
|
|
2155
|
+
<p>Transação homologada e registrada na auditoria corporativa.</p>
|
|
1451
2156
|
</div>
|
|
1452
2157
|
</div>
|
|
1453
2158
|
|
|
1454
2159
|
<div class="praxis-bulk-edit-dialog__totals-grid">
|
|
1455
2160
|
<div class="total-card total-card--executable">
|
|
1456
|
-
<span class="total-label">
|
|
2161
|
+
<span class="total-label">Efetivados</span>
|
|
1457
2162
|
<span class="total-value">{{ execution()?.totals?.confirmed }}</span>
|
|
1458
2163
|
</div>
|
|
1459
2164
|
<div class="total-card">
|
|
1460
|
-
<span class="total-label">
|
|
2165
|
+
<span class="total-label">Preservados</span>
|
|
1461
2166
|
<span class="total-value">{{ execution()?.totals?.unchanged }}</span>
|
|
1462
2167
|
</div>
|
|
1463
2168
|
<div class="total-card" [class.total-card--blocked]="(execution()?.totals?.denied ?? 0) > 0">
|
|
1464
|
-
<span class="total-label">
|
|
2169
|
+
<span class="total-label">Rejeitados</span>
|
|
1465
2170
|
<span class="total-value">{{ execution()?.totals?.denied }}</span>
|
|
1466
2171
|
</div>
|
|
1467
2172
|
</div>
|
|
2173
|
+
|
|
2174
|
+
@if (executionItems().length > 0) {
|
|
2175
|
+
<div class="praxis-bulk-edit-dialog__diagnostics">
|
|
2176
|
+
<h4 class="diagnostics-title">Resultado por Registro ({{ executionItems().length }})</h4>
|
|
2177
|
+
@for (item of executionItems(); track item.id) {
|
|
2178
|
+
<div class="diagnostic-item" [class.diagnostic-item--error]="item.status !== 'CONFIRMED' && item.status !== 'UNCHANGED'">
|
|
2179
|
+
<mat-icon>{{ item.status === 'CONFIRMED' || item.status === 'UNCHANGED' ? 'check_circle' : 'cancel' }}</mat-icon>
|
|
2180
|
+
<div class="diagnostic-content">
|
|
2181
|
+
<span class="diagnostic-target">Registro #{{ item.id }}:</span>
|
|
2182
|
+
<span class="diagnostic-message">{{ item.diagnostics?.[0]?.message || item.status }}</span>
|
|
2183
|
+
</div>
|
|
2184
|
+
</div>
|
|
2185
|
+
}
|
|
2186
|
+
@if (executionNextCursor()) {
|
|
2187
|
+
<button
|
|
2188
|
+
mat-stroked-button
|
|
2189
|
+
type="button"
|
|
2190
|
+
(click)="loadExecutionResults(executionNextCursor()!)"
|
|
2191
|
+
[disabled]="loadingExecutionResults()"
|
|
2192
|
+
>
|
|
2193
|
+
{{ loadingExecutionResults() ? 'Carregando...' : 'Carregar mais resultados' }}
|
|
2194
|
+
</button>
|
|
2195
|
+
}
|
|
2196
|
+
</div>
|
|
2197
|
+
}
|
|
1468
2198
|
</div>
|
|
1469
2199
|
}
|
|
1470
2200
|
|
|
@@ -1511,11 +2241,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1511
2241
|
}
|
|
1512
2242
|
</div>
|
|
1513
2243
|
</div>
|
|
1514
|
-
`, styles: [".cdk-overlay-pane.praxis-bulk-dialog-panel{--mat-dialog-container-color: var(--praxis-surface
|
|
2244
|
+
`, 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"] }]
|
|
1515
2245
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
1516
2246
|
type: Inject,
|
|
1517
2247
|
args: [MAT_DIALOG_DATA]
|
|
1518
|
-
}] }]
|
|
2248
|
+
}] }], propDecorators: { onEscape: [{
|
|
2249
|
+
type: HostListener,
|
|
2250
|
+
args: ['keydown.escape', ['$event']]
|
|
2251
|
+
}] } });
|
|
1519
2252
|
|
|
1520
2253
|
function formatKpiValue(value, format) {
|
|
1521
2254
|
if (value === null || value === undefined || value === '') {
|
|
@@ -1585,6 +2318,7 @@ class PraxisKpiBandComponent {
|
|
|
1585
2318
|
statsError = new EventEmitter();
|
|
1586
2319
|
refreshClick = new EventEmitter();
|
|
1587
2320
|
http = inject(HttpClient);
|
|
2321
|
+
apiUrl = inject(API_URL, { optional: true });
|
|
1588
2322
|
cdr = inject(ChangeDetectorRef);
|
|
1589
2323
|
destroyRef = inject(DestroyRef);
|
|
1590
2324
|
evaluator = new SafeExpressionEvaluator({
|
|
@@ -1595,6 +2329,8 @@ class PraxisKpiBandComponent {
|
|
|
1595
2329
|
evaluatedCards = [];
|
|
1596
2330
|
fetchedData = {};
|
|
1597
2331
|
skeletonPlaceholders = [1, 2, 3, 4];
|
|
2332
|
+
initialized = false;
|
|
2333
|
+
fetchSub;
|
|
1598
2334
|
get isVisible() {
|
|
1599
2335
|
if (!this.config || this.config.enabled === false)
|
|
1600
2336
|
return false;
|
|
@@ -1617,12 +2353,16 @@ class PraxisKpiBandComponent {
|
|
|
1617
2353
|
return gap || '1rem';
|
|
1618
2354
|
}
|
|
1619
2355
|
ngOnInit() {
|
|
2356
|
+
this.initialized = true;
|
|
1620
2357
|
if (this.config?.cards?.length) {
|
|
1621
2358
|
this.skeletonPlaceholders = Array.from({ length: this.config.cards.length }, (_, i) => i + 1);
|
|
1622
2359
|
}
|
|
1623
2360
|
this.refresh();
|
|
1624
2361
|
}
|
|
1625
2362
|
ngOnChanges(changes) {
|
|
2363
|
+
if (!this.initialized) {
|
|
2364
|
+
return;
|
|
2365
|
+
}
|
|
1626
2366
|
if (changes['config'] || changes['dataContext']) {
|
|
1627
2367
|
if (changes['config'] && this.config?.source !== changes['config'].previousValue?.source) {
|
|
1628
2368
|
this.refresh();
|
|
@@ -1644,17 +2384,35 @@ class PraxisKpiBandComponent {
|
|
|
1644
2384
|
this.recomputeCards();
|
|
1645
2385
|
}
|
|
1646
2386
|
}
|
|
2387
|
+
resolveSourceUrl(rawSource) {
|
|
2388
|
+
const trimmed = rawSource.trim();
|
|
2389
|
+
if (!trimmed || trimmed.startsWith('http://') || trimmed.startsWith('https://')) {
|
|
2390
|
+
return trimmed;
|
|
2391
|
+
}
|
|
2392
|
+
const defaultEntry = this.apiUrl?.['default'] || (this.apiUrl ? Object.values(this.apiUrl)[0] : undefined);
|
|
2393
|
+
const base = defaultEntry ? buildApiUrl(defaultEntry).replace(/\/+$/, '') : '';
|
|
2394
|
+
if (!base) {
|
|
2395
|
+
return trimmed;
|
|
2396
|
+
}
|
|
2397
|
+
if (trimmed.startsWith('/api/') && base.endsWith('/api')) {
|
|
2398
|
+
return `${base.slice(0, -4)}${trimmed}`;
|
|
2399
|
+
}
|
|
2400
|
+
const cleanPath = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
|
|
2401
|
+
return `${base}${cleanPath}`;
|
|
2402
|
+
}
|
|
1647
2403
|
fetchFromSource() {
|
|
1648
2404
|
const source = this.config?.source;
|
|
1649
2405
|
if (!source)
|
|
1650
2406
|
return;
|
|
2407
|
+
this.fetchSub?.unsubscribe();
|
|
1651
2408
|
this.isLoading = true;
|
|
1652
2409
|
this.cdr.markForCheck();
|
|
2410
|
+
const effectiveUrl = this.resolveSourceUrl(source);
|
|
1653
2411
|
const method = this.config?.method || 'GET';
|
|
1654
2412
|
const request$ = method.toUpperCase() === 'POST'
|
|
1655
|
-
? this.http.post(
|
|
1656
|
-
: this.http.get(
|
|
1657
|
-
request$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
|
2413
|
+
? this.http.post(effectiveUrl, this.config?.payload || {})
|
|
2414
|
+
: this.http.get(effectiveUrl);
|
|
2415
|
+
this.fetchSub = request$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
|
1658
2416
|
next: (res) => {
|
|
1659
2417
|
const payload = res?.data ?? res ?? {};
|
|
1660
2418
|
this.fetchedData = typeof payload === 'object' ? payload : { value: payload };
|
|
@@ -1801,7 +2559,7 @@ class PraxisKpiBandComponent {
|
|
|
1801
2559
|
</ng-template>
|
|
1802
2560
|
</div>
|
|
1803
2561
|
</div>
|
|
1804
|
-
`, 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
|
|
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 });
|
|
1805
2563
|
}
|
|
1806
2564
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisKpiBandComponent, decorators: [{
|
|
1807
2565
|
type: Component,
|
|
@@ -1876,7 +2634,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1876
2634
|
</ng-template>
|
|
1877
2635
|
</div>
|
|
1878
2636
|
</div>
|
|
1879
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, 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
|
|
2637
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, 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"] }]
|
|
1880
2638
|
}], propDecorators: { config: [{
|
|
1881
2639
|
type: Input
|
|
1882
2640
|
}], dataContext: [{
|
|
@@ -3495,7 +4253,13 @@ class CrudMetadataEditorComponent {
|
|
|
3495
4253
|
errorCount = computed(() => this.diagnostics().filter((issue) => issue.level === 'error').length, ...(ngDevMode ? [{ debugName: "errorCount" }] : /* istanbul ignore next */ []));
|
|
3496
4254
|
warningCount = computed(() => this.diagnostics().filter((issue) => issue.level !== 'error').length, ...(ngDevMode ? [{ debugName: "warningCount" }] : /* istanbul ignore next */ []));
|
|
3497
4255
|
serializedDocument = computed(() => JSON.stringify(serializeCrudAuthoringDocument(this.currentDocument()), null, 2), ...(ngDevMode ? [{ debugName: "serializedDocument" }] : /* istanbul ignore next */ []));
|
|
3498
|
-
tableConfig = computed(() =>
|
|
4256
|
+
tableConfig = computed(() => {
|
|
4257
|
+
const raw = this.currentDocument().metadata.table;
|
|
4258
|
+
return {
|
|
4259
|
+
...(raw || {}),
|
|
4260
|
+
columns: Array.isArray(raw?.columns) ? raw.columns : [],
|
|
4261
|
+
};
|
|
4262
|
+
}, ...(ngDevMode ? [{ debugName: "tableConfig" }] : /* istanbul ignore next */ []));
|
|
3499
4263
|
resourcePath = computed(() => this.currentDocument().metadata.resource?.path || '', ...(ngDevMode ? [{ debugName: "resourcePath" }] : /* istanbul ignore next */ []));
|
|
3500
4264
|
resourceIdField = computed(() => String(this.currentDocument().metadata.resource?.idField ?? ''), ...(ngDevMode ? [{ debugName: "resourceIdField" }] : /* istanbul ignore next */ []));
|
|
3501
4265
|
resourceEndpointKey = computed(() => String(this.currentDocument().metadata.resource?.endpointKey ?? ''), ...(ngDevMode ? [{ debugName: "resourceEndpointKey" }] : /* istanbul ignore next */ []));
|
|
@@ -6070,18 +6834,11 @@ class PraxisCrudComponent {
|
|
|
6070
6834
|
rows = [this.selectedRow];
|
|
6071
6835
|
}
|
|
6072
6836
|
const rawTargets = event?.targets;
|
|
6073
|
-
const
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
(r?.version != null ? String(r.version).trim() : null) ||
|
|
6079
|
-
(r?._etag != null ? String(r._etag).trim() : null) ||
|
|
6080
|
-
(r?.etag != null ? String(r.etag).trim() : null) ||
|
|
6081
|
-
(r?.eTag != null ? String(r.eTag).trim() : null) ||
|
|
6082
|
-
undefined;
|
|
6083
|
-
return { id: id, ...(expectedVersion ? { expectedVersion } : {}) };
|
|
6084
|
-
});
|
|
6837
|
+
const hasSelection = (Array.isArray(rawTargets) && rawTargets.length > 0) || rows.length > 0;
|
|
6838
|
+
if (!hasSelection) {
|
|
6839
|
+
this.snack.open('Nenhum registro selecionado para a operação em lote.', undefined, { duration: 3000 });
|
|
6840
|
+
return;
|
|
6841
|
+
}
|
|
6085
6842
|
const resourcePath = String(this.resolveResourcePath(this.resolvedMetadata) || '').trim();
|
|
6086
6843
|
const resourceKey = String(this.resolvedMetadata?.resource?.resourceKey ||
|
|
6087
6844
|
this.tableCrudContext?.tableId ||
|
|
@@ -6092,14 +6849,28 @@ class PraxisCrudComponent {
|
|
|
6092
6849
|
(a.id || a.action) === action);
|
|
6093
6850
|
const tableBulkAction = (this.effectiveTableConfig?.actions?.bulk?.actions || []).find((a) => this.normalizeCrudActionName(a.id || a.action) === normalizedAction ||
|
|
6094
6851
|
(a.id || a.action) === action);
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6852
|
+
let resolvedBulk = this.resolveSyncBulkExecutionContractForAction(action, normalizedAction, configAction, crudAction, tableBulkAction);
|
|
6853
|
+
if (!resolvedBulk.contract && this.tableCollectionLinks && (!crudAction || !this.hasExplicitOpenBinding(crudAction))) {
|
|
6854
|
+
resolvedBulk = await this.resolveAsyncDiscoveredBulkContractForAction(action, normalizedAction);
|
|
6855
|
+
}
|
|
6856
|
+
const bulkContract = resolvedBulk.contract;
|
|
6857
|
+
const discoveredCatalogAction = resolvedBulk.catalogAction;
|
|
6098
6858
|
if (bulkContract) {
|
|
6099
|
-
const
|
|
6859
|
+
const targets = Array.isArray(rawTargets) && rawTargets.length > 0
|
|
6860
|
+
? rawTargets
|
|
6861
|
+
: await this.resolveBulkTargetsFromRows(rows);
|
|
6862
|
+
if (!targets.length) {
|
|
6863
|
+
this.snack.open('Nenhum registro selecionado para a operação em lote.', undefined, { duration: 3000 });
|
|
6864
|
+
return;
|
|
6865
|
+
}
|
|
6866
|
+
const columns = this.table?.config?.columns?.length
|
|
6867
|
+
? this.table.config.columns
|
|
6868
|
+
: this.effectiveTableConfig?.columns;
|
|
6100
6869
|
const schema = this.resolvedMetadata?.schema || this.resolvedMetadata?.resource?.schema;
|
|
6101
6870
|
if (bulkContract.mode === 'UNIFORM_UPDATE') {
|
|
6102
|
-
const actionTitle = configAction?.title ||
|
|
6871
|
+
const actionTitle = configAction?.title ||
|
|
6872
|
+
tableBulkAction?.title ||
|
|
6873
|
+
discoveredCatalogAction?.title;
|
|
6103
6874
|
const dialogRef = this.dialog.open(PraxisBulkEditDialogComponent, {
|
|
6104
6875
|
width: '680px',
|
|
6105
6876
|
maxWidth: '92vw',
|
|
@@ -6112,12 +6883,16 @@ class PraxisCrudComponent {
|
|
|
6112
6883
|
apiUrlEntry: this.resolveDiscoveryApiEntry(),
|
|
6113
6884
|
columns,
|
|
6114
6885
|
schema,
|
|
6115
|
-
title: actionTitle || 'Atualização de
|
|
6886
|
+
title: actionTitle || 'Atualização de Registros em Massa',
|
|
6116
6887
|
},
|
|
6117
6888
|
panelClass: ['praxis-bulk-dialog-panel'],
|
|
6118
|
-
|
|
6889
|
+
backdropClass: ['praxis-bulk-dialog-backdrop'],
|
|
6890
|
+
disableClose: true,
|
|
6119
6891
|
});
|
|
6120
|
-
dialogRef
|
|
6892
|
+
dialogRef
|
|
6893
|
+
.afterClosed()
|
|
6894
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
6895
|
+
.subscribe((res) => {
|
|
6121
6896
|
if (res?.success) {
|
|
6122
6897
|
this.refreshTable();
|
|
6123
6898
|
this.snack.open('Atualização em lote concluída com sucesso.', undefined, { duration: 3000 });
|
|
@@ -6126,13 +6901,16 @@ class PraxisCrudComponent {
|
|
|
6126
6901
|
return;
|
|
6127
6902
|
}
|
|
6128
6903
|
if (bulkContract.mode === 'DOMAIN_COMMAND') {
|
|
6129
|
-
const actionRef = crudAction || configAction || {
|
|
6904
|
+
const actionRef = discoveredCatalogAction || crudAction || configAction || {
|
|
6130
6905
|
id: action,
|
|
6131
6906
|
action,
|
|
6132
6907
|
label: configAction?.label || tableBulkAction?.label || action,
|
|
6133
6908
|
title: configAction?.title || configAction?.label || tableBulkAction?.label || action,
|
|
6134
6909
|
execution: { bulk: bulkContract },
|
|
6135
6910
|
};
|
|
6911
|
+
if (!actionRef.execution?.bulk) {
|
|
6912
|
+
actionRef.execution = { ...(actionRef.execution || {}), bulk: bulkContract };
|
|
6913
|
+
}
|
|
6136
6914
|
actionRef.title = actionRef.title || actionRef.label || action;
|
|
6137
6915
|
const dialogRef = this.dialog.open(PraxisBulkOperationDialogComponent, {
|
|
6138
6916
|
width: '680px',
|
|
@@ -6148,9 +6926,13 @@ class PraxisCrudComponent {
|
|
|
6148
6926
|
schema,
|
|
6149
6927
|
},
|
|
6150
6928
|
panelClass: ['praxis-bulk-dialog-panel'],
|
|
6151
|
-
|
|
6929
|
+
backdropClass: ['praxis-bulk-dialog-backdrop'],
|
|
6930
|
+
disableClose: true,
|
|
6152
6931
|
});
|
|
6153
|
-
dialogRef
|
|
6932
|
+
dialogRef
|
|
6933
|
+
.afterClosed()
|
|
6934
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
6935
|
+
.subscribe((res) => {
|
|
6154
6936
|
if (res?.success) {
|
|
6155
6937
|
this.refreshTable();
|
|
6156
6938
|
this.snack.open('Operação em lote executada com sucesso.', undefined, { duration: 3000 });
|
|
@@ -6165,6 +6947,79 @@ class PraxisCrudComponent {
|
|
|
6165
6947
|
}
|
|
6166
6948
|
await this.onAction(action, row ?? undefined, event);
|
|
6167
6949
|
}
|
|
6950
|
+
async resolveBulkTargetsFromRows(rows) {
|
|
6951
|
+
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();
|
|
6974
|
+
}
|
|
6975
|
+
}
|
|
6976
|
+
}
|
|
6977
|
+
catch {
|
|
6978
|
+
// Non-blocking fallback when self endpoint is unreachable or unmocked
|
|
6979
|
+
}
|
|
6980
|
+
}
|
|
6981
|
+
return { id: id, ...(expectedVersion ? { expectedVersion } : {}) };
|
|
6982
|
+
}));
|
|
6983
|
+
}
|
|
6984
|
+
resolveSyncBulkExecutionContractForAction(action, normalizedAction, configAction, crudAction, tableBulkAction) {
|
|
6985
|
+
const direct = configAction?.execution?.bulk ||
|
|
6986
|
+
crudAction?.execution?.bulk ||
|
|
6987
|
+
tableBulkAction?.execution?.bulk;
|
|
6988
|
+
if (direct) {
|
|
6989
|
+
return { contract: direct };
|
|
6990
|
+
}
|
|
6991
|
+
const matchKey = (candidate) => {
|
|
6992
|
+
const id = String(candidate?.id || candidate?.action || candidate?.operationId || '').trim();
|
|
6993
|
+
const norm = this.normalizeCrudActionName(id).toLowerCase();
|
|
6994
|
+
return (id === action ||
|
|
6995
|
+
norm === normalizedAction.toLowerCase() ||
|
|
6996
|
+
String(candidate?.operationId || '').trim() === action);
|
|
6997
|
+
};
|
|
6998
|
+
const capAction = (this.collectionCapabilities?.actions || []).find((a) => matchKey(a) && a.execution?.bulk);
|
|
6999
|
+
if (capAction?.execution?.bulk) {
|
|
7000
|
+
return { contract: capAction.execution.bulk, catalogAction: capAction };
|
|
7001
|
+
}
|
|
7002
|
+
const capOp = Object.values(this.collectionCapabilities?.operations || {}).find((op) => matchKey(op) && op?.bulk);
|
|
7003
|
+
if (capOp?.bulk) {
|
|
7004
|
+
return { contract: capOp.bulk };
|
|
7005
|
+
}
|
|
7006
|
+
return {};
|
|
7007
|
+
}
|
|
7008
|
+
async resolveAsyncDiscoveredBulkContractForAction(action, normalizedAction) {
|
|
7009
|
+
const matchKey = (candidate) => {
|
|
7010
|
+
const id = String(candidate?.id || candidate?.action || candidate?.operationId || '').trim();
|
|
7011
|
+
const norm = this.normalizeCrudActionName(id).toLowerCase();
|
|
7012
|
+
return (id === action ||
|
|
7013
|
+
norm === normalizedAction.toLowerCase() ||
|
|
7014
|
+
String(candidate?.operationId || '').trim() === action);
|
|
7015
|
+
};
|
|
7016
|
+
const discoveredCatalog = await this.resolveDiscoveredActionCatalog();
|
|
7017
|
+
const discoveredAction = (discoveredCatalog?.actions || []).find((a) => matchKey(a) && a.execution?.bulk);
|
|
7018
|
+
if (discoveredAction?.execution?.bulk) {
|
|
7019
|
+
return { contract: discoveredAction.execution.bulk, catalogAction: discoveredAction };
|
|
7020
|
+
}
|
|
7021
|
+
return {};
|
|
7022
|
+
}
|
|
6168
7023
|
async onToolbarAction(event) {
|
|
6169
7024
|
if (this.isInspectOnly()) {
|
|
6170
7025
|
return;
|
|
@@ -6173,12 +7028,15 @@ class PraxisCrudComponent {
|
|
|
6173
7028
|
if (!action)
|
|
6174
7029
|
return;
|
|
6175
7030
|
const normalizedAction = this.normalizeCrudActionName(action);
|
|
6176
|
-
const
|
|
6177
|
-
(
|
|
6178
|
-
|
|
6179
|
-
(
|
|
6180
|
-
|
|
6181
|
-
if (
|
|
7031
|
+
const crudAction = (this.resolvedMetadata?.actions || []).find((a) => this.normalizeCrudActionName(a.id || a.action) === normalizedAction ||
|
|
7032
|
+
(a.id || a.action) === action);
|
|
7033
|
+
const tableBulkAction = (this.effectiveTableConfig?.actions?.bulk?.actions || []).find((a) => this.normalizeCrudActionName(a.id || a.action) === normalizedAction ||
|
|
7034
|
+
(a.id || a.action) === action);
|
|
7035
|
+
let resolvedBulk = this.resolveSyncBulkExecutionContractForAction(action, normalizedAction, event?.actionConfig, crudAction, tableBulkAction);
|
|
7036
|
+
if (!resolvedBulk.contract && this.tableCollectionLinks && (!crudAction || !this.hasExplicitOpenBinding(crudAction))) {
|
|
7037
|
+
resolvedBulk = await this.resolveAsyncDiscoveredBulkContractForAction(action, normalizedAction);
|
|
7038
|
+
}
|
|
7039
|
+
if (resolvedBulk.contract) {
|
|
6182
7040
|
await this.onBulkAction(event);
|
|
6183
7041
|
return;
|
|
6184
7042
|
}
|
|
@@ -7605,6 +8463,51 @@ class PraxisCrudComponent {
|
|
|
7605
8463
|
changed = true;
|
|
7606
8464
|
}
|
|
7607
8465
|
}
|
|
8466
|
+
const discoveredBulkActions = this.resolveDiscoveredBulkTableActions(capabilities);
|
|
8467
|
+
if (discoveredBulkActions.length > 0) {
|
|
8468
|
+
cfg.actions = cfg.actions || {};
|
|
8469
|
+
const existingBulk = cfg.actions.bulk || {
|
|
8470
|
+
enabled: true,
|
|
8471
|
+
position: 'both',
|
|
8472
|
+
actions: [],
|
|
8473
|
+
};
|
|
8474
|
+
const mergedActions = Array.isArray(existingBulk.actions) ? [...existingBulk.actions] : [];
|
|
8475
|
+
for (const discovered of discoveredBulkActions) {
|
|
8476
|
+
const idx = mergedActions.findIndex((candidate) => String(candidate?.action || candidate?.id || '').trim().toLowerCase() ===
|
|
8477
|
+
String(discovered.action || discovered.id || '').trim().toLowerCase());
|
|
8478
|
+
if (idx >= 0) {
|
|
8479
|
+
mergedActions[idx] = {
|
|
8480
|
+
...discovered,
|
|
8481
|
+
...mergedActions[idx],
|
|
8482
|
+
execution: mergedActions[idx]?.execution || discovered.execution,
|
|
8483
|
+
};
|
|
8484
|
+
}
|
|
8485
|
+
else {
|
|
8486
|
+
mergedActions.push(discovered);
|
|
8487
|
+
}
|
|
8488
|
+
}
|
|
8489
|
+
cfg.actions.bulk = {
|
|
8490
|
+
...existingBulk,
|
|
8491
|
+
position: existingBulk.position || 'both',
|
|
8492
|
+
enabled: existingBulk.enabled !== false,
|
|
8493
|
+
actions: mergedActions,
|
|
8494
|
+
};
|
|
8495
|
+
cfg.behavior = cfg.behavior || {};
|
|
8496
|
+
if (!cfg.behavior.selection || cfg.behavior.selection.enabled !== false) {
|
|
8497
|
+
const prevSelection = cfg.behavior.selection;
|
|
8498
|
+
cfg.behavior.selection = {
|
|
8499
|
+
...prevSelection,
|
|
8500
|
+
enabled: true,
|
|
8501
|
+
type: prevSelection?.type || 'multiple',
|
|
8502
|
+
mode: prevSelection?.mode || 'checkbox',
|
|
8503
|
+
allowSelectAll: prevSelection?.allowSelectAll ?? true,
|
|
8504
|
+
checkboxPosition: prevSelection?.checkboxPosition || 'start',
|
|
8505
|
+
persistSelection: prevSelection?.persistSelection ?? true,
|
|
8506
|
+
persistOnDataUpdate: prevSelection?.persistOnDataUpdate ?? false,
|
|
8507
|
+
};
|
|
8508
|
+
}
|
|
8509
|
+
changed = true;
|
|
8510
|
+
}
|
|
7608
8511
|
const effectiveOpenMode = meta.defaults?.openMode;
|
|
7609
8512
|
const hasDrawerAction = (meta.actions || []).some((action) => action.openMode === 'drawer');
|
|
7610
8513
|
const drawerRequested = effectiveOpenMode === 'drawer' ||
|
|
@@ -7889,7 +8792,7 @@ class PraxisCrudComponent {
|
|
|
7889
8792
|
return [];
|
|
7890
8793
|
}
|
|
7891
8794
|
return (capabilities.actions || [])
|
|
7892
|
-
.filter((action) => action.scope === 'COLLECTION')
|
|
8795
|
+
.filter((action) => action.scope === 'COLLECTION' && !action.execution?.bulk)
|
|
7893
8796
|
.sort((left, right) => (left.order ?? 0) - (right.order ?? 0))
|
|
7894
8797
|
.map((action) => ({
|
|
7895
8798
|
id: action.id,
|
|
@@ -7905,6 +8808,43 @@ class PraxisCrudComponent {
|
|
|
7905
8808
|
: undefined),
|
|
7906
8809
|
}));
|
|
7907
8810
|
}
|
|
8811
|
+
resolveDiscoveredBulkTableActions(capabilities) {
|
|
8812
|
+
if (!capabilities) {
|
|
8813
|
+
return [];
|
|
8814
|
+
}
|
|
8815
|
+
const items = [];
|
|
8816
|
+
for (const action of (capabilities.actions || [])
|
|
8817
|
+
.filter((a) => a.scope === 'COLLECTION' && a.execution?.bulk)
|
|
8818
|
+
.sort((left, right) => (left.order ?? 0) - (right.order ?? 0))) {
|
|
8819
|
+
items.push({
|
|
8820
|
+
id: action.id,
|
|
8821
|
+
label: action.title || action.id,
|
|
8822
|
+
icon: action.icon || (action.execution?.bulk?.mode === 'UNIFORM_UPDATE' ? 'edit_note' : 'playlist_add_check'),
|
|
8823
|
+
action: action.id,
|
|
8824
|
+
requiresSelection: true,
|
|
8825
|
+
disabled: !this.isCatalogActionAvailable(capabilities, action.id),
|
|
8826
|
+
execution: { bulk: action.execution.bulk },
|
|
8827
|
+
});
|
|
8828
|
+
}
|
|
8829
|
+
for (const [opKey, op] of Object.entries(capabilities.operations || {})) {
|
|
8830
|
+
if (op?.supported &&
|
|
8831
|
+
op?.scope === 'COLLECTION' &&
|
|
8832
|
+
op?.bulk?.mode === 'UNIFORM_UPDATE' &&
|
|
8833
|
+
op.availability?.allowed !== false &&
|
|
8834
|
+
!items.some((item) => String(item['action'] || item['id']).toLowerCase() === opKey.toLowerCase())) {
|
|
8835
|
+
const isAtomic = op.bulk.atomicity === 'ATOMIC' || op.bulk.atomicity === 'ALL_OR_NONE';
|
|
8836
|
+
items.push({
|
|
8837
|
+
id: op.id || opKey,
|
|
8838
|
+
label: isAtomic ? 'Editar Selecionados (Atômico)' : 'Editar Selecionados',
|
|
8839
|
+
icon: 'edit_note',
|
|
8840
|
+
action: op.id || opKey,
|
|
8841
|
+
requiresSelection: true,
|
|
8842
|
+
execution: { bulk: op.bulk },
|
|
8843
|
+
});
|
|
8844
|
+
}
|
|
8845
|
+
}
|
|
8846
|
+
return items;
|
|
8847
|
+
}
|
|
7908
8848
|
supportsCreateCapability(snapshot) {
|
|
7909
8849
|
const operationAvailability = this.resolveOperationAvailability(snapshot, 'create');
|
|
7910
8850
|
if (operationAvailability !== null) {
|
|
@@ -10535,13 +11475,13 @@ const PRAXIS_CRUD_AUTHORING_MANIFEST = {
|
|
|
10535
11475
|
* Pode ser utilizado diretamente como alvo de rotas do Angular:
|
|
10536
11476
|
* ```typescript
|
|
10537
11477
|
* {
|
|
10538
|
-
* path: '
|
|
11478
|
+
* path: 'contracts',
|
|
10539
11479
|
* component: PraxisResourcePage,
|
|
10540
11480
|
* data: {
|
|
10541
|
-
* resource: '
|
|
10542
|
-
* title: '
|
|
10543
|
-
* subtitle: '
|
|
10544
|
-
* domain: { label: '
|
|
11481
|
+
* resource: 'procurement/contracts',
|
|
11482
|
+
* title: 'Gestão de Contratos',
|
|
11483
|
+
* subtitle: 'Acompanhamento de vigência e conformidade.',
|
|
11484
|
+
* domain: { label: 'Suprimentos', icon: 'inventory_2', tone: 'info' },
|
|
10545
11485
|
* scopeBar: { ... }
|
|
10546
11486
|
* }
|
|
10547
11487
|
* }
|
|
@@ -10582,6 +11522,7 @@ class PraxisResourcePage {
|
|
|
10582
11522
|
afterSave = new EventEmitter();
|
|
10583
11523
|
afterDelete = new EventEmitter();
|
|
10584
11524
|
error = new EventEmitter();
|
|
11525
|
+
inputsVersion = signal(0, ...(ngDevMode ? [{ debugName: "inputsVersion" }] : /* istanbul ignore next */ []));
|
|
10585
11526
|
routeResourceSignal = signal(null, ...(ngDevMode ? [{ debugName: "routeResourceSignal" }] : /* istanbul ignore next */ []));
|
|
10586
11527
|
routeMetadataSignal = signal(null, ...(ngDevMode ? [{ debugName: "routeMetadataSignal" }] : /* istanbul ignore next */ []));
|
|
10587
11528
|
routeTitleSignal = signal(null, ...(ngDevMode ? [{ debugName: "routeTitleSignal" }] : /* istanbul ignore next */ []));
|
|
@@ -10594,21 +11535,27 @@ class PraxisResourcePage {
|
|
|
10594
11535
|
activeScopeId = signal('all', ...(ngDevMode ? [{ debugName: "activeScopeId" }] : /* istanbul ignore next */ []));
|
|
10595
11536
|
activeScopeFilter = signal({}, ...(ngDevMode ? [{ debugName: "activeScopeFilter" }] : /* istanbul ignore next */ []));
|
|
10596
11537
|
effectiveResource = computed(() => {
|
|
11538
|
+
this.inputsVersion();
|
|
10597
11539
|
return this.resource || this.resourcePath || this.routeResourceSignal();
|
|
10598
11540
|
}, ...(ngDevMode ? [{ debugName: "effectiveResource" }] : /* istanbul ignore next */ []));
|
|
10599
11541
|
effectiveTitle = computed(() => {
|
|
11542
|
+
this.inputsVersion();
|
|
10600
11543
|
return this.title || this.routeTitleSignal();
|
|
10601
11544
|
}, ...(ngDevMode ? [{ debugName: "effectiveTitle" }] : /* istanbul ignore next */ []));
|
|
10602
11545
|
effectiveSubtitle = computed(() => {
|
|
11546
|
+
this.inputsVersion();
|
|
10603
11547
|
return this.subtitle || this.routeSubtitleSignal();
|
|
10604
11548
|
}, ...(ngDevMode ? [{ debugName: "effectiveSubtitle" }] : /* istanbul ignore next */ []));
|
|
10605
11549
|
effectiveDomain = computed(() => {
|
|
11550
|
+
this.inputsVersion();
|
|
10606
11551
|
return this.domain || this.routeDomainSignal();
|
|
10607
11552
|
}, ...(ngDevMode ? [{ debugName: "effectiveDomain" }] : /* istanbul ignore next */ []));
|
|
10608
11553
|
effectiveEnableCustomization = computed(() => {
|
|
11554
|
+
this.inputsVersion();
|
|
10609
11555
|
return this.enableCustomization || this.routeCustomizationSignal() || false;
|
|
10610
11556
|
}, ...(ngDevMode ? [{ debugName: "effectiveEnableCustomization" }] : /* istanbul ignore next */ []));
|
|
10611
11557
|
effectiveScopeBar = computed(() => {
|
|
11558
|
+
this.inputsVersion();
|
|
10612
11559
|
if (this.scopeBar)
|
|
10613
11560
|
return this.scopeBar;
|
|
10614
11561
|
if (this.scopeItems && this.scopeItems.length > 0) {
|
|
@@ -10652,23 +11599,37 @@ class PraxisResourcePage {
|
|
|
10652
11599
|
return null;
|
|
10653
11600
|
}, ...(ngDevMode ? [{ debugName: "effectiveScopeBar" }] : /* istanbul ignore next */ []));
|
|
10654
11601
|
resolvedCrudId = computed(() => {
|
|
11602
|
+
this.inputsVersion();
|
|
10655
11603
|
if (this.crudId)
|
|
10656
11604
|
return this.crudId;
|
|
10657
11605
|
const res = this.effectiveResource();
|
|
10658
11606
|
return res ? `crud-${res.replace(/\//g, '-')}` : 'praxis-crud-auto';
|
|
10659
11607
|
}, ...(ngDevMode ? [{ debugName: "resolvedCrudId" }] : /* istanbul ignore next */ []));
|
|
10660
11608
|
effectiveMetadata = computed(() => {
|
|
11609
|
+
this.inputsVersion();
|
|
10661
11610
|
const metaSource = this.metadata || this.routeMetadataSignal();
|
|
10662
11611
|
let base;
|
|
10663
11612
|
if (typeof metaSource === 'string') {
|
|
10664
11613
|
const trimmed = metaSource.trim();
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
11614
|
+
if (trimmed.startsWith('{')) {
|
|
11615
|
+
try {
|
|
11616
|
+
base = JSON.parse(trimmed);
|
|
11617
|
+
}
|
|
11618
|
+
catch {
|
|
11619
|
+
base = {
|
|
11620
|
+
component: 'praxis-crud',
|
|
11621
|
+
resource: { path: this.effectiveResource() || 'recurso-auto', idField: 'id' },
|
|
11622
|
+
table: { columns: [] },
|
|
11623
|
+
};
|
|
11624
|
+
}
|
|
11625
|
+
}
|
|
11626
|
+
else {
|
|
11627
|
+
base = {
|
|
10668
11628
|
component: 'praxis-crud',
|
|
10669
11629
|
resource: { path: trimmed, idField: 'id' },
|
|
10670
11630
|
table: { columns: [] },
|
|
10671
11631
|
};
|
|
11632
|
+
}
|
|
10672
11633
|
}
|
|
10673
11634
|
else if (metaSource) {
|
|
10674
11635
|
base = { ...metaSource };
|
|
@@ -10788,6 +11749,15 @@ class PraxisResourcePage {
|
|
|
10788
11749
|
this.contextSub = this.runtimeContext?.contextChanges$
|
|
10789
11750
|
.subscribe((context) => this.onRuntimeContext(context));
|
|
10790
11751
|
}
|
|
11752
|
+
ngOnChanges(changes) {
|
|
11753
|
+
this.inputsVersion.update((v) => v + 1);
|
|
11754
|
+
const scopeInputChanged = (changes['scopeBar'] && !changes['scopeBar'].isFirstChange()) ||
|
|
11755
|
+
(changes['scopeItems'] && !changes['scopeItems'].isFirstChange()) ||
|
|
11756
|
+
(changes['defaultScopeId'] && !changes['defaultScopeId'].isFirstChange());
|
|
11757
|
+
if (scopeInputChanged) {
|
|
11758
|
+
this.restoreDefaultScope();
|
|
11759
|
+
}
|
|
11760
|
+
}
|
|
10791
11761
|
ngOnDestroy() {
|
|
10792
11762
|
this.routeSub?.unsubscribe();
|
|
10793
11763
|
this.contextSub?.unsubscribe();
|
|
@@ -10863,7 +11833,7 @@ class PraxisResourcePage {
|
|
|
10863
11833
|
}
|
|
10864
11834
|
}
|
|
10865
11835
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisResourcePage, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10866
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisResourcePage, isStandalone: true, selector: "praxis-resource-page", inputs: { resource: "resource", resourcePath: "resourcePath", crudId: "crudId", metadata: "metadata", title: "title", subtitle: "subtitle", domain: "domain", scopeBar: "scopeBar", scopeItems: "scopeItems", defaultScopeId: "defaultScopeId", enableCustomization: "enableCustomization", tableConfigPersistenceStrategy: "tableConfigPersistenceStrategy", context: "context", actions: "actions", filterCriteria: "filterCriteria" }, outputs: { rowClick: "rowClick", rowAction: "rowAction", rowDoubleClick: "rowDoubleClick", selectionChange: "selectionChange", drawerOpen: "drawerOpen", drawerClose: "drawerClose", afterOpen: "afterOpen", afterClose: "afterClose", kpiCardClick: "kpiCardClick", afterSave: "afterSave", afterDelete: "afterDelete", error: "error" }, ngImport: i0, template: `
|
|
11836
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisResourcePage, isStandalone: true, selector: "praxis-resource-page", inputs: { resource: "resource", resourcePath: "resourcePath", crudId: "crudId", metadata: "metadata", title: "title", subtitle: "subtitle", domain: "domain", scopeBar: "scopeBar", scopeItems: "scopeItems", defaultScopeId: "defaultScopeId", enableCustomization: "enableCustomization", tableConfigPersistenceStrategy: "tableConfigPersistenceStrategy", context: "context", actions: "actions", filterCriteria: "filterCriteria" }, outputs: { rowClick: "rowClick", rowAction: "rowAction", rowDoubleClick: "rowDoubleClick", selectionChange: "selectionChange", drawerOpen: "drawerOpen", drawerClose: "drawerClose", afterOpen: "afterOpen", afterClose: "afterClose", kpiCardClick: "kpiCardClick", afterSave: "afterSave", afterDelete: "afterDelete", error: "error" }, usesOnChanges: true, ngImport: i0, template: `
|
|
10867
11837
|
<div class="praxis-resource-page page-container">
|
|
10868
11838
|
<!-- Auto-Header Governado -->
|
|
10869
11839
|
@if (effectiveTitle() || effectiveDomain()) {
|
|
@@ -10935,7 +11905,7 @@ class PraxisResourcePage {
|
|
|
10935
11905
|
}
|
|
10936
11906
|
}
|
|
10937
11907
|
</div>
|
|
10938
|
-
`, 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 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 });
|
|
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 });
|
|
10939
11909
|
}
|
|
10940
11910
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisResourcePage, decorators: [{
|
|
10941
11911
|
type: Component,
|
|
@@ -11011,7 +11981,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
11011
11981
|
}
|
|
11012
11982
|
}
|
|
11013
11983
|
</div>
|
|
11014
|
-
`, 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 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"] }]
|
|
11984
|
+
`, 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"] }]
|
|
11015
11985
|
}], propDecorators: { resource: [{
|
|
11016
11986
|
type: Input
|
|
11017
11987
|
}], resourcePath: [{
|