@praxisui/page-builder 7.0.0-beta.0 → 8.0.0-beta.0
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 +32 -0
- package/fesm2022/praxisui-page-builder.mjs +25 -2
- package/index.d.ts +4 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -53,6 +53,7 @@ import { bootstrapApplication } from '@angular/platform-browser';
|
|
|
53
53
|
import { PAGE_BUILDER_WIDGET_AI_CATALOGS, providePageBuilderWidgetAiCatalogs } from '@praxisui/page-builder';
|
|
54
54
|
import { TABLE_AI_CAPABILITIES } from '@praxisui/table';
|
|
55
55
|
import { CRUD_AI_CAPABILITIES } from '@praxisui/crud';
|
|
56
|
+
import { RICH_CONTENT_AI_CAPABILITIES } from '@praxisui/rich-content';
|
|
56
57
|
import { AppComponent } from './app/app.component';
|
|
57
58
|
|
|
58
59
|
bootstrapApplication(AppComponent, {
|
|
@@ -62,6 +63,7 @@ bootstrapApplication(AppComponent, {
|
|
|
62
63
|
useValue: {
|
|
63
64
|
'praxis-table': TABLE_AI_CAPABILITIES,
|
|
64
65
|
'praxis-crud': CRUD_AI_CAPABILITIES,
|
|
66
|
+
'praxis-rich-content': RICH_CONTENT_AI_CAPABILITIES,
|
|
65
67
|
},
|
|
66
68
|
},
|
|
67
69
|
providePageBuilderWidgetAiCatalogs(),
|
|
@@ -75,10 +77,12 @@ Registro manual (util para apps que precisam customizar o mapa):
|
|
|
75
77
|
import { registerWidgetAiCatalogs } from '@praxisui/page-builder';
|
|
76
78
|
import { TABLE_AI_CAPABILITIES } from '@praxisui/table';
|
|
77
79
|
import { CRUD_AI_CAPABILITIES } from '@praxisui/crud';
|
|
80
|
+
import { RICH_CONTENT_AI_CAPABILITIES } from '@praxisui/rich-content';
|
|
78
81
|
|
|
79
82
|
registerWidgetAiCatalogs({
|
|
80
83
|
'praxis-table': TABLE_AI_CAPABILITIES,
|
|
81
84
|
'praxis-crud': CRUD_AI_CAPABILITIES,
|
|
85
|
+
'praxis-rich-content': RICH_CONTENT_AI_CAPABILITIES,
|
|
82
86
|
});
|
|
83
87
|
```
|
|
84
88
|
|
|
@@ -101,10 +105,32 @@ providers: [
|
|
|
101
105
|
]
|
|
102
106
|
```
|
|
103
107
|
|
|
108
|
+
## Component Config Editors
|
|
109
|
+
|
|
110
|
+
O page-builder não deve implementar editores locais para os inputs de cada
|
|
111
|
+
widget. Quando um componente registra `ComponentDocMeta.configEditor`, o runtime
|
|
112
|
+
canônico (`praxis-dynamic-page`) injeta a ação "Configurar conteudo" no shell do
|
|
113
|
+
widget e abre o editor declarado pelo dono do componente.
|
|
114
|
+
|
|
115
|
+
Fluxo canônico:
|
|
116
|
+
|
|
117
|
+
- a lib dona registra `configEditor` em `ComponentMetadataRegistry`
|
|
118
|
+
- o page-builder habilita customization e fornece `SETTINGS_PANEL_BRIDGE`
|
|
119
|
+
- o editor recebe `{ inputs, widgetKey, widgetType }`
|
|
120
|
+
- `Apply` atualiza `definition.inputs` sem fechar o painel; ele não é rollback transacional e pode ser observado pelo host imediatamente
|
|
121
|
+
- `Save` atualiza `definition.inputs` e persiste a página quando houver `pageIdentity`
|
|
122
|
+
- `Reset` restaura o estado interno do editor para o snapshot aberto; ele não desfaz automaticamente um `Apply` já emitido ao runtime/host
|
|
123
|
+
|
|
124
|
+
Exemplo com `praxis-rich-content`: o editor canônico é
|
|
125
|
+
`PraxisRichContentConfigEditor`, publicado por `@praxisui/rich-content`. Ele
|
|
126
|
+
edita `definition.inputs.document`, `layout` e `rootClassName` sem criar uma DSL
|
|
127
|
+
local de page-builder para blocos ricos.
|
|
128
|
+
|
|
104
129
|
Catalogos conhecidos (exports):
|
|
105
130
|
- `TABLE_AI_CAPABILITIES` - `@praxisui/table` (`praxis-table`)
|
|
106
131
|
- `CRUD_AI_CAPABILITIES` - `@praxisui/crud` (`praxis-crud`)
|
|
107
132
|
- `LIST_AI_CAPABILITIES` - `@praxisui/list` (`praxis-list`)
|
|
133
|
+
- `RICH_CONTENT_AI_CAPABILITIES` - `@praxisui/rich-content` (`praxis-rich-content`)
|
|
108
134
|
- `FORM_AI_CAPABILITIES` - `@praxisui/dynamic-form` (`praxis-dynamic-form`)
|
|
109
135
|
- `FILES_UPLOAD_AI_CAPABILITIES` - `@praxisui/files-upload` (`praxis-files-upload`)
|
|
110
136
|
- `STEPPER_AI_CAPABILITIES` - `@praxisui/stepper` (`praxis-stepper`)
|
|
@@ -126,6 +152,12 @@ O builder canonico expoe authoring de shell/palette sobre `praxis-dynamic-page`.
|
|
|
126
152
|
|
|
127
153
|
`page` e um `WidgetPageDefinition` (do `@praxisui/core`) contendo `widgets` e opcionalmente `composition.links`. O envelope `composition` e o caminho `composition.links` formam a superficie canonica persistida para wiring da pagina, com `condition` em Json Logic e `policy` para comportamento operacional.
|
|
128
154
|
|
|
155
|
+
Para conteudo editorial rico dentro da pagina, use um widget `praxis-rich-content`
|
|
156
|
+
com `definition.inputs.document: RichContentDocument`. Isso evita criar uma DSL
|
|
157
|
+
local de page-builder para cards, imagens, timelines ou blocos de apresentacao,
|
|
158
|
+
e preserva `WidgetPageDefinition.widgets` como superficie unica de ocupacao do
|
|
159
|
+
canvas.
|
|
160
|
+
|
|
129
161
|
## Widget Shell (Dashboard Cards)
|
|
130
162
|
|
|
131
163
|
Cada widget pode declarar um `shell` para renderizar um card padronizado com cabecalho rico, acoes de contexto e controles de janela (expandir/recolher).
|
|
@@ -9,7 +9,7 @@ import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
|
9
9
|
import * as i3 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, 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, ComponentMetadataRegistry, generateId, SETTINGS_PANEL_BRIDGE, DynamicWidgetPageComponent, DYNAMIC_PAGE_SHELL_EDITOR } from '@praxisui/core';
|
|
13
13
|
export { WidgetShellComponent } from '@praxisui/core';
|
|
14
14
|
import * as i4 from '@angular/material/tooltip';
|
|
15
15
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
@@ -4614,6 +4614,8 @@ const PAGE_BUILDER_AI_CAPABILITIES = {
|
|
|
4614
4614
|
],
|
|
4615
4615
|
notes: [
|
|
4616
4616
|
'page segue o modelo canonico WidgetPageDefinition (widgets, composition.links, context e state opcional).',
|
|
4617
|
+
'Conteudo editorial rico deve ser modelado como widget praxis-rich-content com definition.inputs.document: RichContentDocument, nao como DSL local do page-builder.',
|
|
4618
|
+
'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.',
|
|
4617
4619
|
'Canvas e o modelo espacial canonico da pagina quando houver posicionamento explicito.',
|
|
4618
4620
|
'Taxonomia editorial: condition usa Json Logic canonico; transform usa pipeline declarativo; policy cobre apenas comportamento operacional.',
|
|
4619
4621
|
'Payloads legados de layout ainda podem ser ingeridos, mas sao normalizados para canvas e nao devem ser reemitidos.',
|
|
@@ -4656,7 +4658,11 @@ const PAGE_BUILDER_AI_CAPABILITIES = {
|
|
|
4656
4658
|
{ path: 'page.widgets[].definition', category: 'widgets', valueKind: 'object', description: 'Definicao do widget (WidgetDefinition).' },
|
|
4657
4659
|
{ path: 'page.widgets[].definition.id', category: 'widgets', valueKind: 'string', description: 'ID do componente registrado.' },
|
|
4658
4660
|
{ path: 'page.widgets[].definition.inputs', category: 'widgets', valueKind: 'object', description: 'Inputs do componente.' },
|
|
4661
|
+
{ path: 'page.widgets[].definition.inputs.document', category: 'widgets', valueKind: 'object', description: 'RichContentDocument quando definition.id for praxis-rich-content.' },
|
|
4659
4662
|
{ path: 'page.widgets[].definition.bindingOrder', category: 'widgets', valueKind: 'array', description: 'Ordem de aplicacao dos inputs.' },
|
|
4663
|
+
{ path: 'ComponentDocMeta.configEditor', category: 'widgets', valueKind: 'object', description: 'Editor canonico de inputs publicado pela lib dona do componente e aberto pelo settings-panel do host.' },
|
|
4664
|
+
{ path: 'ComponentDocMeta.configEditor.component', category: 'widgets', valueKind: 'object', description: 'Componente standalone que implementa SettingsValueProvider para editar definition.inputs.' },
|
|
4665
|
+
{ path: 'ComponentDocMeta.configEditor.title', category: 'widgets', valueKind: 'string', description: 'Titulo opcional usado pelo host ao abrir o editor de inputs do componente.' },
|
|
4660
4666
|
{ path: 'page.composition', category: 'connections', valueKind: 'object', description: 'Envelope canonico da composicao persistida.' },
|
|
4661
4667
|
{ path: 'page.composition.version', category: 'connections', valueKind: 'string', description: 'Versao do envelope de composicao.' },
|
|
4662
4668
|
{ path: 'page.composition.links', category: 'connections', valueKind: 'array', description: 'Links canonicos entre widgets e estado.' },
|
|
@@ -5320,6 +5326,7 @@ class DynamicPageBuilderComponent {
|
|
|
5320
5326
|
dialog;
|
|
5321
5327
|
settingsPanel;
|
|
5322
5328
|
i18n = inject(PraxisI18nService);
|
|
5329
|
+
componentMetadata = inject(ComponentMetadataRegistry);
|
|
5323
5330
|
runtime;
|
|
5324
5331
|
page;
|
|
5325
5332
|
context = null;
|
|
@@ -5372,7 +5379,7 @@ class DynamicPageBuilderComponent {
|
|
|
5372
5379
|
addWidget(type) {
|
|
5373
5380
|
const next = this.clonePage(this.currentPage());
|
|
5374
5381
|
const key = `${type}-${generateId()}`;
|
|
5375
|
-
const widgets = [...(next.widgets || []), { key, definition: { id: type, inputs:
|
|
5382
|
+
const widgets = [...(next.widgets || []), { key, definition: { id: type, inputs: this.defaultInputsFor(type) } }];
|
|
5376
5383
|
next.widgets = widgets;
|
|
5377
5384
|
if (next.canvas) {
|
|
5378
5385
|
const lastRow = Math.max(1, ...Object.values(next.canvas.items || {}).map((item) => (item.row + item.rowSpan) - 1));
|
|
@@ -5423,6 +5430,22 @@ class DynamicPageBuilderComponent {
|
|
|
5423
5430
|
clonePage(page) {
|
|
5424
5431
|
return JSON.parse(JSON.stringify(page));
|
|
5425
5432
|
}
|
|
5433
|
+
defaultInputsFor(type) {
|
|
5434
|
+
const metadata = this.componentMetadata.get(type);
|
|
5435
|
+
const inputs = {};
|
|
5436
|
+
for (const input of metadata?.inputs ?? []) {
|
|
5437
|
+
if (input.default !== undefined) {
|
|
5438
|
+
inputs[input.name] = this.cloneValue(input.default);
|
|
5439
|
+
}
|
|
5440
|
+
}
|
|
5441
|
+
return inputs;
|
|
5442
|
+
}
|
|
5443
|
+
cloneValue(value) {
|
|
5444
|
+
if (value == null || typeof value !== 'object') {
|
|
5445
|
+
return value;
|
|
5446
|
+
}
|
|
5447
|
+
return JSON.parse(JSON.stringify(value));
|
|
5448
|
+
}
|
|
5426
5449
|
tx(key, fallback) {
|
|
5427
5450
|
return resolvePraxisPageBuilderText(this.i18n, key, fallback);
|
|
5428
5451
|
}
|
package/index.d.ts
CHANGED
|
@@ -249,7 +249,7 @@ declare class DynamicPageConfigEditorComponent implements OnInit, SettingsValueP
|
|
|
249
249
|
readonly canvasColumnsControl: FormControl<number>;
|
|
250
250
|
readonly canvasRowUnitControl: FormControl<string>;
|
|
251
251
|
readonly canvasGapControl: FormControl<string>;
|
|
252
|
-
readonly canvasAutoRowsControl: FormControl<"
|
|
252
|
+
readonly canvasAutoRowsControl: FormControl<"content" | "fixed">;
|
|
253
253
|
readonly layoutPresetControl: FormControl<string>;
|
|
254
254
|
readonly themePresetControl: FormControl<string>;
|
|
255
255
|
readonly shellPresetControl: FormControl<string>;
|
|
@@ -600,6 +600,7 @@ declare class DynamicPageBuilderComponent implements OnChanges {
|
|
|
600
600
|
private dialog;
|
|
601
601
|
private settingsPanel;
|
|
602
602
|
private readonly i18n;
|
|
603
|
+
private readonly componentMetadata;
|
|
603
604
|
runtime?: DynamicWidgetPageComponent;
|
|
604
605
|
page?: WidgetPageDefinition | string;
|
|
605
606
|
context?: Record<string, unknown> | null;
|
|
@@ -626,6 +627,8 @@ declare class DynamicPageBuilderComponent implements OnChanges {
|
|
|
626
627
|
focusCanvasWidget(widgetKey: string): void;
|
|
627
628
|
private parsePage;
|
|
628
629
|
private clonePage;
|
|
630
|
+
private defaultInputsFor;
|
|
631
|
+
private cloneValue;
|
|
629
632
|
tx(key: string, fallback: string): string;
|
|
630
633
|
static ɵfac: i0.ɵɵFactoryDeclaration<DynamicPageBuilderComponent, [null, { optional: true; }]>;
|
|
631
634
|
static ɵcmp: i0.ɵɵComponentDeclaration<DynamicPageBuilderComponent, "praxis-dynamic-page-builder", never, { "page": { "alias": "page"; "required": false; }; "context": { "alias": "context"; "required": false; }; "strictValidation": { "alias": "strictValidation"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "showSettingsButton": { "alias": "showSettingsButton"; "required": false; }; "pageIdentity": { "alias": "pageIdentity"; "required": false; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "pageEditorComponent": { "alias": "pageEditorComponent"; "required": false; }; }, { "pageChange": "pageChange"; }, never, never, true, never>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/page-builder",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0-beta.0",
|
|
4
4
|
"description": "Page and widget builder utilities for Praxis UI (grid, dynamic widgets, editors).",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^20.0.0",
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"@angular/forms": "^20.0.0",
|
|
9
9
|
"@angular/cdk": "^20.0.0",
|
|
10
10
|
"@angular/material": "^20.0.0",
|
|
11
|
-
"@praxisui/core": "^
|
|
12
|
-
"@praxisui/settings-panel": "^
|
|
11
|
+
"@praxisui/core": "^8.0.0-beta.0",
|
|
12
|
+
"@praxisui/settings-panel": "^8.0.0-beta.0"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"tslib": "^2.3.0"
|