@praxisui/page-builder 10.0.0-rc.4 → 10.0.0-rc.41
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 +140 -3
- package/ai/component-registry.json +112 -62
- package/fesm2022/praxisui-page-builder.mjs +15256 -8439
- package/package.json +4 -4
- package/types/praxisui-page-builder.d.ts +816 -30
package/README.md
CHANGED
|
@@ -4,6 +4,56 @@ 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
|
+
For the prospective governed-page journey, see [Create, review and publish pages — UX design](https://github.com/codexrodrigues/praxis-ui-angular/blob/main/projects/praxis-page-builder/docs/governed-page-publication-ux.md). This is a storyboard and acceptance criteria for subsequent host/lifecycle integration; it does not make page creation or publication available in the current builder.
|
|
8
|
+
|
|
9
|
+
## Dashboard pages and persistence ownership
|
|
10
|
+
|
|
11
|
+
A dashboard is a `WidgetPageDefinition` rendered by `praxis-dynamic-page` and edited
|
|
12
|
+
by `praxis-dynamic-page-builder`. The beta `PraxisDashboardPage` wrapper was removed;
|
|
13
|
+
use these existing components instead. Application titles, toolbar presentation and
|
|
14
|
+
business navigation remain host concerns.
|
|
15
|
+
|
|
16
|
+
For manual page editing, opt in to the Core persistence lifecycle:
|
|
17
|
+
|
|
18
|
+
```html
|
|
19
|
+
<praxis-dynamic-page-builder
|
|
20
|
+
#builder
|
|
21
|
+
[page]="defaultPage"
|
|
22
|
+
[pageIdentity]="identity"
|
|
23
|
+
[autoPersist]="true"
|
|
24
|
+
[enableCustomization]="editing"
|
|
25
|
+
(persistenceChange)="persistence = $event"
|
|
26
|
+
/>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`autoPersist` defaults to `false` on the builder, preserving its previous effective
|
|
30
|
+
behavior (the child runtime previously always received `false`). Hosts that already
|
|
31
|
+
persist `pageAuthoringChange`/`pageSaveRequested` must leave it disabled. Core Dynamic
|
|
32
|
+
Page keeps its own existing default. Do not enable a second host writer when Core
|
|
33
|
+
owns persistence.
|
|
34
|
+
|
|
35
|
+
Pass `PageIdentity` with the application's actual tenant/user/route. Core uses the
|
|
36
|
+
configured `ASYNC_CONFIG_STORAGE`; no separate localStorage cache, browser globals
|
|
37
|
+
or persona-specific host reconciler is needed. Storage identity is not backend
|
|
38
|
+
authorization. Persisted documents, including an empty widget list, are authoritative;
|
|
39
|
+
new factory widgets are not silently appended to a user's saved page.
|
|
40
|
+
|
|
41
|
+
`persistenceChange` forwards Core's operational `WidgetPagePersistenceState`:
|
|
42
|
+
`idle`, `loading`, `saving`, `saved`, `resetting` or `error`, with `customized`, optional
|
|
43
|
+
ISO `savedAt`, operation and a safe `errorKind`. Show success only after acknowledgement,
|
|
44
|
+
and distinguish conflicts from a pending or failed write. It is not business metadata
|
|
45
|
+
and must not be persisted in `WidgetPageDefinition`.
|
|
46
|
+
|
|
47
|
+
`builder.resetPersistedPage(defaultPage)` deletes this identity's saved page and applies
|
|
48
|
+
the supplied default only after acknowledgement. `builder.reloadPersistedPage(defaultPage)`
|
|
49
|
+
explicitly discards the draft and reloads storage, using the supplied default when no saved
|
|
50
|
+
page exists. Make that destructive-to-draft intent visible in the host. The existing Save
|
|
51
|
+
button retries through Core for manually managed pages; conflicts require an explicit reload.
|
|
52
|
+
|
|
53
|
+
For `authoringDocument` or agentic authoring, Core automatic persistence is disabled even
|
|
54
|
+
when requested: the existing host/server apply lifecycle owns revisions and provenance.
|
|
55
|
+
An AI preview must never be saved through an automatic generic config write.
|
|
56
|
+
|
|
7
57
|
## Widget shell editor integrity
|
|
8
58
|
|
|
9
59
|
The shell editor exposes **Keep header visible while scrolling the page**
|
|
@@ -87,7 +137,7 @@ order, with natural content height. It replaces positions and width bounds only
|
|
|
87
137
|
that device, preserves hidden widgets and other overrides, and leaves the base and
|
|
88
138
|
other device layouts unchanged. Apply/Save materializes the existing
|
|
89
139
|
`deviceLayouts[device].canvas` contract; Reset restores the original draft.
|
|
90
|
-
Advanced JSON overrides remain available under **Advanced overrides
|
|
140
|
+
Advanced JSON overrides remain available under **Advanced overrides** (`widgetOverrides`) and strictly validate the canonical `WidgetPageWidgetLayoutOverride` keys (`className`, `span`, `order`, `hidden`), diagnosing and rejecting unsupported properties such as `definition` or `inputs` without discarding the user's draft text.
|
|
91
141
|
|
|
92
142
|
Reducing a device's column count also reflows inherited base positions in Core.
|
|
93
143
|
Explicit device positions remain authoritative. With no device variant the base
|
|
@@ -113,7 +163,7 @@ documents already clamped by Core remain valid on opening: declared spans need
|
|
|
113
163
|
not equal rendered spans. Invalid inherited bounds can be corrected in the same
|
|
114
164
|
draft. The editor does not rewrite geometry to satisfy newly authored bounds.
|
|
115
165
|
Dynamic title expressions are
|
|
116
|
-
identified by stable widget key, not evaluated in the editor.
|
|
166
|
+
identified by stable widget key and resolved friendly widget titles (from static shell metadata or inner widget titles), not evaluated in the editor.
|
|
117
167
|
|
|
118
168
|
Apply previews the same document returned by Save; Reset reloads the input baseline.
|
|
119
169
|
Pending changes are tracked independently of validity, including edits to an
|
|
@@ -135,7 +185,7 @@ Page, the editor receives transient runtime validation through `SETTINGS_PANEL_D
|
|
|
135
185
|
Apply/Save and reopen check the current active-device geometry and report the minimum
|
|
136
186
|
beside the height field. The callback and observed dimensions never enter the document.
|
|
137
187
|
Changed columns, gap, width or shell styling require Automatic height, Apply, then
|
|
138
|
-
reopening before choosing a measured height. Other device variants must be checked
|
|
188
|
+
reopening before choosing a measured height. When switching a visual template (`themePreset` / `layoutPreset`) triggers rendered-height validation blocks on widgets with adjustable heights, the editor surfaces an actionable banner across Studio tabs listing all affected widgets with their friendly names and current pixel heights, offering direct navigation to **Widget limits** or a one-click conversion to **Automatic** height that preserves a summary of the previous pixel measurements for review. Other device variants must be checked
|
|
139
189
|
on their corresponding device. Standalone/custom hosts without this runtime context
|
|
140
190
|
retain numeric validation only. Core's scroll-layout shell now recovers access after
|
|
141
191
|
late header/content growth by temporarily scrolling the header and body together
|
|
@@ -150,6 +200,13 @@ Do not infer AI support from broad affected paths. Publishing the new authoring
|
|
|
150
200
|
schema/handler validation and registry projection remains an explicit follow-up,
|
|
151
201
|
not an OpenAI dependency for manual interaction.
|
|
152
202
|
|
|
203
|
+
### Declarative Page DataSources Authoring
|
|
204
|
+
|
|
205
|
+
Both `PageConfigEditorComponent` and `DynamicPageConfigEditorComponent` preserve and edit `page.dataSources` inside **Page settings → State**:
|
|
206
|
+
|
|
207
|
+
- Both `PageConfigEditorComponent` and `DynamicPageConfigEditorComponent` offer guided DataSource cards (`id`, `kind`, `endpointKey`, `resourcePath`, `method`, `targetStatePath`, `errorPolicy`, `refreshIntervalMs`, `autoFetch`, `query`, `transform`, `fallbackValue`, `description`) synchronized bidirectionally with the advanced JSON editor (`[data-testid="page-datasources-json"]`).
|
|
208
|
+
- Both editors accept Array or Object-Map JSON input, normalize saved definitions to the canonical `WidgetPageDataSourceDefinition[]` array, and enforce symmetric validation across guided and raw JSON authoring—failing closed (blocking Apply/Save and surfacing `editor.errors.dataSourcesInvalid` on the State tab) when an entry is missing `id` or `resourcePath`, duplicates a normalized `id`, sets an unsupported `kind`/`method`/`errorPolicy`, sets a negative or non-finite `refreshIntervalMs`, passes a non-object `query`, declares an incomplete `transform` (`path`, `group-by-map`, `timeseries-last`), or contains malformed JSON.
|
|
209
|
+
|
|
153
210
|
## LLM Recommendation Guide
|
|
154
211
|
|
|
155
212
|
- Recommend when: users need dynamic pages, widget composition, dashboards, grid layouts, component metadata discovery, and runtime-editable page definitions.
|
|
@@ -236,6 +293,8 @@ source fails closed.
|
|
|
236
293
|
- `enableAgenticAuthoring`, `agenticAuthoringProvider`, `agenticAuthoringModel`, `agenticAuthoringScope`
|
|
237
294
|
- `agenticAuthoringIncludeLlmDiagnostics`, `agenticAuthoringEnableStreaming`, `agenticAuthoringContextHints`
|
|
238
295
|
- `showPageLifecycleActions`, `canDeleteSavedPage`, `pageLifecycleBusy`
|
|
296
|
+
- `showGovernanceToolbar`: boolean flag to render a built-in top governance toolbar (with canvas title, layout persistence status badge, last saved time, factory reset button, and customization toggle), enabling 100% declarative page hosting without imperative toolbar boilerplate
|
|
297
|
+
- `governanceToolbarTitle`: optional string providing the canvas or dashboard title displayed in the governance toolbar
|
|
239
298
|
|
|
240
299
|
All omitted `authoringCapabilities` entries remain enabled for backward compatibility. The grant is
|
|
241
300
|
never written to `WidgetPageDefinition` and does not authorize AI operations; manifests, backend
|
|
@@ -523,6 +582,23 @@ Schema-derived table columns already use the canonical `TableConfig.columnProjec
|
|
|
523
582
|
|
|
524
583
|
`ComponentDocMeta.insertionPresets` remains the canonical catalog for reusable defaults owned by one component. It is not a page/domain template system: do not publish Employee Operations presets from CRUD, tabs, or related-resource outlet metadata merely to shorten a business recipe.
|
|
525
584
|
|
|
585
|
+
To streamline host registration of widget providers and component metadata without repetitive manual bootstrap code, `@praxisui/page-builder` exports the `providePraxisPageBuilderWidgets(widgets?: Array<Provider | ComponentDocMeta>)` helper. Hosts can supply a bundle of standard providers or direct `ComponentDocMeta` objects; any `ComponentDocMeta` passed is automatically registered with `ComponentMetadataRegistry` during environment initialization:
|
|
586
|
+
|
|
587
|
+
```ts
|
|
588
|
+
import { providePraxisPageBuilderWidgets } from '@praxisui/page-builder';
|
|
589
|
+
import { providePraxisListMetadata } from '@praxisui/list';
|
|
590
|
+
import { providePraxisTableMetadata } from '@praxisui/table';
|
|
591
|
+
|
|
592
|
+
export const appConfig: ApplicationConfig = {
|
|
593
|
+
providers: [
|
|
594
|
+
...providePraxisPageBuilderWidgets([
|
|
595
|
+
providePraxisListMetadata(),
|
|
596
|
+
providePraxisTableMetadata(),
|
|
597
|
+
]),
|
|
598
|
+
],
|
|
599
|
+
};
|
|
600
|
+
```
|
|
601
|
+
|
|
526
602
|
For complete governed page templates, the additive `UiCompositionPlanTemplateReference` pins the canonical `ai_registry` key and complete `configJson` SHA-256. The Config Starter resolves the active `SYSTEM/GLOBAL` record, verifies the exact hash, extracts its governed `authoringPlan`, and only then invokes the existing compiler. Angular consumers can use the pure `resolveUiCompositionPlanTemplate` helper only with an explicitly supplied `UiCompositionPlanTemplateMaterialization`; the helper performs no HTTP, search, or implicit selection. The first contract accepts no non-empty overrides, fails closed for missing, inactive, malformed, or stale references, and never persists the unresolved reference. `version` and `etag` are retained as audit evidence, while `configSha256` is the required content pin.
|
|
527
603
|
|
|
528
604
|
Keep the compact authoring plan, the compiled executable page, and the surrounding recipe metadata as distinct artifacts. `UiCompositionPlan` is the reviewable authoring intent; `WidgetPageDefinition` is the explicit runtime graph; recipe metadata and operational evidence document when and how the example should be used. The server compiler must produce the same executable page as the Page Builder compiler before persistence.
|
|
@@ -1072,9 +1148,70 @@ losing unrelated context. Arrangement choices track their draft baseline even wh
|
|
|
1072
1148
|
selected distribution initially produces no changes, so later edits clear stale status.
|
|
1073
1149
|
These fixes are not part of the already published 9.0.68-rc.2 package.
|
|
1074
1150
|
|
|
1151
|
+
`retryPersistedPage()` retries the current draft after a non-conflict save failure,
|
|
1152
|
+
including empty pages, without emitting host save lifecycle events. Conflicts require
|
|
1153
|
+
explicit `reloadPersistedPage(defaultPage)`; reload discards the local draft.
|
|
1154
|
+
|
|
1075
1155
|
<!-- praxis-npm-catalog-links:start -->
|
|
1076
1156
|
## Official documentation and examples
|
|
1077
1157
|
|
|
1078
1158
|
- [Canonical technical overview: Overview](https://praxisui.dev/docs/components/praxis-page-builder)
|
|
1079
1159
|
- [Praxis Angular public catalog](https://praxisui.dev/angular)
|
|
1080
1160
|
<!-- praxis-npm-catalog-links:end -->
|
|
1161
|
+
|
|
1162
|
+
### Optional editing highlight
|
|
1163
|
+
|
|
1164
|
+
This feature was added in source after `10.0.0-rc.36`; it is not yet part of a published package release.
|
|
1165
|
+
|
|
1166
|
+
`WidgetShellConfig.appearance.card.interactionHighlight` selects `standard` or
|
|
1167
|
+
`gradient`. Omit it to inherit the shell preset; the final default is `standard`.
|
|
1168
|
+
An explicit `standard` overrides a gradient preset. This is editing chrome: it
|
|
1169
|
+
appears on selection or keyboard focus while customization is enabled, never as a
|
|
1170
|
+
permanent border in the published page. Focusing a child control does not change selection; the highlight itself does not emit selection.
|
|
1171
|
+
The gradient uses the current primary, tertiary and secondary theme tokens. Resize
|
|
1172
|
+
grips follow the same choice. Internal control focus indicators remain intact;
|
|
1173
|
+
blocked canvas operations retain the error indicator and forced colors use a solid
|
|
1174
|
+
system-color outline. The highlight follows the resolved card radius (square for
|
|
1175
|
+
content-only shells).
|
|
1176
|
+
|
|
1177
|
+
```json
|
|
1178
|
+
{"shell":{"kind":"dashboard-card","appearance":{"card":{"interactionHighlight":"gradient"}}}}
|
|
1179
|
+
```
|
|
1180
|
+
|
|
1181
|
+
In Widget settings → Appearance, choose Inherit, Standard or Gradient and inspect
|
|
1182
|
+
its preview. Apply updates the local draft; the host controls remote persistence.
|
|
1183
|
+
Saving the settings panel alone is not proof of a server write: the reference Page
|
|
1184
|
+
Builder host requires Save page. Reopening and Reset preserve the distinction between
|
|
1185
|
+
an omitted value and an explicit override. Editing appearance on a widget without a
|
|
1186
|
+
shell preserves content-only presentation (`kind: 'none'`); a card requires an explicit
|
|
1187
|
+
choice. The option does not change child component inputs or enable customization.
|
|
1188
|
+
|
|
1189
|
+
This preference controls editing appearance; it grants no authorization and carries
|
|
1190
|
+
no business selection state. The host integrates persistence, identity and tenant
|
|
1191
|
+
scope through the canonical configuration infrastructure, including its ETag
|
|
1192
|
+
contract; this option requires no separate ETag implementation in the host. Editing only this preference must preserve unrelated
|
|
1193
|
+
shell settings, including `bodyLayout`, `windowActions` and action `pressed` values.
|
|
1194
|
+
Local editor round-trip tests do not prove remote tenant isolation or ETag behavior.
|
|
1195
|
+
|
|
1196
|
+
The existing AI operation `widget.shell.configure` merges partial shell input.
|
|
1197
|
+
Omitting `interactionHighlight` from that input preserves an existing override; it
|
|
1198
|
+
does not perform the visual editor's Inherit action, which removes the field from
|
|
1199
|
+
the complete saved document. Explicit `standard` disables the gradient but remains
|
|
1200
|
+
an override. Resetting an existing override to inherited styling through this AI
|
|
1201
|
+
operation remains unsupported; this option does not imply full editor/AI parity.
|
|
1202
|
+
|
|
1203
|
+
The historical live shell-authoring trial recorded in the validation report did
|
|
1204
|
+
not establish SSE, apply and persisted reopen support: its global assistant entry
|
|
1205
|
+
had no pinned widget target. Contextual child authoring also needs the correct
|
|
1206
|
+
operation owner and complete Page Builder document, rather than a child manifest
|
|
1207
|
+
and `definition.inputs`. Schema publication and compiler unit tests alone do not
|
|
1208
|
+
prove that journey. This integration preserves current dispatch; the historical
|
|
1209
|
+
failure is not a claim that every path on the current main has been disproven.
|
|
1210
|
+
Use the separately validated visual editor path for this preference until a
|
|
1211
|
+
successful shell-authoring AI journey is recorded for the integrated source.
|
|
1212
|
+
|
|
1213
|
+
## Reusable copy and save-as journey
|
|
1214
|
+
|
|
1215
|
+
`PraxisPageCopyActionComponent` and `PraxisPageSaveAsComponent` provide reusable authoring controls for copying the current draft and saving a new page with a menu name/icon and confirmed internal route. Hosts provide an explicit `PageSaveAsAdapter`; the controls own validation feedback, retry snapshot/key, busy state, obsolete callback rejection and the last confirmed link. They do not provide storage or grant publication authority.
|
|
1216
|
+
|
|
1217
|
+
Connect `saveRequested` to `DynamicPageBuilderComponent.saveCurrentPage()` and its `pageSaveRequested` to `saveAs.save($event)` with `autoPersist=false`. Keep host routing, persistence and authorization in the adapter. See [contract, integration and proof limits](https://github.com/codexrodrigues/praxis-ui-angular/blob/main/projects/praxis-page-builder/docs/page-save-as.md). The first Hero proof is browser-local, not governed corporate publication; importing hosts require the matching packaged API before merge.
|