ngx-dynamic-entity 2.2.0 → 2.3.1

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
@@ -23,11 +23,18 @@ No Angular Material required. This package has no dependency on Material or the
23
23
 
24
24
  - **`DynamicFormComponent`** — tabbed dynamic forms generated from an `EntityFormConfig`, built on Angular Reactive Forms.
25
25
  - **`DynamicRecordFormComponent`** — record editor with summary drawer (`showOnMinimize`), profile header, and per-section saving.
26
- - **Reactive rules** — real-time condition evaluation driving field/tab visibility, validation errors and warnings, and info banners.
27
- - **Entity references & cascades** — consumer-registered loaders, parent→child dropdown filtering, and `autoPatch` record copying.
26
+ - **`EntityImportComponent`** (`ngx-entity-import`) — a four-step spreadsheet import wizard (choose a file, match columns, review, done) that derives its columns from the config and works with no backend. See [Spreadsheet import](#-spreadsheet-import).
27
+ - **Reactive rules** — real-time condition evaluation driving field/tab visibility, validation errors and warnings, and info banners. A rule names a field by bare id or by `[path]`, at any depth.
28
+ - **Sync and async validation** — built-in validators, named ones you register, async checks against a server, and an abortable `beforeSave` hook. `saveRejected` says why a save was refused.
29
+ - **A refused save explains itself** — Save stays clickable on an invalid form; pressing it lists every field at fault and what is wrong with it, badges each tab with its count, and jumps to the first.
30
+ - **Field help text** — `hint` puts an info icon beside a label, wired to the control with `aria-describedby`.
31
+ - **Entity references, lookup lists & cascades** — consumer-registered loaders, named master lists resolved by name, parent→child dropdown filtering, and `autoPatch` record copying.
32
+ - **Record migration** — register `migrations` and a record saved under an older `config.version` is upgraded as it enters the form.
28
33
  - **27 field types** — each a standalone component, registered explicitly so unused types are never bundled.
34
+ - **Layout** — `layout="auto"` sizes fields by type instead of giving each the full width; `colSpan` sizes one field on a 12-column grid.
29
35
  - **Fully translatable** — config text is `LocalizedText`; the library's own buttons and empty states resolve through `uiText`.
30
36
  - **Configurable masking and dates** — `MASKED_PLACEHOLDER` replaces the `XXXXXXXXX` literal; `setDateFormatters` in `@dynamic-entity/core` replaces the browser-locale date punctuation.
37
+ - **Optional stylesheet** — unstyled by default; import `ngx-dynamic-entity/styles.css` for a token-driven base theme with dark mode.
31
38
 
32
39
  ---
33
40
 
@@ -63,6 +70,24 @@ provideFieldTypes({ text: TextFieldComponent, dropdown: DropdownFieldComponent }
63
70
 
64
71
  Multiple `provideFieldTypes` calls merge; on a key collision the later registration wins. Pass your own component for a key to override a built-in, or add a key of your own for a custom type.
65
72
 
73
+ Everything else is an option on `provideNgxDynamicEntity`:
74
+
75
+ | Option | What it registers |
76
+ |---|---|
77
+ | `maskedRoles` | Roles that see `maskData` fields masked |
78
+ | `fieldTypes` | Field components, the same as `provideFieldTypes` |
79
+ | `entityRefs` | `entity-ref` loaders by registry key |
80
+ | `lookups` | Named option lists (`listName`), sync or async |
81
+ | `validators` / `asyncValidators` | Validators named by `validators.custom` / `customAsync` |
82
+ | `validationMessages` | Error text per validator key, a string or `(language, error) => string` |
83
+ | `uiText` | The library's own text — see below |
84
+ | `hooks` | Lifecycle hooks keyed `<entity>:<hook>` — `beforeSave` may abort a save |
85
+ | `migrations` | `RecordMigration[]` applied as a record enters the form |
86
+ | `sheetParser` | A reader for upload formats beyond delimited text, e.g. `.xlsx` |
87
+ | `importTransport` | Where an import runs — see `provideHttpImportTransport` |
88
+
89
+ Details for each are in [EXTENDING.md](../../EXTENDING.md).
90
+
66
91
  Some field types take an optional collaborator. A `markdown` field renders its source as
67
92
  text until you register a renderer — see
68
93
  [Markdown](../../EXTENDING.md#markdown) for `MARKDOWN_RENDERER`, which is any function from
@@ -154,6 +179,10 @@ summary panel, so one value cannot render two ways depending on where you look.
154
179
  | `readonly` | `boolean` | Renders the whole form read-only. |
155
180
  | `readOnlyFields` | `string[]` | Read-only by field id. |
156
181
  | `loading` / `error` | `boolean` / `string \| null` | Render loading and error states. |
182
+ | `layout` | `'stack' \| 'auto'` | Default `'stack'`, every field full width. `'auto'` sizes fields without a `colSpan` by type. |
183
+ | `changeDebounceMs` | `number` | Debounce for `formChange`. Default `0`, synchronous. |
184
+ | `showInfoBanners` | `boolean` | Render rule `info` banners inline. Default `true`. |
185
+ | `preview` | `boolean` | Seed one empty row per `array` and disable the form, as the builder's live preview does. |
157
186
 
158
187
  ### Outputs
159
188
 
@@ -163,6 +192,7 @@ summary panel, so one value cannot render two ways depending on where you look.
163
192
  | `formChange` | `Record<string, any>` |
164
193
  | `formReset` | `void` |
165
194
  | `activeTabChange` | `string` (tab id) |
195
+ | `saveRejected` | `{ reason, error? }` — a `beforeSave` hook aborted the save. |
166
196
 
167
197
  ---
168
198
 
@@ -194,7 +224,7 @@ that do not want the section flow.
194
224
 
195
225
  | Input | Type | Notes |
196
226
  |---|---|---|
197
- | `config` / `initialData` / `userRoles` / `language` | — | As the form component. |
227
+ | `config` / `initialData` / `userRoles` / `language` / `layout` / `loading` / `error` | — | As the form component. |
198
228
  | `viewMode` | `boolean` | Default `true`. Read-only with a per-tab edit flow. |
199
229
  | `isReadOnly` | `boolean` | Whole record read-only, with no edit affordance at all. |
200
230
  | `readOnlyFields` | `string[]` | Specific ids read-only while the rest stays editable. |
@@ -216,6 +246,34 @@ rendering decision, not an access-control boundary.
216
246
 
217
247
  ---
218
248
 
249
+ ## 📥 Spreadsheet import
250
+
251
+ ```html
252
+ <ngx-entity-import [config]="config" [rules]="rules" (importComplete)="save($event)" />
253
+ ```
254
+
255
+ | Input | Notes |
256
+ |---|---|
257
+ | `config` | Required. The columns, template and validation all derive from it. |
258
+ | `rules` | Pass the same rules the form uses, or a rule-hidden required field rejects rows the form would save. |
259
+ | `lookups` | Option lists already resolved, merged over what `LOOKUP_REGISTRY` provides. |
260
+ | `language` | Default `'en'`. |
261
+ | `templateFormat` | `'csv'` (default) or `'xlsx'`. `xlsx` needs a server transport. |
262
+
263
+ | Output | Payload |
264
+ |---|---|
265
+ | `importComplete` | `ImportResult` — the records, the rows that failed and why. **Nothing is stored for you**: this is where you write them. |
266
+ | `templateReady` | `Blob` — the generated template. |
267
+
268
+ With nothing registered, the file is read and mapped in the browser. The built-in reader
269
+ handles comma CSV, semicolon CSV and TSV, detecting the separator from the header line; a
270
+ `sheetParser` adds other formats. `provideHttpImportTransport({ baseUrl })` moves the same
271
+ wizard onto [`@dynamic-entity/server`](../server) for files a tab cannot hold. The column
272
+ contract, numbered array headers and the validation-parity gap are in
273
+ [EXTENDING.md](../../EXTENDING.md#spreadsheet-import).
274
+
275
+ ---
276
+
219
277
  ## 🗂 Record shape
220
278
 
221
279
  A record is **nested by tab id** by default:
@@ -256,4 +314,18 @@ The visual builder is a separate package and is not an SSR target.
256
314
 
257
315
  ## 🎨 Styling
258
316
 
259
- This package ships no CSS. Field components emit `ngx-field`, `ngx-field__label`, `ngx-field__input`, and `ngx-field__error` for you to style. See `packages/demo-angular/src/styles.css` in the repository for a working reference.
317
+ Nothing is styled unless you ask. Field components emit `ngx-field`, `ngx-field__label`,
318
+ `ngx-field__input`, and `ngx-field__error` for you to style, and the package has no design
319
+ system of its own.
320
+
321
+ An optional base stylesheet ships with it, driven entirely by custom properties and scoped to
322
+ `.ngx-form` / `.ngx-record-editor`, with a dark palette under `prefers-color-scheme: dark`:
323
+
324
+ ```css
325
+ @import 'ngx-dynamic-entity/styles.css';
326
+ ```
327
+
328
+ Re-skin it by redeclaring tokens such as `--ngx-color-accent` on the same selectors. Add
329
+ `ngx-form-sticky-actions` to a wrapper for a Save bar that stays in view. See the
330
+ [root README](../../README.md#-styling) for the full token story, and
331
+ `packages/demo-angular/src/styles.css` for a working reference.