@praxisui/page-builder 8.0.0-beta.0 → 8.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,17 @@
1
1
  import * as i2$1 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { Inject, ChangeDetectionStrategy, Component, EventEmitter, Output, Input, signal, computed, effect, Optional, inject, input, output, InjectionToken, ENVIRONMENT_INITIALIZER, ViewChild } from '@angular/core';
4
+ import { Inject, ChangeDetectionStrategy, Component, EventEmitter, Output, Input, signal, computed, effect, Optional, inject, input, output, InjectionToken, ENVIRONMENT_INITIALIZER, Injectable, ViewChild } from '@angular/core';
5
5
  import * as i2 from '@angular/material/button';
6
6
  import { MatButtonModule } from '@angular/material/button';
7
7
  import * as i1 from '@angular/material/dialog';
8
8
  import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
9
- import * as i3 from '@angular/material/icon';
9
+ import * as i4 from '@angular/material/icon';
10
10
  import { MatIconModule } from '@angular/material/icon';
11
11
  import * as i2$2 from '@praxisui/core';
12
- import { PraxisIconDirective, BUILTIN_SHELL_PRESETS, SETTINGS_PANEL_DATA as SETTINGS_PANEL_DATA$1, providePraxisI18n, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, PraxisI18nService, ComponentMetadataRegistry, generateId, SETTINGS_PANEL_BRIDGE, DynamicWidgetPageComponent, DYNAMIC_PAGE_SHELL_EDITOR } from '@praxisui/core';
12
+ import { PraxisIconDirective, BUILTIN_SHELL_PRESETS, SETTINGS_PANEL_DATA as SETTINGS_PANEL_DATA$1, providePraxisI18n, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, PraxisI18nService, deepMerge, generateId, ComponentMetadataRegistry, SETTINGS_PANEL_BRIDGE, DynamicWidgetPageComponent, DYNAMIC_PAGE_SHELL_EDITOR } from '@praxisui/core';
13
13
  export { WidgetShellComponent } from '@praxisui/core';
14
- import * as i4 from '@angular/material/tooltip';
14
+ import * as i3 from '@angular/material/tooltip';
15
15
  import { MatTooltipModule } from '@angular/material/tooltip';
16
16
  import * as i3$1 from '@angular/material/form-field';
17
17
  import { MatFormFieldModule } from '@angular/material/form-field';
@@ -25,11 +25,13 @@ import * as i6 from '@angular/material/divider';
25
25
  import { MatDividerModule } from '@angular/material/divider';
26
26
  import * as i6$1 from '@angular/material/select';
27
27
  import { MatSelectModule } from '@angular/material/select';
28
- import { BehaviorSubject, merge } from 'rxjs';
28
+ import { BehaviorSubject, merge, firstValueFrom } from 'rxjs';
29
29
  import { SETTINGS_PANEL_DATA } from '@praxisui/settings-panel';
30
30
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
31
31
  import * as i7 from '@angular/material/tabs';
32
32
  import { MatTabsModule } from '@angular/material/tabs';
33
+ import { HttpClient, HttpHeaders } from '@angular/common/http';
34
+ import { PraxisAssistantTurnOrchestratorService, PraxisAiAssistantShellComponent } from '@praxisui/ai';
33
35
 
34
36
  const PLACEHOLDER = 1;
35
37
 
@@ -53,7 +55,7 @@ class ConfirmDialogComponent {
53
55
  <button mat-button mat-dialog-close>{{ data.cancelLabel || 'Cancelar' }}</button>
54
56
  <button mat-raised-button color="warn" [mat-dialog-close]="true">{{ data.confirmLabel || 'Excluir' }}</button>
55
57
  </div>
56
- `, isInline: true, styles: [":host{color:var(--md-sys-color-on-surface)}.dlg-icon{vertical-align:middle;margin-right:8px;color:var(--md-sys-color-error)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
58
+ `, isInline: true, styles: [":host{color:var(--md-sys-color-on-surface)}.dlg-icon{vertical-align:middle;margin-right:8px;color:var(--md-sys-color-error)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
57
59
  }
58
60
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
59
61
  type: Component,
@@ -119,7 +121,7 @@ class TileToolbarComponent {
119
121
  <mat-icon [praxisIcon]="'delete'"></mat-icon>
120
122
  </button>
121
123
  </div>
122
- `, isInline: true, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-tile-toolbar{position:absolute;right:6px;top:-18px;display:flex;gap:6px;z-index:5;opacity:0;transition:opacity .12s ease-in-out;pointer-events:auto;background:var(--md-sys-color-surface-container-low);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border-radius:999px;padding:4px;box-shadow:var(--mat-elevation-level3)}.pdx-tile-toolbar.always-visible{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.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 });
124
+ `, isInline: true, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-tile-toolbar{position:absolute;right:6px;top:-18px;display:flex;gap:6px;z-index:5;opacity:0;transition:opacity .12s ease-in-out;pointer-events:auto;background:var(--md-sys-color-surface-container-low);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border-radius:999px;padding:4px;box-shadow:var(--mat-elevation-level3)}.pdx-tile-toolbar.always-visible{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: i4.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 });
123
125
  }
124
126
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: TileToolbarComponent, decorators: [{
125
127
  type: Component,
@@ -211,7 +213,7 @@ class FloatingToolbarComponent {
211
213
  <ng-content select="[pdx-toolbar-extra]"></ng-content>
212
214
  </div>
213
215
  </div>
214
- `, 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}.pdx-fab{box-shadow:var(--mat-elevation-level4)}@media(max-width:720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: "component", type: i2.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.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 });
216
+ `, 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}.pdx-fab{box-shadow:var(--mat-elevation-level4)}@media(max-width:720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: "component", type: i2.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: 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 });
215
217
  }
216
218
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: FloatingToolbarComponent, decorators: [{
217
219
  type: Component,
@@ -369,7 +371,7 @@ class ComponentPaletteDialogComponent {
369
371
  <div mat-dialog-actions align="end">
370
372
  <button mat-stroked-button color="primary" mat-dialog-close>Cancelar</button>
371
373
  </div>
372
- `, isInline: true, styles: [":host{display:block}h2[mat-dialog-title]{margin:0;padding:12px 24px 10px;border-bottom:1px solid var(--md-sys-color-outline-variant)}.dlg-title{display:flex;align-items:center;gap:10px}.dlg-icon{color:var(--md-sys-color-primary)}.dlg-head{font-size:18px;font-weight:600;line-height:1.2}.dlg-sub{font-size:12px;opacity:.85;color:var(--md-sys-color-on-surface-variant)}.pdx-palette-content{min-width:480px;max-width:920px;padding-top:8px}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px}.pdx-grid.dense{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-grid.roomy{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}.pdx-card{position:relative;display:grid;grid-template-columns:44px 1fr;grid-template-rows:auto auto;gap:10px;padding:14px;border:1px solid transparent;border-radius:14px;cursor:pointer;outline:none;min-height:92px;background:var(--md-sys-color-surface);border-color:var(--md-sys-color-outline-variant);transition:box-shadow .2s ease,background .25s ease,transform .06s ease}.pdx-grid.dense .pdx-card{padding:10px;border-radius:12px;min-height:84px}.pdx-grid.roomy .pdx-card{padding:16px;border-radius:16px;min-height:100px}.pdx-card:focus,.pdx-card:hover{box-shadow:var(--mat-elevation-level4);background:var(--md-sys-color-surface-container-low);border-color:var(--md-sys-color-primary)}.pdx-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-card:active{transform:translateY(1px)}.pdx-card-icon{grid-row:span 2;display:flex;align-items:center;justify-content:center;color:var(--md-sys-color-primary)}.pdx-card-title{font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-card-desc{color:var(--md-sys-color-on-surface-variant);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.pdx-empty{padding:24px;display:grid;place-items:center;color:var(--md-sys-color-on-surface-variant);gap:8px}@media(max-width:600px){.pdx-palette-content{min-width:320px}.pdx-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
374
+ `, isInline: true, styles: [":host{display:block}h2[mat-dialog-title]{margin:0;padding:12px 24px 10px;border-bottom:1px solid var(--md-sys-color-outline-variant)}.dlg-title{display:flex;align-items:center;gap:10px}.dlg-icon{color:var(--md-sys-color-primary)}.dlg-head{font-size:18px;font-weight:600;line-height:1.2}.dlg-sub{font-size:12px;opacity:.85;color:var(--md-sys-color-on-surface-variant)}.pdx-palette-content{min-width:480px;max-width:920px;padding-top:8px}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px}.pdx-grid.dense{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-grid.roomy{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}.pdx-card{position:relative;display:grid;grid-template-columns:44px 1fr;grid-template-rows:auto auto;gap:10px;padding:14px;border:1px solid transparent;border-radius:14px;cursor:pointer;outline:none;min-height:92px;background:var(--md-sys-color-surface);border-color:var(--md-sys-color-outline-variant);transition:box-shadow .2s ease,background .25s ease,transform .06s ease}.pdx-grid.dense .pdx-card{padding:10px;border-radius:12px;min-height:84px}.pdx-grid.roomy .pdx-card{padding:16px;border-radius:16px;min-height:100px}.pdx-card:focus,.pdx-card:hover{box-shadow:var(--mat-elevation-level4);background:var(--md-sys-color-surface-container-low);border-color:var(--md-sys-color-primary)}.pdx-card:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-card:active{transform:translateY(1px)}.pdx-card-icon{grid-row:span 2;display:flex;align-items:center;justify-content:center;color:var(--md-sys-color-primary)}.pdx-card-title{font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-card-desc{color:var(--md-sys-color-on-surface-variant);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.pdx-empty{padding:24px;display:grid;place-items:center;color:var(--md-sys-color-on-surface-variant);gap:8px}@media(max-width:600px){.pdx-palette-content{min-width:320px}.pdx-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: 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: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
373
375
  }
374
376
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ComponentPaletteDialogComponent, decorators: [{
375
377
  type: Component,
@@ -1516,7 +1518,7 @@ class WidgetShellEditorComponent {
1516
1518
  <div class="shell-empty">Nenhuma ação configurada.</div>
1517
1519
  </ng-template>
1518
1520
  </div>
1519
- `, isInline: true, styles: [".shell-editor{display:grid;gap:12px;padding:16px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.shell-head{display:flex;align-items:center;gap:12px}.shell-title{font-weight:600}.shell-subtitle{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-section{font-weight:600;margin-top:8px}.shell-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.shell-flags{display:flex;gap:16px;align-items:center}.shell-actions-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.shell-available{display:grid;gap:12px}.shell-available-toolbar{display:grid;gap:12px;grid-template-columns:minmax(200px,1fr)}.shell-available-filters{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.shell-available-list{display:grid;gap:10px}.shell-available-item{display:grid;gap:8px;grid-template-columns:1fr auto;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;background:var(--md-sys-color-surface-container-low)}.shell-available-title{display:flex;align-items:center;gap:10px}.shell-available-text{display:grid;gap:4px}.shell-available-label{font-weight:600}.shell-available-meta{display:flex;gap:8px;flex-wrap:wrap;font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-available-payload{font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-warning{font-size:11px;color:var(--md-sys-color-error)}.shell-available-actions{display:flex;align-items:flex-start;justify-content:flex-end}.shell-badge{padding:2px 6px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);font-size:10px}.shell-code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.shell-actions{display:grid;gap:12px}.shell-action{border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;display:grid;gap:8px}.shell-action-row{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.shell-action-actions{display:flex;justify-content:flex-end}.shell-action-hint,.shell-empty{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-hint{align-self:center;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-quick-inputs{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));align-items:end}.shell-input-path{font-size:12px;color:var(--md-sys-color-on-surface-variant);align-self:center}.shell-editor .mat-mdc-form-field{width:100%}.shell-preview{border:1px dashed var(--md-sys-color-outline-variant);border-radius:12px;padding:12px}.shell-preview-card{background:var(--pdx-shell-card-bg, var(--md-sys-color-surface));border:1px solid var(--pdx-shell-card-border, var(--md-sys-color-outline-variant));border-radius:var(--pdx-shell-card-radius, 14px);box-shadow:var(--pdx-shell-card-shadow, var(--mat-elevation-level2));overflow:hidden}.shell-preview-card.no-shell{background:transparent;border:none;box-shadow:none}.shell-preview-card.expanded{box-shadow:var(--pdx-shell-card-shadow, 0 16px 34px rgba(0,0,0,.32));transform:scale(1.01)}.shell-preview-header{display:flex;align-items:center;gap:12px;padding:10px 12px 8px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.shell-preview-title{display:flex;align-items:center;gap:10px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.shell-preview-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.shell-preview-text{min-width:0}.shell-preview-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 14px);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-subtitle{font-size:var(--pdx-shell-subtitle-size, 12px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-actions{display:flex;align-items:center;gap:6px}.pdx-preview-text{padding:0 8px}.pdx-preview-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-preview-label{font-size:12px;font-weight:500}.shell-preview-body{padding:var(--pdx-shell-body-padding, 10px 12px 12px 12px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit);font-size:12px}.shell-preview-body.hidden{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i6.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1521
+ `, isInline: true, styles: [".shell-editor{display:grid;gap:12px;padding:16px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.shell-head{display:flex;align-items:center;gap:12px}.shell-title{font-weight:600}.shell-subtitle{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-section{font-weight:600;margin-top:8px}.shell-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.shell-flags{display:flex;gap:16px;align-items:center}.shell-actions-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.shell-available{display:grid;gap:12px}.shell-available-toolbar{display:grid;gap:12px;grid-template-columns:minmax(200px,1fr)}.shell-available-filters{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.shell-available-list{display:grid;gap:10px}.shell-available-item{display:grid;gap:8px;grid-template-columns:1fr auto;border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;background:var(--md-sys-color-surface-container-low)}.shell-available-title{display:flex;align-items:center;gap:10px}.shell-available-text{display:grid;gap:4px}.shell-available-label{font-weight:600}.shell-available-meta{display:flex;gap:8px;flex-wrap:wrap;font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-desc{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-available-payload{font-size:11px;color:var(--md-sys-color-on-surface-variant)}.shell-available-warning{font-size:11px;color:var(--md-sys-color-error)}.shell-available-actions{display:flex;align-items:flex-start;justify-content:flex-end}.shell-badge{padding:2px 6px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);font-size:10px}.shell-code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.shell-actions{display:grid;gap:12px}.shell-action{border:1px solid var(--md-sys-color-outline-variant);border-radius:12px;padding:12px;display:grid;gap:8px}.shell-action-row{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.shell-action-actions{display:flex;justify-content:flex-end}.shell-action-hint,.shell-empty{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-hint{align-self:center;font-size:12px;color:var(--md-sys-color-on-surface-variant)}.shell-quick-inputs{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));align-items:end}.shell-input-path{font-size:12px;color:var(--md-sys-color-on-surface-variant);align-self:center}.shell-editor .mat-mdc-form-field{width:100%}.shell-preview{border:1px dashed var(--md-sys-color-outline-variant);border-radius:12px;padding:12px}.shell-preview-card{background:var(--pdx-shell-card-bg, var(--md-sys-color-surface));border:1px solid var(--pdx-shell-card-border, var(--md-sys-color-outline-variant));border-radius:var(--pdx-shell-card-radius, 14px);box-shadow:var(--pdx-shell-card-shadow, var(--mat-elevation-level2));overflow:hidden}.shell-preview-card.no-shell{background:transparent;border:none;box-shadow:none}.shell-preview-card.expanded{box-shadow:var(--pdx-shell-card-shadow, 0 16px 34px rgba(0,0,0,.32));transform:scale(1.01)}.shell-preview-header{display:flex;align-items:center;gap:12px;padding:10px 12px 8px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.shell-preview-title{display:flex;align-items:center;gap:10px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.shell-preview-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.shell-preview-text{min-width:0}.shell-preview-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 14px);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-subtitle{font-size:var(--pdx-shell-subtitle-size, 12px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.shell-preview-actions{display:flex;align-items:center;gap:6px}.pdx-preview-text{padding:0 8px}.pdx-preview-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-preview-label{font-size:12px;font-weight:500}.shell-preview-body{padding:var(--pdx-shell-body-padding, 10px 12px 12px 12px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit);font-size:12px}.shell-preview-body.hidden{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i6.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1520
1522
  }
1521
1523
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: WidgetShellEditorComponent, decorators: [{
1522
1524
  type: Component,
@@ -2101,7 +2103,7 @@ class DynamicPageConfigEditorComponent {
2101
2103
  <mat-tab label="Estado da Pagina"><mat-form-field appearance="outline" class="wide"><mat-label>State (JSON)</mat-label><textarea matInput rows="14" [formControl]="stateControl"></textarea></mat-form-field></mat-tab>
2102
2104
  </mat-tab-group>
2103
2105
  </div>
2104
- `, isInline: true, styles: [".editor,.panel{display:grid;gap:16px}.head,.summary{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.card{display:grid;gap:12px;padding:16px;border:1px solid #d8e0ea;border-radius:16px;background:#fbfcfe}.wide{grid-column:1/-1}.hint{color:#5b6472;font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2106
+ `, isInline: true, styles: [".editor,.panel{display:grid;gap:16px}.head,.summary{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.card{display:grid;gap:12px;padding:16px;border:1px solid #d8e0ea;border-radius:16px;background:#fbfcfe}.wide{grid-column:1/-1}.hint{color:#5b6472;font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2105
2107
  }
2106
2108
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicPageConfigEditorComponent, decorators: [{
2107
2109
  type: Component,
@@ -2300,6 +2302,84 @@ const PRAXIS_PAGE_BUILDER_EN_US = {
2300
2302
  'praxis.pageBuilder.connections.details.policy': 'Policy',
2301
2303
  'praxis.pageBuilder.connections.details.diagnostics': 'Diagnostics',
2302
2304
  'praxis.pageBuilder.connections.palette.insertComponent': 'Insert component',
2305
+ 'praxis.pageBuilder.agentic.toggle': 'Create with AI',
2306
+ 'praxis.pageBuilder.agentic.panelAria': 'AI page authoring',
2307
+ 'praxis.pageBuilder.agentic.title': 'AI assistant',
2308
+ 'praxis.pageBuilder.agentic.subtitle': 'Chat, confirm the intent, and review the result before saving.',
2309
+ 'praxis.pageBuilder.agentic.close': 'Close',
2310
+ 'praxis.pageBuilder.agentic.promptLabel': 'Message',
2311
+ 'praxis.pageBuilder.agentic.promptPlaceholder': 'Describe the page, dashboard, form, or change you need.',
2312
+ 'praxis.pageBuilder.agentic.emptyConversation': 'Tell me what you want to create or change. I will ask follow-up questions before applying the preview.',
2313
+ 'praxis.pageBuilder.agentic.conversationAria': 'AI conversation',
2314
+ 'praxis.pageBuilder.agentic.quickRepliesAria': 'Quick replies',
2315
+ 'praxis.pageBuilder.agentic.contextAria': 'Active context',
2316
+ 'praxis.pageBuilder.agentic.attachmentsAria': 'Attached context',
2317
+ 'praxis.pageBuilder.agentic.context.component': 'Component',
2318
+ 'praxis.pageBuilder.agentic.context.pageBuilder': 'Page Builder',
2319
+ 'praxis.pageBuilder.agentic.context.route': 'Route',
2320
+ 'praxis.pageBuilder.agentic.context.selection': 'Selection',
2321
+ 'praxis.pageBuilder.agentic.editMessage': 'Edit',
2322
+ 'praxis.pageBuilder.agentic.resendMessage': 'Resend',
2323
+ 'praxis.pageBuilder.agentic.removeAttachment': 'Remove attachment',
2324
+ 'praxis.pageBuilder.agentic.mode.config': 'Configuration',
2325
+ 'praxis.pageBuilder.agentic.mode.agenticAuthoring': 'Authoring',
2326
+ 'praxis.pageBuilder.agentic.mode.chat': 'Chat',
2327
+ 'praxis.pageBuilder.agentic.mode.diagnostic': 'Diagnostic',
2328
+ 'praxis.pageBuilder.agentic.mode.review': 'Review',
2329
+ 'praxis.pageBuilder.agentic.mode.inlineHelp': 'Help',
2330
+ 'praxis.pageBuilder.agentic.state.idle': 'Idle',
2331
+ 'praxis.pageBuilder.agentic.state.listening': 'Ready',
2332
+ 'praxis.pageBuilder.agentic.state.processing': 'Processing',
2333
+ 'praxis.pageBuilder.agentic.state.clarification': 'Waiting for input',
2334
+ 'praxis.pageBuilder.agentic.state.review': 'Review',
2335
+ 'praxis.pageBuilder.agentic.state.applying': 'Applying',
2336
+ 'praxis.pageBuilder.agentic.state.success': 'Done',
2337
+ 'praxis.pageBuilder.agentic.state.error': 'Error',
2338
+ 'praxis.pageBuilder.agentic.quickReplies.confirm': 'Yes, create it',
2339
+ 'praxis.pageBuilder.agentic.quickReplies.revise': 'I want to adjust',
2340
+ 'praxis.pageBuilder.agentic.quickReplies.cancel': 'Cancel',
2341
+ 'praxis.pageBuilder.agentic.quickReplies.payrollExecutiveDashboard': 'Executive dashboard',
2342
+ 'praxis.pageBuilder.agentic.quickReplies.payrollDepartmentDrilldown': 'Department drill-down',
2343
+ 'praxis.pageBuilder.agentic.quickReplies.payrollDetailTable': 'Detailed table',
2344
+ 'praxis.pageBuilder.agentic.quickReplies.dashboardSuggestion': 'Dashboard',
2345
+ 'praxis.pageBuilder.agentic.quickReplies.formSuggestion': 'Form',
2346
+ 'praxis.pageBuilder.agentic.quickReplies.masterDetailSuggestion': 'Master detail',
2347
+ 'praxis.pageBuilder.agentic.quickReplies.confirmPromptSuffix': 'Confirmed:',
2348
+ 'praxis.pageBuilder.agentic.attachments.currentPage': 'Current page',
2349
+ 'praxis.pageBuilder.agentic.suggestionPrompts.payrollExecutiveDashboard': 'Create a payroll dashboard with KPIs, payroll by department, monthly evolution, and a detail table.',
2350
+ 'praxis.pageBuilder.agentic.suggestionPrompts.payrollDepartmentDrilldown': 'Create a payroll dashboard with a department chart that filters a detail table when a bar is selected.',
2351
+ 'praxis.pageBuilder.agentic.suggestionPrompts.payrollDetailTable': 'Create a payroll detail table with filters, formatted currency values, and employee-level columns.',
2352
+ 'praxis.pageBuilder.agentic.suggestionPrompts.dashboardSuggestion': 'Create a dashboard with KPIs, a chart, and a detail table.',
2353
+ 'praxis.pageBuilder.agentic.suggestionPrompts.formSuggestion': 'Create a form with only the fields required for the selected business process.',
2354
+ 'praxis.pageBuilder.agentic.suggestionPrompts.masterDetailSuggestion': 'Create a master-detail page with a summary list and a linked detail area.',
2355
+ 'praxis.pageBuilder.agentic.exploratory.payrollOptions': 'For payroll, the best options are: 1. executive dashboard with KPIs and total payroll; 2. department drill-down with chart filtering a detail table; 3. monthly evolution to identify cost trends; 4. detailed table with filters and currency formatting. Choose one option or describe the change you want me to create.',
2356
+ 'praxis.pageBuilder.agentic.exploratory.genericOptions': 'I can help you choose before creating. Common options are dashboards for analysis, forms for data entry, master-detail pages for navigation, and tables for operational detail. Choose one option or describe what you want me to create.',
2357
+ 'praxis.pageBuilder.agentic.exploratory.capability.chart': 'charts',
2358
+ 'praxis.pageBuilder.agentic.exploratory.capability.table': 'tables',
2359
+ 'praxis.pageBuilder.agentic.exploratory.capability.form': 'forms',
2360
+ 'praxis.pageBuilder.agentic.exploratory.capability.masterDetail': 'master-detail pages',
2361
+ 'praxis.pageBuilder.agentic.dragHandleAria': 'Move AI assistant',
2362
+ 'praxis.pageBuilder.agentic.resizeHandleAria': 'Resize AI assistant',
2363
+ 'praxis.pageBuilder.agentic.resizeHandleTooltip': 'Resize',
2364
+ 'praxis.pageBuilder.agentic.preview': 'Preview',
2365
+ 'praxis.pageBuilder.agentic.persist': 'Save',
2366
+ 'praxis.pageBuilder.agentic.status.resolvingIntent': 'Resolving intent...',
2367
+ 'praxis.pageBuilder.agentic.status.waitingRevision': 'Refine your prompt and preview again.',
2368
+ 'praxis.pageBuilder.agentic.status.cancelled': 'Request cancelled.',
2369
+ 'praxis.pageBuilder.agentic.status.previewing': 'Generating preview...',
2370
+ 'praxis.pageBuilder.agentic.status.previewReady': 'Preview applied to the page.',
2371
+ 'praxis.pageBuilder.agentic.status.acceptedAddLocalField': 'Local field added to the form.',
2372
+ 'praxis.pageBuilder.agentic.status.acceptedRemoveLocalField': 'Local field removed from the form.',
2373
+ 'praxis.pageBuilder.agentic.status.acceptedRelabelField': 'Field label updated.',
2374
+ 'praxis.pageBuilder.agentic.status.saving': 'Saving page...',
2375
+ 'praxis.pageBuilder.agentic.status.saved': 'Page saved.',
2376
+ 'praxis.pageBuilder.agentic.errors.applyLocal': 'Preview could not be applied.',
2377
+ 'praxis.pageBuilder.agentic.errors.componentId': 'Configure a component id before saving.',
2378
+ 'praxis.pageBuilder.agentic.errors.invalidPreview': 'Generated preview is invalid.',
2379
+ 'praxis.pageBuilder.agentic.errors.intentResolution': 'Intent could not be resolved.',
2380
+ 'praxis.pageBuilder.agentic.errors.duplicateField': 'This field already exists in the selected form.',
2381
+ 'praxis.pageBuilder.agentic.errors.nonLocalFieldRemoval': 'Only local fields created by AI can be removed in this flow.',
2382
+ 'praxis.pageBuilder.agentic.errors.generic': 'AI authoring failed.',
2303
2383
  };
2304
2384
 
2305
2385
  const PRAXIS_PAGE_BUILDER_PT_BR = {
@@ -2463,6 +2543,84 @@ const PRAXIS_PAGE_BUILDER_PT_BR = {
2463
2543
  'praxis.pageBuilder.connections.details.policy': 'Policy',
2464
2544
  'praxis.pageBuilder.connections.details.diagnostics': 'Diagnostics',
2465
2545
  'praxis.pageBuilder.connections.palette.insertComponent': 'Inserir componente',
2546
+ 'praxis.pageBuilder.agentic.toggle': 'Criar com IA',
2547
+ 'praxis.pageBuilder.agentic.panelAria': 'Autoria de página com IA',
2548
+ 'praxis.pageBuilder.agentic.title': 'Assistente de IA',
2549
+ 'praxis.pageBuilder.agentic.subtitle': 'Converse, confirme a intenção e revise o resultado antes de salvar.',
2550
+ 'praxis.pageBuilder.agentic.close': 'Fechar',
2551
+ 'praxis.pageBuilder.agentic.promptLabel': 'Mensagem',
2552
+ 'praxis.pageBuilder.agentic.promptPlaceholder': 'Descreva a página, dashboard, formulário ou alteração que você precisa.',
2553
+ 'praxis.pageBuilder.agentic.emptyConversation': 'Diga o que você quer criar ou alterar. Vou fazer perguntas antes de aplicar a pré-visualização.',
2554
+ 'praxis.pageBuilder.agentic.conversationAria': 'Conversa com IA',
2555
+ 'praxis.pageBuilder.agentic.quickRepliesAria': 'Respostas rápidas',
2556
+ 'praxis.pageBuilder.agentic.contextAria': 'Contexto ativo',
2557
+ 'praxis.pageBuilder.agentic.attachmentsAria': 'Contexto anexado',
2558
+ 'praxis.pageBuilder.agentic.context.component': 'Componente',
2559
+ 'praxis.pageBuilder.agentic.context.pageBuilder': 'Page Builder',
2560
+ 'praxis.pageBuilder.agentic.context.route': 'Rota',
2561
+ 'praxis.pageBuilder.agentic.context.selection': 'Seleção',
2562
+ 'praxis.pageBuilder.agentic.editMessage': 'Editar',
2563
+ 'praxis.pageBuilder.agentic.resendMessage': 'Reenviar',
2564
+ 'praxis.pageBuilder.agentic.removeAttachment': 'Remover anexo',
2565
+ 'praxis.pageBuilder.agentic.mode.config': 'Configuração',
2566
+ 'praxis.pageBuilder.agentic.mode.agenticAuthoring': 'Autoria',
2567
+ 'praxis.pageBuilder.agentic.mode.chat': 'Chat',
2568
+ 'praxis.pageBuilder.agentic.mode.diagnostic': 'Diagnóstico',
2569
+ 'praxis.pageBuilder.agentic.mode.review': 'Revisão',
2570
+ 'praxis.pageBuilder.agentic.mode.inlineHelp': 'Ajuda',
2571
+ 'praxis.pageBuilder.agentic.state.idle': 'Ocioso',
2572
+ 'praxis.pageBuilder.agentic.state.listening': 'Pronto',
2573
+ 'praxis.pageBuilder.agentic.state.processing': 'Processando',
2574
+ 'praxis.pageBuilder.agentic.state.clarification': 'Aguardando resposta',
2575
+ 'praxis.pageBuilder.agentic.state.review': 'Revisão',
2576
+ 'praxis.pageBuilder.agentic.state.applying': 'Aplicando',
2577
+ 'praxis.pageBuilder.agentic.state.success': 'Concluído',
2578
+ 'praxis.pageBuilder.agentic.state.error': 'Erro',
2579
+ 'praxis.pageBuilder.agentic.quickReplies.confirm': 'Sim, criar',
2580
+ 'praxis.pageBuilder.agentic.quickReplies.revise': 'Quero ajustar',
2581
+ 'praxis.pageBuilder.agentic.quickReplies.cancel': 'Cancelar',
2582
+ 'praxis.pageBuilder.agentic.quickReplies.payrollExecutiveDashboard': 'Dashboard executivo',
2583
+ 'praxis.pageBuilder.agentic.quickReplies.payrollDepartmentDrilldown': 'Drill-down por departamento',
2584
+ 'praxis.pageBuilder.agentic.quickReplies.payrollDetailTable': 'Tabela detalhada',
2585
+ 'praxis.pageBuilder.agentic.quickReplies.dashboardSuggestion': 'Dashboard',
2586
+ 'praxis.pageBuilder.agentic.quickReplies.formSuggestion': 'Formulário',
2587
+ 'praxis.pageBuilder.agentic.quickReplies.masterDetailSuggestion': 'Master detail',
2588
+ 'praxis.pageBuilder.agentic.quickReplies.confirmPromptSuffix': 'Confirmado:',
2589
+ 'praxis.pageBuilder.agentic.attachments.currentPage': 'Página atual',
2590
+ 'praxis.pageBuilder.agentic.suggestionPrompts.payrollExecutiveDashboard': 'Crie um dashboard de folha de pagamento com KPIs, folha por departamento, evolução mensal e tabela de detalhes.',
2591
+ 'praxis.pageBuilder.agentic.suggestionPrompts.payrollDepartmentDrilldown': 'Crie um dashboard de folha de pagamento com gráfico por departamento que filtre uma tabela detalhada ao selecionar uma barra.',
2592
+ 'praxis.pageBuilder.agentic.suggestionPrompts.payrollDetailTable': 'Crie uma tabela detalhada de folha de pagamento com filtros, valores monetários formatados e colunas por funcionário.',
2593
+ 'praxis.pageBuilder.agentic.suggestionPrompts.dashboardSuggestion': 'Crie um dashboard com indicadores, gráfico e tabela de detalhes.',
2594
+ 'praxis.pageBuilder.agentic.suggestionPrompts.formSuggestion': 'Crie um formulário com apenas os campos necessários para o processo de negócio selecionado.',
2595
+ 'praxis.pageBuilder.agentic.suggestionPrompts.masterDetailSuggestion': 'Crie uma página master-detail com lista resumida e área de detalhes vinculada.',
2596
+ 'praxis.pageBuilder.agentic.exploratory.payrollOptions': 'Para folha de pagamento, as melhores opções são: 1. dashboard executivo com KPIs e total da folha; 2. drill-down por departamento com gráfico filtrando uma tabela; 3. evolução mensal para identificar tendência de custo; 4. tabela detalhada com filtros e valores monetários. Escolha uma opção ou descreva o que você quer que eu crie.',
2597
+ 'praxis.pageBuilder.agentic.exploratory.genericOptions': 'Posso ajudar você a escolher antes de criar. As opções mais comuns são dashboards para análise, formulários para entrada de dados, páginas master-detail para navegação e tabelas para detalhe operacional. Escolha uma opção ou descreva o que você quer que eu crie.',
2598
+ 'praxis.pageBuilder.agentic.exploratory.capability.chart': 'gráficos',
2599
+ 'praxis.pageBuilder.agentic.exploratory.capability.table': 'tabelas',
2600
+ 'praxis.pageBuilder.agentic.exploratory.capability.form': 'formulários',
2601
+ 'praxis.pageBuilder.agentic.exploratory.capability.masterDetail': 'páginas master-detail',
2602
+ 'praxis.pageBuilder.agentic.dragHandleAria': 'Mover assistente de IA',
2603
+ 'praxis.pageBuilder.agentic.resizeHandleAria': 'Redimensionar assistente de IA',
2604
+ 'praxis.pageBuilder.agentic.resizeHandleTooltip': 'Redimensionar',
2605
+ 'praxis.pageBuilder.agentic.preview': 'Pré-visualizar',
2606
+ 'praxis.pageBuilder.agentic.persist': 'Salvar',
2607
+ 'praxis.pageBuilder.agentic.status.resolvingIntent': 'Resolvendo intenção...',
2608
+ 'praxis.pageBuilder.agentic.status.waitingRevision': 'Ajuste o prompt e pré-visualize novamente.',
2609
+ 'praxis.pageBuilder.agentic.status.cancelled': 'Solicitação cancelada.',
2610
+ 'praxis.pageBuilder.agentic.status.previewing': 'Gerando pré-visualização...',
2611
+ 'praxis.pageBuilder.agentic.status.previewReady': 'Pré-visualização aplicada à página.',
2612
+ 'praxis.pageBuilder.agentic.status.acceptedAddLocalField': 'Campo local adicionado ao formulário.',
2613
+ 'praxis.pageBuilder.agentic.status.acceptedRemoveLocalField': 'Campo local removido do formulário.',
2614
+ 'praxis.pageBuilder.agentic.status.acceptedRelabelField': 'Rótulo do campo atualizado.',
2615
+ 'praxis.pageBuilder.agentic.status.saving': 'Salvando página...',
2616
+ 'praxis.pageBuilder.agentic.status.saved': 'Página salva.',
2617
+ 'praxis.pageBuilder.agentic.errors.applyLocal': 'A pré-visualização não pôde ser aplicada.',
2618
+ 'praxis.pageBuilder.agentic.errors.componentId': 'Configure um id de componente antes de salvar.',
2619
+ 'praxis.pageBuilder.agentic.errors.invalidPreview': 'A pré-visualização gerada é inválida.',
2620
+ 'praxis.pageBuilder.agentic.errors.intentResolution': 'A intenção não pôde ser resolvida.',
2621
+ 'praxis.pageBuilder.agentic.errors.duplicateField': 'Este campo já existe no formulário selecionado.',
2622
+ 'praxis.pageBuilder.agentic.errors.nonLocalFieldRemoval': 'Somente campos locais criados pela IA podem ser removidos neste fluxo.',
2623
+ 'praxis.pageBuilder.agentic.errors.generic': 'Falha na autoria com IA.',
2466
2624
  };
2467
2625
 
2468
2626
  function createPraxisPageBuilderI18nConfig(options = {}) {
@@ -3964,7 +4122,7 @@ class PageConfigEditorComponent {
3964
4122
  </div>
3965
4123
  }
3966
4124
  </div>
3967
- `, isInline: true, styles: [".page-config{display:grid;gap:12px;padding:16px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.page-head{display:flex;align-items:flex-start;gap:12px}.page-head__copy{display:grid;gap:4px}.page-title{font-weight:600;font-size:18px;line-height:1.2}.page-subtitle{max-width:72ch;color:var(--md-sys-color-on-surface-variant);font-size:13px;line-height:1.45}.spacer{flex:1}.page-summary{display:flex;flex-wrap:wrap;gap:8px}.page-tabs{border-radius:16px;overflow:hidden;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent)}.page-tabs ::ng-deep .mdc-tab{min-width:120px}.page-tabs ::ng-deep .mdc-tab__text-label{font-size:13px;font-weight:600}.page-tab-panel{display:grid;gap:12px;padding:16px 4px 4px}.page-chip{display:inline-flex;align-items:center;gap:8px;min-height:36px;padding:0 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 88%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:500}.page-chip mat-icon{width:18px;height:18px;font-size:18px}.page-chip--accent{border-color:color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 30%,transparent)}.page-chip--warning{border-color:color-mix(in srgb,var(--md-sys-color-error) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error-container) 35%,transparent)}.page-identity{display:grid;gap:4px;padding:12px 14px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 70%,transparent);font-size:13px;color:var(--md-sys-color-on-surface-variant)}.page-section{font-weight:600;margin-top:8px}.page-section-help{margin-top:-4px;color:var(--md-sys-color-on-surface-variant);font-size:13px;line-height:1.45}.grid-form{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.state-grid{display:grid;gap:16px}.state-values,.state-group{padding:14px;border:1px solid var(--md-sys-color-outline-variant);border-radius:14px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface-container-low) 92%,transparent),transparent),var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface))}.state-group{display:grid;gap:12px}.state-group-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.state-group-title{font-weight:600}.state-group-help{color:var(--md-sys-color-on-surface-variant);font-size:13px}.state-list{display:grid;gap:12px}.state-card{display:grid;gap:12px;padding:12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 80%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container) 84%,transparent)}.state-card-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.state-card-title{font-weight:600}.state-card-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.span-2{grid-column:span 2}.span-3{grid-column:1 / -1}.state-empty{color:var(--md-sys-color-on-surface-variant);font-size:13px}.state-operator-hint{display:flex;align-items:center;gap:8px;min-height:48px;padding:0 12px;border-radius:12px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-secondary-container) 35%,transparent)}.state-operator-hint mat-icon{color:var(--md-sys-color-secondary)}.page-actions{display:flex;justify-content:flex-end}.page-error{color:var(--md-sys-color-error);font-size:13px}.page-config .mat-mdc-form-field{width:100%;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}@media(max-width:720px){.span-2,.span-3{grid-column:auto}.page-head{flex-direction:column}.state-group-head{align-items:stretch;flex-direction:column}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4125
+ `, isInline: true, styles: [".page-config{display:grid;gap:12px;padding:16px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.page-head{display:flex;align-items:flex-start;gap:12px}.page-head__copy{display:grid;gap:4px}.page-title{font-weight:600;font-size:18px;line-height:1.2}.page-subtitle{max-width:72ch;color:var(--md-sys-color-on-surface-variant);font-size:13px;line-height:1.45}.spacer{flex:1}.page-summary{display:flex;flex-wrap:wrap;gap:8px}.page-tabs{border-radius:16px;overflow:hidden;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 78%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent)}.page-tabs ::ng-deep .mdc-tab{min-width:120px}.page-tabs ::ng-deep .mdc-tab__text-label{font-size:13px;font-weight:600}.page-tab-panel{display:grid;gap:12px;padding:16px 4px 4px}.page-chip{display:inline-flex;align-items:center;gap:8px;min-height:36px;padding:0 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 88%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 82%,transparent);color:var(--md-sys-color-on-surface-variant);font-size:12px;font-weight:500}.page-chip mat-icon{width:18px;height:18px;font-size:18px}.page-chip--accent{border-color:color-mix(in srgb,var(--md-sys-color-primary) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 30%,transparent)}.page-chip--warning{border-color:color-mix(in srgb,var(--md-sys-color-error) 35%,var(--md-sys-color-outline-variant));color:var(--md-sys-color-error);background:color-mix(in srgb,var(--md-sys-color-error-container) 35%,transparent)}.page-identity{display:grid;gap:4px;padding:12px 14px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 82%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 70%,transparent);font-size:13px;color:var(--md-sys-color-on-surface-variant)}.page-section{font-weight:600;margin-top:8px}.page-section-help{margin-top:-4px;color:var(--md-sys-color-on-surface-variant);font-size:13px;line-height:1.45}.grid-form{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.state-grid{display:grid;gap:16px}.state-values,.state-group{padding:14px;border:1px solid var(--md-sys-color-outline-variant);border-radius:14px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-surface-container-low) 92%,transparent),transparent),var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface))}.state-group{display:grid;gap:12px}.state-group-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.state-group-title{font-weight:600}.state-group-help{color:var(--md-sys-color-on-surface-variant);font-size:13px}.state-list{display:grid;gap:12px}.state-card{display:grid;gap:12px;padding:12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 80%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container) 84%,transparent)}.state-card-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.state-card-title{font-weight:600}.state-card-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.span-2{grid-column:span 2}.span-3{grid-column:1 / -1}.state-empty{color:var(--md-sys-color-on-surface-variant);font-size:13px}.state-operator-hint{display:flex;align-items:center;gap:8px;min-height:48px;padding:0 12px;border-radius:12px;color:var(--md-sys-color-on-surface-variant);background:color-mix(in srgb,var(--md-sys-color-secondary-container) 35%,transparent)}.state-operator-hint mat-icon{color:var(--md-sys-color-secondary)}.page-actions{display:flex;justify-content:flex-end}.page-error{color:var(--md-sys-color-error);font-size:13px}.page-config .mat-mdc-form-field{width:100%;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.help-icon-button{--mdc-icon-button-state-layer-size: 28px;--mdc-icon-button-icon-size: 18px;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;margin-right:-4px}.help-icon-button mat-icon{font-size:18px;width:18px;height:18px}.mat-mdc-form-field-icon-suffix{align-self:center}@media(max-width:720px){.span-2,.span-3{grid-column:auto}.page-head{flex-direction:column}.state-group-head{align-items:stretch;flex-direction:column}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3968
4126
  }
3969
4127
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PageConfigEditorComponent, decorators: [{
3970
4128
  type: Component,
@@ -4603,7 +4761,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
4603
4761
  * Capabilities catalog for the canonical dynamic page builder/runtime.
4604
4762
  */
4605
4763
  const PAGE_BUILDER_AI_CAPABILITIES = {
4606
- version: 'v1.1',
4764
+ version: 'v1.2',
4607
4765
  enums: {},
4608
4766
  targets: [
4609
4767
  'page-builder',
@@ -4618,10 +4776,30 @@ const PAGE_BUILDER_AI_CAPABILITIES = {
4618
4776
  'Edicao visual de inputs de widget deve usar ComponentDocMeta.configEditor publicado pela lib dona do componente; nao criar editor local no page-builder para semantica de outro pacote.',
4619
4777
  'Canvas e o modelo espacial canonico da pagina quando houver posicionamento explicito.',
4620
4778
  'Taxonomia editorial: condition usa Json Logic canonico; transform usa pipeline declarativo; policy cobre apenas comportamento operacional.',
4779
+ 'Para criacao agentic de paginas, o preview pode trazer uiCompositionPlan como plano intermediario validavel; o page-builder compila esse plano para WidgetPageDefinition antes de aplicar.',
4780
+ 'UiCompositionPlan usa widgets[].componentId e bindings declarativos. O JSON persistido continua sendo page.widgets[].definition.id e page.composition.links.',
4621
4781
  'Payloads legados de layout ainda podem ser ingeridos, mas sao normalizados para canvas e nao devem ser reemitidos.',
4622
4782
  'pageIdentity identifica o escopo de persistencia e nao pertence ao objeto page.',
4623
4783
  ],
4624
4784
  capabilities: [
4785
+ { path: 'uiCompositionPlan', category: 'page', valueKind: 'object', description: 'Plano declarativo intermediario aceito em preview agentic antes do WidgetPageDefinition.' },
4786
+ { path: 'uiCompositionPlan.version', category: 'page', valueKind: 'string', description: 'Versao do plano. Valor atual: 1.0.' },
4787
+ { path: 'uiCompositionPlan.kind', category: 'page', valueKind: 'string', description: 'Discriminador do plano. Valor atual: praxis.ui-composition-plan.' },
4788
+ { path: 'uiCompositionPlan.layoutPreset', category: 'layout', valueKind: 'string', description: 'Preset semantico opcional da composicao planejada.' },
4789
+ { path: 'uiCompositionPlan.state', category: 'state', valueKind: 'object', description: 'Estado inicial/declarativo que sera compilado para page.state.' },
4790
+ { path: 'uiCompositionPlan.widgets', category: 'widgets', valueKind: 'array', description: 'Widgets planejados antes da compilacao para page.widgets.' },
4791
+ { path: 'uiCompositionPlan.widgets[].key', category: 'widgets', valueKind: 'string', description: 'ID estavel do widget planejado.', critical: true },
4792
+ { path: 'uiCompositionPlan.widgets[].componentId', category: 'widgets', valueKind: 'string', description: 'Componente registrado que sera compilado para definition.id.', critical: true },
4793
+ { path: 'uiCompositionPlan.widgets[].inputs', category: 'widgets', valueKind: 'object', description: 'Inputs canonicos do componente, compilados para definition.inputs.' },
4794
+ { path: 'uiCompositionPlan.widgets[].bindingOrder', category: 'widgets', valueKind: 'array', description: 'Ordem declarativa de binding, compilada para definition.bindingOrder.' },
4795
+ { path: 'uiCompositionPlan.bindings', category: 'connections', valueKind: 'array', description: 'Bindings declarativos que serao compilados para page.composition.links.' },
4796
+ { path: 'uiCompositionPlan.bindings[].id', category: 'connections', valueKind: 'string', description: 'Identificador estavel do binding planejado.' },
4797
+ { path: 'uiCompositionPlan.bindings[].from', category: 'connections', valueKind: 'object', description: 'Endpoint de origem: component-port ou state.' },
4798
+ { path: 'uiCompositionPlan.bindings[].to', category: 'connections', valueKind: 'object', description: 'Endpoint de destino: component-port ou state.' },
4799
+ { path: 'uiCompositionPlan.bindings[].intent', category: 'connections', valueKind: 'string', description: 'Intencao semantica do binding.' },
4800
+ { path: 'uiCompositionPlan.bindings[].condition', category: 'connections', valueKind: 'expression', description: 'Guarda opcional em Json Logic.' },
4801
+ { path: 'uiCompositionPlan.bindings[].transform', category: 'connections', valueKind: 'object', description: 'Transform declarativo: pick-path, query-context, template ou constant.' },
4802
+ { path: 'uiCompositionPlan.bindings[].policy', category: 'connections', valueKind: 'object', description: 'Politica operacional opcional do binding.' },
4625
4803
  { path: 'page', category: 'page', valueKind: 'object', description: 'Definicao da pagina (WidgetPageDefinition).' },
4626
4804
  { path: 'context', category: 'context', valueKind: 'object', description: 'Contexto extra mesclado ao page.context.' },
4627
4805
  { path: 'enableCustomization', category: 'behavior', valueKind: 'boolean', description: 'Habilita modo de edicao.' },
@@ -4831,6 +5009,1004 @@ function providePageBuilderWidgetAiCatalogs() {
4831
5009
  };
4832
5010
  }
4833
5011
 
5012
+ const PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS = new InjectionToken('PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS');
5013
+ class PageBuilderAgenticAuthoringService {
5014
+ http = inject(HttpClient);
5015
+ options = inject(PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS, {
5016
+ optional: true,
5017
+ });
5018
+ baseUrl = (this.options?.baseUrl || '/api/praxis/config/ai/authoring').replace(/\/$/, '');
5019
+ headersFactory = this.options?.headersFactory || (() => ({}));
5020
+ getComponentCapabilities() {
5021
+ return this.http.get(`${this.baseUrl}/component-capabilities`, { headers: this.buildHeaders() });
5022
+ }
5023
+ previewPage(request) {
5024
+ return this.http.post(`${this.baseUrl}/page-preview`, request, { headers: this.buildHeaders() });
5025
+ }
5026
+ resolveIntent(request) {
5027
+ return this.http.post(`${this.baseUrl}/intent-resolution`, request, { headers: this.buildHeaders() });
5028
+ }
5029
+ applyPage(request) {
5030
+ const { ifMatch, ...body } = request;
5031
+ return this.http.post(`${this.baseUrl}/page-apply`, {
5032
+ componentType: body.componentType || 'praxis-dynamic-page',
5033
+ componentId: body.componentId,
5034
+ scope: body.scope,
5035
+ tags: body.tags,
5036
+ compiledFormPatch: body.compiledFormPatch,
5037
+ }, {
5038
+ headers: this.buildHeaders(ifMatch ? { 'If-Match': this.formatEtag(ifMatch) } : undefined),
5039
+ });
5040
+ }
5041
+ buildHeaders(extra) {
5042
+ const merged = {
5043
+ ...(this.options?.defaultHeaders ?? {}),
5044
+ };
5045
+ const runtime = this.headersFactory();
5046
+ for (const [key, value] of Object.entries(runtime)) {
5047
+ if (typeof value === 'string' && value.trim()) {
5048
+ merged[key] = value;
5049
+ }
5050
+ }
5051
+ for (const [key, value] of Object.entries(extra ?? {})) {
5052
+ if (typeof value === 'string' && value.trim()) {
5053
+ merged[key] = value;
5054
+ }
5055
+ }
5056
+ return new HttpHeaders(merged);
5057
+ }
5058
+ formatEtag(etag) {
5059
+ const trimmed = etag.trim();
5060
+ return trimmed.startsWith('"') ? trimmed : `"${trimmed}"`;
5061
+ }
5062
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PageBuilderAgenticAuthoringService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5063
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PageBuilderAgenticAuthoringService, providedIn: 'root' });
5064
+ }
5065
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PageBuilderAgenticAuthoringService, decorators: [{
5066
+ type: Injectable,
5067
+ args: [{ providedIn: 'root' }]
5068
+ }] });
5069
+
5070
+ function compileUiCompositionPlan(plan) {
5071
+ const diagnostics = validateUiCompositionPlan(plan);
5072
+ if (diagnostics.length) {
5073
+ return {
5074
+ valid: false,
5075
+ page: null,
5076
+ diagnostics,
5077
+ };
5078
+ }
5079
+ return {
5080
+ valid: true,
5081
+ page: {
5082
+ layoutPreset: plan.layoutPreset,
5083
+ canvas: clone(plan.canvas),
5084
+ state: clone(plan.state),
5085
+ widgets: plan.widgets.map(toWidgetInstance),
5086
+ composition: {
5087
+ version: '1.0.0',
5088
+ links: (plan.bindings ?? []).map(toCompositionLink),
5089
+ },
5090
+ },
5091
+ diagnostics: [],
5092
+ };
5093
+ }
5094
+ function validateUiCompositionPlan(plan) {
5095
+ const diagnostics = [];
5096
+ const widgetKeys = new Set();
5097
+ if (plan.kind !== 'praxis.ui-composition-plan') {
5098
+ diagnostics.push({
5099
+ code: 'invalid-kind',
5100
+ message: 'UiCompositionPlan.kind must be "praxis.ui-composition-plan".',
5101
+ path: 'kind',
5102
+ });
5103
+ }
5104
+ if (plan.version !== '1.0') {
5105
+ diagnostics.push({
5106
+ code: 'invalid-version',
5107
+ message: 'UiCompositionPlan.version must be "1.0".',
5108
+ path: 'version',
5109
+ });
5110
+ }
5111
+ for (const [index, widget] of (plan.widgets ?? []).entries()) {
5112
+ if (!widget.key?.trim()) {
5113
+ diagnostics.push({
5114
+ code: 'widget-key-required',
5115
+ message: 'Every planned widget must declare a stable key.',
5116
+ path: `widgets.${index}.key`,
5117
+ });
5118
+ continue;
5119
+ }
5120
+ if (widgetKeys.has(widget.key)) {
5121
+ diagnostics.push({
5122
+ code: 'widget-key-duplicated',
5123
+ message: `Widget key "${widget.key}" is duplicated.`,
5124
+ path: `widgets.${index}.key`,
5125
+ });
5126
+ }
5127
+ widgetKeys.add(widget.key);
5128
+ if (!widget.componentId?.trim()) {
5129
+ diagnostics.push({
5130
+ code: 'component-id-required',
5131
+ message: `Widget "${widget.key}" must declare a componentId.`,
5132
+ path: `widgets.${index}.componentId`,
5133
+ });
5134
+ }
5135
+ }
5136
+ for (const [index, binding] of (plan.bindings ?? []).entries()) {
5137
+ validateEndpoint(binding.from, widgetKeys, diagnostics, `bindings.${index}.from`);
5138
+ validateEndpoint(binding.to, widgetKeys, diagnostics, `bindings.${index}.to`);
5139
+ if (!binding.id?.trim()) {
5140
+ diagnostics.push({
5141
+ code: 'binding-id-required',
5142
+ message: 'Every planned binding must declare a stable id.',
5143
+ path: `bindings.${index}.id`,
5144
+ });
5145
+ }
5146
+ }
5147
+ validateCanvas(plan.canvas, widgetKeys, diagnostics);
5148
+ return diagnostics;
5149
+ }
5150
+ function validateCanvas(canvas, widgetKeys, diagnostics) {
5151
+ if (!canvas)
5152
+ return;
5153
+ for (const key of Object.keys(canvas.items ?? {})) {
5154
+ if (!widgetKeys.has(key)) {
5155
+ diagnostics.push({
5156
+ code: 'canvas-widget-not-found',
5157
+ message: `Canvas item references unknown widget "${key}".`,
5158
+ path: `canvas.items.${key}`,
5159
+ });
5160
+ }
5161
+ }
5162
+ }
5163
+ function validateEndpoint(endpoint, widgetKeys, diagnostics, path) {
5164
+ if (endpoint.kind === 'component-port') {
5165
+ if (!widgetKeys.has(endpoint.widget)) {
5166
+ diagnostics.push({
5167
+ code: 'endpoint-widget-not-found',
5168
+ message: `Endpoint references unknown widget "${endpoint.widget}".`,
5169
+ path: `${path}.widget`,
5170
+ });
5171
+ }
5172
+ if (!endpoint.port?.trim()) {
5173
+ diagnostics.push({
5174
+ code: 'endpoint-port-required',
5175
+ message: 'Component endpoint must declare a port.',
5176
+ path: `${path}.port`,
5177
+ });
5178
+ }
5179
+ return;
5180
+ }
5181
+ if (!endpoint.path?.trim()) {
5182
+ diagnostics.push({
5183
+ code: 'endpoint-state-path-required',
5184
+ message: 'State endpoint must declare a path.',
5185
+ path: `${path}.path`,
5186
+ });
5187
+ }
5188
+ }
5189
+ function toWidgetInstance(widget) {
5190
+ return {
5191
+ key: widget.key,
5192
+ definition: {
5193
+ id: widget.componentId,
5194
+ bindingOrder: widget.bindingOrder,
5195
+ inputs: clone(widget.inputs ?? {}),
5196
+ outputs: clone(widget.outputs ?? {}),
5197
+ },
5198
+ };
5199
+ }
5200
+ function toCompositionLink(binding) {
5201
+ const transform = binding.transform ? toCompositionTransform(binding.transform) : undefined;
5202
+ return {
5203
+ id: binding.id,
5204
+ from: toCompositionEndpoint(binding.from),
5205
+ to: toCompositionEndpoint(binding.to),
5206
+ intent: binding.intent,
5207
+ condition: clone(binding.condition),
5208
+ transform,
5209
+ policy: clone(binding.policy),
5210
+ metadata: clone(binding.metadata),
5211
+ };
5212
+ }
5213
+ function toCompositionEndpoint(endpoint) {
5214
+ if (endpoint.kind === 'component-port') {
5215
+ return {
5216
+ kind: 'component-port',
5217
+ ref: {
5218
+ widget: endpoint.widget,
5219
+ port: endpoint.port,
5220
+ direction: endpoint.direction,
5221
+ },
5222
+ };
5223
+ }
5224
+ return {
5225
+ kind: 'state',
5226
+ ref: {
5227
+ path: endpoint.path,
5228
+ layer: endpoint.layer,
5229
+ },
5230
+ };
5231
+ }
5232
+ function toCompositionTransform(transform) {
5233
+ if (transform.kind === 'query-context') {
5234
+ const valuePath = transform.valueVar?.trim() || 'payload';
5235
+ return {
5236
+ version: '2.0',
5237
+ phase: 'link-propagation',
5238
+ mode: 'single-value',
5239
+ steps: [
5240
+ {
5241
+ id: transform.id,
5242
+ kind: 'template',
5243
+ phase: 'link-propagation',
5244
+ input: { source: transform.inputSource ?? 'event' },
5245
+ config: {
5246
+ template: {
5247
+ filters: {
5248
+ [transform.field]: `\${${valuePath}}`,
5249
+ },
5250
+ },
5251
+ },
5252
+ },
5253
+ ],
5254
+ };
5255
+ }
5256
+ if (transform.kind === 'template') {
5257
+ return {
5258
+ version: '2.0',
5259
+ phase: 'link-propagation',
5260
+ mode: 'single-value',
5261
+ steps: [
5262
+ {
5263
+ id: transform.id,
5264
+ kind: 'template',
5265
+ phase: 'link-propagation',
5266
+ input: { source: transform.inputSource ?? 'event' },
5267
+ config: {
5268
+ template: clone(transform.template),
5269
+ },
5270
+ },
5271
+ ],
5272
+ };
5273
+ }
5274
+ if (transform.kind === 'constant') {
5275
+ return {
5276
+ version: '2.0',
5277
+ phase: 'link-propagation',
5278
+ mode: 'single-value',
5279
+ steps: [
5280
+ {
5281
+ id: transform.id,
5282
+ kind: 'constant',
5283
+ phase: 'link-propagation',
5284
+ config: {
5285
+ value: clone(transform.value),
5286
+ },
5287
+ },
5288
+ ],
5289
+ };
5290
+ }
5291
+ return {
5292
+ version: '2.0',
5293
+ phase: 'link-propagation',
5294
+ mode: 'single-value',
5295
+ steps: [
5296
+ {
5297
+ id: transform.id,
5298
+ kind: 'pick-path',
5299
+ phase: 'link-propagation',
5300
+ input: { source: transform.inputSource ?? 'event' },
5301
+ config: {
5302
+ path: transform.path,
5303
+ },
5304
+ },
5305
+ ],
5306
+ };
5307
+ }
5308
+ function clone(value) {
5309
+ if (value == null || typeof value !== 'object')
5310
+ return value;
5311
+ try {
5312
+ return structuredClone(value);
5313
+ }
5314
+ catch {
5315
+ return JSON.parse(JSON.stringify(value));
5316
+ }
5317
+ }
5318
+
5319
+ const LEGACY_OPTIONS_KEY = 'options';
5320
+ const LEGACY_LAYOUT_KEY = 'layout';
5321
+ class PageBuilderAiAdapter {
5322
+ host;
5323
+ registry;
5324
+ componentName = 'Page Builder';
5325
+ componentId = 'praxis-dynamic-page-builder';
5326
+ componentType = 'page';
5327
+ constructor(host, registry) {
5328
+ this.host = host;
5329
+ this.registry = registry;
5330
+ }
5331
+ getCurrentConfig() {
5332
+ const page = this.normalizePageForAi(this.parsePage(this.host.page));
5333
+ const config = {
5334
+ page: page ? this.clone(page) : { widgets: [] },
5335
+ context: this.clone(this.host.context ?? null),
5336
+ enableCustomization: this.host.enableCustomization,
5337
+ showSettingsButton: this.host.showSettingsButton,
5338
+ strictValidation: this.host.strictValidation,
5339
+ layoutOptions: this.pickLayoutOptions(this.host.layoutOptions),
5340
+ pageIdentity: this.clone(this.host.pageIdentity),
5341
+ };
5342
+ return config;
5343
+ }
5344
+ getCapabilities() {
5345
+ return getPageAiCatalog(this.getCurrentConfig()).capabilities;
5346
+ }
5347
+ getRuntimeState() {
5348
+ const page = this.normalizePageForAi(this.parsePage(this.host.page));
5349
+ const widgets = page?.widgets || [];
5350
+ const links = page?.composition?.links || [];
5351
+ return {
5352
+ widgetsCount: widgets.length,
5353
+ linksCount: links.length,
5354
+ widgetKeys: widgets.map((w) => w.key),
5355
+ widgetTypes: widgets.map((w) => w.definition?.id).filter((id) => !!id),
5356
+ componentCatalog: this.buildComponentCatalog(),
5357
+ };
5358
+ }
5359
+ createSnapshot() {
5360
+ return this.getCurrentConfig();
5361
+ }
5362
+ async restoreSnapshot(snapshot) {
5363
+ if (!snapshot)
5364
+ return;
5365
+ this.applyConfig(snapshot);
5366
+ }
5367
+ async applyPatch(patch, _intent) {
5368
+ try {
5369
+ const warnings = [];
5370
+ const current = this.getCurrentConfig();
5371
+ const normalizedPatch = this.normalizePatch(patch, current, warnings);
5372
+ const merged = deepMerge(current, normalizedPatch);
5373
+ const next = this.normalizeConfigForRuntime(merged, warnings);
5374
+ this.applyConfig(next);
5375
+ return warnings.length ? { success: true, warnings } : { success: true };
5376
+ }
5377
+ catch (error) {
5378
+ const message = error instanceof Error ? error.message : 'Unknown error applying patch';
5379
+ return { success: false, error: message };
5380
+ }
5381
+ }
5382
+ async applyCompiledFormPatch(compiledFormPatch) {
5383
+ const page = compiledFormPatch?.patch?.page;
5384
+ if (!page) {
5385
+ return {
5386
+ success: false,
5387
+ error: 'CompiledFormPatch must contain patch.page.',
5388
+ };
5389
+ }
5390
+ return this.applyPatch({ page }, 'agentic-authoring.compiled-form-patch');
5391
+ }
5392
+ async applyUiCompositionPlan(plan) {
5393
+ const compiled = compileUiCompositionPlan(plan);
5394
+ if (!compiled.valid) {
5395
+ return {
5396
+ success: false,
5397
+ error: compiled.diagnostics.map((diagnostic) => diagnostic.message).join('\n'),
5398
+ warnings: compiled.diagnostics.map((diagnostic) => diagnostic.path
5399
+ ? `${diagnostic.code} at ${diagnostic.path}`
5400
+ : diagnostic.code),
5401
+ };
5402
+ }
5403
+ return this.applyPatch({ page: compiled.page }, 'agentic-authoring.ui-composition-plan');
5404
+ }
5405
+ applyConfig(config) {
5406
+ this.host.applyConfigFromAdapter(config);
5407
+ }
5408
+ parsePage(input) {
5409
+ if (!input)
5410
+ return undefined;
5411
+ if (typeof input === 'string') {
5412
+ try {
5413
+ return JSON.parse(input);
5414
+ }
5415
+ catch {
5416
+ return undefined;
5417
+ }
5418
+ }
5419
+ return input;
5420
+ }
5421
+ normalizePageForAi(page) {
5422
+ if (!page)
5423
+ return page;
5424
+ const cloned = this.clone(page);
5425
+ const { [LEGACY_OPTIONS_KEY]: _legacyOptions, ...rest } = cloned;
5426
+ const widgets = (cloned.widgets || []).map((w) => this.stripLegacyLayoutFields(w));
5427
+ return {
5428
+ ...rest,
5429
+ widgets,
5430
+ canvas: this.ensureCanvasLayout(cloned),
5431
+ };
5432
+ }
5433
+ normalizeConfigForRuntime(config, warnings) {
5434
+ const page = this.normalizePageForRuntime(config.page, warnings);
5435
+ return {
5436
+ ...config,
5437
+ page,
5438
+ layoutOptions: config.layoutOptions || this.deriveLayoutOptionsFromCanvas(page) || this.host.layoutOptions,
5439
+ };
5440
+ }
5441
+ normalizePageForRuntime(page, warnings) {
5442
+ if (!page)
5443
+ return page;
5444
+ const cloned = this.clone(page);
5445
+ const { [LEGACY_OPTIONS_KEY]: _legacyOptions, ...rest } = cloned;
5446
+ const widgets = (cloned.widgets || []).map((w) => this.stripLegacyLayoutFields(w));
5447
+ return {
5448
+ ...rest,
5449
+ widgets,
5450
+ canvas: this.ensureCanvasLayout(cloned, warnings),
5451
+ };
5452
+ }
5453
+ normalizePatch(patch, base, warnings) {
5454
+ if (!patch || typeof patch !== 'object')
5455
+ return {};
5456
+ const cloned = this.clone(patch);
5457
+ const legacyPage = cloned.page;
5458
+ if (cloned.page?.widgets) {
5459
+ cloned.page = {
5460
+ ...cloned.page,
5461
+ widgets: cloned.page.widgets.map((w) => this.clone(w)),
5462
+ };
5463
+ }
5464
+ if (cloned.page?.composition?.links) {
5465
+ cloned.page = {
5466
+ ...cloned.page,
5467
+ composition: {
5468
+ ...(cloned.page.composition || {}),
5469
+ links: cloned.page.composition.links.filter((link) => {
5470
+ if (!this.linkKey(link)) {
5471
+ warnings.push('Composition link missing from/to information was ignored.');
5472
+ return false;
5473
+ }
5474
+ return true;
5475
+ }),
5476
+ },
5477
+ };
5478
+ }
5479
+ if (legacyPage?.[LEGACY_OPTIONS_KEY]) {
5480
+ cloned.layoutOptions = deepMerge(cloned.layoutOptions || {}, legacyPage[LEGACY_OPTIONS_KEY]);
5481
+ }
5482
+ if (cloned.page?.widgets) {
5483
+ const mergedWidgets = this.mergeWidgets(base.page?.widgets || [], cloned.page.widgets, warnings);
5484
+ cloned.page = { ...cloned.page, widgets: mergedWidgets };
5485
+ }
5486
+ if (cloned.page?.composition?.links) {
5487
+ const mergedLinks = this.mergeLinks(base.page?.composition?.links || [], cloned.page.composition.links);
5488
+ cloned.page = {
5489
+ ...cloned.page,
5490
+ composition: {
5491
+ ...(cloned.page.composition || {}),
5492
+ links: mergedLinks,
5493
+ },
5494
+ };
5495
+ }
5496
+ return cloned;
5497
+ }
5498
+ mergeWidgets(baseWidgets, patchWidgets, warnings) {
5499
+ const normalizedPatch = patchWidgets.map((w) => this.clone(w));
5500
+ // Process updates and removals
5501
+ const merged = baseWidgets
5502
+ .map((orig) => {
5503
+ const key = this.getWidgetKey(orig);
5504
+ const match = key
5505
+ ? normalizedPatch.find((p) => this.getWidgetKey(p) === key)
5506
+ : undefined;
5507
+ if (match && match._delete) {
5508
+ return null; // Mark for removal
5509
+ }
5510
+ return match ? deepMerge(orig, match) : orig;
5511
+ })
5512
+ .filter((w) => w !== null);
5513
+ // Process additions
5514
+ for (const patch of normalizedPatch) {
5515
+ if (patch._delete)
5516
+ continue; // Skip deletion patches here
5517
+ const key = this.getWidgetKey(patch) || this.generateWidgetKey(patch);
5518
+ if (!key) {
5519
+ warnings.push('Widget without key/id was ignored.');
5520
+ continue;
5521
+ }
5522
+ if (!baseWidgets.find((w) => this.getWidgetKey(w) === key)) {
5523
+ const next = { ...patch, key };
5524
+ merged.push(next);
5525
+ }
5526
+ }
5527
+ return merged;
5528
+ }
5529
+ mergeLinks(baseLinks, patchLinks) {
5530
+ const base = baseLinks || [];
5531
+ const patch = patchLinks || [];
5532
+ if (patch.length === 0)
5533
+ return base;
5534
+ // Process updates and removals
5535
+ const merged = base
5536
+ .map((orig) => {
5537
+ const key = this.linkKey(orig);
5538
+ const match = key ? patch.find((p) => this.linkKey(p) === key) : undefined;
5539
+ if (match && match._delete) {
5540
+ return null; // Mark for removal
5541
+ }
5542
+ return match ? deepMerge(orig, match) : orig;
5543
+ })
5544
+ .filter((c) => c !== null);
5545
+ // Process additions
5546
+ for (const conn of patch) {
5547
+ if (conn._delete)
5548
+ continue;
5549
+ const key = this.linkKey(conn);
5550
+ if (!key)
5551
+ continue;
5552
+ if (!base.find((c) => this.linkKey(c) === key)) {
5553
+ merged.push(conn);
5554
+ }
5555
+ }
5556
+ return merged;
5557
+ }
5558
+ layoutFromLegacy(widget) {
5559
+ if (widget[LEGACY_LAYOUT_KEY])
5560
+ return widget[LEGACY_LAYOUT_KEY];
5561
+ if (typeof widget.x !== 'number' || typeof widget.y !== 'number')
5562
+ return undefined;
5563
+ const colSpan = typeof widget.cols === 'number' ? widget.cols : 3;
5564
+ const rowSpan = typeof widget.rows === 'number' ? widget.rows : 3;
5565
+ return { col: widget.x + 1, row: widget.y + 1, colSpan, rowSpan };
5566
+ }
5567
+ ensureCanvasLayout(page, warnings = []) {
5568
+ const widgets = page.widgets || [];
5569
+ const legacyOptions = page[LEGACY_OPTIONS_KEY] ?? this.host.layoutOptions;
5570
+ const baseCanvas = this.clone(page.canvas || {
5571
+ mode: 'grid',
5572
+ columns: legacyOptions?.cols || 12,
5573
+ rowUnit: typeof legacyOptions?.rowHeight === 'number' ? `${legacyOptions.rowHeight}px` : '80px',
5574
+ gap: typeof legacyOptions?.gap === 'number' ? `${legacyOptions.gap}px` : '16px',
5575
+ autoRows: 'fixed',
5576
+ items: {},
5577
+ });
5578
+ const items = { ...(baseCanvas.items || {}) };
5579
+ let nextRow = this.maxCanvasRow(items);
5580
+ for (const widget of widgets) {
5581
+ const key = this.getWidgetKey(widget);
5582
+ if (!key || items[key])
5583
+ continue;
5584
+ const layout = this.layoutFromLegacy(widget);
5585
+ if (layout) {
5586
+ items[key] = {
5587
+ col: this.coerceNumber(layout.col, 1),
5588
+ row: this.coerceNumber(layout.row, 1),
5589
+ colSpan: this.coerceNumber(layout.colSpan, 3),
5590
+ rowSpan: this.coerceNumber(layout.rowSpan, 3),
5591
+ };
5592
+ nextRow = Math.max(nextRow, items[key].row + items[key].rowSpan - 1);
5593
+ continue;
5594
+ }
5595
+ items[key] = { col: 1, row: nextRow + 1, colSpan: 3, rowSpan: 3 };
5596
+ nextRow = items[key].row + items[key].rowSpan - 1;
5597
+ warnings.push(`Widget "${key}" missing canvas placement; using defaults.`);
5598
+ }
5599
+ return {
5600
+ mode: 'grid',
5601
+ columns: baseCanvas.columns || legacyOptions?.cols || 12,
5602
+ rowUnit: baseCanvas.rowUnit || (typeof legacyOptions?.rowHeight === 'number' ? `${legacyOptions.rowHeight}px` : '80px'),
5603
+ gap: baseCanvas.gap || (typeof legacyOptions?.gap === 'number' ? `${legacyOptions.gap}px` : '16px'),
5604
+ autoRows: baseCanvas.autoRows || 'fixed',
5605
+ collisionPolicy: baseCanvas.collisionPolicy,
5606
+ items,
5607
+ };
5608
+ }
5609
+ stripLegacyLayoutFields(widget) {
5610
+ const { x: _x, y: _y, cols: _cols, rows: _rows, minItemCols: _minItemCols, minItemRows: _minItemRows, maxItemCols: _maxItemCols, maxItemRows: _maxItemRows, ...rest } = widget;
5611
+ delete rest[LEGACY_LAYOUT_KEY];
5612
+ return rest;
5613
+ }
5614
+ deriveLayoutOptionsFromCanvas(page) {
5615
+ const canvas = page?.canvas;
5616
+ if (!canvas)
5617
+ return undefined;
5618
+ const derived = {};
5619
+ if (typeof canvas.columns === 'number')
5620
+ derived.cols = canvas.columns;
5621
+ const rowHeight = this.parsePixelValue(canvas.rowUnit);
5622
+ if (typeof rowHeight === 'number')
5623
+ derived.rowHeight = rowHeight;
5624
+ const gap = this.parsePixelValue(canvas.gap);
5625
+ if (typeof gap === 'number')
5626
+ derived.gap = gap;
5627
+ return Object.keys(derived).length ? derived : undefined;
5628
+ }
5629
+ maxCanvasRow(items) {
5630
+ return Object.values(items).reduce((max, item) => Math.max(max, item.row + item.rowSpan - 1), 0);
5631
+ }
5632
+ getWidgetKey(widget) {
5633
+ if (!widget)
5634
+ return undefined;
5635
+ const key = widget.key;
5636
+ if (typeof key !== 'string')
5637
+ return undefined;
5638
+ const trimmed = key.trim();
5639
+ return trimmed ? trimmed : undefined;
5640
+ }
5641
+ generateWidgetKey(widget) {
5642
+ const id = widget.definition?.id;
5643
+ const prefix = typeof id === 'string' && id.trim() ? id.trim() : 'widget';
5644
+ return `${prefix}-${generateId()}`;
5645
+ }
5646
+ linkKey(link) {
5647
+ if (!link)
5648
+ return null;
5649
+ const from = link.from.kind === 'component-port'
5650
+ ? (link.from.ref.widget && link.from.ref.port
5651
+ ? `widget:${link.from.ref.widget}::${link.from.ref.port}::${link.from.ref.direction}`
5652
+ : null)
5653
+ : (link.from.ref.path ? `state:${link.from.ref.path}::${link.from.ref.layer || 'values'}` : null);
5654
+ const to = link.to.kind === 'component-port'
5655
+ ? (link.to.ref.widget && link.to.ref.port
5656
+ ? `widget:${link.to.ref.widget}::${link.to.ref.port}::${link.to.ref.direction}`
5657
+ : null)
5658
+ : (link.to.ref.path ? `state:${link.to.ref.path}::${link.to.ref.layer || 'values'}` : null);
5659
+ if (!from || !to)
5660
+ return null;
5661
+ return `${from}->${to}`;
5662
+ }
5663
+ pickLayoutOptions(options) {
5664
+ if (!options)
5665
+ return undefined;
5666
+ const picked = {};
5667
+ if (typeof options.cols === 'number')
5668
+ picked.cols = options.cols;
5669
+ if (typeof options.rowHeight === 'number')
5670
+ picked.rowHeight = options.rowHeight;
5671
+ if (typeof options.gap === 'number')
5672
+ picked.gap = options.gap;
5673
+ return Object.keys(picked).length ? picked : undefined;
5674
+ }
5675
+ buildComponentCatalog() {
5676
+ if (!this.registry)
5677
+ return [];
5678
+ return this.registry.getAll().map((meta) => ({
5679
+ id: meta.id,
5680
+ friendlyName: meta.friendlyName,
5681
+ description: meta.description,
5682
+ icon: meta.icon,
5683
+ tags: meta.tags,
5684
+ inputs: (meta.inputs || []).map((input) => input.name),
5685
+ outputs: (meta.outputs || []).map((output) => output.name),
5686
+ layoutHints: meta.layoutHints,
5687
+ }));
5688
+ }
5689
+ coerceNumber(value, fallback) {
5690
+ return typeof value === 'number' && !Number.isNaN(value) ? value : fallback;
5691
+ }
5692
+ parsePixelValue(value) {
5693
+ if (typeof value !== 'string')
5694
+ return undefined;
5695
+ const match = value.trim().match(/^(\d+(?:\.\d+)?)px$/);
5696
+ if (!match)
5697
+ return undefined;
5698
+ return Number(match[1]);
5699
+ }
5700
+ clone(value) {
5701
+ if (value == null || typeof value !== 'object')
5702
+ return value;
5703
+ try {
5704
+ return structuredClone(value);
5705
+ }
5706
+ catch {
5707
+ return JSON.parse(JSON.stringify(value));
5708
+ }
5709
+ }
5710
+ }
5711
+
5712
+ class PageBuilderAgenticAuthoringTurnFlow {
5713
+ service;
5714
+ context;
5715
+ mode = 'agentic-authoring';
5716
+ constructor(service, context) {
5717
+ this.service = service;
5718
+ this.context = context;
5719
+ }
5720
+ async submit(request) {
5721
+ const prompt = request.prompt?.trim();
5722
+ if (!prompt) {
5723
+ return {
5724
+ state: 'listening',
5725
+ phase: 'capture',
5726
+ };
5727
+ }
5728
+ try {
5729
+ const authoringContext = this.buildAuthoringContext(request);
5730
+ const componentCapabilities = await this.context.loadComponentCapabilities();
5731
+ const selectedWidgetKey = this.context.selectedWidgetKey();
5732
+ const intentResolution = await firstValueFrom(this.service.resolveIntent({
5733
+ userPrompt: prompt,
5734
+ targetApp: this.context.targetApp,
5735
+ targetComponentId: this.context.targetComponentId,
5736
+ currentPage: this.context.currentPage(),
5737
+ selectedWidgetKey,
5738
+ provider: this.context.provider(),
5739
+ model: this.context.model(),
5740
+ apiKey: this.context.apiKey(),
5741
+ componentCapabilities,
5742
+ ...authoringContext,
5743
+ }));
5744
+ const intentAssistantMessage = this.resolveIntentAssistantMessage(intentResolution);
5745
+ if (intentAssistantMessage) {
5746
+ return {
5747
+ state: 'clarification',
5748
+ phase: 'clarify',
5749
+ assistantMessage: intentAssistantMessage,
5750
+ quickReplies: this.toShellQuickReplies(intentResolution.quickReplies ?? []),
5751
+ canApply: false,
5752
+ statusText: '',
5753
+ errorText: '',
5754
+ preview: null,
5755
+ pendingClarification: this.resolvePendingClarificationForNextTurn(intentResolution, request, this.resolveEffectivePrompt(intentResolution, prompt), intentAssistantMessage),
5756
+ diagnostics: { intentResolution },
5757
+ };
5758
+ }
5759
+ const clarification = this.resolveIntentClarification(intentResolution);
5760
+ if (clarification) {
5761
+ return {
5762
+ state: 'clarification',
5763
+ phase: 'clarify',
5764
+ assistantMessage: clarification,
5765
+ quickReplies: this.toShellQuickReplies(intentResolution.quickReplies ?? []),
5766
+ canApply: false,
5767
+ statusText: '',
5768
+ errorText: '',
5769
+ preview: null,
5770
+ pendingClarification: this.resolvePendingClarificationForNextTurn(intentResolution, request, this.resolveEffectivePrompt(intentResolution, prompt), clarification),
5771
+ diagnostics: { intentResolution },
5772
+ };
5773
+ }
5774
+ const intentFailure = this.describeIntentResolutionFailure(intentResolution);
5775
+ if (intentFailure) {
5776
+ return {
5777
+ state: 'error',
5778
+ phase: 'contextualize',
5779
+ assistantMessage: intentFailure,
5780
+ canApply: false,
5781
+ statusText: '',
5782
+ errorText: intentFailure,
5783
+ preview: null,
5784
+ diagnostics: { intentResolution },
5785
+ };
5786
+ }
5787
+ const preview = await firstValueFrom(this.service.previewPage({
5788
+ userPrompt: prompt,
5789
+ provider: this.context.provider(),
5790
+ model: this.context.model(),
5791
+ apiKey: this.context.apiKey(),
5792
+ currentPage: this.context.currentPage(),
5793
+ selectedWidgetKey,
5794
+ intentResolution,
5795
+ componentCapabilities,
5796
+ ...authoringContext,
5797
+ }));
5798
+ if (!preview.valid) {
5799
+ const message = this.context.describePreviewFailure(preview);
5800
+ return {
5801
+ state: 'error',
5802
+ phase: 'preview',
5803
+ assistantMessage: message,
5804
+ canApply: false,
5805
+ statusText: '',
5806
+ errorText: message,
5807
+ preview: null,
5808
+ diagnostics: { intentResolution, preview },
5809
+ };
5810
+ }
5811
+ const applied = await this.context.applyLocalPreview(preview);
5812
+ if (!applied.success) {
5813
+ const message = applied.error || this.context.tx('agentic.errors.applyLocal', 'Preview could not be applied.');
5814
+ return {
5815
+ state: 'error',
5816
+ phase: 'preview',
5817
+ assistantMessage: message,
5818
+ canApply: false,
5819
+ statusText: '',
5820
+ errorText: message,
5821
+ preview: null,
5822
+ diagnostics: { intentResolution, preview },
5823
+ };
5824
+ }
5825
+ const status = this.context.describePreviewStatus(preview);
5826
+ return {
5827
+ state: 'review',
5828
+ phase: 'review',
5829
+ assistantMessage: status,
5830
+ canApply: true,
5831
+ statusText: status,
5832
+ errorText: '',
5833
+ preview,
5834
+ diagnostics: { intentResolution },
5835
+ };
5836
+ }
5837
+ catch (error) {
5838
+ const message = this.context.describeError(error);
5839
+ return {
5840
+ state: 'error',
5841
+ phase: 'contextualize',
5842
+ assistantMessage: message,
5843
+ canApply: false,
5844
+ statusText: '',
5845
+ errorText: message,
5846
+ preview: null,
5847
+ };
5848
+ }
5849
+ }
5850
+ async cancel() {
5851
+ return {
5852
+ state: 'listening',
5853
+ phase: 'capture',
5854
+ assistantMessage: this.context.tx('agentic.status.cancelled', 'Request cancelled.'),
5855
+ quickReplies: [],
5856
+ canApply: false,
5857
+ statusText: '',
5858
+ errorText: '',
5859
+ preview: null,
5860
+ pendingPatch: null,
5861
+ };
5862
+ }
5863
+ resolveIntentAssistantMessage(intentResolution) {
5864
+ const message = intentResolution.assistantMessage?.trim();
5865
+ return message || null;
5866
+ }
5867
+ resolveIntentClarification(intentResolution) {
5868
+ const questions = intentResolution.clarificationQuestions?.filter((question) => !!question) ?? [];
5869
+ if (!intentResolution.valid && questions.length) {
5870
+ return questions.join(' ');
5871
+ }
5872
+ return null;
5873
+ }
5874
+ describeIntentResolutionFailure(intentResolution) {
5875
+ if (intentResolution.valid && intentResolution.gate?.status === 'eligible' && intentResolution.selectedCandidate) {
5876
+ return null;
5877
+ }
5878
+ const questions = intentResolution.clarificationQuestions?.filter((question) => !!question) ?? [];
5879
+ if (questions.length) {
5880
+ return questions.join(' ');
5881
+ }
5882
+ const failures = intentResolution.failureCodes?.filter((code) => !!code) ?? [];
5883
+ if (failures.length) {
5884
+ return `${this.context.tx('agentic.errors.intentResolution', 'Intent could not be resolved.')}: ${failures.join(', ')}`;
5885
+ }
5886
+ const gateMessages = intentResolution.gate?.messages?.filter((message) => !!message) ?? [];
5887
+ if (gateMessages.length) {
5888
+ return gateMessages.join(' ');
5889
+ }
5890
+ return this.context.tx('agentic.errors.intentResolution', 'Intent could not be resolved.');
5891
+ }
5892
+ toShellQuickReplies(quickReplies) {
5893
+ return quickReplies
5894
+ .filter((reply) => !!reply.id && !!reply.label && (!!reply.prompt || reply.kind === 'cancel'))
5895
+ .map((reply) => ({
5896
+ id: reply.id,
5897
+ kind: reply.kind,
5898
+ label: reply.label,
5899
+ prompt: reply.prompt,
5900
+ }));
5901
+ }
5902
+ buildPendingClarificationForNextTurn(request, sourcePrompt, clarification) {
5903
+ return {
5904
+ sourcePrompt,
5905
+ assistantMessage: clarification,
5906
+ questions: [
5907
+ {
5908
+ id: 'clarification',
5909
+ type: 'text',
5910
+ label: clarification,
5911
+ },
5912
+ ],
5913
+ clientTurnId: request.clientTurnId,
5914
+ };
5915
+ }
5916
+ resolvePendingClarificationForNextTurn(intentResolution, request, fallbackSourcePrompt, fallbackClarification) {
5917
+ return this.toShellPendingClarification(intentResolution.pendingClarification)
5918
+ ?? this.buildPendingClarificationForNextTurn(request, fallbackSourcePrompt, fallbackClarification);
5919
+ }
5920
+ toShellPendingClarification(pending) {
5921
+ const sourcePrompt = pending?.sourcePrompt?.trim();
5922
+ if (!sourcePrompt) {
5923
+ return null;
5924
+ }
5925
+ const questionLabels = (pending?.questions ?? [])
5926
+ .map((question) => question?.trim())
5927
+ .filter((question) => !!question);
5928
+ const assistantMessage = pending?.assistantMessage?.trim() || questionLabels[0] || '';
5929
+ const questions = questionLabels.length
5930
+ ? questionLabels.map((label, index) => ({
5931
+ id: `clarification-${index + 1}`,
5932
+ type: 'text',
5933
+ label,
5934
+ }))
5935
+ : assistantMessage
5936
+ ? [{
5937
+ id: 'clarification',
5938
+ type: 'text',
5939
+ label: assistantMessage,
5940
+ }]
5941
+ : [];
5942
+ return {
5943
+ sourcePrompt,
5944
+ assistantMessage,
5945
+ questions,
5946
+ clientTurnId: pending?.clientTurnId ?? undefined,
5947
+ diagnostics: this.toJsonObject(pending?.diagnostics) ?? undefined,
5948
+ };
5949
+ }
5950
+ resolveEffectivePrompt(intentResolution, fallbackPrompt) {
5951
+ return intentResolution.effectivePrompt?.trim() || fallbackPrompt;
5952
+ }
5953
+ buildAuthoringContext(request) {
5954
+ return {
5955
+ sessionId: request.sessionId,
5956
+ clientTurnId: request.clientTurnId,
5957
+ conversationMessages: this.toConversationMessages(request.messages ?? []),
5958
+ pendingClarification: this.toPendingClarification(request.pendingClarification),
5959
+ attachmentSummaries: this.toAttachmentSummaries(request.attachments ?? []),
5960
+ };
5961
+ }
5962
+ toAttachmentSummaries(attachments) {
5963
+ return attachments.map((attachment) => ({
5964
+ id: attachment.id,
5965
+ name: attachment.name,
5966
+ kind: attachment.kind,
5967
+ mimeType: attachment.mimeType ?? null,
5968
+ sizeBytes: attachment.sizeBytes ?? null,
5969
+ source: attachment.source ?? null,
5970
+ hasPreview: !!attachment.previewUrl,
5971
+ }));
5972
+ }
5973
+ toConversationMessages(messages) {
5974
+ return messages
5975
+ .filter((message) => !!message.text?.trim() && this.isAuthoringConversationRole(message.role))
5976
+ .slice(-12)
5977
+ .flatMap((message) => {
5978
+ if (!this.isAuthoringConversationRole(message.role)) {
5979
+ return [];
5980
+ }
5981
+ return [{
5982
+ id: message.id,
5983
+ role: message.role,
5984
+ text: message.text,
5985
+ }];
5986
+ });
5987
+ }
5988
+ toPendingClarification(pending) {
5989
+ if (!pending?.sourcePrompt) {
5990
+ return null;
5991
+ }
5992
+ return {
5993
+ sourcePrompt: pending.sourcePrompt,
5994
+ questions: pending.questions.map((question) => question.label),
5995
+ assistantMessage: pending.assistantMessage,
5996
+ clientTurnId: pending.clientTurnId,
5997
+ diagnostics: this.toJsonObject(pending.diagnostics),
5998
+ };
5999
+ }
6000
+ isAuthoringConversationRole(role) {
6001
+ return role === 'user' || role === 'assistant' || role === 'system';
6002
+ }
6003
+ toJsonObject(value) {
6004
+ return value && typeof value === 'object' && !Array.isArray(value)
6005
+ ? value
6006
+ : null;
6007
+ }
6008
+ }
6009
+
4834
6010
  function buildConnectionsViewerModel(page) {
4835
6011
  const widgets = page?.widgets ?? [];
4836
6012
  const links = page?.composition?.links ?? [];
@@ -5327,19 +6503,50 @@ class DynamicPageBuilderComponent {
5327
6503
  settingsPanel;
5328
6504
  i18n = inject(PraxisI18nService);
5329
6505
  componentMetadata = inject(ComponentMetadataRegistry);
6506
+ agenticAuthoring = inject(PageBuilderAgenticAuthoringService);
6507
+ agenticTurnOrchestrator = inject(PraxisAssistantTurnOrchestratorService);
5330
6508
  runtime;
5331
6509
  page;
5332
6510
  context = null;
5333
6511
  strictValidation = true;
6512
+ autoPersist = true;
5334
6513
  enableCustomization = false;
5335
6514
  showSettingsButton = true;
5336
6515
  pageIdentity;
5337
6516
  componentInstanceId;
5338
6517
  pageEditorComponent = DynamicPageConfigEditorComponent;
6518
+ enableAgenticAuthoring = false;
6519
+ agenticAuthoringProvider;
6520
+ agenticAuthoringModel;
6521
+ agenticAuthoringApiKey;
6522
+ agenticAuthoringComponentId;
6523
+ agenticAuthoringScope = 'user';
6524
+ agenticAuthoringEtag;
5339
6525
  pageChange = new EventEmitter();
6526
+ agenticAuthoringApplied = new EventEmitter();
5340
6527
  currentPage = signal({ widgets: [] }, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
5341
6528
  connectionsViewerOpen = signal(false, ...(ngDevMode ? [{ debugName: "connectionsViewerOpen" }] : []));
6529
+ agenticAuthoringOpen = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringOpen" }] : []));
6530
+ agenticAuthoringPrompt = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringPrompt" }] : []));
6531
+ agenticAuthoringBusy = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringBusy" }] : []));
6532
+ agenticAuthoringStatus = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringStatus" }] : []));
6533
+ agenticAuthoringError = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringError" }] : []));
6534
+ agenticAuthoringPreviewResult = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringPreviewResult" }] : []));
6535
+ agenticAuthoringLastEtag = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringLastEtag" }] : []));
6536
+ agenticAuthoringConversation = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringConversation" }] : []));
6537
+ agenticAuthoringQuickReplies = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringQuickReplies" }] : []));
6538
+ agenticAuthoringAttachments = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringAttachments" }] : []));
6539
+ agenticAuthoringEditingMessageId = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringEditingMessageId" }] : []));
6540
+ agenticAuthoringPanelLayout = signal({
6541
+ left: 16,
6542
+ top: 16,
6543
+ width: 440,
6544
+ height: 560,
6545
+ }, ...(ngDevMode ? [{ debugName: "agenticAuthoringPanelLayout" }] : []));
5342
6546
  previewMode = false;
6547
+ agenticComponentCapabilities;
6548
+ agenticComponentCapabilitiesPromise;
6549
+ agenticTurnController;
5343
6550
  constructor(dialog, settingsPanel) {
5344
6551
  this.dialog = dialog;
5345
6552
  this.settingsPanel = settingsPanel;
@@ -5409,6 +6616,315 @@ class DynamicPageBuilderComponent {
5409
6616
  this.currentPage.set(cloned);
5410
6617
  this.pageChange.emit(cloned);
5411
6618
  }
6619
+ applyConfigFromAdapter(config) {
6620
+ if (!config.page)
6621
+ return;
6622
+ const cloned = this.clonePage(config.page);
6623
+ this.currentPage.set(cloned);
6624
+ this.pageChange.emit(cloned);
6625
+ }
6626
+ createAdapterHost() {
6627
+ return {
6628
+ page: this.currentPage(),
6629
+ context: this.context,
6630
+ enableCustomization: this.enableCustomization,
6631
+ showSettingsButton: this.showSettingsButton,
6632
+ strictValidation: this.strictValidation,
6633
+ pageIdentity: this.pageIdentity,
6634
+ applyConfigFromAdapter: (config) => this.applyConfigFromAdapter(config),
6635
+ };
6636
+ }
6637
+ toggleAgenticAuthoring() {
6638
+ this.agenticAuthoringOpen.update((current) => !current);
6639
+ this.agenticAuthoringError.set('');
6640
+ }
6641
+ agenticAuthoringShellLabels() {
6642
+ return {
6643
+ title: this.tx('agentic.title', 'AI assistant'),
6644
+ subtitle: this.tx('agentic.subtitle', 'Chat, confirm the intent, and review the result before saving.'),
6645
+ close: this.tx('agentic.close', 'Close'),
6646
+ prompt: this.tx('agentic.promptLabel', 'Message'),
6647
+ promptPlaceholder: this.tx('agentic.promptPlaceholder', 'Describe the page, dashboard, form or change you need.'),
6648
+ emptyConversation: this.tx('agentic.emptyConversation', 'Tell me what you want to create or change. I will ask follow-up questions before applying the preview.'),
6649
+ submit: this.tx('agentic.preview', 'Preview'),
6650
+ apply: this.tx('agentic.persist', 'Save'),
6651
+ conversationAria: this.tx('agentic.conversationAria', 'AI conversation'),
6652
+ quickRepliesAria: this.tx('agentic.quickRepliesAria', 'Quick replies'),
6653
+ dragHandleAria: this.tx('agentic.dragHandleAria', 'Move AI assistant'),
6654
+ resizeHandleAria: this.tx('agentic.resizeHandleAria', 'Resize AI assistant'),
6655
+ contextAria: this.tx('agentic.contextAria', 'Active context'),
6656
+ attachmentsAria: this.tx('agentic.attachmentsAria', 'Attached context'),
6657
+ attach: this.tx('agentic.attach', 'Attach'),
6658
+ removeAttachment: this.tx('agentic.removeAttachment', 'Remove attachment'),
6659
+ editMessage: this.tx('agentic.editMessage', 'Edit'),
6660
+ resendMessage: this.tx('agentic.resendMessage', 'Resend'),
6661
+ modeAgenticAuthoring: this.tx('agentic.mode.agenticAuthoring', 'Authoring'),
6662
+ modeConfig: this.tx('agentic.mode.config', 'Configuration'),
6663
+ modeChat: this.tx('agentic.mode.chat', 'Chat'),
6664
+ modeDiagnostic: this.tx('agentic.mode.diagnostic', 'Diagnostic'),
6665
+ modeReview: this.tx('agentic.mode.review', 'Review'),
6666
+ modeInlineHelp: this.tx('agentic.mode.inlineHelp', 'Help'),
6667
+ stateIdle: this.tx('agentic.state.idle', 'Idle'),
6668
+ stateListening: this.tx('agentic.state.listening', 'Ready'),
6669
+ stateProcessing: this.tx('agentic.state.processing', 'Processing'),
6670
+ stateClarification: this.tx('agentic.state.clarification', 'Waiting for input'),
6671
+ stateReview: this.tx('agentic.state.review', 'Review'),
6672
+ stateApplying: this.tx('agentic.state.applying', 'Applying'),
6673
+ stateSuccess: this.tx('agentic.state.success', 'Done'),
6674
+ stateError: this.tx('agentic.state.error', 'Error'),
6675
+ };
6676
+ }
6677
+ agenticAuthoringShellState() {
6678
+ if (this.agenticAuthoringBusy())
6679
+ return 'processing';
6680
+ if (this.agenticAuthoringError())
6681
+ return 'error';
6682
+ if (this.agenticAuthoringPreviewResult()?.valid)
6683
+ return 'review';
6684
+ if (this.agenticAuthoringConversation().length)
6685
+ return 'listening';
6686
+ return 'idle';
6687
+ }
6688
+ agenticAuthoringContextItems() {
6689
+ const items = [
6690
+ {
6691
+ id: 'component',
6692
+ kind: 'component',
6693
+ label: this.tx('agentic.context.component', 'Component'),
6694
+ value: this.tx('agentic.context.pageBuilder', 'Page Builder'),
6695
+ icon: 'dashboard_customize',
6696
+ },
6697
+ ];
6698
+ const routePath = this.pageIdentity?.routePath?.trim();
6699
+ if (routePath) {
6700
+ items.push({
6701
+ id: 'route',
6702
+ kind: 'route',
6703
+ label: this.tx('agentic.context.route', 'Route'),
6704
+ value: routePath,
6705
+ icon: 'route',
6706
+ });
6707
+ }
6708
+ const selectedWidgetKey = this.resolveSelectedWidgetKey();
6709
+ if (selectedWidgetKey) {
6710
+ items.push({
6711
+ id: 'selection',
6712
+ kind: 'selection',
6713
+ label: this.tx('agentic.context.selection', 'Selection'),
6714
+ value: selectedWidgetKey,
6715
+ icon: 'select_all',
6716
+ });
6717
+ }
6718
+ return items;
6719
+ }
6720
+ async previewAgenticAuthoring() {
6721
+ const prompt = this.agenticAuthoringPrompt().trim();
6722
+ if (!prompt || this.agenticAuthoringBusy())
6723
+ return;
6724
+ this.agenticAuthoringBusy.set(true);
6725
+ this.agenticAuthoringError.set('');
6726
+ this.agenticAuthoringPreviewResult.set(null);
6727
+ this.agenticAuthoringStatus.set(this.tx('agentic.status.resolvingIntent', 'Resolving intent...'));
6728
+ try {
6729
+ const controller = this.ensureAgenticTurnController();
6730
+ const editingMessageId = this.agenticAuthoringEditingMessageId();
6731
+ const state = await firstValueFrom(editingMessageId
6732
+ ? controller.submitEditedMessage(editingMessageId, prompt)
6733
+ : controller.submitPrompt(prompt));
6734
+ this.agenticAuthoringEditingMessageId.set(null);
6735
+ this.applyAgenticTurnState(state);
6736
+ }
6737
+ catch (error) {
6738
+ this.agenticAuthoringStatus.set('');
6739
+ const message = this.describeAgenticError(error);
6740
+ this.agenticAuthoringError.set(message);
6741
+ this.appendAgenticMessage('error', message);
6742
+ }
6743
+ finally {
6744
+ this.agenticAuthoringBusy.set(false);
6745
+ }
6746
+ }
6747
+ async submitAgenticQuickReply(reply) {
6748
+ if (reply.kind !== 'cancel' && reply.kind !== 'revise' && reply.kind !== 'confirm' && reply.kind !== 'suggestion') {
6749
+ return;
6750
+ }
6751
+ if (reply.kind === 'cancel') {
6752
+ this.agenticAuthoringEditingMessageId.set(null);
6753
+ const state = await firstValueFrom(this.ensureAgenticTurnController().cancel());
6754
+ this.applyAgenticTurnState(state);
6755
+ return;
6756
+ }
6757
+ if (reply.kind === 'revise') {
6758
+ this.agenticAuthoringEditingMessageId.set(null);
6759
+ this.agenticAuthoringQuickReplies.set([]);
6760
+ this.agenticAuthoringStatus.set(this.tx('agentic.status.waitingRevision', 'Refine your prompt and preview again.'));
6761
+ return;
6762
+ }
6763
+ this.agenticAuthoringEditingMessageId.set(null);
6764
+ this.agenticAuthoringPrompt.set(reply.prompt);
6765
+ await this.previewAgenticAuthoring();
6766
+ }
6767
+ attachAgenticContext() {
6768
+ const controller = this.ensureAgenticTurnController();
6769
+ const pageSnapshot = JSON.stringify(this.currentPage());
6770
+ controller.addAttachment({
6771
+ id: `current-page-${Date.now()}`,
6772
+ name: this.tx('agentic.attachments.currentPage', 'Current page'),
6773
+ kind: 'json',
6774
+ mimeType: 'application/json',
6775
+ sizeBytes: pageSnapshot.length,
6776
+ status: 'ready',
6777
+ });
6778
+ this.applyAgenticTurnState(controller.snapshot());
6779
+ }
6780
+ addAgenticAttachments(attachments) {
6781
+ if (!attachments.length)
6782
+ return;
6783
+ const controller = this.ensureAgenticTurnController();
6784
+ for (const attachment of attachments) {
6785
+ controller.addAttachment(attachment);
6786
+ }
6787
+ this.applyAgenticTurnState(controller.snapshot());
6788
+ }
6789
+ removeAgenticAttachment(attachment) {
6790
+ const controller = this.ensureAgenticTurnController();
6791
+ controller.removeAttachment(attachment.id);
6792
+ this.applyAgenticTurnState(controller.snapshot());
6793
+ }
6794
+ editAgenticMessage(message) {
6795
+ if (message.role !== 'user')
6796
+ return;
6797
+ this.agenticAuthoringEditingMessageId.set(message.id);
6798
+ this.agenticAuthoringPrompt.set(message.text);
6799
+ this.agenticAuthoringStatus.set(this.tx('agentic.status.waitingRevision', 'Refine your prompt and preview again.'));
6800
+ }
6801
+ async resendAgenticMessage(message) {
6802
+ if (message.role !== 'user' || this.agenticAuthoringBusy())
6803
+ return;
6804
+ this.agenticAuthoringEditingMessageId.set(null);
6805
+ this.agenticAuthoringBusy.set(true);
6806
+ this.agenticAuthoringStatus.set(this.tx('agentic.status.resolvingIntent', 'Resolving intent...'));
6807
+ this.agenticAuthoringError.set('');
6808
+ this.agenticAuthoringPreviewResult.set(null);
6809
+ try {
6810
+ const state = await firstValueFrom(this.ensureAgenticTurnController().resendMessage(message.id));
6811
+ this.applyAgenticTurnState(state);
6812
+ }
6813
+ catch (error) {
6814
+ this.agenticAuthoringStatus.set('');
6815
+ const errorMessage = this.describeAgenticError(error);
6816
+ this.agenticAuthoringError.set(errorMessage);
6817
+ this.appendAgenticMessage('error', errorMessage);
6818
+ }
6819
+ finally {
6820
+ this.agenticAuthoringBusy.set(false);
6821
+ }
6822
+ }
6823
+ async persistAgenticAuthoring() {
6824
+ const preview = this.agenticAuthoringPreviewResult();
6825
+ if (!preview || this.agenticAuthoringBusy())
6826
+ return;
6827
+ const componentId = this.resolveAgenticComponentId();
6828
+ if (!componentId) {
6829
+ this.agenticAuthoringError.set(this.tx('agentic.errors.componentId', 'Configure a component id before saving.'));
6830
+ return;
6831
+ }
6832
+ this.agenticAuthoringBusy.set(true);
6833
+ this.agenticAuthoringError.set('');
6834
+ this.agenticAuthoringStatus.set(this.tx('agentic.status.saving', 'Saving page...'));
6835
+ try {
6836
+ const compiledFormPatch = this.resolvePreviewCompiledFormPatch(preview);
6837
+ const result = await firstValueFrom(this.agenticAuthoring.applyPage({
6838
+ compiledFormPatch,
6839
+ componentId,
6840
+ scope: this.agenticAuthoringScope,
6841
+ ifMatch: this.agenticAuthoringEtag || this.agenticAuthoringLastEtag() || undefined,
6842
+ tags: {
6843
+ source: 'page-builder-agentic-authoring',
6844
+ },
6845
+ }));
6846
+ this.agenticAuthoringLastEtag.set(result.etag ?? null);
6847
+ this.agenticAuthoringApplied.emit(result);
6848
+ this.agenticAuthoringStatus.set(this.tx('agentic.status.saved', 'Page saved.'));
6849
+ }
6850
+ catch (error) {
6851
+ this.agenticAuthoringStatus.set('');
6852
+ this.agenticAuthoringError.set(this.describeAgenticError(error));
6853
+ }
6854
+ finally {
6855
+ this.agenticAuthoringBusy.set(false);
6856
+ }
6857
+ }
6858
+ async loadAgenticComponentCapabilities() {
6859
+ if (this.agenticComponentCapabilities) {
6860
+ return this.agenticComponentCapabilities;
6861
+ }
6862
+ this.agenticComponentCapabilitiesPromise ??= firstValueFrom(this.agenticAuthoring.getComponentCapabilities()).then((result) => {
6863
+ this.agenticComponentCapabilities = result;
6864
+ return result;
6865
+ }).finally(() => {
6866
+ this.agenticComponentCapabilitiesPromise = undefined;
6867
+ });
6868
+ return this.agenticComponentCapabilitiesPromise;
6869
+ }
6870
+ ensureAgenticTurnController() {
6871
+ if (!this.agenticTurnController) {
6872
+ const flow = new PageBuilderAgenticAuthoringTurnFlow(this.agenticAuthoring, {
6873
+ targetApp: 'praxis-ui-angular',
6874
+ targetComponentId: 'praxis-dynamic-page-builder',
6875
+ currentPage: () => this.currentPage(),
6876
+ selectedWidgetKey: () => this.resolveSelectedWidgetKey(),
6877
+ provider: () => this.agenticAuthoringProvider,
6878
+ model: () => this.agenticAuthoringModel,
6879
+ apiKey: () => this.agenticAuthoringApiKey,
6880
+ loadComponentCapabilities: () => this.loadAgenticComponentCapabilities(),
6881
+ applyLocalPreview: (result) => this.applyAgenticPreviewLocally(result),
6882
+ describePreviewFailure: (result) => this.describeAgenticPreviewFailure(result),
6883
+ describePreviewStatus: (result) => this.describeAgenticPreviewStatus(result),
6884
+ describeError: (error) => this.describeAgenticError(error),
6885
+ tx: (key, fallback) => this.tx(key, fallback),
6886
+ });
6887
+ this.agenticTurnController = this.agenticTurnOrchestrator.createController(flow, {
6888
+ componentId: 'praxis-dynamic-page-builder',
6889
+ componentType: 'page-builder',
6890
+ contextItems: this.agenticAuthoringContextItems(),
6891
+ attachments: this.agenticAuthoringAttachments(),
6892
+ });
6893
+ }
6894
+ this.agenticTurnController.setContextItems(this.agenticAuthoringContextItems());
6895
+ this.agenticTurnController.setMessages(this.agenticAuthoringConversation());
6896
+ this.agenticTurnController.setAttachments(this.agenticAuthoringAttachments());
6897
+ return this.agenticTurnController;
6898
+ }
6899
+ async applyAgenticPreviewLocally(result) {
6900
+ const adapter = new PageBuilderAiAdapter(this.createAdapterHost(), this.componentMetadata);
6901
+ return result.uiCompositionPlan
6902
+ ? adapter.applyUiCompositionPlan(result.uiCompositionPlan)
6903
+ : adapter.applyCompiledFormPatch(result.compiledFormPatch);
6904
+ }
6905
+ applyAgenticTurnState(state) {
6906
+ this.agenticAuthoringConversation.set(state.messages);
6907
+ this.agenticAuthoringQuickReplies.set(state.quickReplies);
6908
+ this.agenticAuthoringStatus.set(state.statusText);
6909
+ this.agenticAuthoringError.set(state.errorText);
6910
+ this.agenticAuthoringPreviewResult.set(state.preview ?? null);
6911
+ this.agenticAuthoringAttachments.set(state.attachments);
6912
+ }
6913
+ resolvePreviewCompiledFormPatch(preview) {
6914
+ if (preview.uiCompositionPlan) {
6915
+ return {
6916
+ ...preview.compiledFormPatch,
6917
+ patch: {
6918
+ ...(preview.compiledFormPatch?.patch ?? {}),
6919
+ page: this.clonePage(this.currentPage()),
6920
+ },
6921
+ };
6922
+ }
6923
+ if (preview.compiledFormPatch?.patch?.page) {
6924
+ return preview.compiledFormPatch;
6925
+ }
6926
+ return preview.compiledFormPatch;
6927
+ }
5412
6928
  focusCanvasWidget(widgetKey) {
5413
6929
  if (!widgetKey)
5414
6930
  return;
@@ -5440,6 +6956,83 @@ class DynamicPageBuilderComponent {
5440
6956
  }
5441
6957
  return inputs;
5442
6958
  }
6959
+ resolveAgenticComponentId() {
6960
+ const explicit = this.agenticAuthoringComponentId?.trim();
6961
+ if (explicit)
6962
+ return explicit;
6963
+ const routePath = this.pageIdentity?.routePath?.trim();
6964
+ if (routePath)
6965
+ return `page:${routePath}`;
6966
+ return null;
6967
+ }
6968
+ resolveSelectedWidgetKey() {
6969
+ const runtime = this.runtime;
6970
+ if (!runtime)
6971
+ return null;
6972
+ for (const widget of this.currentPage().widgets ?? []) {
6973
+ if (widget?.key && runtime.isCanvasWidgetSelected(widget.key)) {
6974
+ return widget.key;
6975
+ }
6976
+ }
6977
+ return null;
6978
+ }
6979
+ formatAgenticFailures(failureCodes) {
6980
+ const codes = (failureCodes ?? []).filter((code) => !!code);
6981
+ if (codes.length === 0) {
6982
+ return this.tx('agentic.errors.invalidPreview', 'Generated preview is invalid.');
6983
+ }
6984
+ return `${this.tx('agentic.errors.invalidPreview', 'Generated preview is invalid.')}: ${codes.join(', ')}`;
6985
+ }
6986
+ describeAgenticPreviewFailure(result) {
6987
+ switch (result.diagnostics?.fieldScopeDecision) {
6988
+ case 'rejected-duplicate-field':
6989
+ return this.tx('agentic.errors.duplicateField', 'This field already exists in the selected form.');
6990
+ case 'rejected-non-local-field-removal':
6991
+ return this.tx('agentic.errors.nonLocalFieldRemoval', 'Only local fields created by AI can be removed in this flow.');
6992
+ default:
6993
+ return this.formatAgenticFailures(result.failureCodes);
6994
+ }
6995
+ }
6996
+ describeAgenticPreviewStatus(result) {
6997
+ switch (result.diagnostics?.fieldScopeDecision) {
6998
+ case 'accepted-add-local-field':
6999
+ return this.tx('agentic.status.acceptedAddLocalField', 'Local field added to the form.');
7000
+ case 'accepted-remove-local-field':
7001
+ return this.tx('agentic.status.acceptedRemoveLocalField', 'Local field removed from the form.');
7002
+ case 'accepted-relabel-server-backed-field':
7003
+ return this.tx('agentic.status.acceptedRelabelField', 'Field label updated.');
7004
+ default:
7005
+ return this.tx('agentic.status.previewReady', 'Preview applied to the page.');
7006
+ }
7007
+ }
7008
+ appendAgenticMessage(role, text) {
7009
+ const normalized = text.trim();
7010
+ if (!normalized)
7011
+ return;
7012
+ this.agenticAuthoringConversation.update((messages) => [
7013
+ ...messages,
7014
+ {
7015
+ id: `${Date.now()}-${messages.length}-${role}`,
7016
+ role,
7017
+ text: normalized,
7018
+ },
7019
+ ]);
7020
+ }
7021
+ describeAgenticError(error) {
7022
+ if (typeof error?.error?.message === 'string' && error.error.message.trim()) {
7023
+ return error.error.message.trim();
7024
+ }
7025
+ if (typeof error?.error === 'string' && error.error.trim()) {
7026
+ return error.error.trim();
7027
+ }
7028
+ if (typeof error?.message === 'string' && error.message.trim()) {
7029
+ return error.message.trim();
7030
+ }
7031
+ if (typeof error?.status === 'number') {
7032
+ return `HTTP ${error.status}`;
7033
+ }
7034
+ return this.tx('agentic.errors.generic', 'AI authoring failed.');
7035
+ }
5443
7036
  cloneValue(value) {
5444
7037
  if (value == null || typeof value !== 'object') {
5445
7038
  return value;
@@ -5450,7 +7043,7 @@ class DynamicPageBuilderComponent {
5450
7043
  return resolvePraxisPageBuilderText(this.i18n, key, fallback);
5451
7044
  }
5452
7045
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicPageBuilderComponent, deps: [{ token: i1.MatDialog }, { token: SETTINGS_PANEL_BRIDGE, optional: true }], target: i0.ɵɵFactoryTarget.Component });
5453
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: DynamicPageBuilderComponent, isStandalone: true, selector: "praxis-dynamic-page-builder", inputs: { page: "page", context: "context", strictValidation: "strictValidation", enableCustomization: "enableCustomization", showSettingsButton: "showSettingsButton", pageIdentity: "pageIdentity", componentInstanceId: "componentInstanceId", pageEditorComponent: "pageEditorComponent" }, outputs: { pageChange: "pageChange" }, providers: [
7046
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", 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" }, outputs: { pageChange: "pageChange", agenticAuthoringApplied: "agenticAuthoringApplied" }, providers: [
5454
7047
  providePraxisPageBuilderI18n(),
5455
7048
  { provide: DYNAMIC_PAGE_SHELL_EDITOR, useValue: WidgetShellEditorComponent },
5456
7049
  ], viewQueries: [{ propertyName: "runtime", first: true, predicate: ["runtime"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
@@ -5460,6 +7053,7 @@ class DynamicPageBuilderComponent {
5460
7053
  [page]="currentPage()"
5461
7054
  [context]="context"
5462
7055
  [strictValidation]="strictValidation"
7056
+ [autoPersist]="autoPersist"
5463
7057
  [enableCustomization]="showSettings()"
5464
7058
  [showPageSettingsButton]="false"
5465
7059
  [pageIdentity]="pageIdentity"
@@ -5475,6 +7069,44 @@ class DynamicPageBuilderComponent {
5475
7069
  (openPageSettings)="openPageSettings()"
5476
7070
  />
5477
7071
 
7072
+ <praxis-ai-assistant-shell
7073
+ *ngIf="showSettings() && enableAgenticAuthoring && agenticAuthoringOpen()"
7074
+ panelTestId="page-builder-agentic-authoring-panel"
7075
+ testIdPrefix="page-builder-agentic"
7076
+ submitTestId="page-builder-agentic-preview"
7077
+ applyTestId="page-builder-agentic-persist"
7078
+ [labels]="agenticAuthoringShellLabels()"
7079
+ mode="agentic-authoring"
7080
+ [state]="agenticAuthoringShellState()"
7081
+ [contextItems]="agenticAuthoringContextItems()"
7082
+ [attachments]="agenticAuthoringAttachments()"
7083
+ [messages]="agenticAuthoringConversation()"
7084
+ [quickReplies]="agenticAuthoringQuickReplies()"
7085
+ [prompt]="agenticAuthoringPrompt()"
7086
+ [statusText]="agenticAuthoringStatus()"
7087
+ [errorText]="agenticAuthoringError()"
7088
+ [busy]="agenticAuthoringBusy()"
7089
+ [canApply]="!!agenticAuthoringPreviewResult()?.valid"
7090
+ [enableFileAttachments]="true"
7091
+ attachmentAccept="image/*,application/json,text/plain,application/pdf"
7092
+ [layout]="agenticAuthoringPanelLayout()"
7093
+ [minWidth]="320"
7094
+ [minHeight]="280"
7095
+ [margin]="8"
7096
+ (promptChange)="agenticAuthoringPrompt.set($event)"
7097
+ (submitPrompt)="agenticAuthoringPrompt.set($event); previewAgenticAuthoring()"
7098
+ (apply)="persistAgenticAuthoring()"
7099
+ (quickReply)="submitAgenticQuickReply($event)"
7100
+ (attach)="attachAgenticContext()"
7101
+ (attachmentsPasted)="addAgenticAttachments($event)"
7102
+ (attachmentsSelected)="addAgenticAttachments($event)"
7103
+ (removeAttachment)="removeAgenticAttachment($event)"
7104
+ (editMessage)="editAgenticMessage($event)"
7105
+ (resendMessage)="resendAgenticMessage($event)"
7106
+ (layoutChange)="agenticAuthoringPanelLayout.set($event)"
7107
+ (close)="toggleAgenticAuthoring()"
7108
+ />
7109
+
5478
7110
  <praxis-floating-toolbar
5479
7111
  [visible]="showSettings()"
5480
7112
  [canUndo]="false"
@@ -5484,6 +7116,18 @@ class DynamicPageBuilderComponent {
5484
7116
  (save)="saveCurrentPage()"
5485
7117
  (preview)="togglePreview()"
5486
7118
  >
7119
+ <button
7120
+ *ngIf="enableAgenticAuthoring"
7121
+ pdx-toolbar-extra
7122
+ mat-mini-fab
7123
+ type="button"
7124
+ [attr.data-testid]="'page-builder-agentic-toggle'"
7125
+ [matTooltip]="tx('agentic.toggle', 'Create with AI')"
7126
+ [attr.aria-label]="tx('agentic.toggle', 'Create with AI')"
7127
+ (click)="toggleAgenticAuthoring()"
7128
+ >
7129
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
7130
+ </button>
5487
7131
  <button
5488
7132
  pdx-toolbar-extra
5489
7133
  mat-mini-fab
@@ -5497,7 +7141,7 @@ class DynamicPageBuilderComponent {
5497
7141
  </button>
5498
7142
  </praxis-floating-toolbar>
5499
7143
  </div>
5500
- `, isInline: true, styles: [":host,.builder-shell{display:block;position:relative;min-height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.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"], outputs: ["pageChange", "widgetDiagnosticsChange"] }, { kind: "component", type: FloatingToolbarComponent, selector: "praxis-floating-toolbar", inputs: ["visible", "canUndo", "canRedo"], outputs: ["add", "undo", "redo", "settings", "preview", "save"] }, { kind: "component", type: ConnectionsViewerPanelComponent, selector: "praxis-connections-viewer-panel", inputs: ["open", "page"], outputs: ["focusWidget", "openPageSettings"] }] });
7144
+ `, 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%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: i4.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"], outputs: ["pageChange", "widgetEvent", "widgetDiagnosticsChange"] }, { kind: "component", type: FloatingToolbarComponent, selector: "praxis-floating-toolbar", inputs: ["visible", "canUndo", "canRedo"], outputs: ["add", "undo", "redo", "settings", "preview", "save"] }, { kind: "component", type: ConnectionsViewerPanelComponent, selector: "praxis-connections-viewer-panel", inputs: ["open", "page"], outputs: ["focusWidget", "openPageSettings"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "busy", "canSubmit", "canApply", "submitOnEnter", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "layoutChange"] }] });
5501
7145
  }
5502
7146
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicPageBuilderComponent, decorators: [{
5503
7147
  type: Component,
@@ -5510,6 +7154,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
5510
7154
  DynamicWidgetPageComponent,
5511
7155
  FloatingToolbarComponent,
5512
7156
  ConnectionsViewerPanelComponent,
7157
+ PraxisAiAssistantShellComponent,
5513
7158
  ], providers: [
5514
7159
  providePraxisPageBuilderI18n(),
5515
7160
  { provide: DYNAMIC_PAGE_SHELL_EDITOR, useValue: WidgetShellEditorComponent },
@@ -5520,6 +7165,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
5520
7165
  [page]="currentPage()"
5521
7166
  [context]="context"
5522
7167
  [strictValidation]="strictValidation"
7168
+ [autoPersist]="autoPersist"
5523
7169
  [enableCustomization]="showSettings()"
5524
7170
  [showPageSettingsButton]="false"
5525
7171
  [pageIdentity]="pageIdentity"
@@ -5535,6 +7181,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
5535
7181
  (openPageSettings)="openPageSettings()"
5536
7182
  />
5537
7183
 
7184
+ <praxis-ai-assistant-shell
7185
+ *ngIf="showSettings() && enableAgenticAuthoring && agenticAuthoringOpen()"
7186
+ panelTestId="page-builder-agentic-authoring-panel"
7187
+ testIdPrefix="page-builder-agentic"
7188
+ submitTestId="page-builder-agentic-preview"
7189
+ applyTestId="page-builder-agentic-persist"
7190
+ [labels]="agenticAuthoringShellLabels()"
7191
+ mode="agentic-authoring"
7192
+ [state]="agenticAuthoringShellState()"
7193
+ [contextItems]="agenticAuthoringContextItems()"
7194
+ [attachments]="agenticAuthoringAttachments()"
7195
+ [messages]="agenticAuthoringConversation()"
7196
+ [quickReplies]="agenticAuthoringQuickReplies()"
7197
+ [prompt]="agenticAuthoringPrompt()"
7198
+ [statusText]="agenticAuthoringStatus()"
7199
+ [errorText]="agenticAuthoringError()"
7200
+ [busy]="agenticAuthoringBusy()"
7201
+ [canApply]="!!agenticAuthoringPreviewResult()?.valid"
7202
+ [enableFileAttachments]="true"
7203
+ attachmentAccept="image/*,application/json,text/plain,application/pdf"
7204
+ [layout]="agenticAuthoringPanelLayout()"
7205
+ [minWidth]="320"
7206
+ [minHeight]="280"
7207
+ [margin]="8"
7208
+ (promptChange)="agenticAuthoringPrompt.set($event)"
7209
+ (submitPrompt)="agenticAuthoringPrompt.set($event); previewAgenticAuthoring()"
7210
+ (apply)="persistAgenticAuthoring()"
7211
+ (quickReply)="submitAgenticQuickReply($event)"
7212
+ (attach)="attachAgenticContext()"
7213
+ (attachmentsPasted)="addAgenticAttachments($event)"
7214
+ (attachmentsSelected)="addAgenticAttachments($event)"
7215
+ (removeAttachment)="removeAgenticAttachment($event)"
7216
+ (editMessage)="editAgenticMessage($event)"
7217
+ (resendMessage)="resendAgenticMessage($event)"
7218
+ (layoutChange)="agenticAuthoringPanelLayout.set($event)"
7219
+ (close)="toggleAgenticAuthoring()"
7220
+ />
7221
+
5538
7222
  <praxis-floating-toolbar
5539
7223
  [visible]="showSettings()"
5540
7224
  [canUndo]="false"
@@ -5544,6 +7228,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
5544
7228
  (save)="saveCurrentPage()"
5545
7229
  (preview)="togglePreview()"
5546
7230
  >
7231
+ <button
7232
+ *ngIf="enableAgenticAuthoring"
7233
+ pdx-toolbar-extra
7234
+ mat-mini-fab
7235
+ type="button"
7236
+ [attr.data-testid]="'page-builder-agentic-toggle'"
7237
+ [matTooltip]="tx('agentic.toggle', 'Create with AI')"
7238
+ [attr.aria-label]="tx('agentic.toggle', 'Create with AI')"
7239
+ (click)="toggleAgenticAuthoring()"
7240
+ >
7241
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
7242
+ </button>
5547
7243
  <button
5548
7244
  pdx-toolbar-extra
5549
7245
  mat-mini-fab
@@ -5557,7 +7253,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
5557
7253
  </button>
5558
7254
  </praxis-floating-toolbar>
5559
7255
  </div>
5560
- `, styles: [":host,.builder-shell{display:block;position:relative;min-height:100%}\n"] }]
7256
+ `, 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%}\n"] }]
5561
7257
  }], ctorParameters: () => [{ type: i1.MatDialog }, { type: undefined, decorators: [{
5562
7258
  type: Optional
5563
7259
  }, {
@@ -5572,6 +7268,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
5572
7268
  type: Input
5573
7269
  }], strictValidation: [{
5574
7270
  type: Input
7271
+ }], autoPersist: [{
7272
+ type: Input
5575
7273
  }], enableCustomization: [{
5576
7274
  type: Input
5577
7275
  }], showSettingsButton: [{
@@ -5582,8 +7280,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
5582
7280
  type: Input
5583
7281
  }], pageEditorComponent: [{
5584
7282
  type: Input
7283
+ }], enableAgenticAuthoring: [{
7284
+ type: Input
7285
+ }], agenticAuthoringProvider: [{
7286
+ type: Input
7287
+ }], agenticAuthoringModel: [{
7288
+ type: Input
7289
+ }], agenticAuthoringApiKey: [{
7290
+ type: Input
7291
+ }], agenticAuthoringComponentId: [{
7292
+ type: Input
7293
+ }], agenticAuthoringScope: [{
7294
+ type: Input
7295
+ }], agenticAuthoringEtag: [{
7296
+ type: Input
5585
7297
  }], pageChange: [{
5586
7298
  type: Output
7299
+ }], agenticAuthoringApplied: [{
7300
+ type: Output
5587
7301
  }] } });
5588
7302
 
5589
7303
  /*
@@ -5595,4 +7309,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
5595
7309
  * Generated bundle index. Do not edit.
5596
7310
  */
5597
7311
 
5598
- export { ComponentPaletteDialogComponent, ConfirmDialogComponent, DynamicPageBuilderComponent, DynamicPageConfigEditorComponent, FloatingToolbarComponent, PAGE_BUILDER_AI_CAPABILITIES, PAGE_BUILDER_WIDGET_AI_CATALOGS, PLACEHOLDER, PageConfigEditorComponent, TileToolbarComponent, WidgetShellEditorComponent, clearWidgetAiCatalogs, getPageAiCatalog, getWidgetAiCapabilities, providePageBuilderWidgetAiCatalogs, registerWidgetAiCatalog, registerWidgetAiCatalogs };
7312
+ export { ComponentPaletteDialogComponent, ConfirmDialogComponent, DynamicPageBuilderComponent, DynamicPageConfigEditorComponent, FloatingToolbarComponent, PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS, PAGE_BUILDER_AI_CAPABILITIES, PAGE_BUILDER_WIDGET_AI_CATALOGS, PLACEHOLDER, PageBuilderAgenticAuthoringService, PageConfigEditorComponent, TileToolbarComponent, WidgetShellEditorComponent, clearWidgetAiCatalogs, getPageAiCatalog, getWidgetAiCapabilities, providePageBuilderWidgetAiCatalogs, registerWidgetAiCatalog, registerWidgetAiCatalogs };