@praxisui/dynamic-form 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 +92 -0
- package/ai/component-registry.json +630 -156
- package/docs/custom-fields-enterprise-review.md +229 -0
- package/docs/dynamic-form-authoring-document-semantics.md +68 -2
- package/docs/evidence/form-authoring-635-20261023/final-review.md +46 -0
- package/docs/evidence/form-authoring-635-20261023/independent-review-vb-form.md +50 -0
- package/docs/evidence/form-authoring-635-20261023/validation.md +76 -0
- package/docs/evidence/p1-authoring-20261022/validation.md +134 -0
- package/docs/governed-page-widget-adapter.md +58 -0
- package/docs/hot-metadata-updates.md +16 -0
- package/fesm2022/praxisui-dynamic-form.mjs +4177 -1130
- package/package.json +8 -8
- package/src/lib/config-editor/praxis-dynamic-form-config-editor.json-api.md +11 -3
- package/src/lib/praxis-dynamic-form.json-api.md +41 -7
- package/types/praxisui-dynamic-form.d.ts +310 -27
package/README.md
CHANGED
|
@@ -29,6 +29,14 @@ Peer dependencies:
|
|
|
29
29
|
- `@praxisui/ai`, `@praxisui/core`, `@praxisui/dynamic-fields`, `@praxisui/metadata-editor`, `@praxisui/rich-content`, `@praxisui/settings-panel`, `@praxisui/visual-builder` `^9.0.0-beta.12`
|
|
30
30
|
- `rxjs` `^7.8.0`
|
|
31
31
|
|
|
32
|
+
## Original item revision on submit
|
|
33
|
+
|
|
34
|
+
In edit mode, the form keeps a single strong `ETag` together with the item representation returned by its hydration GET (`readUrl`, custom `getById` endpoint or ordinary resource GET). Automatic PUT/PATCH sends that exact tag as `If-Match`; it never performs another GET during submit to acquire a newer revision. A successful response that contains the corresponding item representation replaces both cached data and revision from that same response, including server normalization. A command acknowledgment or incomplete representation cannot rotate the original item snapshot. A shared CRUD cache read by another consumer cannot replace the form's original revision.
|
|
35
|
+
|
|
36
|
+
The snapshot is transient and belongs to the resource identity, read/write target and API context. Preparation, reads and writes share a generation: switching away and back, reloading or destroying the surface cannot make an old callback current again. Obsolete automatic responses do not emit submit result events, run result hooks, publish field errors or reset a newer submit's loading state. If an obsolete preparation hook retained the reused form group, the draft requires explicit reload before another write. Changing those bindings requires hydration again. Missing or weak read ETags are not converted into versions; unversioned endpoints remain usable, while a versioned host can reject a missing precondition with `428`. After `412`/`428`, or a successful versioned write without its next ETag, automatic submission requires an explicit reload. Closing and reopening a surface or retrying its initialization loads the new representation; retrying submit alone cannot silently refresh the revision.
|
|
37
|
+
|
|
38
|
+
Explicit `submitResourceVersion` and the existing cross-resource version target inputs retain their command semantics and precedence. They remain host-owned inputs; same-resource editing needs no additional authoring fields. Backend authorization, concurrency and lifecycle policy remain authoritative.
|
|
39
|
+
|
|
32
40
|
## Reactive backend determinations
|
|
33
41
|
|
|
34
42
|
When the exact request schema from `/schemas/filtered` publishes root-level `x-ui.reactiveDeterminations`, the form executes the Metadata-compiled backend capability after a valid source changes and applies server-derived draft values. After edit/create hydration, an already populated source is also validated before the draft can be reported as stable; an empty initial source settles as not applicable without an HTTP call. The projection is one closed graph: if any definition is malformed, the complete projection is rejected instead of partially executing. It remains backend-owned, tenant-neutral and transient: it is never copied to `FormConfig` and cannot be authored as a callback, URL or local write policy.
|
|
@@ -47,6 +55,12 @@ Use `optionSource.dependsOn` for dependent option lists and workflow actions for
|
|
|
47
55
|
|
|
48
56
|
Use a local `FormConfig` when the host already knows the sections and fields.
|
|
49
57
|
|
|
58
|
+
With `configPersistenceStrategy="input-first"`, an explicitly bound host configuration remains authoritative even when it contains only actions or other policies. The schema for the current operation supplies missing fields and layout; stale persisted fields are not used to fill those gaps.
|
|
59
|
+
|
|
60
|
+
Each form owns its mutable `GenericCrudService` and editor field/rule context. Sibling forms cannot change one another's resource, custom endpoints or schema client. This is a breaking beta correction for hosts that previously replaced an ancestor `GenericCrudService`: configure the form through `resourcePath`, `apiEndpointKey`, `apiUrlEntry` and the direct-form `customEndpoints` input. An ancestor service subclass is no longer used by the form; HTTP interceptors, `API_URL` and shared infrastructure remain inherited. Tests that substitute the client must use `TestBed.overrideComponent(PraxisDynamicForm, { add: { providers: [{ provide: GenericCrudService, useValue: crudMock }] } })`, retaining the other component providers.
|
|
61
|
+
|
|
62
|
+
An explorer combining selectors from several resources is a local form, not an edit command for one of those resource DTOs. Its fields may query real API options through their own resource metadata while remaining `source: 'local'` with `submitPolicy: 'omit'`. Use a distinct form identity when replacing a schema-backed command with such an explorer; persisted connections are still restored for their original identity. The `/dependency-fields-demo` reference follows this pattern and gives the current host definition precedence with `configPersistenceStrategy="input-first"`; its previous `cascade-*` configurations and connections are left untouched.
|
|
63
|
+
|
|
50
64
|
```ts
|
|
51
65
|
import { Component } from '@angular/core';
|
|
52
66
|
import { FormConfig } from '@praxisui/core';
|
|
@@ -739,3 +753,81 @@ suportada, ocupa a linha seguinte. Nenhum documento ou protocolo de Save é alte
|
|
|
739
753
|
- [Canonical technical overview: Overview](https://praxisui.dev/docs/components/praxis-dynamic-form)
|
|
740
754
|
- [Praxis Angular public catalog](https://praxisui.dev/angular)
|
|
741
755
|
<!-- praxis-npm-catalog-links:end -->
|
|
756
|
+
|
|
757
|
+
### Filhos de páginas governadas
|
|
758
|
+
|
|
759
|
+
Consulte [o adapter nativo de página](docs/governed-page-widget-adapter.md) para reconstrução sem defaults, presença exata, identidade derivada e execução sem preferências concorrentes.
|
|
760
|
+
|
|
761
|
+
### Schema-backed custom fields
|
|
762
|
+
|
|
763
|
+
Core expands an object marked `x-ui.customFieldsContainer: true` (or the inline
|
|
764
|
+
`customFields` object) into fields named `customFields.<key>`. Dynamic Form uses
|
|
765
|
+
those names as nested reactive-form paths and keeps the wire payload nested:
|
|
766
|
+
`{ "customFields": { "numero_calcado": 38, "data_exame": "2026-10-27" } }`.
|
|
767
|
+
The `customField`, `customFieldKey` and `customFieldScope` metadata identifies
|
|
768
|
+
schema-backed fields; it does not make them local/transient authoring fields.
|
|
769
|
+
Saved containers colliding with the server's expanded namespace are replaced by
|
|
770
|
+
its direct children, including a container previously marked `source: 'local'`.
|
|
771
|
+
Noncolliding local fields and existing child placement remain. Restrictive parent
|
|
772
|
+
flags remain restrictive in children; they do not create a submit omission policy.
|
|
773
|
+
|
|
774
|
+
Date controls hydrate nested API values without mutating the input. Submit applies
|
|
775
|
+
the same date/lookup serialization, required/dirty handling and omission policies
|
|
776
|
+
to flat and dotted names. Missing nested values do not create containers. Filter
|
|
777
|
+
Form preserves supported nested values during same-context metadata rebuilds,
|
|
778
|
+
unless the new field has an explicit default (reset). A removed server field can
|
|
779
|
+
remain as metadata for layout continuity, but becomes disabled and omitted from
|
|
780
|
+
applicable payloads. Hidden alone is not omission: explicit local and legitimate
|
|
781
|
+
hidden fields keep their published semantics. No host adapter is needed for the
|
|
782
|
+
supported nested value paths.
|
|
783
|
+
|
|
784
|
+
Temporal normalization is metadata-aware: legacy date tuples and local datetime
|
|
785
|
+
strings are transformed only on declared temporal fields, including collection
|
|
786
|
+
item schemas. Numeric/unknown arrays such as `[2026, 10, 27]` remain arrays;
|
|
787
|
+
ordinary/unknown strings retain their spaces and date-like text. The `DateInput`
|
|
788
|
+
control follows date-only serialization. A same-context metadata rebuild can
|
|
789
|
+
restore nested dirty/touched control paths, including collection items, without
|
|
790
|
+
marking unrelated controls touched. This does not preserve a draft across every
|
|
791
|
+
reset, identity switch or retry.
|
|
792
|
+
|
|
793
|
+
Scalar arrays use the operation schema's `fieldMetadata[].items`, separately
|
|
794
|
+
from object collections' `array.itemSchema.fields`. Core's shared normalizer turns
|
|
795
|
+
valid UI tokens into declared strings, safe integers, finite numbers or exact
|
|
796
|
+
booleans and enforces the item enum after conversion. Date/date-time item formats
|
|
797
|
+
use that same contract. An invalid/null item rejects the entire projection rather
|
|
798
|
+
than silently dropping it; an optional null container and an empty array remain
|
|
799
|
+
distinct valid inputs. Form validation and prepared submit must agree, so a token
|
|
800
|
+
such as `12.5` cannot be submitted as an integer. This subset does not promise
|
|
801
|
+
integer precision beyond JavaScript's safe range or an object-array editor.
|
|
802
|
+
|
|
803
|
+
Record paths do not traverse array intermediates in computed-rule contexts;
|
|
804
|
+
collection submit uses its own item-schema pipeline. The canonical Metadata key
|
|
805
|
+
policy rejects reserved control names such as `constructor`, `toString` and
|
|
806
|
+
`hasOwnProperty`; payload helper support does not relax that policy. Existing
|
|
807
|
+
stored definitions with such keys require a backend migration.
|
|
808
|
+
|
|
809
|
+
Read-only/disabled does not automatically mean omission from `getRawValue()`.
|
|
810
|
+
The canonical backend command request projection excludes read-only custom fields
|
|
811
|
+
from properties and required, while response schemas retain them for display.
|
|
812
|
+
Use the exact operation request schema; merging response fields into commands or
|
|
813
|
+
adding an unimplemented `x-ui.submitPolicy` adapter would break that boundary.
|
|
814
|
+
Reconciliation treats a successful empty schema as authoritative. Removed
|
|
815
|
+
server-backed fields become hidden, disabled and `submitPolicy: 'omit'`, including
|
|
816
|
+
manual sync and Filter; explicit local fields remain local. Reappearance restores
|
|
817
|
+
the current server constraints rather than stale saved required/type/enum/items.
|
|
818
|
+
|
|
819
|
+
Each fresh schema-loading cycle revalidates HTTP and normalizes its body; compiled
|
|
820
|
+
L1 is not a readiness shortcut. A matching 304 can reuse the cached representation.
|
|
821
|
+
Status 0, denied access, malformed schema and failed saved-config reconciliation
|
|
822
|
+
cannot make the old form ready. Authorization errors show access feedback without
|
|
823
|
+
a generic retry action; timeout/transport failures retain their retry surface.
|
|
824
|
+
Schema loading/error or a known unconfirmed enterprise context blocks submit.
|
|
825
|
+
Context changes cancel obsolete reads, revalidate metadata and invalidate the old
|
|
826
|
+
initial-value seed; retry is not a general cross-context autosave guarantee.
|
|
827
|
+
|
|
828
|
+
The confirmed enterprise context supplies effective tenant/locale and context
|
|
829
|
+
version. Explicit schema URLs conflicting with that context are rejected. Identity
|
|
830
|
+
visible only to cookies/interceptors still requires a captured context version or
|
|
831
|
+
complete cache/session invalidation by the host; backend authorization is always
|
|
832
|
+
required. See the [enterprise review](https://github.com/codexrodrigues/praxis-ui-angular/pull/658)
|
|
833
|
+
for source, candidate gates, host proof and remaining adoption limits.
|