@praxisui/page-builder 8.0.0-beta.104 → 8.0.0-beta.106

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.
@@ -181,6 +181,12 @@ class FloatingToolbarComponent {
181
181
  canRedo = false;
182
182
  showSave = true;
183
183
  showPreview = true;
184
+ editingEnabled = true;
185
+ previewActive = false;
186
+ connectionMode = false;
187
+ modeLabel = '';
188
+ previewLabel = 'Pre-visualizar';
189
+ exitPreviewLabel = 'Voltar para edicao';
184
190
  add = new EventEmitter();
185
191
  undo = new EventEmitter();
186
192
  redo = new EventEmitter();
@@ -188,79 +194,107 @@ class FloatingToolbarComponent {
188
194
  preview = new EventEmitter();
189
195
  save = new EventEmitter();
190
196
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FloatingToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
191
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: FloatingToolbarComponent, isStandalone: true, selector: "praxis-floating-toolbar", inputs: { visible: "visible", canUndo: "canUndo", canRedo: "canRedo", showSave: "showSave", showPreview: "showPreview" }, outputs: { add: "add", undo: "undo", redo: "redo", settings: "settings", preview: "preview", save: "save" }, ngImport: i0, template: `
197
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: FloatingToolbarComponent, isStandalone: true, selector: "praxis-floating-toolbar", inputs: { visible: "visible", canUndo: "canUndo", canRedo: "canRedo", showSave: "showSave", showPreview: "showPreview", editingEnabled: "editingEnabled", previewActive: "previewActive", connectionMode: "connectionMode", modeLabel: "modeLabel", previewLabel: "previewLabel", exitPreviewLabel: "exitPreviewLabel" }, outputs: { add: "add", undo: "undo", redo: "redo", settings: "settings", preview: "preview", save: "save" }, ngImport: i0, template: `
192
198
  @if (visible) {
193
- <div class="pdx-floating-toolbar">
199
+ <div
200
+ class="pdx-floating-toolbar"
201
+ [class.pdx-floating-toolbar--connections]="connectionMode"
202
+ [class.pdx-floating-toolbar--preview]="previewActive"
203
+ >
204
+ @if (modeLabel) {
205
+ <span class="pdx-mode-chip" [attr.data-testid]="'page-builder-toolbar-mode'">{{ modeLabel }}</span>
206
+ }
194
207
  <div class="pdx-actions">
195
- <button mat-mini-fab color="primary" (click)="add.emit()" [matTooltip]="'Inserir componente'" aria-label="Inserir componente">
208
+ <button mat-mini-fab color="primary" (click)="add.emit()" [disabled]="!editingEnabled" [matTooltip]="'Inserir componente'" aria-label="Inserir componente">
196
209
  <mat-icon [praxisIcon]="'add'"></mat-icon>
197
210
  </button>
198
211
  @if (showSave) {
199
- <button mat-mini-fab color="accent" (click)="save.emit()" [matTooltip]="'Salvar pagina'" aria-label="Salvar pagina">
212
+ <button mat-mini-fab color="accent" (click)="save.emit()" [disabled]="!editingEnabled" [matTooltip]="'Salvar pagina'" aria-label="Salvar pagina">
200
213
  <mat-icon [praxisIcon]="'save'"></mat-icon>
201
214
  </button>
202
215
  }
203
216
  @if (canUndo) {
204
- <button mat-mini-fab (click)="undo.emit()" [matTooltip]="'Desfazer'" aria-label="Desfazer">
217
+ <button mat-mini-fab (click)="undo.emit()" [disabled]="!editingEnabled" [matTooltip]="'Desfazer'" aria-label="Desfazer">
205
218
  <mat-icon [praxisIcon]="'undo'"></mat-icon>
206
219
  </button>
207
220
  }
208
221
  @if (canRedo) {
209
- <button mat-mini-fab (click)="redo.emit()" [matTooltip]="'Refazer'" aria-label="Refazer">
222
+ <button mat-mini-fab (click)="redo.emit()" [disabled]="!editingEnabled" [matTooltip]="'Refazer'" aria-label="Refazer">
210
223
  <mat-icon [praxisIcon]="'redo'"></mat-icon>
211
224
  </button>
212
225
  }
213
- <button mat-mini-fab (click)="settings.emit()" [matTooltip]="'Configuracoes da pagina'" aria-label="Configuracoes da pagina">
226
+ <button mat-mini-fab (click)="settings.emit()" [disabled]="!editingEnabled" [matTooltip]="'Configuracoes da pagina'" aria-label="Configuracoes da pagina">
214
227
  <mat-icon [praxisIcon]="'settings'"></mat-icon>
215
228
  </button>
216
229
  @if (showPreview) {
217
- <button mat-mini-fab (click)="preview.emit()" [matTooltip]="'Pre-visualizar'" aria-label="Pre-visualizar">
218
- <mat-icon [praxisIcon]="'visibility'"></mat-icon>
230
+ <button
231
+ mat-mini-fab
232
+ (click)="preview.emit()"
233
+ [class.pdx-preview-toggle--active]="previewActive"
234
+ [matTooltip]="previewActive ? exitPreviewLabel : previewLabel"
235
+ [attr.aria-label]="previewActive ? exitPreviewLabel : previewLabel"
236
+ [attr.aria-pressed]="previewActive"
237
+ >
238
+ <mat-icon [praxisIcon]="previewActive ? 'edit' : 'visibility'"></mat-icon>
219
239
  </button>
220
240
  }
221
241
  <ng-content select="[pdx-toolbar-extra]"></ng-content>
222
242
  </div>
223
243
  </div>
224
244
  }
225
- `, isInline: true, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-floating-toolbar{position:absolute;right:16px;bottom:16px;display:flex;gap:8px;align-items:center;pointer-events:auto}.pdx-actions{display:flex;gap:8px}@media(max-width:720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", 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: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
245
+ `, isInline: true, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-floating-toolbar{position:absolute;right:16px;bottom:16px;display:flex;gap:8px;align-items:center;pointer-events:auto}.pdx-floating-toolbar--connections{top:16px;bottom:auto}.pdx-mode-chip{display:inline-flex;align-items:center;min-height:28px;max-width:148px;padding:3px 9px;border:1px solid rgba(103,80,164,.22);border-radius:999px;background:#ffffffeb;color:#3f2d75;font-size:11px;font-weight:700;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;box-shadow:0 8px 22px #0f172a1f}.pdx-actions{display:flex;gap:8px}.pdx-preview-toggle--active{outline:2px solid rgba(103,80,164,.48);outline-offset:2px}@media(max-width:720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}.pdx-floating-toolbar--connections{top:12px;bottom:auto}.pdx-mode-chip{max-width:112px}}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", 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: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
226
246
  }
227
247
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FloatingToolbarComponent, decorators: [{
228
248
  type: Component,
229
249
  args: [{ selector: 'praxis-floating-toolbar', standalone: true, imports: [MatButtonModule, MatIconModule, MatTooltipModule, PraxisIconDirective], template: `
230
250
  @if (visible) {
231
- <div class="pdx-floating-toolbar">
251
+ <div
252
+ class="pdx-floating-toolbar"
253
+ [class.pdx-floating-toolbar--connections]="connectionMode"
254
+ [class.pdx-floating-toolbar--preview]="previewActive"
255
+ >
256
+ @if (modeLabel) {
257
+ <span class="pdx-mode-chip" [attr.data-testid]="'page-builder-toolbar-mode'">{{ modeLabel }}</span>
258
+ }
232
259
  <div class="pdx-actions">
233
- <button mat-mini-fab color="primary" (click)="add.emit()" [matTooltip]="'Inserir componente'" aria-label="Inserir componente">
260
+ <button mat-mini-fab color="primary" (click)="add.emit()" [disabled]="!editingEnabled" [matTooltip]="'Inserir componente'" aria-label="Inserir componente">
234
261
  <mat-icon [praxisIcon]="'add'"></mat-icon>
235
262
  </button>
236
263
  @if (showSave) {
237
- <button mat-mini-fab color="accent" (click)="save.emit()" [matTooltip]="'Salvar pagina'" aria-label="Salvar pagina">
264
+ <button mat-mini-fab color="accent" (click)="save.emit()" [disabled]="!editingEnabled" [matTooltip]="'Salvar pagina'" aria-label="Salvar pagina">
238
265
  <mat-icon [praxisIcon]="'save'"></mat-icon>
239
266
  </button>
240
267
  }
241
268
  @if (canUndo) {
242
- <button mat-mini-fab (click)="undo.emit()" [matTooltip]="'Desfazer'" aria-label="Desfazer">
269
+ <button mat-mini-fab (click)="undo.emit()" [disabled]="!editingEnabled" [matTooltip]="'Desfazer'" aria-label="Desfazer">
243
270
  <mat-icon [praxisIcon]="'undo'"></mat-icon>
244
271
  </button>
245
272
  }
246
273
  @if (canRedo) {
247
- <button mat-mini-fab (click)="redo.emit()" [matTooltip]="'Refazer'" aria-label="Refazer">
274
+ <button mat-mini-fab (click)="redo.emit()" [disabled]="!editingEnabled" [matTooltip]="'Refazer'" aria-label="Refazer">
248
275
  <mat-icon [praxisIcon]="'redo'"></mat-icon>
249
276
  </button>
250
277
  }
251
- <button mat-mini-fab (click)="settings.emit()" [matTooltip]="'Configuracoes da pagina'" aria-label="Configuracoes da pagina">
278
+ <button mat-mini-fab (click)="settings.emit()" [disabled]="!editingEnabled" [matTooltip]="'Configuracoes da pagina'" aria-label="Configuracoes da pagina">
252
279
  <mat-icon [praxisIcon]="'settings'"></mat-icon>
253
280
  </button>
254
281
  @if (showPreview) {
255
- <button mat-mini-fab (click)="preview.emit()" [matTooltip]="'Pre-visualizar'" aria-label="Pre-visualizar">
256
- <mat-icon [praxisIcon]="'visibility'"></mat-icon>
282
+ <button
283
+ mat-mini-fab
284
+ (click)="preview.emit()"
285
+ [class.pdx-preview-toggle--active]="previewActive"
286
+ [matTooltip]="previewActive ? exitPreviewLabel : previewLabel"
287
+ [attr.aria-label]="previewActive ? exitPreviewLabel : previewLabel"
288
+ [attr.aria-pressed]="previewActive"
289
+ >
290
+ <mat-icon [praxisIcon]="previewActive ? 'edit' : 'visibility'"></mat-icon>
257
291
  </button>
258
292
  }
259
293
  <ng-content select="[pdx-toolbar-extra]"></ng-content>
260
294
  </div>
261
295
  </div>
262
296
  }
263
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-floating-toolbar{position:absolute;right:16px;bottom:16px;display:flex;gap:8px;align-items:center;pointer-events:auto}.pdx-actions{display:flex;gap:8px}@media(max-width:720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}}\n"] }]
297
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-floating-toolbar{position:absolute;right:16px;bottom:16px;display:flex;gap:8px;align-items:center;pointer-events:auto}.pdx-floating-toolbar--connections{top:16px;bottom:auto}.pdx-mode-chip{display:inline-flex;align-items:center;min-height:28px;max-width:148px;padding:3px 9px;border:1px solid rgba(103,80,164,.22);border-radius:999px;background:#ffffffeb;color:#3f2d75;font-size:11px;font-weight:700;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;box-shadow:0 8px 22px #0f172a1f}.pdx-actions{display:flex;gap:8px}.pdx-preview-toggle--active{outline:2px solid rgba(103,80,164,.48);outline-offset:2px}@media(max-width:720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}.pdx-floating-toolbar--connections{top:12px;bottom:auto}.pdx-mode-chip{max-width:112px}}\n"] }]
264
298
  }], propDecorators: { visible: [{
265
299
  type: Input
266
300
  }], canUndo: [{
@@ -271,6 +305,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
271
305
  type: Input
272
306
  }], showPreview: [{
273
307
  type: Input
308
+ }], editingEnabled: [{
309
+ type: Input
310
+ }], previewActive: [{
311
+ type: Input
312
+ }], connectionMode: [{
313
+ type: Input
314
+ }], modeLabel: [{
315
+ type: Input
316
+ }], previewLabel: [{
317
+ type: Input
318
+ }], exitPreviewLabel: [{
319
+ type: Input
274
320
  }], add: [{
275
321
  type: Output
276
322
  }], undo: [{
@@ -337,6 +383,7 @@ class ComponentPaletteDialogComponent {
337
383
  const q = (this.query() || '').toLowerCase();
338
384
  const allowIds = new Set((this.data?.allowedWidgetIds || []).map((s) => s.toLowerCase()));
339
385
  const allowTags = new Set((this.data?.allowedWidgetTags || []).map((s) => s.toLowerCase()));
386
+ const allowPresets = new Set((this.data?.allowedPresetIds || []).map((s) => s.toLowerCase()));
340
387
  const metadataById = new Map(this.registry.getAll().map((meta) => [meta.id, meta]));
341
388
  return list.filter((entry) => {
342
389
  const meta = metadataById.get(entry.componentId);
@@ -349,6 +396,8 @@ class ComponentPaletteDialogComponent {
349
396
  return false;
350
397
  if (allowTags.size > 0 && !meta.tags?.some(t => allowTags.has(t.toLowerCase())))
351
398
  return false;
399
+ if (entry.presetId && allowPresets.size > 0 && !allowPresets.has(entry.presetId.toLowerCase()))
400
+ return false;
352
401
  if (typeof this.data?.predicate === 'function' && !this.data.predicate(meta))
353
402
  return false;
354
403
  return true;
@@ -2390,8 +2439,22 @@ const PRAXIS_PAGE_BUILDER_EN_US = {
2390
2439
  'praxis.pageBuilder.editor.hints.schemaInitial': 'Define the initial value of this state path. This helps the page start in a consistent state even before remote connections and data.',
2391
2440
  'praxis.pageBuilder.editor.hints.templateJson': 'JSON templates are useful to generate complete derived objects, such as texts, summary cards or shell settings.',
2392
2441
  'praxis.pageBuilder.editor.hints.transformerOptions': 'Pass the registered transformer options here. Prefer lean JSON with only the parameters actually used by the runtime.',
2442
+ 'praxis.pageBuilder.toolbar.preview': 'Preview',
2443
+ 'praxis.pageBuilder.toolbar.exitPreview': 'Back to editing',
2444
+ 'praxis.pageBuilder.builderMode.editing': 'Editing',
2445
+ 'praxis.pageBuilder.builderMode.connections': 'Connections',
2446
+ 'praxis.pageBuilder.builderMode.ai': 'AI',
2447
+ 'praxis.pageBuilder.builderMode.preview': 'Preview',
2448
+ 'praxis.pageBuilder.builderMode.presentation': 'Presentation',
2449
+ 'praxis.pageBuilder.premiumReadiness.actions.openPageSettings': 'Open page settings',
2450
+ 'praxis.pageBuilder.premiumReadiness.actions.reviewTheme': 'Review theme',
2451
+ 'praxis.pageBuilder.premiumReadiness.actions.openDeviceLayouts': 'Open layouts',
2452
+ 'praxis.pageBuilder.premiumReadiness.actions.openConnections': 'Open connections',
2453
+ 'praxis.pageBuilder.premiumReadiness.actions.openWidgetConfig': 'Open widget',
2454
+ 'praxis.pageBuilder.premiumReadiness.actions.focusChart': 'Focus chart',
2393
2455
  'praxis.pageBuilder.connections.toggle': 'Edit connections',
2394
2456
  'praxis.pageBuilder.connections.toggleAria': 'Edit connections',
2457
+ 'praxis.pageBuilder.connections.close': 'Close connections',
2395
2458
  'praxis.pageBuilder.connections.title': 'Connections',
2396
2459
  'praxis.pageBuilder.connections.editor.panelAria': 'Connection editor',
2397
2460
  'praxis.pageBuilder.connections.editor.eyebrow': 'Radial connection studio',
@@ -2666,6 +2729,7 @@ const PRAXIS_PAGE_BUILDER_EN_US = {
2666
2729
  'praxis.pageBuilder.agentic.dragHandleAria': 'Move AI assistant',
2667
2730
  'praxis.pageBuilder.agentic.resizeHandleAria': 'Resize AI assistant',
2668
2731
  'praxis.pageBuilder.agentic.resizeHandleTooltip': 'Resize',
2732
+ 'praxis.pageBuilder.agentic.submit': 'Send request',
2669
2733
  'praxis.pageBuilder.agentic.preview': 'Generate preview',
2670
2734
  'praxis.pageBuilder.agentic.persist': 'Save',
2671
2735
  'praxis.pageBuilder.pageLifecycle.restart': 'Restart page',
@@ -2864,8 +2928,22 @@ const PRAXIS_PAGE_BUILDER_PT_BR = {
2864
2928
  'praxis.pageBuilder.editor.hints.schemaInitial': 'Defina o valor inicial desse caminho de estado. Isso ajuda a página a nascer em um estado consistente mesmo antes de conexões e dados remotos.',
2865
2929
  'praxis.pageBuilder.editor.hints.templateJson': 'Modelos em JSON são úteis para gerar objetos derivados completos, como textos, cartões de resumo ou configurações de shell.',
2866
2930
  'praxis.pageBuilder.editor.hints.transformerOptions': 'Passe aqui as opções do transformador registrado. Prefira JSON enxuto com os parâmetros realmente usados pelo runtime.',
2931
+ 'praxis.pageBuilder.toolbar.preview': 'Pré-visualizar',
2932
+ 'praxis.pageBuilder.toolbar.exitPreview': 'Voltar para edição',
2933
+ 'praxis.pageBuilder.builderMode.editing': 'Edição',
2934
+ 'praxis.pageBuilder.builderMode.connections': 'Conexões',
2935
+ 'praxis.pageBuilder.builderMode.ai': 'IA',
2936
+ 'praxis.pageBuilder.builderMode.preview': 'Prévia',
2937
+ 'praxis.pageBuilder.builderMode.presentation': 'Apresentação',
2938
+ 'praxis.pageBuilder.premiumReadiness.actions.openPageSettings': 'Abrir configurações da página',
2939
+ 'praxis.pageBuilder.premiumReadiness.actions.reviewTheme': 'Revisar tema',
2940
+ 'praxis.pageBuilder.premiumReadiness.actions.openDeviceLayouts': 'Abrir layouts',
2941
+ 'praxis.pageBuilder.premiumReadiness.actions.openConnections': 'Abrir conexões',
2942
+ 'praxis.pageBuilder.premiumReadiness.actions.openWidgetConfig': 'Abrir widget',
2943
+ 'praxis.pageBuilder.premiumReadiness.actions.focusChart': 'Focar gráfico',
2867
2944
  'praxis.pageBuilder.connections.toggle': 'Editar conexões',
2868
2945
  'praxis.pageBuilder.connections.toggleAria': 'Editar conexões',
2946
+ 'praxis.pageBuilder.connections.close': 'Fechar conexões',
2869
2947
  'praxis.pageBuilder.connections.title': 'Conexões',
2870
2948
  'praxis.pageBuilder.connections.editor.panelAria': 'Editor de conexões',
2871
2949
  'praxis.pageBuilder.connections.editor.eyebrow': 'Estúdio radial de conexões',
@@ -3131,7 +3209,7 @@ const PRAXIS_PAGE_BUILDER_PT_BR = {
3131
3209
  'praxis.pageBuilder.agentic.resourceDiscovery.useResource': 'Usar {resourcePath}',
3132
3210
  'praxis.pageBuilder.agentic.resourceDiscovery.defaultRecommendedLabel': 'a primeira opção',
3133
3211
  'praxis.pageBuilder.agentic.resourceDiscovery.cardDescription': 'Fonte recomendada para transformar {label} em painel: ajuda a escolher gráficos, listas, filtros e formatos antes de materializar a tela.',
3134
- 'praxis.pageBuilder.agentic.resourceDiscovery.cardBestFor': 'Quando você quer entender se {label} responde ao objetivo de negócio antes de criar widgets.',
3212
+ 'praxis.pageBuilder.agentic.resourceDiscovery.cardBestFor': 'Quando você precisa decidir se {label} é a melhor fonte para a experiência que está criando.',
3135
3213
  'praxis.pageBuilder.agentic.resourceDiscovery.cardReturns': 'Sugere métricas, dimensões, filtros, formatos de valor, gráficos e listas de detalhe compatíveis com a fonte.',
3136
3214
  'praxis.pageBuilder.agentic.resourceDiscovery.cardNextStep': 'Selecione para eu propor uma pré-visualização governada com cards ricos, drill-down e formatos adequados por padrão.',
3137
3215
  'praxis.pageBuilder.agentic.diagnostics.title': 'Diagnóstico do LLM',
@@ -3140,6 +3218,7 @@ const PRAXIS_PAGE_BUILDER_PT_BR = {
3140
3218
  'praxis.pageBuilder.agentic.dragHandleAria': 'Mover assistente de IA',
3141
3219
  'praxis.pageBuilder.agentic.resizeHandleAria': 'Redimensionar assistente de IA',
3142
3220
  'praxis.pageBuilder.agentic.resizeHandleTooltip': 'Redimensionar',
3221
+ 'praxis.pageBuilder.agentic.submit': 'Enviar pedido',
3143
3222
  'praxis.pageBuilder.agentic.preview': 'Gerar prévia',
3144
3223
  'praxis.pageBuilder.agentic.persist': 'Salvar',
3145
3224
  'praxis.pageBuilder.pageLifecycle.restart': 'Recomeçar tela',
@@ -12115,7 +12194,7 @@ const PAGE_BUILDER_COMPONENT_CONTEXT_PACK = {
12115
12194
  const DEFAULT_AGENTIC_AUTHORING_REQUEST_TIMEOUT_MS = 120000;
12116
12195
  const DEFAULT_TURN_STREAM_START_TIMEOUT_MS = 10000;
12117
12196
  const DEFAULT_TURN_STREAM_TIMEOUT_MS = 240000;
12118
- const DEFAULT_TURN_STREAM_RESULT_FALLBACK_MS = 90000;
12197
+ const DEFAULT_TURN_STREAM_RESULT_FALLBACK_MS = 210000;
12119
12198
  const DEFAULT_TURN_STREAM_SILENCE_STATUS_MS = 20000;
12120
12199
  const PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS = new InjectionToken('PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS');
12121
12200
  class PageBuilderAgenticAuthoringService {
@@ -13980,6 +14059,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
13980
14059
  state: 'success',
13981
14060
  phase: 'summarize',
13982
14061
  assistantMessage: intentAssistantMessage,
14062
+ assistantContent: this.toJsonObject(intentResolution.assistantContent),
13983
14063
  quickReplies,
13984
14064
  canApply: false,
13985
14065
  statusText: '',
@@ -13994,6 +14074,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
13994
14074
  state: 'clarification',
13995
14075
  phase: 'clarify',
13996
14076
  assistantMessage: intentAssistantMessage,
14077
+ assistantContent: this.toJsonObject(intentResolution.assistantContent),
13997
14078
  quickReplies,
13998
14079
  canApply: false,
13999
14080
  statusText: '',
@@ -14008,6 +14089,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
14008
14089
  state: 'clarification',
14009
14090
  phase: 'clarify',
14010
14091
  assistantMessage: intentAssistantMessage,
14092
+ assistantContent: this.toJsonObject(intentResolution.assistantContent),
14011
14093
  quickReplies,
14012
14094
  canApply: false,
14013
14095
  statusText: '',
@@ -15142,9 +15224,6 @@ class PageBuilderAgenticAuthoringTurnFlow {
15142
15224
  }
15143
15225
  async buildTurnStreamRequest(request, prompt) {
15144
15226
  const startedAt = Date.now();
15145
- const capabilitiesStartedAt = Date.now();
15146
- const componentCapabilities = await this.context.loadComponentCapabilities();
15147
- const capabilitiesElapsedMs = Math.max(0, Date.now() - capabilitiesStartedAt);
15148
15227
  const authoringContextStartedAt = Date.now();
15149
15228
  const selectedWidgetKey = this.context.selectedWidgetKey();
15150
15229
  const authoringContext = this.buildAuthoringContext(request);
@@ -15162,7 +15241,6 @@ class PageBuilderAgenticAuthoringTurnFlow {
15162
15241
  provider: this.context.provider(),
15163
15242
  model: this.context.model(),
15164
15243
  apiKey: this.context.apiKey(),
15165
- componentCapabilities,
15166
15244
  ...authoringContext,
15167
15245
  ...(this.runtimeRelatedSurfaceDisambiguationContext
15168
15246
  ? {
@@ -15184,12 +15262,9 @@ class PageBuilderAgenticAuthoringTurnFlow {
15184
15262
  schemaVersion: 'praxis-turn-stream-preparation-diagnostics.v1',
15185
15263
  source: 'page-builder-agentic-authoring-turn-flow',
15186
15264
  totalElapsedMs: Math.max(0, Date.now() - startedAt),
15187
- capabilitiesElapsedMs,
15265
+ componentCapabilitiesSource: 'server-resolved',
15188
15266
  authoringContextElapsedMs,
15189
15267
  runtimeObservationsElapsedMs,
15190
- catalogCount: componentCapabilities.catalogs?.length ?? 0,
15191
- capabilityCount: componentCapabilities.catalogs
15192
- .reduce((count, catalog) => count + (catalog.capabilities?.length ?? 0), 0),
15193
15268
  attachmentCount: authoringContext.attachmentSummaries?.length ?? 0,
15194
15269
  hasPendingClarification: !!authoringContext.pendingClarification,
15195
15270
  hasContextHints: !!authoringContext.contextHints,
@@ -15290,6 +15365,9 @@ class PageBuilderAgenticAuthoringTurnFlow {
15290
15365
  const quickReplies = this.resolveShellQuickReplies(intentResolution, rawQuickReplies);
15291
15366
  this.captureRuntimeRelatedSurfaceDisambiguationContext(payload, event);
15292
15367
  const assistantMessage = this.normalizeAssistantMessageForQuickReplies(rawAssistantMessage, quickReplies);
15368
+ const assistantContent = this.toJsonObject(payload['assistantContent'])
15369
+ ?? this.toJsonObject(intentResolution.assistantContent)
15370
+ ?? null;
15293
15371
  const canApply = payload['canApply'] === true && !!preview?.valid;
15294
15372
  const contextualExecutableIntent = request
15295
15373
  ? this.toExecutableContextualComponentIntent(intentResolution, request)
@@ -15328,7 +15406,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
15328
15406
  state: 'review',
15329
15407
  phase: 'review',
15330
15408
  assistantMessage: status,
15331
- quickReplies: this.mergeDashboardQualityQuickReplies(quickReplies, intentResolution, preview),
15409
+ quickReplies: this.governedBlockedReviewQuickReplies(quickReplies, intentResolution, preview),
15332
15410
  canApply: false,
15333
15411
  statusText: this.reviewStatusText(status, false),
15334
15412
  errorText: '',
@@ -15355,6 +15433,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
15355
15433
  state: pendingClarification || requiresChoice ? 'clarification' : 'success',
15356
15434
  phase: pendingClarification || requiresChoice ? 'clarify' : 'summarize',
15357
15435
  assistantMessage,
15436
+ assistantContent,
15358
15437
  quickReplies,
15359
15438
  canApply: false,
15360
15439
  statusText: '',
@@ -15997,6 +16076,15 @@ class PageBuilderAgenticAuthoringTurnFlow {
15997
16076
  ? this.mergeDashboardQualityQuickReplies(quickReplies, intentResolution, preview)
15998
16077
  : [...quickReplies];
15999
16078
  }
16079
+ governedBlockedReviewQuickReplies(quickReplies, intentResolution, preview) {
16080
+ const replies = this.reviewQuickReplies(quickReplies, intentResolution, preview);
16081
+ if (intentResolution.artifactKind === 'dashboard'
16082
+ && !this.dashboardReviewCanApply(intentResolution, preview)
16083
+ && replies.length === 0) {
16084
+ return [this.dashboardQualityFallbackQuickReply(intentResolution, preview)];
16085
+ }
16086
+ return replies;
16087
+ }
16000
16088
  describeDashboardQualityWarning(code) {
16001
16089
  switch (code) {
16002
16090
  case 'dashboard-without-chart-widget':
@@ -16228,6 +16316,34 @@ class PageBuilderAgenticAuthoringTurnFlow {
16228
16316
  },
16229
16317
  };
16230
16318
  }
16319
+ dashboardQualityFallbackQuickReply(intentResolution, preview) {
16320
+ const diagnostics = this.buildDashboardAuthoringDiagnostics(intentResolution, preview);
16321
+ const validation = this.toJsonObject(diagnostics?.['validation']);
16322
+ const warnings = this.arrayFromUnknown(validation?.['warnings']).map((warning) => `${warning}`);
16323
+ const selectedCandidate = this.toJsonObject(intentResolution.selectedCandidate);
16324
+ const target = this.toJsonObject(intentResolution.target);
16325
+ const resourcePath = this.readString(this.toJsonObject(diagnostics?.['dto']) ?? {}, 'resourcePath')
16326
+ || this.readString(selectedCandidate, 'resourcePath')
16327
+ || this.readString(target, 'resourcePath')
16328
+ || '';
16329
+ const dashboardQuality = this.toDashboardQualityRepairContext(diagnostics);
16330
+ return this.dashboardQualityQuickReply({
16331
+ id: 'dashboard-quality-refine',
16332
+ label: this.context.tx('agentic.dashboardQuality.quickReply.refine', 'Refinar painel'),
16333
+ prompt: this.context.tx('agentic.dashboardQuality.prompt.refine', 'Ajuste o painel para resolver os pontos pendentes e manter apenas decisões compatíveis com os dados confirmados.'),
16334
+ icon: 'auto_fix_high',
16335
+ changeKind: 'refine_dashboard_quality',
16336
+ contextHints: {
16337
+ source: 'dashboard-quality-gate',
16338
+ kind: 'dashboard-repair-action',
16339
+ artifactKind: 'dashboard',
16340
+ resourcePath,
16341
+ warnings,
16342
+ ...(dashboardQuality ? { dashboardQuality } : {}),
16343
+ ...this.dashboardRepairSnapshot(preview),
16344
+ },
16345
+ });
16346
+ }
16231
16347
  phaseForStreamPayload(payload) {
16232
16348
  const phase = this.readString(payload, 'phase');
16233
16349
  if (phase === 'intent.resolve')
@@ -17484,30 +17600,37 @@ class PageBuilderAgenticAuthoringTurnFlow {
17484
17600
  && !!String(presentation[key]).trim());
17485
17601
  }
17486
17602
  resourceQuickReplyDescription(reply) {
17603
+ const label = this.resourceQuickReplySubjectLabel(reply.label);
17487
17604
  const description = reply.description?.trim() ?? '';
17488
17605
  if (description
17489
17606
  && !this.isTechnicalResourceDescription(description)
17490
17607
  && !this.isGenericResourceDescription(description)) {
17491
17608
  return description;
17492
17609
  }
17493
- return this.context.tx('agentic.resourceDiscovery.cardDescription', 'Fonte recomendada para transformar {label} em painel: ajuda a escolher graficos, listas, filtros e formatos antes de materializar a tela.').replace('{label}', reply.label);
17610
+ return this.context.tx('agentic.resourceDiscovery.cardDescription', 'Fonte recomendada para transformar {label} em painel: ajuda a escolher graficos, listas, filtros e formatos antes de materializar a tela.').replace('{label}', label);
17494
17611
  }
17495
17612
  resourceQuickReplyPresentation(reply) {
17496
17613
  const contextHints = this.toJsonObject(reply.contextHints);
17497
17614
  const artifactKind = this.readString(contextHints, 'artifactKind');
17615
+ const label = this.resourceQuickReplySubjectLabel(reply.label);
17498
17616
  if (artifactKind === 'table') {
17499
17617
  return {
17500
- bestFor: `Boa quando voce quer transformar ${reply.label} em uma tabela navegavel.`,
17501
- returns: 'Retorna uma pre-visualizacao com colunas, filtros e fonte semantica preservada.',
17618
+ bestFor: `Boa quando você quer navegar, filtrar e comparar registros de ${label}.`,
17619
+ returns: 'Retorna uma pré-visualização com colunas, filtros e fonte semântica preservada.',
17502
17620
  nextStep: 'Clique para criar a tabela e revisar antes de salvar.',
17503
17621
  };
17504
17622
  }
17505
17623
  return {
17506
- bestFor: this.context.tx('agentic.resourceDiscovery.cardBestFor', 'Quando voce quer entender se {label} responde ao objetivo de negocio antes de criar widgets.').replace('{label}', reply.label),
17507
- returns: this.context.tx('agentic.resourceDiscovery.cardReturns', 'Sugere metricas, dimensoes, filtros, formatos de valor, graficos e listas de detalhe compativeis com a fonte.'),
17508
- nextStep: this.context.tx('agentic.resourceDiscovery.cardNextStep', 'Selecione para eu propor uma pre-visualizacao governada com cards ricos, drill-down e formatos adequados por padrao.'),
17624
+ bestFor: this.context.tx('agentic.resourceDiscovery.cardBestFor', 'Quando você precisa decidir se {label} é a melhor fonte para a experiência que está criando.').replace('{label}', label),
17625
+ returns: this.context.tx('agentic.resourceDiscovery.cardReturns', 'Sugere métricas, dimensões, filtros, formatos de valor, gráficos e listas de detalhe compatíveis com a fonte.'),
17626
+ nextStep: this.context.tx('agentic.resourceDiscovery.cardNextStep', 'Selecione para eu propor uma pré-visualização governada com cards ricos, drill-down e formatos adequados por padrão.'),
17509
17627
  };
17510
17628
  }
17629
+ resourceQuickReplySubjectLabel(label) {
17630
+ const normalized = (label || '').trim();
17631
+ return normalized.replace(/^(?:Criar\s+)?(?:tabela|gr[aá]fico|formul[aá]rio|dashboard|p[aá]gina)\s*:\s*/iu, '').trim()
17632
+ || normalized;
17633
+ }
17511
17634
  isTechnicalResourceDescription(description) {
17512
17635
  return /(?:^|\s)(?:GET|POST|PUT|PATCH|DELETE)\s+\//iu.test(description)
17513
17636
  || /\/api\//iu.test(description)
@@ -17624,15 +17747,53 @@ class PageBuilderAgenticAuthoringTurnFlow {
17624
17747
  buildContextHints(request) {
17625
17748
  const base = this.toJsonObject(request.action?.contextHints)
17626
17749
  ?? this.toJsonObject(request.contextHints);
17750
+ const normalizedBase = this.normalizeAmbientDomainCatalogContextHints(base);
17627
17751
  const includeLlmDiagnostics = this.context.includeLlmDiagnostics?.() === true;
17628
17752
  if (!includeLlmDiagnostics) {
17629
- return base ?? undefined;
17753
+ return normalizedBase ?? undefined;
17630
17754
  }
17631
17755
  return {
17632
- ...(base ?? {}),
17756
+ ...(normalizedBase ?? {}),
17633
17757
  includeLlmDiagnostics: true,
17634
17758
  };
17635
17759
  }
17760
+ normalizeAmbientDomainCatalogContextHints(contextHints) {
17761
+ if (!contextHints) {
17762
+ return null;
17763
+ }
17764
+ const domainCatalog = this.toJsonObject(contextHints['domainCatalog']);
17765
+ if (!domainCatalog || !this.isAmbientUiCompositionDomainCatalog(domainCatalog, contextHints)) {
17766
+ return contextHints;
17767
+ }
17768
+ const normalizedDomainCatalog = { ...domainCatalog };
17769
+ delete normalizedDomainCatalog['resourceKey'];
17770
+ delete normalizedDomainCatalog['query'];
17771
+ return {
17772
+ ...contextHints,
17773
+ domainCatalog: normalizedDomainCatalog,
17774
+ };
17775
+ }
17776
+ isAmbientUiCompositionDomainCatalog(domainCatalog, contextHints) {
17777
+ const recommendedFlow = this.readString(domainCatalog, 'recommendedAuthoringFlow');
17778
+ if (recommendedFlow !== 'ui_composition_authoring') {
17779
+ return false;
17780
+ }
17781
+ if (this.readString(domainCatalog, 'type') === 'governance'
17782
+ || this.readString(domainCatalog, 'recommendedRuleType')
17783
+ || this.readString(domainCatalog, 'ruleType')
17784
+ || this.readString(domainCatalog, 'domainRuleType')
17785
+ || this.readString(domainCatalog, 'targetLayer')) {
17786
+ return false;
17787
+ }
17788
+ return !this.hasExplicitResourceTarget(contextHints);
17789
+ }
17790
+ hasExplicitResourceTarget(contextHints) {
17791
+ return !!(this.readString(contextHints, 'resourcePath')
17792
+ || this.readString(contextHints, 'submitUrl')
17793
+ || this.readString(contextHints, 'schemaUrl')
17794
+ || this.readString(contextHints, 'selectedResourcePath')
17795
+ || this.readString(contextHints, 'targetResourcePath'));
17796
+ }
17636
17797
  toAttachmentSummaries(attachments) {
17637
17798
  return attachments.map((attachment) => ({
17638
17799
  id: attachment.id,
@@ -17813,13 +17974,14 @@ function projectKnowledgeTarget(changeSet, conceptKey) {
17813
17974
  };
17814
17975
  }
17815
17976
 
17816
- const AGENTIC_AUTHORING_TURN_TERMINAL_TIMEOUT_MS = 120_000;
17977
+ const AGENTIC_AUTHORING_TURN_TERMINAL_TIMEOUT_MS = 270_000;
17817
17978
  const AGENTIC_PAGE_COMPOSITION_REQUEST_OUTPUT = 'agenticPageCompositionRequested';
17818
17979
  class DynamicPageBuilderComponent {
17819
17980
  dialog;
17820
17981
  settingsPanel;
17821
17982
  i18n = inject(PraxisI18nService);
17822
17983
  injector = inject(Injector);
17984
+ hostElement = inject((ElementRef));
17823
17985
  componentMetadata = inject(ComponentMetadataRegistry);
17824
17986
  agenticAuthoring = inject(PageBuilderAgenticAuthoringService);
17825
17987
  agenticTurnOrchestrator = inject(PraxisAssistantTurnOrchestratorService);
@@ -17836,6 +17998,9 @@ class DynamicPageBuilderComponent {
17836
17998
  pageIdentity;
17837
17999
  componentInstanceId;
17838
18000
  pageEditorComponent = DynamicPageConfigEditorComponent;
18001
+ componentPaletteAllowedWidgetIds = null;
18002
+ componentPaletteAllowedWidgetTags = null;
18003
+ componentPaletteAllowedPresetIds = null;
17839
18004
  enableAgenticAuthoring = false;
17840
18005
  agenticAuthoringProvider;
17841
18006
  agenticAuthoringModel;
@@ -17859,6 +18024,7 @@ class DynamicPageBuilderComponent {
17859
18024
  savedPageDeleteRequested = new EventEmitter();
17860
18025
  currentPage = signal({ widgets: [] }, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
17861
18026
  hasPageWidgets = computed(() => (this.currentPage().widgets || []).length > 0, ...(ngDevMode ? [{ debugName: "hasPageWidgets" }] : /* istanbul ignore next */ []));
18027
+ premiumReadinessIssues = computed(() => this.evaluatePremiumReadiness(this.currentPage()).slice(0, 3), ...(ngDevMode ? [{ debugName: "premiumReadinessIssues" }] : /* istanbul ignore next */ []));
17862
18028
  connectionsViewerOpen = signal(false, ...(ngDevMode ? [{ debugName: "connectionsViewerOpen" }] : /* istanbul ignore next */ []));
17863
18029
  agenticAuthoringOpen = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringOpen" }] : /* istanbul ignore next */ []));
17864
18030
  agenticAuthoringPrompt = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringPrompt" }] : /* istanbul ignore next */ []));
@@ -17934,6 +18100,24 @@ class DynamicPageBuilderComponent {
17934
18100
  showSettings() {
17935
18101
  return !!this.enableCustomization && !this.previewMode;
17936
18102
  }
18103
+ isPreviewMode() {
18104
+ return this.previewMode;
18105
+ }
18106
+ builderModeLabel() {
18107
+ if (this.previewMode) {
18108
+ return this.tx('builderMode.preview', 'Prévia');
18109
+ }
18110
+ if (this.showSettings() && this.connectionsViewerOpen()) {
18111
+ return this.tx('builderMode.connections', 'Conexões');
18112
+ }
18113
+ if (this.showSettings() && this.enableAgenticAuthoring && this.agenticAuthoringOpen()) {
18114
+ return this.tx('builderMode.ai', 'AI');
18115
+ }
18116
+ if (this.showSettings()) {
18117
+ return this.tx('builderMode.editing', 'Editing');
18118
+ }
18119
+ return this.tx('builderMode.presentation', 'Presentation');
18120
+ }
17937
18121
  onRuntimePageChange(next) {
17938
18122
  const cloned = this.clonePage(next);
17939
18123
  this.currentPage.set(cloned);
@@ -17993,10 +18177,21 @@ class DynamicPageBuilderComponent {
17993
18177
  toggleConnectionsViewer() {
17994
18178
  this.connectionsViewerOpen.update((current) => !current);
17995
18179
  }
18180
+ connectionsToggleLabel() {
18181
+ if (this.connectionsViewerOpen()) {
18182
+ return this.tx('connections.close', 'Close connections');
18183
+ }
18184
+ return this.tx('connections.toggle', 'Edit connections');
18185
+ }
17996
18186
  onAddComponent() {
17997
18187
  const ref = this.dialog.open(ComponentPaletteDialogComponent, {
17998
18188
  width: '720px',
17999
- data: { title: this.tx('connections.palette.insertComponent', 'Insert component') },
18189
+ data: {
18190
+ title: this.tx('connections.palette.insertComponent', 'Insert component'),
18191
+ allowedWidgetIds: this.componentPaletteAllowedWidgetIds || undefined,
18192
+ allowedWidgetTags: this.componentPaletteAllowedWidgetTags || undefined,
18193
+ allowedPresetIds: this.componentPaletteAllowedPresetIds || undefined,
18194
+ },
18000
18195
  });
18001
18196
  ref.afterClosed().subscribe((selection) => {
18002
18197
  if (selection)
@@ -18015,6 +18210,10 @@ class DynamicPageBuilderComponent {
18015
18210
  next.widgets = widgets;
18016
18211
  if (next.canvas) {
18017
18212
  const lastRow = Math.max(1, ...Object.values(next.canvas.items || {}).map((item) => (item.row + item.rowSpan) - 1));
18213
+ const canvasColumns = Math.max(1, next.canvas.columns || 1);
18214
+ const layoutHints = this.layoutHintsFor(type);
18215
+ const colSpan = Math.min(canvasColumns, Math.max(1, layoutHints?.recommendedCols ?? Math.min(4, canvasColumns)));
18216
+ const rowSpan = Math.max(1, layoutHints?.recommendedRows ?? 2);
18018
18217
  next.canvas = {
18019
18218
  ...next.canvas,
18020
18219
  items: {
@@ -18022,18 +18221,38 @@ class DynamicPageBuilderComponent {
18022
18221
  [key]: {
18023
18222
  col: 1,
18024
18223
  row: lastRow + 1,
18025
- colSpan: Math.min(4, Math.max(1, next.canvas.columns || 1)),
18026
- rowSpan: 2,
18224
+ colSpan,
18225
+ rowSpan,
18027
18226
  },
18028
18227
  },
18029
18228
  };
18030
18229
  }
18031
18230
  this.currentPage.set(next);
18231
+ this.selectInsertedWidget(key, widgets.length);
18032
18232
  this.pageChange.emit(this.clonePage(next));
18033
18233
  }
18234
+ layoutHintsFor(componentId) {
18235
+ const metadataHints = this.componentMetadata.get(componentId)?.layoutHints;
18236
+ if (metadataHints) {
18237
+ return metadataHints;
18238
+ }
18239
+ switch (componentId) {
18240
+ case 'praxis-table':
18241
+ return { recommendedCols: 8, recommendedRows: 6 };
18242
+ case 'praxis-filter':
18243
+ return { recommendedCols: 12, recommendedRows: 3 };
18244
+ case 'praxis-chart':
18245
+ case 'praxis-list':
18246
+ case 'praxis-crud':
18247
+ return { recommendedCols: 8, recommendedRows: 5 };
18248
+ default:
18249
+ return undefined;
18250
+ }
18251
+ }
18034
18252
  openPageSettings() {
18035
18253
  if (!this.pageEditorComponent)
18036
18254
  return;
18255
+ this.connectionsViewerOpen.set(false);
18037
18256
  this.runtime?.openPageSettings();
18038
18257
  }
18039
18258
  saveCurrentPage() {
@@ -18050,6 +18269,181 @@ class DynamicPageBuilderComponent {
18050
18269
  canSaveCurrentPage() {
18051
18270
  return this.hasPageWidgets() && !this.hasBlockingAgenticReview();
18052
18271
  }
18272
+ evaluatePremiumReadiness(page) {
18273
+ const widgets = page.widgets || [];
18274
+ if (!widgets.length) {
18275
+ return [];
18276
+ }
18277
+ const issues = [];
18278
+ const themePreset = (page.themePreset || '').trim();
18279
+ const hasKnownThemePreset = !!themePreset && Object.prototype.hasOwnProperty.call(BUILTIN_PAGE_THEME_PRESETS, themePreset);
18280
+ const isDashboard = this.isPremiumReadinessCandidate(page);
18281
+ if (!isDashboard) {
18282
+ return [];
18283
+ }
18284
+ if (!themePreset) {
18285
+ issues.push({
18286
+ id: 'theme-missing',
18287
+ severity: 'warning',
18288
+ title: this.tx('premiumReadiness.themeMissing.title', 'Defina um tema executivo'),
18289
+ description: this.tx('premiumReadiness.themeMissing.description', 'Dashboards corporativos precisam de preset visual para densidade, shell e tokens consistentes.'),
18290
+ action: {
18291
+ kind: 'open-page-settings',
18292
+ label: this.tx('premiumReadiness.actions.openPageSettings', 'Abrir configurações da página'),
18293
+ },
18294
+ });
18295
+ }
18296
+ else if (!hasKnownThemePreset) {
18297
+ issues.push({
18298
+ id: 'theme-unknown',
18299
+ severity: 'error',
18300
+ title: this.tx('premiumReadiness.themeUnknown.title', 'Tema não reconhecido'),
18301
+ description: this.tx('premiumReadiness.themeUnknown.description', 'O preset informado não existe no catálogo canônico e pode cair em aparência genérica.'),
18302
+ action: {
18303
+ kind: 'open-page-settings',
18304
+ label: this.tx('premiumReadiness.actions.reviewTheme', 'Revisar tema'),
18305
+ },
18306
+ });
18307
+ }
18308
+ if (isDashboard && page.canvas && !page.deviceLayouts?.mobile?.canvas) {
18309
+ issues.push({
18310
+ id: 'mobile-layout-missing',
18311
+ severity: 'warning',
18312
+ title: this.tx('premiumReadiness.mobileMissing.title', 'Inclua layout mobile'),
18313
+ description: this.tx('premiumReadiness.mobileMissing.description', 'Uma página premium precisa preservar hierarquia e leitura em telas menores.'),
18314
+ action: {
18315
+ kind: 'open-page-settings',
18316
+ label: this.tx('premiumReadiness.actions.openDeviceLayouts', 'Abrir layouts'),
18317
+ },
18318
+ });
18319
+ }
18320
+ if (this.hasDisconnectedOperationalWidgets(page)) {
18321
+ issues.push({
18322
+ id: 'widgets-disconnected',
18323
+ severity: 'warning',
18324
+ title: this.tx('premiumReadiness.disconnected.title', 'Conecte filtros, gráficos e filas'),
18325
+ description: this.tx('premiumReadiness.disconnected.description', 'A composição parece visualmente rica, mas ainda não mostra causa e efeito entre widgets.'),
18326
+ action: {
18327
+ kind: 'open-connections',
18328
+ label: this.tx('premiumReadiness.actions.openConnections', 'Abrir conexões'),
18329
+ },
18330
+ });
18331
+ }
18332
+ const localAnalyticWidget = widgets.find((widget) => this.usesLocalAnalyticData(widget));
18333
+ if (localAnalyticWidget) {
18334
+ issues.push({
18335
+ id: 'local-data-source',
18336
+ severity: 'info',
18337
+ title: this.tx('premiumReadiness.localData.title', 'Troque dados locais por fonte governada'),
18338
+ description: this.tx('premiumReadiness.localData.description', 'Dados locais ajudam a prototipar, mas produção deve apontar para recurso, endpoint ou estado governado.'),
18339
+ action: {
18340
+ kind: 'open-widget-config',
18341
+ label: this.tx('premiumReadiness.actions.openWidgetConfig', 'Abrir widget'),
18342
+ widgetKey: localAnalyticWidget.key,
18343
+ },
18344
+ });
18345
+ }
18346
+ const latePrimaryChartKey = this.latePrimaryChartKey(page);
18347
+ if (latePrimaryChartKey) {
18348
+ issues.push({
18349
+ id: 'late-primary-chart',
18350
+ severity: 'info',
18351
+ title: this.tx('premiumReadiness.chartHierarchy.title', 'Suba o gráfico principal'),
18352
+ description: this.tx('premiumReadiness.chartHierarchy.description', 'O primeiro gráfico deveria aparecer cedo o bastante para orientar a primeira dobra.'),
18353
+ action: {
18354
+ kind: 'focus-widget',
18355
+ label: this.tx('premiumReadiness.actions.focusChart', 'Focar gráfico'),
18356
+ widgetKey: latePrimaryChartKey,
18357
+ },
18358
+ });
18359
+ }
18360
+ return issues;
18361
+ }
18362
+ runPremiumReadinessAction(issue) {
18363
+ const action = issue.action;
18364
+ if (!action)
18365
+ return;
18366
+ if (this.previewMode) {
18367
+ this.previewMode = false;
18368
+ }
18369
+ switch (action.kind) {
18370
+ case 'open-page-settings':
18371
+ this.openPageSettings();
18372
+ return;
18373
+ case 'open-connections':
18374
+ this.connectionsViewerOpen.set(true);
18375
+ return;
18376
+ case 'open-widget-config':
18377
+ if (action.widgetKey) {
18378
+ this.openWidgetConfiguration(action.widgetKey);
18379
+ }
18380
+ return;
18381
+ case 'focus-widget':
18382
+ if (action.widgetKey) {
18383
+ this.connectionsViewerOpen.set(false);
18384
+ this.focusCanvasWidget(action.widgetKey);
18385
+ }
18386
+ return;
18387
+ }
18388
+ }
18389
+ isPremiumReadinessCandidate(page) {
18390
+ const widgets = page.widgets || [];
18391
+ if (widgets.length >= 4) {
18392
+ return true;
18393
+ }
18394
+ const analyticWidgets = widgets.filter((widget) => this.isAnalyticWidget(widget.definition?.id));
18395
+ if (analyticWidgets.length >= 2) {
18396
+ return true;
18397
+ }
18398
+ const hasFilter = widgets.some((widget) => widget.definition?.id === 'praxis-filter');
18399
+ if (hasFilter && analyticWidgets.length > 0) {
18400
+ return true;
18401
+ }
18402
+ return (page.composition?.links || []).length > 0 && analyticWidgets.length > 0;
18403
+ }
18404
+ hasDisconnectedOperationalWidgets(page) {
18405
+ const widgets = page.widgets || [];
18406
+ const hasFilter = widgets.some((widget) => widget.definition?.id === 'praxis-filter');
18407
+ const hasConsumer = widgets.some((widget) => {
18408
+ const id = widget.definition?.id;
18409
+ return id === 'praxis-chart' || id === 'praxis-list' || id === 'praxis-table';
18410
+ });
18411
+ if (!hasFilter || !hasConsumer) {
18412
+ return false;
18413
+ }
18414
+ return !(page.composition?.links || []).length;
18415
+ }
18416
+ latePrimaryChartKey(page) {
18417
+ const chartKeys = (page.widgets || [])
18418
+ .filter((widget) => widget.definition?.id === 'praxis-chart')
18419
+ .map((widget) => widget.key)
18420
+ .filter(Boolean);
18421
+ if (!chartKeys.length || !page.canvas?.items) {
18422
+ return null;
18423
+ }
18424
+ const firstChart = chartKeys
18425
+ .map((key) => ({ key, row: page.canvas?.items?.[key]?.row }))
18426
+ .filter((item) => typeof item.row === 'number')
18427
+ .sort((left, right) => left.row - right.row)[0];
18428
+ return firstChart && firstChart.row > 8 ? firstChart.key : null;
18429
+ }
18430
+ usesLocalAnalyticData(widget) {
18431
+ if (!this.isAnalyticWidget(widget.definition?.id)) {
18432
+ return false;
18433
+ }
18434
+ const config = widget.definition?.inputs?.['config'];
18435
+ const configRecord = this.toRecord(config);
18436
+ if (!configRecord) {
18437
+ return false;
18438
+ }
18439
+ const dataSource = this.toRecord(configRecord['dataSource']);
18440
+ return dataSource?.['kind'] === 'local';
18441
+ }
18442
+ isAnalyticWidget(componentId) {
18443
+ return componentId === 'praxis-chart'
18444
+ || componentId === 'praxis-list'
18445
+ || componentId === 'praxis-table';
18446
+ }
18053
18447
  applyConfigFromAdapter(config) {
18054
18448
  if (!config.page)
18055
18449
  return;
@@ -18096,9 +18490,9 @@ class DynamicPageBuilderComponent {
18096
18490
  this.syncAgenticAuthoringSession('active');
18097
18491
  }
18098
18492
  minimizeAgenticAuthoring() {
18099
- this.agenticAuthoringOpen.set(false);
18100
18493
  this.agenticAuthoringError.set('');
18101
18494
  this.syncAgenticAuthoringSession('minimized');
18495
+ this.agenticAuthoringOpen.set(false);
18102
18496
  }
18103
18497
  onAgenticAuthoringLayoutChange(layout) {
18104
18498
  this.agenticAuthoringPanelLayoutTouched = true;
@@ -18122,24 +18516,24 @@ class DynamicPageBuilderComponent {
18122
18516
  }
18123
18517
  agenticAuthoringToggleLabel() {
18124
18518
  if (this.agenticAuthoringOpen()) {
18125
- return this.tx('agentic.toggle.minimize', 'Minimize Praxis copilot');
18519
+ return this.tx('agentic.toggle.minimize', 'Minimizar copiloto Praxis');
18126
18520
  }
18127
18521
  if (this.agenticAuthoringMinimized()) {
18128
- return this.tx('agentic.dock.openTooltip', 'Reopen Praxis copilot');
18522
+ return this.tx('agentic.dock.openTooltip', 'Reabrir copiloto Praxis');
18129
18523
  }
18130
- return this.tx('agentic.toggle', 'Create with AI');
18524
+ return this.tx('agentic.toggle', 'Criar com IA');
18131
18525
  }
18132
18526
  agenticAuthoringHeaderTitle() {
18133
18527
  if (this.agenticAuthoringSharedRuleHandoffState()) {
18134
- return this.tx('agentic.header.title.governed', 'Praxis governed copilot');
18528
+ return this.tx('agentic.header.title.governed', 'Copiloto governado Praxis');
18135
18529
  }
18136
18530
  if (this.agenticAuthoringPreviewResult()?.valid) {
18137
- return this.tx('agentic.header.title.review', 'Praxis review copilot');
18531
+ return this.tx('agentic.header.title.review', 'Copiloto de revisão Praxis');
18138
18532
  }
18139
18533
  if (this.resolveSelectedWidgetKey()) {
18140
- return this.tx('agentic.header.title.widget', 'Praxis widget copilot');
18534
+ return this.tx('agentic.header.title.widget', 'Copiloto de componente Praxis');
18141
18535
  }
18142
- return this.tx('agentic.header.title.page', 'Praxis page decision copilot');
18536
+ return this.tx('agentic.header.title.page', 'Copiloto de página Praxis');
18143
18537
  }
18144
18538
  agenticAuthoringHeaderSubtitle() {
18145
18539
  const selectedWidgetLabel = this.resolveSelectedWidgetLabel();
@@ -18165,47 +18559,47 @@ class DynamicPageBuilderComponent {
18165
18559
  }
18166
18560
  agenticAuthoringHeaderModeLabel() {
18167
18561
  if (this.agenticAuthoringSharedRuleHandoffState()) {
18168
- return this.tx('agentic.header.mode.governed', 'Governed');
18562
+ return this.tx('agentic.header.mode.governed', 'Governado');
18169
18563
  }
18170
18564
  if (this.resolveSelectedWidgetKey()) {
18171
18565
  return this.tx('agentic.header.mode.widget', 'Widget');
18172
18566
  }
18173
- return this.tx('agentic.header.mode.page', 'Page');
18567
+ return this.tx('agentic.header.mode.page', 'Página');
18174
18568
  }
18175
18569
  agenticAuthoringShellLabels() {
18176
18570
  return {
18177
18571
  title: this.agenticAuthoringHeaderTitle(),
18178
18572
  subtitle: this.agenticAuthoringHeaderSubtitle(),
18179
- close: this.tx('agentic.minimize', 'Minimize'),
18180
- prompt: this.tx('agentic.promptLabel', 'Message'),
18181
- promptPlaceholder: this.tx('agentic.promptPlaceholder', 'Describe the page, dashboard, form or change you need.'),
18573
+ close: this.tx('agentic.minimize', 'Minimizar'),
18574
+ prompt: this.tx('agentic.promptLabel', 'Mensagem'),
18575
+ promptPlaceholder: this.tx('agentic.promptPlaceholder', 'Descreva a página, dashboard, formulário ou alteração que você precisa.'),
18182
18576
  emptyConversation: this.agenticAuthoringEmptyConversationMessage(),
18183
- submit: this.tx('agentic.preview', 'Criar prévia'),
18577
+ submit: this.tx('agentic.submit', 'Enviar pedido'),
18184
18578
  apply: this.tx('agentic.persist', 'Salvar'),
18185
- conversationAria: this.tx('agentic.conversationAria', 'AI conversation'),
18186
- quickRepliesAria: this.tx('agentic.quickRepliesAria', 'Quick replies'),
18187
- dragHandleAria: this.tx('agentic.dragHandleAria', 'Move AI assistant'),
18188
- resizeHandleAria: this.tx('agentic.resizeHandleAria', 'Resize AI assistant'),
18189
- contextAria: this.tx('agentic.contextAria', 'Active context'),
18190
- attachmentsAria: this.tx('agentic.attachmentsAria', 'Attached context'),
18191
- attach: this.tx('agentic.attach', 'Attach'),
18192
- removeAttachment: this.tx('agentic.removeAttachment', 'Remove attachment'),
18193
- editMessage: this.tx('agentic.editMessage', 'Edit'),
18194
- resendMessage: this.tx('agentic.resendMessage', 'Resend'),
18579
+ conversationAria: this.tx('agentic.conversationAria', 'Conversa com IA'),
18580
+ quickRepliesAria: this.tx('agentic.quickRepliesAria', 'Respostas rápidas'),
18581
+ dragHandleAria: this.tx('agentic.dragHandleAria', 'Mover assistente de IA'),
18582
+ resizeHandleAria: this.tx('agentic.resizeHandleAria', 'Redimensionar assistente de IA'),
18583
+ contextAria: this.tx('agentic.contextAria', 'Contexto ativo'),
18584
+ attachmentsAria: this.tx('agentic.attachmentsAria', 'Contexto anexado'),
18585
+ attach: this.tx('agentic.attach', 'Anexar'),
18586
+ removeAttachment: this.tx('agentic.removeAttachment', 'Remover anexo'),
18587
+ editMessage: this.tx('agentic.editMessage', 'Editar'),
18588
+ resendMessage: this.tx('agentic.resendMessage', 'Reenviar'),
18195
18589
  modeAgenticAuthoring: this.agenticAuthoringHeaderModeLabel(),
18196
- modeConfig: this.tx('agentic.mode.config', 'Configuration'),
18590
+ modeConfig: this.tx('agentic.mode.config', 'Configuração'),
18197
18591
  modeChat: this.tx('agentic.mode.chat', 'Chat'),
18198
- modeDiagnostic: this.tx('agentic.mode.diagnostic', 'Diagnostic'),
18199
- modeReview: this.tx('agentic.mode.review', 'Review'),
18200
- modeInlineHelp: this.tx('agentic.mode.inlineHelp', 'Help'),
18201
- stateIdle: this.tx('agentic.state.idle', 'Ready'),
18202
- stateListening: this.tx('agentic.state.listening', 'Ready'),
18203
- stateProcessing: this.tx('agentic.state.processing', 'Processing'),
18204
- stateClarification: this.tx('agentic.state.clarification', 'Waiting for input'),
18205
- stateReview: this.tx('agentic.state.review', 'Review'),
18206
- stateApplying: this.tx('agentic.state.applying', 'Applying'),
18207
- stateSuccess: this.tx('agentic.state.success', 'Done'),
18208
- stateError: this.tx('agentic.state.error', 'Error'),
18592
+ modeDiagnostic: this.tx('agentic.mode.diagnostic', 'Diagnóstico'),
18593
+ modeReview: this.tx('agentic.mode.review', 'Revisão'),
18594
+ modeInlineHelp: this.tx('agentic.mode.inlineHelp', 'Ajuda'),
18595
+ stateIdle: this.tx('agentic.state.idle', 'Pronto'),
18596
+ stateListening: this.tx('agentic.state.listening', 'Pronto'),
18597
+ stateProcessing: this.tx('agentic.state.processing', 'Processando'),
18598
+ stateClarification: this.tx('agentic.state.clarification', 'Aguardando resposta'),
18599
+ stateReview: this.tx('agentic.state.review', 'Revisão'),
18600
+ stateApplying: this.tx('agentic.state.applying', 'Aplicando'),
18601
+ stateSuccess: this.tx('agentic.state.success', 'Concluído'),
18602
+ stateError: this.tx('agentic.state.error', 'Erro'),
18209
18603
  };
18210
18604
  }
18211
18605
  agenticAuthoringEmptyConversationMessage() {
@@ -18245,7 +18639,7 @@ class DynamicPageBuilderComponent {
18245
18639
  return !!this.agenticAuthoringPreviewResult()?.valid && !this.agenticAuthoringCanApply();
18246
18640
  }
18247
18641
  agenticAuthoringSubmitAction() {
18248
- const label = this.tx('agentic.preview', 'Criar prévia');
18642
+ const label = this.tx('agentic.submit', 'Enviar pedido');
18249
18643
  return {
18250
18644
  id: 'submit',
18251
18645
  kind: 'submit-prompt',
@@ -18273,14 +18667,14 @@ class DynamicPageBuilderComponent {
18273
18667
  agenticAuthoringDockBadge() {
18274
18668
  const state = this.agenticAuthoringShellState();
18275
18669
  if (state === 'error')
18276
- return this.tx('agentic.dock.badgeError', 'Attention');
18670
+ return this.tx('agentic.dock.badgeError', 'Atenção');
18277
18671
  if (state === 'processing' || state === 'applying')
18278
- return this.tx('agentic.dock.badgeWorking', 'Working');
18672
+ return this.tx('agentic.dock.badgeWorking', 'Trabalhando');
18279
18673
  if (state === 'review')
18280
- return this.tx('agentic.dock.badgeReview', 'Review');
18674
+ return this.tx('agentic.dock.badgeReview', 'Revisão');
18281
18675
  if (state === 'clarification')
18282
- return this.tx('agentic.dock.badgeGoverned', 'Governed');
18283
- return this.tx('agentic.dock.badgeReady', 'Ready');
18676
+ return this.tx('agentic.dock.badgeGoverned', 'Governado');
18677
+ return this.tx('agentic.dock.badgeReady', 'Pronto');
18284
18678
  }
18285
18679
  agenticAuthoringDockSummary() {
18286
18680
  const status = this.agenticAuthoringStatus().trim();
@@ -19210,7 +19604,7 @@ class DynamicPageBuilderComponent {
19210
19604
  return null;
19211
19605
  if (handoff.ruleDefinitionId?.trim()) {
19212
19606
  this.sharedRuleCockpitError.set('');
19213
- this.appendAgenticMessage('assistant', this.tx('agentic.sharedRuleCockpit.definitionReady', 'Governed definition is ready for simulation and review.'));
19607
+ this.appendAgenticMessage('assistant', this.tx('agentic.sharedRuleCockpit.definitionReady', 'Definição governada pronta para simulação e revisão.'));
19214
19608
  await this.refreshSharedRuleTimeline();
19215
19609
  return this.sharedRuleCockpitDefinition();
19216
19610
  }
@@ -19345,8 +19739,8 @@ class DynamicPageBuilderComponent {
19345
19739
  const enforcement = this.summarizeSharedRuleEnforcement(materializations);
19346
19740
  this.sharedRuleCockpitEnforcement.set(enforcement);
19347
19741
  this.appendAgenticMessage('assistant', enforcement.status === 'ready'
19348
- ? this.tx('agentic.sharedRuleCockpit.enforcementReady', 'Runtime enforcement validation is ready: applied materializations are available for consumer runtimes.')
19349
- : this.tx('agentic.sharedRuleCockpit.enforcementWaiting', 'Runtime enforcement is still waiting for applied materializations. Publish or review materialization status before validating a consumer runtime.'));
19742
+ ? this.tx('agentic.sharedRuleCockpit.enforcementReady', 'Validação de enforcement runtime pronta: materializações aplicadas estão disponíveis para os runtimes consumidores.')
19743
+ : this.tx('agentic.sharedRuleCockpit.enforcementWaiting', 'O enforcement runtime ainda aguarda materializações aplicadas. Publique ou revise o status de materialização antes de validar um runtime consumidor.'));
19350
19744
  await this.refreshSharedRuleTimeline();
19351
19745
  return enforcement;
19352
19746
  });
@@ -20396,8 +20790,46 @@ class DynamicPageBuilderComponent {
20396
20790
  focusCanvasWidget(widgetKey) {
20397
20791
  if (!widgetKey)
20398
20792
  return;
20793
+ this.selectedWidgetKey.set(widgetKey);
20399
20794
  this.runtime?.selectWidget(widgetKey);
20400
20795
  }
20796
+ openWidgetConfiguration(widgetKey) {
20797
+ if (!widgetKey)
20798
+ return;
20799
+ this.connectionsViewerOpen.set(false);
20800
+ this.focusCanvasWidget(widgetKey);
20801
+ this.runtime?.openWidgetComponentSettings(widgetKey);
20802
+ }
20803
+ selectInsertedWidget(widgetKey, expectedWidgetCount) {
20804
+ this.selectedWidgetKey.set(widgetKey);
20805
+ this.deferInsertedWidgetFocus(widgetKey, expectedWidgetCount, 0);
20806
+ }
20807
+ deferInsertedWidgetFocus(widgetKey, expectedWidgetCount, attempt) {
20808
+ setTimeout(() => {
20809
+ const ready = this.scrollInsertedWidgetIntoView(widgetKey, expectedWidgetCount);
20810
+ if (!ready && attempt < 5) {
20811
+ this.deferInsertedWidgetFocus(widgetKey, expectedWidgetCount, attempt + 1);
20812
+ return;
20813
+ }
20814
+ setTimeout(() => this.focusCanvasWidget(widgetKey), 120);
20815
+ }, attempt === 0 ? 50 : 120);
20816
+ }
20817
+ scrollInsertedWidgetIntoView(widgetKey, expectedWidgetCount) {
20818
+ const widgets = this.hostElement.nativeElement.querySelectorAll('praxis-dynamic-page .pdx-widget');
20819
+ if (widgets.length < expectedWidgetCount) {
20820
+ return false;
20821
+ }
20822
+ const target = this.hostElement.nativeElement.querySelector(`praxis-dynamic-page .pdx-widget[data-widget-key="${this.escapeAttributeValue(widgetKey)}"]`) || widgets.item(widgets.length - 1);
20823
+ target?.scrollIntoView?.({
20824
+ block: 'center',
20825
+ inline: 'nearest',
20826
+ behavior: 'smooth',
20827
+ });
20828
+ return !!target;
20829
+ }
20830
+ escapeAttributeValue(value) {
20831
+ return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
20832
+ }
20401
20833
  parsePage(input) {
20402
20834
  if (!input)
20403
20835
  return undefined;
@@ -20582,7 +21014,7 @@ class DynamicPageBuilderComponent {
20582
21014
  return resolvePraxisPageBuilderText(this.i18n, key, fallback);
20583
21015
  }
20584
21016
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicPageBuilderComponent, deps: [{ token: i1.MatDialog }, { token: SETTINGS_PANEL_BRIDGE, optional: true }], target: i0.ɵɵFactoryTarget.Component });
20585
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: DynamicPageBuilderComponent, isStandalone: true, selector: "praxis-dynamic-page-builder", inputs: { page: "page", context: "context", strictValidation: "strictValidation", autoPersist: "autoPersist", enableCustomization: "enableCustomization", showSettingsButton: "showSettingsButton", pageIdentity: "pageIdentity", componentInstanceId: "componentInstanceId", pageEditorComponent: "pageEditorComponent", enableAgenticAuthoring: "enableAgenticAuthoring", agenticAuthoringProvider: "agenticAuthoringProvider", agenticAuthoringModel: "agenticAuthoringModel", agenticAuthoringApiKey: "agenticAuthoringApiKey", agenticAuthoringComponentId: "agenticAuthoringComponentId", agenticAuthoringScope: "agenticAuthoringScope", agenticAuthoringEtag: "agenticAuthoringEtag", agenticAuthoringIncludeLlmDiagnostics: "agenticAuthoringIncludeLlmDiagnostics", agenticAuthoringEnableStreaming: "agenticAuthoringEnableStreaming", agenticAuthoringContextHints: "agenticAuthoringContextHints", showPageLifecycleActions: "showPageLifecycleActions", canDeleteSavedPage: "canDeleteSavedPage", pageLifecycleBusy: "pageLifecycleBusy", pageLifecycleResetRevision: "pageLifecycleResetRevision" }, outputs: { pageChange: "pageChange", widgetEvent: "widgetEvent", pageSaveRequested: "pageSaveRequested", agenticAuthoringApplied: "agenticAuthoringApplied", agenticAuthoringSharedRuleHandoff: "agenticAuthoringSharedRuleHandoff", pageRestart: "pageRestart", savedPageDeleteRequested: "savedPageDeleteRequested" }, providers: [
21017
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: DynamicPageBuilderComponent, isStandalone: true, selector: "praxis-dynamic-page-builder", inputs: { page: "page", context: "context", strictValidation: "strictValidation", autoPersist: "autoPersist", enableCustomization: "enableCustomization", showSettingsButton: "showSettingsButton", pageIdentity: "pageIdentity", componentInstanceId: "componentInstanceId", pageEditorComponent: "pageEditorComponent", componentPaletteAllowedWidgetIds: "componentPaletteAllowedWidgetIds", componentPaletteAllowedWidgetTags: "componentPaletteAllowedWidgetTags", componentPaletteAllowedPresetIds: "componentPaletteAllowedPresetIds", enableAgenticAuthoring: "enableAgenticAuthoring", agenticAuthoringProvider: "agenticAuthoringProvider", agenticAuthoringModel: "agenticAuthoringModel", agenticAuthoringApiKey: "agenticAuthoringApiKey", agenticAuthoringComponentId: "agenticAuthoringComponentId", agenticAuthoringScope: "agenticAuthoringScope", agenticAuthoringEtag: "agenticAuthoringEtag", agenticAuthoringIncludeLlmDiagnostics: "agenticAuthoringIncludeLlmDiagnostics", agenticAuthoringEnableStreaming: "agenticAuthoringEnableStreaming", agenticAuthoringContextHints: "agenticAuthoringContextHints", showPageLifecycleActions: "showPageLifecycleActions", canDeleteSavedPage: "canDeleteSavedPage", pageLifecycleBusy: "pageLifecycleBusy", pageLifecycleResetRevision: "pageLifecycleResetRevision" }, outputs: { pageChange: "pageChange", widgetEvent: "widgetEvent", pageSaveRequested: "pageSaveRequested", agenticAuthoringApplied: "agenticAuthoringApplied", agenticAuthoringSharedRuleHandoff: "agenticAuthoringSharedRuleHandoff", pageRestart: "pageRestart", savedPageDeleteRequested: "savedPageDeleteRequested" }, providers: [
20586
21018
  providePraxisPageBuilderI18n(),
20587
21019
  { provide: DYNAMIC_PAGE_SHELL_EDITOR, useValue: WidgetShellEditorComponent },
20588
21020
  ], viewQueries: [{ propertyName: "runtime", first: true, predicate: ["runtime"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
@@ -20590,6 +21022,47 @@ class DynamicPageBuilderComponent {
20590
21022
  class="builder-shell"
20591
21023
  [class.builder-shell--agentic-review-rail]="agenticAuthoringReviewRailActive()"
20592
21024
  >
21025
+ @if (showSettings() && !connectionsViewerOpen() && premiumReadinessIssues().length) {
21026
+ <section
21027
+ class="builder-premium-readiness"
21028
+ data-testid="page-builder-premium-readiness"
21029
+ [attr.aria-label]="tx('premiumReadiness.title', 'Premium readiness')"
21030
+ >
21031
+ <header class="builder-premium-readiness__header">
21032
+ <span class="builder-premium-readiness__icon material-symbols-outlined" aria-hidden="true">auto_awesome</span>
21033
+ <div>
21034
+ <strong>{{ tx('premiumReadiness.title', 'Premium readiness') }}</strong>
21035
+ <p>{{ tx('premiumReadiness.subtitle', 'Qualidade visual e operacional antes de publicar.') }}</p>
21036
+ </div>
21037
+ </header>
21038
+ <ul class="builder-premium-readiness__list">
21039
+ @for (issue of premiumReadinessIssues(); track issue.id) {
21040
+ <li
21041
+ class="builder-premium-readiness__item"
21042
+ [attr.data-severity]="issue.severity"
21043
+ [attr.data-testid]="'page-builder-premium-readiness-' + issue.id"
21044
+ >
21045
+ <span class="builder-premium-readiness__severity" aria-hidden="true"></span>
21046
+ <div>
21047
+ <strong>{{ issue.title }}</strong>
21048
+ <p>{{ issue.description }}</p>
21049
+ @if (issue.action) {
21050
+ <button
21051
+ type="button"
21052
+ class="builder-premium-readiness__action"
21053
+ [attr.data-testid]="'page-builder-premium-readiness-action-' + issue.id"
21054
+ (click)="runPremiumReadinessAction(issue)"
21055
+ >
21056
+ {{ issue.action.label }}
21057
+ </button>
21058
+ }
21059
+ </div>
21060
+ </li>
21061
+ }
21062
+ </ul>
21063
+ </section>
21064
+ }
21065
+
20593
21066
  <praxis-dynamic-page
20594
21067
  #runtime
20595
21068
  [page]="currentPage()"
@@ -20656,7 +21129,7 @@ class DynamicPageBuilderComponent {
20656
21129
  (close)="minimizeAgenticAuthoring()"
20657
21130
  />
20658
21131
  }
20659
-
21132
+
20660
21133
  @if (agenticAuthoringIncludeLlmDiagnostics && agenticAuthoringLlmDiagnosticsText()) {
20661
21134
  <section
20662
21135
  class="agentic-diagnostics-panel"
@@ -20940,17 +21413,23 @@ class DynamicPageBuilderComponent {
20940
21413
  }
20941
21414
 
20942
21415
  <praxis-floating-toolbar
20943
- [visible]="showSettings()"
21416
+ [visible]="!!enableCustomization"
20944
21417
  [canUndo]="false"
20945
21418
  [canRedo]="false"
20946
21419
  [showSave]="canSaveCurrentPage()"
20947
21420
  [showPreview]="hasPageWidgets()"
21421
+ [editingEnabled]="showSettings()"
21422
+ [previewActive]="isPreviewMode()"
21423
+ [connectionMode]="showSettings() && connectionsViewerOpen()"
21424
+ [modeLabel]="builderModeLabel()"
21425
+ [previewLabel]="tx('toolbar.preview', 'Pré-visualizar')"
21426
+ [exitPreviewLabel]="tx('toolbar.exitPreview', 'Voltar para edição')"
20948
21427
  (add)="onAddComponent()"
20949
21428
  (settings)="openPageSettings()"
20950
21429
  (save)="saveCurrentPage()"
20951
21430
  (preview)="togglePreview()"
20952
21431
  >
20953
- @if (showPageLifecycleActions && hasPageWidgets()) {
21432
+ @if (showSettings() && showPageLifecycleActions && hasPageWidgets()) {
20954
21433
  <button
20955
21434
  pdx-toolbar-extra
20956
21435
  mat-mini-fab
@@ -20964,7 +21443,7 @@ class DynamicPageBuilderComponent {
20964
21443
  <mat-icon [praxisIcon]="'restart_alt'"></mat-icon>
20965
21444
  </button>
20966
21445
  }
20967
- @if (showPageLifecycleActions && canDeleteSavedPage) {
21446
+ @if (showSettings() && showPageLifecycleActions && canDeleteSavedPage) {
20968
21447
  <button
20969
21448
  pdx-toolbar-extra
20970
21449
  mat-mini-fab
@@ -20979,7 +21458,7 @@ class DynamicPageBuilderComponent {
20979
21458
  <mat-icon [praxisIcon]="'delete'"></mat-icon>
20980
21459
  </button>
20981
21460
  }
20982
- @if (enableAgenticAuthoring) {
21461
+ @if (showSettings() && enableAgenticAuthoring) {
20983
21462
  <button
20984
21463
  pdx-toolbar-extra
20985
21464
  mat-mini-fab
@@ -20995,14 +21474,17 @@ class DynamicPageBuilderComponent {
20995
21474
  <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
20996
21475
  </button>
20997
21476
  }
20998
- @if (hasPageWidgets()) {
21477
+ @if (showSettings() && hasPageWidgets()) {
20999
21478
  <button
21000
21479
  pdx-toolbar-extra
21001
21480
  mat-mini-fab
21002
21481
  type="button"
21482
+ class="builder-shell__connections-toggle"
21483
+ [class.builder-shell__connections-toggle--open]="connectionsViewerOpen()"
21003
21484
  [attr.data-testid]="'page-builder-connections-toggle'"
21004
- [matTooltip]="tx('connections.toggle', 'Edit connections')"
21005
- [attr.aria-label]="tx('connections.toggleAria', 'Edit connections')"
21485
+ [matTooltip]="connectionsToggleLabel()"
21486
+ [attr.aria-label]="connectionsToggleLabel()"
21487
+ [disabled]="!showSettings()"
21006
21488
  (click)="toggleConnectionsViewer()"
21007
21489
  >
21008
21490
  <mat-icon [praxisIcon]="'hub'"></mat-icon>
@@ -21010,7 +21492,7 @@ class DynamicPageBuilderComponent {
21010
21492
  }
21011
21493
  </praxis-floating-toolbar>
21012
21494
  </div>
21013
- `, isInline: true, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.builder-shell:has(.pdx-shell.fullscreen) praxis-floating-toolbar{display:none}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:relative;z-index:140}@media(min-width:1100px){.builder-shell--agentic-review-rail{box-sizing:border-box;padding-right:464px}}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"], dependencies: [{ 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.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", 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: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: DynamicWidgetPageComponent, selector: "praxis-dynamic-page", inputs: ["page", "context", "strictValidation", "enableCustomization", "showPageSettingsButton", "shellEditorComponent", "pageEditorComponent", "autoPersist", "pageIdentity", "componentInstanceId", "showWidgetAssistantButton"], outputs: ["pageChange", "widgetEvent", "widgetSelectionChange", "widgetAssistantRequested", "widgetDiagnosticsChange"] }, { kind: "component", type: FloatingToolbarComponent, selector: "praxis-floating-toolbar", inputs: ["visible", "canUndo", "canRedo", "showSave", "showPreview"], outputs: ["add", "undo", "redo", "settings", "preview", "save"] }, { kind: "component", type: ConnectionEditorComponent, selector: "praxis-connection-editor", inputs: ["open", "page"], outputs: ["pageChange", "focusWidget", "openPageSettings", "close"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "recommendedIntents", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "voiceInputMode", "voiceLanguage", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "recommendedIntent", "layoutChange"] }] });
21495
+ `, isInline: true, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.builder-shell:has(.pdx-shell.fullscreen) praxis-floating-toolbar{display:none}.builder-premium-readiness{display:grid;grid-template-columns:minmax(220px,.72fr) minmax(0,1.28fr);gap:12px;width:100%;margin:0 0 14px;padding:14px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #cac4d0) 72%,transparent);border-radius:12px;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary, #6750a4) 10%,transparent),transparent 36%),color-mix(in srgb,var(--md-sys-color-surface-container-lowest, #fff) 96%,transparent);color:var(--md-sys-color-on-surface, #1d1b20);box-shadow:inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface, #1d1b20) 5%,transparent)}.builder-premium-readiness__header{display:flex;align-items:flex-start;gap:10px;min-width:0}.builder-premium-readiness__header strong{display:block;font-size:13px;line-height:1.25}.builder-premium-readiness__header p,.builder-premium-readiness__item p{margin:2px 0 0;color:var(--md-sys-color-on-surface-variant, #49454f);font-size:11px;line-height:1.35}.builder-premium-readiness__icon{color:var(--md-sys-color-primary, #6750a4);font-size:20px;line-height:1}.builder-premium-readiness__list{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:8px;margin:0;padding:0;list-style:none}.builder-premium-readiness__item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:8px;min-width:0;padding:9px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #cac4d0) 64%,transparent);border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low, #f7f2fa) 84%,transparent)}.builder-premium-readiness__item strong{display:block;font-size:12px;line-height:1.25}.builder-premium-readiness__action{appearance:none;display:inline-flex;align-items:center;justify-content:center;min-height:26px;margin-top:7px;padding:4px 8px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary, #6750a4) 34%,transparent);border-radius:7px;background:color-mix(in srgb,var(--md-sys-color-primary, #6750a4) 9%,var(--md-sys-color-surface, #fff));color:var(--md-sys-color-primary, #6750a4);cursor:pointer;font:inherit;font-size:11px;font-weight:700;line-height:1.2;text-align:left}.builder-premium-readiness__severity{width:8px;height:8px;margin-top:4px;border-radius:999px;background:var(--md-sys-color-primary, #6750a4)}.builder-premium-readiness__item[data-severity=warning] .builder-premium-readiness__severity{background:var(--praxis-warning, #b26a00)}.builder-premium-readiness__item[data-severity=error] .builder-premium-readiness__severity{background:var(--md-sys-color-error, #b3261e)}@media(max-width:760px){.builder-premium-readiness{grid-template-columns:1fr}}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:fixed;inset:0;z-index:140;pointer-events:none}@media(min-width:1100px){.builder-shell--agentic-review-rail{box-sizing:border-box;padding-right:464px}}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.builder-shell__connections-toggle--open{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary, #6750a4) 52%,transparent);outline-offset:2px}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"], dependencies: [{ 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.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", 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: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: DynamicWidgetPageComponent, selector: "praxis-dynamic-page", inputs: ["page", "context", "strictValidation", "enableCustomization", "showPageSettingsButton", "shellEditorComponent", "pageEditorComponent", "autoPersist", "pageIdentity", "componentInstanceId", "showWidgetAssistantButton"], outputs: ["pageChange", "widgetEvent", "widgetSelectionChange", "widgetAssistantRequested", "widgetDiagnosticsChange"] }, { kind: "component", type: FloatingToolbarComponent, selector: "praxis-floating-toolbar", inputs: ["visible", "canUndo", "canRedo", "showSave", "showPreview", "editingEnabled", "previewActive", "connectionMode", "modeLabel", "previewLabel", "exitPreviewLabel"], outputs: ["add", "undo", "redo", "settings", "preview", "save"] }, { kind: "component", type: ConnectionEditorComponent, selector: "praxis-connection-editor", inputs: ["open", "page"], outputs: ["pageChange", "focusWidget", "openPageSettings", "close"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "recommendedIntents", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "voiceInputMode", "voiceLanguage", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "recommendedIntent", "layoutChange"] }] });
21014
21496
  }
21015
21497
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicPageBuilderComponent, decorators: [{
21016
21498
  type: Component,
@@ -21031,6 +21513,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
21031
21513
  class="builder-shell"
21032
21514
  [class.builder-shell--agentic-review-rail]="agenticAuthoringReviewRailActive()"
21033
21515
  >
21516
+ @if (showSettings() && !connectionsViewerOpen() && premiumReadinessIssues().length) {
21517
+ <section
21518
+ class="builder-premium-readiness"
21519
+ data-testid="page-builder-premium-readiness"
21520
+ [attr.aria-label]="tx('premiumReadiness.title', 'Premium readiness')"
21521
+ >
21522
+ <header class="builder-premium-readiness__header">
21523
+ <span class="builder-premium-readiness__icon material-symbols-outlined" aria-hidden="true">auto_awesome</span>
21524
+ <div>
21525
+ <strong>{{ tx('premiumReadiness.title', 'Premium readiness') }}</strong>
21526
+ <p>{{ tx('premiumReadiness.subtitle', 'Qualidade visual e operacional antes de publicar.') }}</p>
21527
+ </div>
21528
+ </header>
21529
+ <ul class="builder-premium-readiness__list">
21530
+ @for (issue of premiumReadinessIssues(); track issue.id) {
21531
+ <li
21532
+ class="builder-premium-readiness__item"
21533
+ [attr.data-severity]="issue.severity"
21534
+ [attr.data-testid]="'page-builder-premium-readiness-' + issue.id"
21535
+ >
21536
+ <span class="builder-premium-readiness__severity" aria-hidden="true"></span>
21537
+ <div>
21538
+ <strong>{{ issue.title }}</strong>
21539
+ <p>{{ issue.description }}</p>
21540
+ @if (issue.action) {
21541
+ <button
21542
+ type="button"
21543
+ class="builder-premium-readiness__action"
21544
+ [attr.data-testid]="'page-builder-premium-readiness-action-' + issue.id"
21545
+ (click)="runPremiumReadinessAction(issue)"
21546
+ >
21547
+ {{ issue.action.label }}
21548
+ </button>
21549
+ }
21550
+ </div>
21551
+ </li>
21552
+ }
21553
+ </ul>
21554
+ </section>
21555
+ }
21556
+
21034
21557
  <praxis-dynamic-page
21035
21558
  #runtime
21036
21559
  [page]="currentPage()"
@@ -21097,7 +21620,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
21097
21620
  (close)="minimizeAgenticAuthoring()"
21098
21621
  />
21099
21622
  }
21100
-
21623
+
21101
21624
  @if (agenticAuthoringIncludeLlmDiagnostics && agenticAuthoringLlmDiagnosticsText()) {
21102
21625
  <section
21103
21626
  class="agentic-diagnostics-panel"
@@ -21381,17 +21904,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
21381
21904
  }
21382
21905
 
21383
21906
  <praxis-floating-toolbar
21384
- [visible]="showSettings()"
21907
+ [visible]="!!enableCustomization"
21385
21908
  [canUndo]="false"
21386
21909
  [canRedo]="false"
21387
21910
  [showSave]="canSaveCurrentPage()"
21388
21911
  [showPreview]="hasPageWidgets()"
21912
+ [editingEnabled]="showSettings()"
21913
+ [previewActive]="isPreviewMode()"
21914
+ [connectionMode]="showSettings() && connectionsViewerOpen()"
21915
+ [modeLabel]="builderModeLabel()"
21916
+ [previewLabel]="tx('toolbar.preview', 'Pré-visualizar')"
21917
+ [exitPreviewLabel]="tx('toolbar.exitPreview', 'Voltar para edição')"
21389
21918
  (add)="onAddComponent()"
21390
21919
  (settings)="openPageSettings()"
21391
21920
  (save)="saveCurrentPage()"
21392
21921
  (preview)="togglePreview()"
21393
21922
  >
21394
- @if (showPageLifecycleActions && hasPageWidgets()) {
21923
+ @if (showSettings() && showPageLifecycleActions && hasPageWidgets()) {
21395
21924
  <button
21396
21925
  pdx-toolbar-extra
21397
21926
  mat-mini-fab
@@ -21405,7 +21934,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
21405
21934
  <mat-icon [praxisIcon]="'restart_alt'"></mat-icon>
21406
21935
  </button>
21407
21936
  }
21408
- @if (showPageLifecycleActions && canDeleteSavedPage) {
21937
+ @if (showSettings() && showPageLifecycleActions && canDeleteSavedPage) {
21409
21938
  <button
21410
21939
  pdx-toolbar-extra
21411
21940
  mat-mini-fab
@@ -21420,7 +21949,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
21420
21949
  <mat-icon [praxisIcon]="'delete'"></mat-icon>
21421
21950
  </button>
21422
21951
  }
21423
- @if (enableAgenticAuthoring) {
21952
+ @if (showSettings() && enableAgenticAuthoring) {
21424
21953
  <button
21425
21954
  pdx-toolbar-extra
21426
21955
  mat-mini-fab
@@ -21436,14 +21965,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
21436
21965
  <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
21437
21966
  </button>
21438
21967
  }
21439
- @if (hasPageWidgets()) {
21968
+ @if (showSettings() && hasPageWidgets()) {
21440
21969
  <button
21441
21970
  pdx-toolbar-extra
21442
21971
  mat-mini-fab
21443
21972
  type="button"
21973
+ class="builder-shell__connections-toggle"
21974
+ [class.builder-shell__connections-toggle--open]="connectionsViewerOpen()"
21444
21975
  [attr.data-testid]="'page-builder-connections-toggle'"
21445
- [matTooltip]="tx('connections.toggle', 'Edit connections')"
21446
- [attr.aria-label]="tx('connections.toggleAria', 'Edit connections')"
21976
+ [matTooltip]="connectionsToggleLabel()"
21977
+ [attr.aria-label]="connectionsToggleLabel()"
21978
+ [disabled]="!showSettings()"
21447
21979
  (click)="toggleConnectionsViewer()"
21448
21980
  >
21449
21981
  <mat-icon [praxisIcon]="'hub'"></mat-icon>
@@ -21451,7 +21983,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
21451
21983
  }
21452
21984
  </praxis-floating-toolbar>
21453
21985
  </div>
21454
- `, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.builder-shell:has(.pdx-shell.fullscreen) praxis-floating-toolbar{display:none}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:relative;z-index:140}@media(min-width:1100px){.builder-shell--agentic-review-rail{box-sizing:border-box;padding-right:464px}}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"] }]
21986
+ `, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.builder-shell:has(.pdx-shell.fullscreen) praxis-floating-toolbar{display:none}.builder-premium-readiness{display:grid;grid-template-columns:minmax(220px,.72fr) minmax(0,1.28fr);gap:12px;width:100%;margin:0 0 14px;padding:14px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #cac4d0) 72%,transparent);border-radius:12px;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary, #6750a4) 10%,transparent),transparent 36%),color-mix(in srgb,var(--md-sys-color-surface-container-lowest, #fff) 96%,transparent);color:var(--md-sys-color-on-surface, #1d1b20);box-shadow:inset 0 1px color-mix(in srgb,var(--md-sys-color-on-surface, #1d1b20) 5%,transparent)}.builder-premium-readiness__header{display:flex;align-items:flex-start;gap:10px;min-width:0}.builder-premium-readiness__header strong{display:block;font-size:13px;line-height:1.25}.builder-premium-readiness__header p,.builder-premium-readiness__item p{margin:2px 0 0;color:var(--md-sys-color-on-surface-variant, #49454f);font-size:11px;line-height:1.35}.builder-premium-readiness__icon{color:var(--md-sys-color-primary, #6750a4);font-size:20px;line-height:1}.builder-premium-readiness__list{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:8px;margin:0;padding:0;list-style:none}.builder-premium-readiness__item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:8px;min-width:0;padding:9px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, #cac4d0) 64%,transparent);border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low, #f7f2fa) 84%,transparent)}.builder-premium-readiness__item strong{display:block;font-size:12px;line-height:1.25}.builder-premium-readiness__action{appearance:none;display:inline-flex;align-items:center;justify-content:center;min-height:26px;margin-top:7px;padding:4px 8px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary, #6750a4) 34%,transparent);border-radius:7px;background:color-mix(in srgb,var(--md-sys-color-primary, #6750a4) 9%,var(--md-sys-color-surface, #fff));color:var(--md-sys-color-primary, #6750a4);cursor:pointer;font:inherit;font-size:11px;font-weight:700;line-height:1.2;text-align:left}.builder-premium-readiness__severity{width:8px;height:8px;margin-top:4px;border-radius:999px;background:var(--md-sys-color-primary, #6750a4)}.builder-premium-readiness__item[data-severity=warning] .builder-premium-readiness__severity{background:var(--praxis-warning, #b26a00)}.builder-premium-readiness__item[data-severity=error] .builder-premium-readiness__severity{background:var(--md-sys-color-error, #b3261e)}@media(max-width:760px){.builder-premium-readiness{grid-template-columns:1fr}}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:fixed;inset:0;z-index:140;pointer-events:none}@media(min-width:1100px){.builder-shell--agentic-review-rail{box-sizing:border-box;padding-right:464px}}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.builder-shell__connections-toggle--open{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary, #6750a4) 52%,transparent);outline-offset:2px}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"] }]
21455
21987
  }], ctorParameters: () => [{ type: i1.MatDialog }, { type: undefined, decorators: [{
21456
21988
  type: Optional
21457
21989
  }, {
@@ -21478,6 +22010,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
21478
22010
  type: Input
21479
22011
  }], pageEditorComponent: [{
21480
22012
  type: Input
22013
+ }], componentPaletteAllowedWidgetIds: [{
22014
+ type: Input
22015
+ }], componentPaletteAllowedWidgetTags: [{
22016
+ type: Input
22017
+ }], componentPaletteAllowedPresetIds: [{
22018
+ type: Input
21481
22019
  }], enableAgenticAuthoring: [{
21482
22020
  type: Input
21483
22021
  }], agenticAuthoringProvider: [{