@praxisui/page-builder 9.0.0-beta.0 → 9.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.
- package/README.md +137 -375
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,197 +1,118 @@
|
|
|
1
1
|
# @praxisui/page-builder
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Visual page and dashboard builder for Praxis UI applications.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Use this package when an application must let users compose governed operational pages from registered widgets, visual layout, shell settings, component editors, `composition.links`, and optional AI-assisted authoring.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- Aplicacao de referencia: https://github.com/codexrodrigues/praxis-ui-quickstart
|
|
9
|
-
- Indicado para: times que precisam criar paginas operacionais, dashboards e fluxos master-detail sem transformar cada variacao em uma nova tela Angular
|
|
7
|
+
## Official Links
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
- Documentation: https://praxisui.dev/docs/components
|
|
10
|
+
- Live demo: https://praxis-ui-4e602.web.app
|
|
11
|
+
- Quickstart app: https://github.com/codexrodrigues/praxis-ui-quickstart
|
|
12
|
+
- Source: https://github.com/codexrodrigues/praxis-ui-angular/tree/main/projects/praxis-page-builder
|
|
13
|
+
- Issues: https://github.com/codexrodrigues/praxis-ui-angular/issues
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
- Entregar experiencia de configuracao de pagina/widget com editor visual canonico de conexoes
|
|
15
|
-
- Integrar page composition com IA, settings panel e contratos compartilhados do Praxis UI
|
|
16
|
-
|
|
17
|
-
O pacote permanece focado no shell canonico de authoring em torno de `praxis-dynamic-page`: palette, page settings, widget shell, catalogos de IA e edicao visual de `composition.links`. A fonte de verdade da pagina continua sendo o contrato `WidgetPageDefinition` do `@praxisui/core`; o editor visual materializa esse contrato canonico sem virar uma segunda fonte de regra de negocio.
|
|
18
|
-
|
|
19
|
-
## Instalacao
|
|
15
|
+
## Install
|
|
20
16
|
|
|
21
17
|
```bash
|
|
22
|
-
npm i @praxisui/page-builder@
|
|
18
|
+
npm i @praxisui/page-builder@latest
|
|
23
19
|
```
|
|
24
20
|
|
|
25
|
-
Peer dependencies
|
|
26
|
-
- `@angular/core` `^20.0.0`
|
|
27
|
-
- `@angular/common` `^20.0.0`
|
|
28
|
-
- `@angular/forms` `^20.0.0`
|
|
29
|
-
- `@angular/cdk` `^20.0.0`
|
|
30
|
-
- `@angular/material` `^20.0.0`
|
|
31
|
-
- `@praxisui/ai` `*`
|
|
32
|
-
- `@praxisui/core` `*`
|
|
33
|
-
- `@praxisui/settings-panel` `*`
|
|
34
|
-
|
|
35
|
-
## Visao Geral
|
|
36
|
-
|
|
37
|
-
Este pacote expoe o shell ativo do builder canonico de pagina dinamica:
|
|
38
|
-
- `ComponentPaletteDialogComponent` para adicionar widgets a pagina.
|
|
39
|
-
- `FloatingToolbarComponent` para ações de página/canvas e ações contextuais do widget selecionado no runtime `praxis-dynamic-page`. Quando o widget possui `WidgetShell` com cabeçalho visível, as ações editoriais transitórias entram no próprio header do shell; quando não há header, o runtime usa uma toolbar contextual de fallback. Em ambos os casos o widget ativo fica identificado e pode abrir assistente com contexto, configuração e remoção governada sem persistir controles editoriais no `shell.actions`.
|
|
40
|
-
- `ConnectionEditorComponent` para inspecionar, criar e remover conexoes canonicas em `composition.links`.
|
|
41
|
-
- `WidgetShellEditorComponent` e `DynamicPageConfigEditorComponent` para authoring de shell/canvas sem redefinir a semantica canonica de composicao.
|
|
42
|
-
|
|
43
|
-
Conexoes continuam pertencendo ao contrato `WidgetPageDefinition`. O editor visual do Page Builder cria, remove e edita links inline preservando o envelope canonico `page.composition.links`, incluindo `condition` em Json Logic, `policy` operacional e `transform` canônico, sem introduzir modelo paralelo de grafo. O historico de desfazer/refazer do editor e transitorio: ele reemite snapshots canonicos por `pageChange`, mas nao persiste estado de historico dentro da pagina.
|
|
44
|
-
|
|
45
|
-
Cada link persistido usa `CompositionLink.id` como identidade estavel. Superficies de authoring tambem devem usar `id` ao criar ou remover links; aliases como `linkId` nao fazem parte do contrato canonico.
|
|
46
|
-
|
|
47
|
-
O roadmap tecnico para evoluir o editor radial esta registrado em [`connection-editor-reference-study.md`](./connection-editor-reference-study.md).
|
|
48
|
-
|
|
49
|
-
Nested component ports devem ser modeladas no mesmo contrato `composition.links`, usando `component-port + nestedPath`.
|
|
50
|
-
O editor representa o endpoint nested como sub-identidade do owner top-level, sem criar um no de canvas separado para o widget filho.
|
|
51
|
-
Planos de IA (`UiCompositionPlan`) tambem devem usar `nestedPath` para widgets internos; nao gere `widgetEvent`, wrappers host-specific ou `bindingPath` profundo como caminho principal para nested ports.
|
|
52
|
-
|
|
53
|
-
## AI Capabilities Registration
|
|
21
|
+
Peer dependencies:
|
|
54
22
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```ts
|
|
60
|
-
import { bootstrapApplication } from '@angular/platform-browser';
|
|
61
|
-
import { PAGE_BUILDER_WIDGET_AI_CATALOGS, providePageBuilderWidgetAiCatalogs } from '@praxisui/page-builder';
|
|
62
|
-
import { TABLE_AI_CAPABILITIES } from '@praxisui/table';
|
|
63
|
-
import { CRUD_AI_CAPABILITIES } from '@praxisui/crud';
|
|
64
|
-
import { RICH_CONTENT_AI_CAPABILITIES } from '@praxisui/rich-content';
|
|
65
|
-
import { AppComponent } from './app/app.component';
|
|
66
|
-
|
|
67
|
-
bootstrapApplication(AppComponent, {
|
|
68
|
-
providers: [
|
|
69
|
-
{
|
|
70
|
-
provide: PAGE_BUILDER_WIDGET_AI_CATALOGS,
|
|
71
|
-
useValue: {
|
|
72
|
-
'praxis-table': TABLE_AI_CAPABILITIES,
|
|
73
|
-
'praxis-crud': CRUD_AI_CAPABILITIES,
|
|
74
|
-
'praxis-rich-content': RICH_CONTENT_AI_CAPABILITIES,
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
providePageBuilderWidgetAiCatalogs(),
|
|
78
|
-
],
|
|
79
|
-
});
|
|
80
|
-
```
|
|
23
|
+
- `@angular/common`, `@angular/core`, `@angular/forms`, `@angular/cdk`, `@angular/material` `^21.0.0`
|
|
24
|
+
- `@praxisui/ai`, `@praxisui/core`, `@praxisui/settings-panel` `^9.0.0-beta.1`
|
|
25
|
+
- `rxjs` `~7.8.0`
|
|
81
26
|
|
|
82
|
-
##
|
|
83
|
-
|
|
84
|
-
O fluxo de dashboard 360 de funcionarios tem um E2E dedicado:
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
npm run e2e:page-builder-agentic-dashboard
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
O teste usa o runner agentic oficial para subir quickstart + UI e valida a rota `/page-builder-ia` com provider LLM real. Dentro do spec, apenas a persistencia inicial de `/api/praxis/config/ui` e isolada para começar com uma pagina vazia; chamadas de authoring, materializacao LLM e dados dos funcionarios continuam passando pelo backend real. O contrato coberto inclui materializacao de filtro, graficos, tabela, `composition.links` e clique em grafico filtrando a tabela.
|
|
91
|
-
|
|
92
|
-
Registro manual (util para apps que precisam customizar o mapa):
|
|
27
|
+
## Quick Start
|
|
93
28
|
|
|
94
29
|
```ts
|
|
95
|
-
import {
|
|
96
|
-
import {
|
|
97
|
-
import {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
'
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
30
|
+
import { Component } from '@angular/core';
|
|
31
|
+
import { DynamicPageBuilderComponent } from '@praxisui/page-builder';
|
|
32
|
+
import { WidgetPageDefinition } from '@praxisui/core';
|
|
33
|
+
|
|
34
|
+
@Component({
|
|
35
|
+
standalone: true,
|
|
36
|
+
selector: 'app-page-authoring',
|
|
37
|
+
imports: [DynamicPageBuilderComponent],
|
|
38
|
+
template: `
|
|
39
|
+
<praxis-dynamic-page-builder
|
|
40
|
+
[page]="page"
|
|
41
|
+
[enableCustomization]="true"
|
|
42
|
+
(pageChange)="page = $event"
|
|
43
|
+
(pageSaveRequested)="save($event)">
|
|
44
|
+
</praxis-dynamic-page-builder>
|
|
45
|
+
`,
|
|
46
|
+
})
|
|
47
|
+
export class PageAuthoringComponent {
|
|
48
|
+
page: WidgetPageDefinition = {
|
|
49
|
+
id: 'operations-dashboard',
|
|
50
|
+
title: 'Operations Dashboard',
|
|
51
|
+
widgets: [],
|
|
52
|
+
composition: { links: [] },
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
save(page: WidgetPageDefinition): void {
|
|
56
|
+
this.page = page;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
105
59
|
```
|
|
106
60
|
|
|
107
|
-
|
|
108
|
-
- Use o InjectionToken `PAGE_BUILDER_WIDGET_AI_CATALOGS` para fornecer o mapa no host.
|
|
109
|
-
|
|
110
|
-
## Agentic Authoring
|
|
111
|
-
|
|
112
|
-
Para gerar uma página a partir de um prompt usando o backend canônico do `praxis-config-starter`, configure `PageBuilderAgenticAuthoringService` com o endpoint interno opt-in `/api/praxis/config/ai/authoring`.
|
|
113
|
-
|
|
114
|
-
O chrome conversacional do assistente usa `PraxisAiAssistantShellComponent` de `@praxisui/ai`, mas a presença minimizada deve ser renderizada pelo shell da aplicação com `PraxisAiAssistantSessionHostComponent`, lendo o `PraxisAssistantSessionRegistryService`. O Page Builder apenas registra sua sessão com identidade estável e contexto `Page Builder`; a identidade pública continua sendo o copiloto semântico Praxis. O Page Builder continua dono da semântica agentic de página: resolução de intenção, preview, apply, save, reopen e compilação do plano validado para `WidgetPageDefinition`.
|
|
61
|
+
The persisted document remains `WidgetPageDefinition` from `@praxisui/core`. Page Builder edits that canonical document; it does not introduce a separate page DSL.
|
|
115
62
|
|
|
116
|
-
|
|
63
|
+
## Runtime Contract
|
|
117
64
|
|
|
118
|
-
|
|
119
|
-
as observações runtime registradas em `PraxisRuntimeComponentObservationRegistryService`
|
|
120
|
-
e as envia no request do turno com `runtimeComponentObservationTrustBoundary:
|
|
121
|
-
"untrusted_frontend_observation"`. Essas observações são evidência redigida de
|
|
122
|
-
página, widgets e superfícies relacionadas; o Page Builder não as promove a
|
|
123
|
-
capability canônica nem decide intent a partir delas.
|
|
65
|
+
`praxis-dynamic-page-builder` accepts:
|
|
124
66
|
|
|
125
|
-
|
|
67
|
+
- `page`: `WidgetPageDefinition | string`
|
|
68
|
+
- `context`: runtime context shared with widgets and composition links
|
|
69
|
+
- `enableCustomization`: enables builder affordances
|
|
70
|
+
- `pageIdentity`: persistence identity used by governed config flows
|
|
71
|
+
- `componentInstanceId`: stable component instance id
|
|
72
|
+
- `componentPaletteAllowedWidgetIds`, `componentPaletteAllowedWidgetTags`, `componentPaletteAllowedPresetIds`
|
|
73
|
+
- `enableAgenticAuthoring`, `agenticAuthoringProvider`, `agenticAuthoringModel`, `agenticAuthoringScope`
|
|
74
|
+
- `agenticAuthoringIncludeLlmDiagnostics`, `agenticAuthoringEnableStreaming`, `agenticAuthoringContextHints`
|
|
75
|
+
- `showPageLifecycleActions`, `canDeleteSavedPage`, `pageLifecycleBusy`
|
|
126
76
|
|
|
127
|
-
|
|
77
|
+
It emits:
|
|
128
78
|
|
|
129
|
-
|
|
79
|
+
- `pageChange`: updated `WidgetPageDefinition`
|
|
80
|
+
- `widgetEvent`: runtime widget event envelope
|
|
81
|
+
- `pageSaveRequested`: save intent for the current page
|
|
82
|
+
- `agenticAuthoringApplied`: AI preview/apply result
|
|
83
|
+
- `agenticAuthoringSharedRuleHandoff`: governed shared-rule continuation handoff
|
|
84
|
+
- `pageRestart`, `savedPageDeleteRequested`
|
|
130
85
|
|
|
131
|
-
|
|
86
|
+
## Composition Links
|
|
132
87
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
As fronteiras canônicas são:
|
|
136
|
-
- o documento persistido continua sendo `WidgetPageDefinition`;
|
|
137
|
-
- `UiCompositionPlan` é apenas o plano intermediário de IA e deve compilar antes do preview/apply local;
|
|
138
|
-
- wiring persistido usa `page.composition.links`, incluindo `nestedPath` para component ports internas;
|
|
139
|
-
- o Page Builder não redefine inputs de widgets filhos. Edições de `definition.inputs` devem delegar para `ComponentDocMeta.authoringManifestRef` ou `ComponentDocMeta.configEditor` publicado pela lib dona do componente;
|
|
140
|
-
- `pageIdentity` e ETag pertencem ao fluxo de persistência do `praxis-config-starter` e não entram no documento runtime da página.
|
|
88
|
+
Widget wiring is stored in `page.composition.links`.
|
|
141
89
|
|
|
142
90
|
```ts
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
domainKnowledge.transitionChangeSetStatus(changeSetId, request, options),
|
|
160
|
-
applyProjectKnowledgeChangeSet: (changeSetId, options) => domainKnowledge.applyChangeSet(changeSetId, options),
|
|
161
|
-
sharedRuleIntake: (request, options) => domainRules.intake(request, options),
|
|
162
|
-
headersFactory: () => ({
|
|
163
|
-
'X-Tenant-ID': tenantId,
|
|
164
|
-
'X-User-ID': userId,
|
|
165
|
-
'X-Env': 'local',
|
|
166
|
-
}),
|
|
167
|
-
};
|
|
168
|
-
},
|
|
91
|
+
const page: WidgetPageDefinition = {
|
|
92
|
+
id: 'tickets-dashboard',
|
|
93
|
+
title: 'Tickets Dashboard',
|
|
94
|
+
widgets: [
|
|
95
|
+
{ key: 'status-chart', type: 'praxis-chart', inputs: {} },
|
|
96
|
+
{ key: 'tickets-table', type: 'praxis-table', inputs: {} },
|
|
97
|
+
],
|
|
98
|
+
composition: {
|
|
99
|
+
links: [
|
|
100
|
+
{
|
|
101
|
+
id: 'status-chart-filters-table',
|
|
102
|
+
from: { kind: 'widget', ref: { widget: 'status-chart', event: 'selectionChange' } },
|
|
103
|
+
to: { kind: 'widget', ref: { widget: 'tickets-table', input: 'filters' } },
|
|
104
|
+
policy: { distinct: true },
|
|
105
|
+
},
|
|
106
|
+
],
|
|
169
107
|
},
|
|
170
|
-
|
|
108
|
+
};
|
|
171
109
|
```
|
|
172
110
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
- `resolveIntent` envia todo prompt de authoring, pagina atual e widget selecionado para resolver operacao, recurso, schema, surface e elegibilidade no backend canonico. O Page Builder nao deve inferir intencao, recurso ou operacao por heuristica local antes dessa chamada.
|
|
176
|
-
- `previewPage` envia o prompt junto de `intentResolution` elegivel e recebe `MinimalFormPlan` + `CompiledFormPatch`.
|
|
177
|
-
- `DomainKnowledgeService` em `@praxisui/core` e o cliente canonico para continuar propostas de Project Knowledge como change-sets governados em `/api/praxis/config/domain-knowledge/change-sets`; o Page Builder pode acionar essa trilha como cockpit, mas nao deve materializar evidencias localmente nem tratar o frontend como fonte primaria da decisao.
|
|
178
|
-
- Hosts podem habilitar `[agenticAuthoringEnableStreaming]="true"` para usar `/api/praxis/config/ai/authoring/turn/stream/**`. O Page Builder consome eventos SSE de progresso e usa o `result` terminal como a mesma fonte de preview; se o endpoint de start ainda nao estiver disponivel, o fluxo pode voltar para `resolveIntent` + `previewPage`. Depois que a conexao SSE e iniciada, erros de transporte sao tolerados por uma janela curta de reconexao e, se persistirem, sao exibidos como falha do stream em vez de disparar uma segunda execucao sincrona silenciosa.
|
|
179
|
-
- Em streaming, a conversa deve refletir estados intermediarios do turno, como resolucao de intencao, selecao de recurso, planejamento e geracao de preview. Nao trate o SSE apenas como transporte do resultado final: cada `PraxisAssistantTurnViewState` emitido precisa atualizar status, mensagens, anexos, respostas rapidas, diagnosticos e preview disponivel.
|
|
180
|
-
- Para cenarios corporativos, mantenha streaming e diagnosticos como capacidades opt-in do host. Streaming melhora feedback percebido em prompts curtos ou ambiguos; diagnosticos exibem prompt/contexto/catalogos e devem ficar restritos a auditoria, suporte ou ambientes controlados.
|
|
181
|
-
- `resolveIntent` e `previewPage` tambem aceitam `sessionId`, `clientTurnId`, `conversationMessages`, `pendingClarification` e `attachmentSummaries` para que respostas curtas e contexto anexado continuem o turno sem reescrever o prompt no frontend.
|
|
182
|
-
- `attachmentSummaries` deve conter apenas metadados serializaveis (`id`, `name`, `kind`, `mimeType`, `sizeBytes`, `source`, `hasPreview`). O frontend nao envia `File`, bytes, base64 nem URLs locais `blob:`. Quando uma pergunta de clarificacao nasce de um turno com anexos, o backend pode ecoar esses resumos em `pendingClarification.diagnostics.attachmentSummaries`; o Page Builder reenvia esse estado no proximo turno.
|
|
183
|
-
- Enquanto o contrato LLM do Page Builder for metadata-only para anexos, o shell agentic deve ocultar a acao de anexar e desabilitar anexos colados. Nao exponha seletor de arquivo ou paste de imagem como se a LLM fosse processar pixels, PDF ou conteudo binario.
|
|
184
|
-
- Quando `resolveIntent` retornar candidatos ambiguos, o Page Builder deve preservar `quickReplies` como chips clicaveis ricos. Campos como `description`, `icon`, `tone` e `contextHints` pertencem ao contrato do backend e nao devem ser recriados ou descartados no frontend.
|
|
185
|
-
- Hosts podem habilitar `[agenticAuthoringIncludeLlmDiagnostics]="true"` apenas em cenarios de auditoria/debug. O input adiciona `contextHints.includeLlmDiagnostics=true` nas chamadas `resolveIntent` e, quando o backend retorna `llmDiagnostics`, o Page Builder mostra esse JSON em um painel tecnico separado da conversa. O padrao permanece desligado para nao expor prompt/contexto operacional em fluxos comuns.
|
|
186
|
-
- Para criacao de dashboard apos escolha de recurso, `previewPage` pode retornar `uiCompositionPlan.layoutPreset=resource-dashboard`; o builder deve aplicar esse plano como preview de pagina, nao tratar o artefato como fluxo restrito a formulario.
|
|
187
|
-
- `PageBuilderAiAdapter.applyCompiledFormPatch` aplica somente `compiledFormPatch.patch.page` no runtime do builder, materializando uma cópia local antes de atualizar a página.
|
|
188
|
-
- `applyPage` persiste a página renderizável corrente após o preview local em `ui_user_config`, com `componentType`, `componentId`, `scope` e `If-Match` delegados ao backend canônico.
|
|
189
|
-
|
|
190
|
-
O frontend não deve persistir o envelope completo do patch como payload de runtime. O envelope fica para preview, auditoria e diagnóstico; o documento salvo é a página renderizável.
|
|
111
|
+
Use the same canonical `composition.links` contract for widget-to-widget links, nested component ports through `nestedPath`, and global actions through `to.kind = "global-action"`.
|
|
191
112
|
|
|
192
113
|
## Settings Panel Bridge
|
|
193
114
|
|
|
194
|
-
|
|
115
|
+
Register the Settings Panel bridge when the host must open page, shell, and component config editors in a side panel.
|
|
195
116
|
|
|
196
117
|
```ts
|
|
197
118
|
import { SETTINGS_PANEL_BRIDGE } from '@praxisui/core';
|
|
@@ -202,238 +123,79 @@ providers: [
|
|
|
202
123
|
provide: SETTINGS_PANEL_BRIDGE,
|
|
203
124
|
useExisting: SettingsPanelService,
|
|
204
125
|
},
|
|
205
|
-
]
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## Component Config Editors
|
|
209
|
-
|
|
210
|
-
O page-builder não deve implementar editores locais para os inputs de cada
|
|
211
|
-
widget. Quando um componente registra `ComponentDocMeta.configEditor`, o runtime
|
|
212
|
-
canônico (`praxis-dynamic-page`) injeta a ação "Configurar conteudo" no shell do
|
|
213
|
-
widget e abre o editor declarado pelo dono do componente.
|
|
214
|
-
|
|
215
|
-
Fluxo canônico:
|
|
216
|
-
|
|
217
|
-
- a lib dona registra `configEditor` em `ComponentMetadataRegistry`
|
|
218
|
-
- o page-builder habilita customization e fornece `SETTINGS_PANEL_BRIDGE`
|
|
219
|
-
- o editor recebe `{ inputs, widgetKey, widgetType }`
|
|
220
|
-
- `Apply` atualiza `definition.inputs` sem fechar o painel; ele não é rollback transacional e pode ser observado pelo host imediatamente
|
|
221
|
-
- `Save` atualiza `definition.inputs` e persiste a página quando houver `pageIdentity`
|
|
222
|
-
- `Reset` restaura o estado interno do editor para o snapshot aberto; ele não desfaz automaticamente um `Apply` já emitido ao runtime/host
|
|
223
|
-
|
|
224
|
-
Exemplo com `praxis-rich-content`: o editor canônico é
|
|
225
|
-
`PraxisRichContentConfigEditor`, publicado por `@praxisui/rich-content`. Ele
|
|
226
|
-
edita `definition.inputs.document`, `layout` e `rootClassName` sem criar uma DSL
|
|
227
|
-
local de page-builder para blocos ricos.
|
|
228
|
-
|
|
229
|
-
Exemplo com `praxis-chart`: o editor canônico publicado por
|
|
230
|
-
`@praxisui/charts` usa um adaptador de widget sobre `PraxisChartConfigEditor`.
|
|
231
|
-
O editor de domínio continua editando `PraxisXUiChartContract`; o adaptador
|
|
232
|
-
devolve `{ inputs: { ...chartInputs, chartDocument } }` para que o runtime
|
|
233
|
-
atualize `definition.inputs` sem lógica específica de chart no Page Builder.
|
|
234
|
-
|
|
235
|
-
Exemplo com `praxis-table`: o editor canônico publicado por `@praxisui/table`
|
|
236
|
-
usa um adaptador de widget sobre `PraxisTableConfigEditor`. O editor de domínio
|
|
237
|
-
continua editando `TableAuthoringDocument`; o adaptador devolve
|
|
238
|
-
`{ inputs: { ...tableInputs, config, resourcePath, horizontalScroll } }`,
|
|
239
|
-
preservando `tableId` e `componentInstanceId` enquanto publica apenas inputs
|
|
240
|
-
declarados pelo contrato público da tabela.
|
|
241
|
-
|
|
242
|
-
Exemplo com `praxis-dynamic-form`: o editor canônico publicado por
|
|
243
|
-
`@praxisui/dynamic-form` usa um adaptador de widget sobre
|
|
244
|
-
`PraxisDynamicFormConfigEditor`. O editor de domínio continua editando
|
|
245
|
-
`DynamicFormAuthoringDocument`; o adaptador devolve
|
|
246
|
-
`{ inputs: { ...formInputs, config, mode, formId, componentInstanceId } }` e
|
|
247
|
-
projeta preferências públicas como `backConfig`, `notifyIfOutdated`, `snoozeMs`
|
|
248
|
-
e `autoOpenSettingsOnOutdated`. O Page Builder não interpreta campos, regras ou
|
|
249
|
-
seções do formulário.
|
|
250
|
-
|
|
251
|
-
Exemplo com `praxis-filter-form`: o editor canônico publicado por
|
|
252
|
-
`@praxisui/dynamic-form` também usa `PraxisDynamicFormConfigEditor`, mas por um
|
|
253
|
-
adaptador próprio de widget. O filtro consome o mesmo contrato `FormConfig`,
|
|
254
|
-
enquanto o adaptador devolve somente os inputs públicos do filtro:
|
|
255
|
-
`{ inputs: { ...filterInputs, config, formId, resourcePath, mode } }`.
|
|
256
|
-
|
|
257
|
-
Exemplo com `praxis-files-upload`: o editor canônico publicado por
|
|
258
|
-
`@praxisui/files-upload` usa um adaptador de widget sobre
|
|
259
|
-
`PraxisFilesUploadConfigEditor`. O editor de domínio continua editando
|
|
260
|
-
`FilesUploadConfig`; o adaptador devolve
|
|
261
|
-
`{ inputs: { ...uploadInputs, config, filesUploadId, componentInstanceId } }`
|
|
262
|
-
e preserva bindings públicos como `baseUrl`, `displayMode`, `context` e
|
|
263
|
-
`enableCustomization`. O Page Builder não interpreta estratégia, limites,
|
|
264
|
-
opções de backend, quotas ou rate-limit.
|
|
265
|
-
|
|
266
|
-
Exemplo com `praxis-crud`: o editor canônico publicado por `@praxisui/crud`
|
|
267
|
-
usa um adaptador de widget sobre `CrudMetadataEditorComponent`. O editor de
|
|
268
|
-
domínio continua editando `CrudAuthoringDocument`/`CrudMetadata`; o adaptador
|
|
269
|
-
devolve `{ inputs: { ...crudInputs, metadata, crudId, componentInstanceId } }`
|
|
270
|
-
e preserva `context` e `enableCustomization`. O Page Builder não interpreta
|
|
271
|
-
resource binding, tabela interna, open modes, ações ou defaults de
|
|
272
|
-
modal/drawer.
|
|
273
|
-
|
|
274
|
-
Exemplo com `praxis-list`: o editor canônico publicado por `@praxisui/list`
|
|
275
|
-
usa um adaptador de widget sobre `PraxisListConfigEditor`. O editor de domínio
|
|
276
|
-
continua editando `PraxisListConfig`; o adaptador devolve
|
|
277
|
-
`{ inputs: { ...listInputs, config } }`, preservando `listId` e demais inputs
|
|
278
|
-
do widget.
|
|
279
|
-
|
|
280
|
-
Exemplo com `praxis-expansion`: o editor canônico publicado por
|
|
281
|
-
`@praxisui/expansion` usa um adaptador de widget sobre
|
|
282
|
-
`PraxisExpansionConfigEditor`. O editor de domínio continua editando
|
|
283
|
-
`ExpansionMetadata`; o adaptador devolve
|
|
284
|
-
`{ inputs: { ...expansionInputs, config } }`, preservando `expansionId` e demais
|
|
285
|
-
inputs do widget. Para widgets recém-inseridos sem `config` inicial, o adaptador
|
|
286
|
-
mantém um fallback estável para não sobrescrever edições durante change
|
|
287
|
-
detection.
|
|
288
|
-
|
|
289
|
-
Exemplo com `praxis-tabs`: o editor canônico publicado por `@praxisui/tabs`
|
|
290
|
-
usa um adaptador de widget sobre `PraxisTabsConfigEditor`. O editor de domínio
|
|
291
|
-
continua editando `TabsAuthoringDocument`; o adaptador devolve
|
|
292
|
-
`{ inputs: { ...tabsInputs, config, tabsId } }`, preservando bindings como
|
|
293
|
-
`tabsId` e `componentInstanceId` enquanto publica apenas os inputs consumidos
|
|
294
|
-
pelo runtime.
|
|
295
|
-
|
|
296
|
-
Exemplo com `praxis-stepper`: o editor canônico publicado por
|
|
297
|
-
`@praxisui/stepper` usa um adaptador de widget sobre
|
|
298
|
-
`PraxisStepperConfigEditor`. O editor de domínio continua editando
|
|
299
|
-
`StepperMetadata`; o adaptador devolve
|
|
300
|
-
`{ inputs: { ...stepperInputs, config, stepperId, selectedIndex } }`. Sub-editores
|
|
301
|
-
internos de form/list/upload continuam pertencendo ao editor do stepper. Eles
|
|
302
|
-
devem abrir em host aninhado próprio do `@praxisui/stepper`, mantendo o editor
|
|
303
|
-
pai montado; o Page Builder apenas hospeda o editor publicado pela metadata.
|
|
304
|
-
No fluxo de inclusão, `Apply` e `Save` do sub-editor devem atualizar o mesmo
|
|
305
|
-
widget filho pendente, evitando duplicação de lista/upload dentro do step.
|
|
306
|
-
|
|
307
|
-
## Child AI Authoring Manifests
|
|
308
|
-
|
|
309
|
-
Componentes que suportam edições governadas por IA devem publicar
|
|
310
|
-
`ComponentDocMeta.authoringManifestRef` na própria lib dona. O Page Builder usa
|
|
311
|
-
esse sinal apenas para discovery, readiness e delegação; ele não recompila nem
|
|
312
|
-
redeclara operações internas do componente filho.
|
|
313
|
-
|
|
314
|
-
Exemplos já publicados pelo catálogo de componentes:
|
|
315
|
-
- `praxis-table` -> `PRAXIS_TABLE_AUTHORING_MANIFEST`
|
|
316
|
-
- `praxis-list` -> `PRAXIS_LIST_AUTHORING_MANIFEST`
|
|
317
|
-
- `praxis-dynamic-form` -> `PRAXIS_DYNAMIC_FORM_AUTHORING_MANIFEST`
|
|
318
|
-
- `praxis-tabs` -> `PRAXIS_TABS_AUTHORING_MANIFEST`
|
|
319
|
-
- `praxis-stepper` -> `PRAXIS_STEPPER_AUTHORING_MANIFEST`
|
|
320
|
-
- `praxis-expansion` -> `PRAXIS_EXPANSION_AUTHORING_MANIFEST`
|
|
321
|
-
|
|
322
|
-
Catalogos conhecidos (exports):
|
|
323
|
-
- `TABLE_AI_CAPABILITIES` - `@praxisui/table` (`praxis-table`)
|
|
324
|
-
- `CRUD_AI_CAPABILITIES` - `@praxisui/crud` (`praxis-crud`)
|
|
325
|
-
- `LIST_AI_CAPABILITIES` - `@praxisui/list` (`praxis-list`)
|
|
326
|
-
- `RICH_CONTENT_AI_CAPABILITIES` - `@praxisui/rich-content` (`praxis-rich-content`)
|
|
327
|
-
- `FORM_AI_CAPABILITIES` - `@praxisui/dynamic-form` (`praxis-dynamic-form`)
|
|
328
|
-
- `FILES_UPLOAD_AI_CAPABILITIES` - `@praxisui/files-upload` (`praxis-files-upload`)
|
|
329
|
-
- `STEPPER_AI_CAPABILITIES` - `@praxisui/stepper` (`praxis-stepper`)
|
|
330
|
-
- `TABS_AI_CAPABILITIES` - `@praxisui/tabs` (`praxis-tabs`)
|
|
331
|
-
- `EXPANSION_AI_CAPABILITIES` - `@praxisui/expansion` (`praxis-expansion`)
|
|
332
|
-
|
|
333
|
-
## Quick Start
|
|
334
|
-
|
|
335
|
-
O builder canonico expoe authoring de shell/palette sobre `praxis-dynamic-page`. Exemplo de uso no template:
|
|
336
|
-
|
|
337
|
-
```html
|
|
338
|
-
<praxis-dynamic-page-builder
|
|
339
|
-
#page
|
|
340
|
-
[page]="page"
|
|
341
|
-
[enableCustomization]="true"
|
|
342
|
-
(pageChange)="onPageChange($event)">
|
|
343
|
-
</praxis-dynamic-page-builder>
|
|
126
|
+
];
|
|
344
127
|
```
|
|
345
128
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
Links para acoes globais tambem pertencem a `composition.links`: use
|
|
349
|
-
`composition.links[].to.kind = "global-action"` com `to.ref.actionId` e, quando necessario,
|
|
350
|
-
`to.ref.payload`, `to.ref.payloadExpr` ou `to.ref.meta`. O Page Builder nao cria executor universal
|
|
351
|
-
nem campos paralelos de comando; ele apenas materializa o `GlobalActionRef` governado que o runtime de composicao
|
|
352
|
-
entrega.
|
|
353
|
-
|
|
354
|
-
Para conectar portas de widgets internos em containers como `praxis-tabs` ou `praxis-expansion`, use `composition.links[].from/to.ref.nestedPath`.
|
|
355
|
-
`ref.widget` continua sendo o owner top-level no canvas, e o ultimo segmento de `nestedPath` deve ser `kind: "widget"` com `key` estavel.
|
|
356
|
-
|
|
357
|
-
Para conteudo editorial rico dentro da pagina, use um widget `praxis-rich-content`
|
|
358
|
-
com `definition.inputs.document: RichContentDocument`. Isso evita criar uma DSL
|
|
359
|
-
local de page-builder para cards, imagens, timelines ou blocos de apresentacao,
|
|
360
|
-
e preserva `WidgetPageDefinition.widgets` como superficie unica de ocupacao do
|
|
361
|
-
canvas.
|
|
129
|
+
Component input editors belong to the component owner. Page Builder discovers `ComponentDocMeta.configEditor` and hosts the published editor instead of redefining table, form, chart, list, upload, stepper, tab, expansion, CRUD, or rich-content configuration locally.
|
|
362
130
|
|
|
363
|
-
##
|
|
131
|
+
## AI Authoring
|
|
364
132
|
|
|
365
|
-
|
|
133
|
+
Register widget capability catalogs so the assistant can reason about component inputs and supported operations.
|
|
366
134
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
## Editor do Card (Shell)
|
|
135
|
+
```ts
|
|
136
|
+
import {
|
|
137
|
+
PAGE_BUILDER_WIDGET_AI_CATALOGS,
|
|
138
|
+
providePageBuilderWidgetAiCatalogs,
|
|
139
|
+
} from '@praxisui/page-builder';
|
|
140
|
+
import { TABLE_AI_CAPABILITIES } from '@praxisui/table';
|
|
141
|
+
import { CRUD_AI_CAPABILITIES } from '@praxisui/crud';
|
|
376
142
|
|
|
377
|
-
|
|
143
|
+
providers: [
|
|
144
|
+
{
|
|
145
|
+
provide: PAGE_BUILDER_WIDGET_AI_CATALOGS,
|
|
146
|
+
useValue: {
|
|
147
|
+
'praxis-table': TABLE_AI_CAPABILITIES,
|
|
148
|
+
'praxis-crud': CRUD_AI_CAPABILITIES,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
providePageBuilderWidgetAiCatalogs(),
|
|
152
|
+
];
|
|
153
|
+
```
|
|
378
154
|
|
|
379
|
-
|
|
155
|
+
For backend-assisted authoring, configure `PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS` with the canonical `/api/praxis/config/ai/authoring` endpoints exposed by `praxis-config-starter`.
|
|
380
156
|
|
|
381
157
|
```ts
|
|
382
|
-
import {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
158
|
+
import { PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS } from '@praxisui/page-builder';
|
|
159
|
+
|
|
160
|
+
providers: [
|
|
161
|
+
{
|
|
162
|
+
provide: PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS,
|
|
163
|
+
useValue: {
|
|
164
|
+
baseUrl: '/api/praxis/config/ai/authoring',
|
|
165
|
+
headersFactory: () => ({
|
|
166
|
+
'X-Tenant-ID': tenantId,
|
|
167
|
+
'X-User-ID': userId,
|
|
168
|
+
'X-Env': 'local',
|
|
169
|
+
}),
|
|
170
|
+
},
|
|
390
171
|
},
|
|
391
|
-
|
|
172
|
+
];
|
|
392
173
|
```
|
|
393
174
|
|
|
394
|
-
|
|
175
|
+
The package exports `PRAXIS_PAGE_BUILDER_AUTHORING_MANIFEST` for governed operation discovery. The persisted runtime page is still `WidgetPageDefinition`; intermediate AI plans such as `UiCompositionPlan` must compile before preview, apply, or save.
|
|
395
176
|
|
|
396
|
-
|
|
397
|
-
- Use `composition.links[].condition` para guardas semanticas em Json Logic e `composition.links[].policy` para debounce/distinct/missing-value.
|
|
398
|
-
- Quando precisar revisar ligacoes, use o editor visual para interacao e mantenha a inspecao textual/versionada do contrato como fonte de auditoria.
|
|
177
|
+
## Public API
|
|
399
178
|
|
|
400
|
-
|
|
179
|
+
Main exports:
|
|
401
180
|
|
|
402
|
-
|
|
181
|
+
- `DynamicPageBuilderComponent`
|
|
403
182
|
- `ComponentPaletteDialogComponent`
|
|
404
183
|
- `FloatingToolbarComponent`
|
|
405
184
|
- `TileToolbarComponent`
|
|
406
185
|
- `WidgetShellEditorComponent`
|
|
407
186
|
- `ConnectionEditorComponent`
|
|
408
187
|
- `DynamicPageConfigEditorComponent`
|
|
409
|
-
- `
|
|
188
|
+
- `PageConfigEditorComponent`
|
|
410
189
|
- `PageBuilderAgenticAuthoringService`
|
|
411
190
|
- `PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS`
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
- `
|
|
420
|
-
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
- O Page Builder emite o handoff canonico de `shared_rule_authoring` e oferece um cockpit governado para continuar a decisao sem assumir autoria primaria da regra de negocio.
|
|
424
|
-
- O cockpit chama, por cliente real, a sequencia `definition/intake -> simulation -> governed review -> status transition -> semantic publication confirmation -> publication/materializations -> enforcement validation`.
|
|
425
|
-
- Quando um preview traz `diagnostics.projectKnowledgeAudit`, o cockpit de Project Knowledge pode propor `add_evidence` via `/api/praxis/config/domain-knowledge/change-sets`, validar, aprovar, aplicar e reler a projecao segura sem expor o conteudo bruto da evidencia na UI.
|
|
426
|
-
- Quando o prompt de authoring trouxer um caminho explicito como `/api/helpdesk/chamados`, a validacao do cockpit deve confirmar que o backend preservou esse alvo canonico no handoff, sem re-grounding por vocabulario solto do prompt.
|
|
427
|
-
- Timeline e historico governado sao observabilidade derivada. O cockpit pode exibir indisponibilidade dessa projecao, mas nao deve tratar a timeline como fonte primaria ou bloquear create/simulate/approve/activate quando o backend antigo ainda nao expuser o endpoint.
|
|
428
|
-
- A revisao deve exibir readiness, approvals, warnings, diagnostics e predicted materializations vindos do backend; nao reconstrua heuristicas de publicacao no frontend.
|
|
429
|
-
- A publicacao deve ser uma acao deliberada e confirmada semanticamente antes de chamar `/domain-rules/publications`.
|
|
430
|
-
- Materializacoes resultantes devem ser apresentadas como projecoes derivadas irmas (`option_source`, `backend_validation`, `workflow_action`, `approval_policy` ou futuras camadas), nao como novas regras primarias.
|
|
431
|
-
- A validacao de enforcement no cockpit consulta materializacoes aplicadas e prepara a evidencia para o runtime consumidor; ela nao reimplementa localmente a politica publicada.
|
|
432
|
-
|
|
433
|
-
Integracoes comuns:
|
|
434
|
-
- `SettingsPanelService.open({ id, title, content: { component, inputs } })` para page settings e shell editors
|
|
435
|
-
|
|
436
|
-
## Links
|
|
437
|
-
|
|
438
|
-
- Repo: https://github.com/codexrodrigues/praxis
|
|
439
|
-
- Issues: https://github.com/codexrodrigues/praxis/issues
|
|
191
|
+
- `PAGE_BUILDER_WIDGET_AI_CATALOGS`
|
|
192
|
+
- `providePageBuilderWidgetAiCatalogs`
|
|
193
|
+
- `PRAXIS_PAGE_BUILDER_AUTHORING_MANIFEST`
|
|
194
|
+
- `UiCompositionPlan` contracts
|
|
195
|
+
|
|
196
|
+
## Notes
|
|
197
|
+
|
|
198
|
+
- Treat `composition.links` as part of the saved page contract.
|
|
199
|
+
- Use component-owned config editors through metadata instead of duplicating widget-specific editors in Page Builder.
|
|
200
|
+
- Keep diagnostics and streaming opt-in for hosts that need auditability or richer authoring feedback.
|
|
201
|
+
- Use the official documentation for extended recipes, playground routes, and advanced AI authoring flows.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/page-builder",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.2",
|
|
4
4
|
"description": "Page and widget builder utilities for Praxis UI (grid, dynamic widgets, editors).",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^21.0.0",
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
"@angular/forms": "^21.0.0",
|
|
9
9
|
"@angular/cdk": "^21.0.0",
|
|
10
10
|
"@angular/material": "^21.0.0",
|
|
11
|
-
"@praxisui/ai": "^9.0.0-beta.
|
|
12
|
-
"@praxisui/core": "^9.0.0-beta.
|
|
13
|
-
"@praxisui/settings-panel": "^9.0.0-beta.
|
|
11
|
+
"@praxisui/ai": "^9.0.0-beta.2",
|
|
12
|
+
"@praxisui/core": "^9.0.0-beta.2",
|
|
13
|
+
"@praxisui/settings-panel": "^9.0.0-beta.2",
|
|
14
14
|
"rxjs": "~7.8.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
|
25
|
-
"url": "https://github.com/codexrodrigues/praxis-ui-angular"
|
|
25
|
+
"url": "git+https://github.com/codexrodrigues/praxis-ui-angular.git"
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://praxisui.dev",
|
|
28
28
|
"bugs": {
|