@praxisui/crud 9.0.0-beta.8 → 9.0.0-beta.80

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 CHANGED
@@ -26,7 +26,7 @@ npm i @praxisui/crud@latest
26
26
  Peer dependencies:
27
27
 
28
28
  - `@angular/common`, `@angular/core`, `@angular/forms`, `@angular/cdk`, `@angular/material`, `@angular/router` `^21.0.0`
29
- - `@praxisui/core`, `@praxisui/table`, `@praxisui/dynamic-form`, `@praxisui/dynamic-fields`, `@praxisui/settings-panel`, `@praxisui/ai` `^9.0.0-beta.4`
29
+ - `@praxisui/core`, `@praxisui/table`, `@praxisui/dynamic-form`, `@praxisui/dynamic-fields`, `@praxisui/settings-panel`, `@praxisui/ai` `^9.0.0-beta.12`
30
30
  - `rxjs` `~7.8.0`
31
31
 
32
32
  ## Quick Start
@@ -94,6 +94,7 @@ export class EmployeesCrudComponent {
94
94
  - `componentInstanceId`: optional host-level instance id
95
95
  - `context`: host/runtime context passed into table and form flows
96
96
  - `enableCustomization`: enables the package authoring surface
97
+ - `authoringCapability`: optionally requires the exact capability from `EnterpriseRuntimeContext.capabilities` before authoring controls, the CRUD editor, and its internal table authoring are available. This is a UX gate; governed persistence must enforce the same policy server-side.
97
98
 
98
99
  It emits:
99
100
 
@@ -127,22 +128,72 @@ Child component semantics stay with their owners:
127
128
  CRUD actions can open by route, modal, or drawer. `CrudLauncherService` resolves the final mode from persisted overrides, action metadata, and global/default configuration.
128
129
 
129
130
  ```ts
130
- const editAction = {
131
+ const editAction: CrudAction = {
131
132
  id: 'edit',
132
- label: 'Edit',
133
+ action: 'edit',
134
+ label: 'Edit employee',
133
135
  openMode: 'drawer',
134
- route: '/employees/:id/edit',
136
+ };
137
+ ```
138
+
139
+ For canonical `create`, `view`, `edit`, and `delete` operations, prefer inferred
140
+ contracts. The runtime resolves the stable form id, request schema, submit URL,
141
+ and HTTP method from the resource path, capabilities, surfaces, and HATEOAS
142
+ links. Use an explicit form contract only when the operation deliberately
143
+ overrides that baseline:
144
+
145
+ ```ts
146
+ const explicitEditAction: CrudAction = {
147
+ id: 'edit',
148
+ action: 'edit',
149
+ label: 'Edit employee',
150
+ openMode: 'drawer',
151
+ formId: 'employee-edit',
152
+ mode: 'explicit',
135
153
  form: {
136
- formId: 'employee-edit',
137
154
  schemaUrl: '/api/employees/schemas/edit',
138
- submitUrl: '/api/employees/:id',
139
- submitMethod: 'PUT',
155
+ submitUrl: '/api/employees/{id}',
156
+ submitMethod: 'put',
140
157
  },
141
- params: [{ from: 'row.id', to: 'path.id', name: 'id' }],
142
158
  };
143
159
  ```
144
160
 
145
- Hosts that use drawer mode must provide the drawer adapter expected by the CRUD launcher. Modal mode uses the package form dialog host.
161
+ Drawer mode works without a host adapter: the package opens its standard form
162
+ dialog host with drawer presentation. Provide `CRUD_DRAWER_ADAPTER` only when a
163
+ host must replace that standard shell with a real corporate drawer implementation.
164
+
165
+ For native edit drawers, the runtime presents the selected record's canonical
166
+ `x-ui.resource.identity` above the command form when the table has materialized
167
+ it. This is read-only context: immutable keys remain outside the request schema
168
+ and are never added to the update payload. Custom drawer adapters retain their
169
+ own presentation responsibility.
170
+
171
+ ## Empty collection state
172
+
173
+ When collection creation is available, `PraxisCrudComponent` derives the initial
174
+ empty state for its table from the resource label and the canonical `create`
175
+ action. The compact state uses the shared `praxis-empty-state-card`, repeats the
176
+ same create label/icon exposed by the toolbar, and invokes the same action path.
177
+
178
+ Filtered or searched empty results remain distinct and use the table no-results
179
+ copy without suggesting that the user create a duplicate record. An explicit
180
+ `table.behavior.emptyState` always wins, allowing domain-specific read-only or
181
+ guided states without host CSS or a parallel empty-state component.
182
+
183
+ ## Duplicate Draft
184
+
185
+ `PraxisCrudComponent` recognizes the canonical optional `duplicate-draft`
186
+ operation published by `praxis-metadata-starter`. When a selected row exposes
187
+ `_links['duplicate-draft']`, the runtime:
188
+
189
+ 1. invokes the non-mutating draft endpoint;
190
+ 2. unwraps the returned draft DTO;
191
+ 3. opens the canonical `create` form with that DTO as `initialValue`;
192
+ 4. refreshes the table only after the user saves the new record.
193
+
194
+ The host does not need to call `HttpClient`, rebuild create schema URLs, or own
195
+ a second launcher. Absence of the HATEOAS link keeps the operation unavailable;
196
+ the runtime does not infer permission from labels, tags, or frontend flags.
146
197
 
147
198
  ## Visual Authoring
148
199