@smartsoft001/crud-shell-angular 2.124.0 โ†’ 2.126.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 CHANGED
@@ -1,7 +1,290 @@
1
- # crud-shell-angular
1
+ # ๐Ÿ“ฆ @smartsoft001/crud-shell-angular
2
2
 
3
- This library was generated with [Nx](https://nx.dev).
3
+ ![npm](https://img.shields.io/npm/v/@smartsoft001/crud-shell-angular) ![downloads](https://img.shields.io/npm/dm/@smartsoft001/crud-shell-angular)
4
4
 
5
- ## Running unit tests
5
+ ## ๐Ÿงญ Overview
6
6
 
7
- Run `nx test crud-shell-angular` to execute the unit tests.
7
+ `@smartsoft001/crud-shell-angular` is the **config / metadata-driven container layer** for
8
+ CRUD screens โ€” **not** a primitive-component library. You do not place a table here, a form
9
+ there, and wire them by hand. Instead you describe **what** the entity is (model decorators)
10
+ and **how** its screens should behave (a config object), and the engine **generates** the UI.
11
+
12
+ Three inputs drive every screen:
13
+
14
+ 1. **Model decorators** โ€” `@Model` / `@Field` from `@smartsoft001/models`, plus a `FieldType`
15
+ per field. These describe the entity's shape, labels, validation and which fields appear in
16
+ list / details / edit / filters.
17
+ 2. **A `CrudFullConfig`** โ€” declares the API endpoint, the entity name, and the screen behavior
18
+ (title, pagination, search, export, sort, list mode, groups, buttons, styling, โ€ฆ).
19
+ 3. **The engine** โ€” `CreateDynamicComponent` and the page components read the config + model
20
+ metadata and instantiate the right children dynamically.
21
+
22
+ The **free** library renders with the free `@smartsoft001/angular` components (Tailwind +
23
+ signals, OnPush, HTML-template-first). The **pro** library
24
+ (`@smartsoft001/pro-crud-shell-angular`, FRA-294) does **not** fork these screens โ€” it
25
+ **extends the `@Directive()` base classes exported here** and registers richer `smartpro-*`
26
+ implementations via the base + token precedent established in `@smartsoft001/angular`.
27
+
28
+ ## ๐Ÿš€ Usage
29
+
30
+ ```bash
31
+ npm i @smartsoft001/crud-shell-angular
32
+ ```
33
+
34
+ ### 1. Describe the entity with model decorators
35
+
36
+ ```typescript
37
+ import { Model, Field, FieldType } from '@smartsoft001/models';
38
+
39
+ @Model({ name: 'user' })
40
+ export class User {
41
+ @Field({ list: true, details: true, create: true, update: true })
42
+ firstName!: string;
43
+
44
+ @Field({ list: true, details: true, create: true, update: true })
45
+ lastName!: string;
46
+
47
+ @Field({
48
+ list: true,
49
+ filter: true,
50
+ fieldType: FieldType.flag,
51
+ })
52
+ active!: boolean;
53
+ }
54
+ ```
55
+
56
+ ### 2. Declare a `CrudFullConfig`
57
+
58
+ ```typescript
59
+ import { CrudFullConfig } from '@smartsoft001/crud-shell-angular';
60
+ import { ListMode, PaginationMode } from '@smartsoft001/angular';
61
+
62
+ export const userConfig: CrudFullConfig<User> = {
63
+ // CrudConfig (base)
64
+ apiUrl: 'https://api.example.com',
65
+ entity: 'user',
66
+ type: User,
67
+
68
+ // CrudFullConfig
69
+ title: 'Users',
70
+ details: true,
71
+ edit: true,
72
+ add: true,
73
+ remove: true,
74
+ search: true,
75
+ export: true,
76
+ pagination: { limit: 25 },
77
+ sort: { default: 'lastName', defaultDesc: false },
78
+ list: {
79
+ mode: ListMode.desktop,
80
+ paginationMode: PaginationMode.singlePage,
81
+ },
82
+
83
+ // Declarative styling (tier 2)
84
+ cssClass: 'smart:bg-gray-50',
85
+ variant: 'standard',
86
+ };
87
+ ```
88
+
89
+ ### 3. Register the module
90
+
91
+ ```typescript
92
+ import { CrudModule } from '@smartsoft001/crud-shell-angular';
93
+
94
+ @NgModule({
95
+ imports: [
96
+ CrudModule.forFeature({
97
+ routing: true, // true -> CrudFullModule (with pages/routing); false -> CrudCoreModule
98
+ config: userConfig,
99
+ // socket: true, // opt-in realtime provider wiring (inert stub today)
100
+ }),
101
+ ],
102
+ })
103
+ export class UserModule {}
104
+ ```
105
+
106
+ ### 4. Place the pages
107
+
108
+ The engine-generated container pages are the **only** hand-placed entry points:
109
+
110
+ ```html
111
+ <!-- List screen (page, search, end-buttons, generated list) -->
112
+ <smart-crud-list-page></smart-crud-list-page>
113
+
114
+ <!-- Item screen (create / update / details) -->
115
+ <smart-crud-item-page></smart-crud-item-page>
116
+ ```
117
+
118
+ When `routing: true`, `CrudFullModule` wires these pages into routes for you.
119
+
120
+ ## โš™๏ธ Configuration
121
+
122
+ ### `CrudConfig<T>` (base)
123
+
124
+ | Property | Type | Description |
125
+ | ---------------- | ----------------------------- | --------------------------------------------------------------- |
126
+ | `apiUrl` | `string` | Backend base URL (also fed to `FILE_SERVICE_CONFIG`) |
127
+ | `entity` | `string` | Entity name โ€” keys the NgRx reducer registration |
128
+ | `type` | `any` | Model class decorated with `@Model` / `@Field` |
129
+ | `reducerFactory` | `() => any` | Optional custom reducer factory (defaults to `getReducer`) |
130
+ | `baseQuery` | `Array<ICrudFilterQueryItem>` | Optional always-applied query items |
131
+
132
+ ### `CrudFullConfig<T>` (extends `CrudConfig<T>`)
133
+
134
+ | Property | Type | Description |
135
+ | ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
136
+ | `title` | `string` | Page title (translated) |
137
+ | `details` | `boolean \| { cellPipe?; components?: { top?; bottom? } }` | Enable details view; optionally a `cellPipe` and top/bottom dynamic components |
138
+ | `edit` | `boolean \| { cellPipe?; components?: { top?; bottom? } }` | Enable edit; optional cell pipe and top/bottom components |
139
+ | `add` | `boolean \| { components?: { top?; bottom? } }` | Enable create; optional top/bottom components |
140
+ | `remove` | `boolean` | Enable row remove |
141
+ | `search` | `boolean` | Enable the page search bar |
142
+ | `export` | `boolean` | Enable the export control |
143
+ | `pagination` | `{ limit: number }` | Page size |
144
+ | `sort` | `boolean \| { default?: string; defaultDesc?: boolean }` | Enable sort; optional default column + direction |
145
+ | `list` | `{ cellPipe?; components?: { top?; multi? }; mode?; paginationMode?; resetQuery?; groups? }` | List behavior (see below) |
146
+ | `buttons` | `Array<IIconButtonOptions>` | Extra header/end buttons rendered through `<smart-page>` |
147
+ | `inputComponents` | `{ [key: string]: Type<InputBaseComponent<T>> }` | Per-field input component overrides (keyed by field name) |
148
+ | `cssClass` | `string` | **Tier-2 styling** โ€” forwarded to `<smart-page [class]>` on the list/item pages |
149
+ | `variant` | `SmartPageVariant` | **Tier-2 styling** โ€” threaded into `pageOptions().variant` to pick a `<smart-page>` variant |
150
+
151
+ `list` sub-fields:
152
+
153
+ | Field | Type | Description |
154
+ | ---------------- | ----------------------------------- | ------------------------------------------------------------ |
155
+ | `mode` | `ListMode` | `desktop` / `mobile` / `masonryGrid` list rendering |
156
+ | `paginationMode` | `PaginationMode` | `singlePage` / `infiniteScroll` |
157
+ | `groups` | `Array<ICrudListGroup>` | Grouped (accordion) list sections |
158
+ | `components` | `{ top?; multi? }` | Dynamic top component + multi-select action component |
159
+ | `cellPipe` | `ICellPipe<T>` | Per-cell value transform |
160
+ | `resetQuery` | `'beforeInit'` | Reset the active filter query before first read |
161
+
162
+ ## ๐Ÿงฉ Components
163
+
164
+ The CRUD module exposes the following selectors. Only the **page** components and `smart-crud-export`
165
+ are normally hand-placed; the rest are mounted by the engine / containers.
166
+
167
+ | Selector | Purpose |
168
+ | --------------------------------------- | ---------------------------------------------------------------------------- |
169
+ | `smart-crud-list-page` | List container page (wraps `<smart-page>`; search, header buttons, list) |
170
+ | `smart-crud-item-page` | Item container page (create / update / details; mode action buttons) |
171
+ | `smart-crud-export` | Export control + post-export popover |
172
+ | `smart-crud-filters` | Filters panel (header, scrollable list of per-field filters) |
173
+ | `smart-crud-filters-config` | Active-filter chips (dismissible badges; remove active query) |
174
+ | `smart-crud-multiselect` | Multi-select header / action bar (`selected: N`, close) |
175
+ | `smart-crud-group` | Grouped list disclosure (accessible HTML accordion, two-way `show`) |
176
+ | `smart-crud-filter` | **Filter dispatcher** โ€” switches on `FieldType` to the right widget below |
177
+ | `smart-crud-filter-text` | Text filter |
178
+ | `smart-crud-filter-int` | Integer filter (value + advanced min/max range) |
179
+ | `smart-crud-filter-flag` | Boolean flag filter |
180
+ | `smart-crud-filter-radio` | Single-choice (radio) filter |
181
+ | `smart-crud-filter-check` | Multi-choice (checkbox list) filter |
182
+ | `smart-crud-filter-date` | Single-date filter |
183
+ | `smart-crud-filter-date-time` | Datetime "from"/"to" range filter |
184
+ | `smart-crud-filter-date-with-edit` | Editable-date filter (value + advanced min/max range) |
185
+
186
+ > The page component selectors have `*-standard` variant children
187
+ > (`smart-crud-list-standard-page`, `smart-crud-item-standard-page`) that hold the actual
188
+ > generated body; the public wrappers above are what you place.
189
+
190
+ ## ๐Ÿ”Ž Filter widgets
191
+
192
+ `smart-crud-filter` is a dispatcher: it reads `item().fieldType` and renders the matching widget
193
+ (`@switch` on `FieldType`, `text` as default). Each widget reuses the **shared input components**
194
+ from `@smartsoft001/angular` wherever the shape fits, is authored **OnPush**, and binds through a
195
+ reactive `FormControl` bridged to the filter state by the base class.
196
+
197
+ | `FieldType` | Widget | Rendering |
198
+ | --------------- | ---------------------------------- | -------------------------------------------------------------------------- |
199
+ | `text` (default)| `smart-crud-filter-text` | `smart-input-text` (reactive `[formControl]`) |
200
+ | `flag` | `smart-crud-filter-flag` | `smart-input-flag` |
201
+ | `radio` | `smart-crud-filter-radio` | `smart-input-radio` (+ possibilities bridge) |
202
+ | `int` | `smart-crud-filter-int` | `smart-input-int` for the value; native Tailwind "from"/"to" range inputs |
203
+ | `check` | `smart-crud-filter-check` | Native Tailwind checkbox list (scalar-id + array value shape) |
204
+ | `date` | `smart-crud-filter-date` | `smart-date-edit` |
205
+ | `dateTime` | `smart-crud-filter-date-time` | Native `<input type="datetime-local">` "from"/"to" |
206
+ | `dateWithEdit` | `smart-crud-filter-date-with-edit` | `smart-date-edit` + native "from"/"to" range |
207
+
208
+ Notes:
209
+
210
+ - **Possibilities** (radio / check options) flow through `options.possibilities` on the shared
211
+ input. The base class maps `possibilities` into the `{ id, text, checked }` shape via
212
+ `buildInputOptions(control, withPossibilities)`. Possibilities resolve from
213
+ `item.possibilities`, and (when provided) the deprecated
214
+ `CRUD_MODEL_POSSIBILITIES_PROVIDER` keyed by `config.type` + field key.
215
+ - **Labels** resolve via the shared `ModelLabelPipe`. The CRUD module ships a default
216
+ `CrudModelLabelProvider` (registered for `IModelLabelProvider`) which delegates to an
217
+ app-level `IModelLabelProvider` higher in the injector tree if one exists, otherwise translates
218
+ `MODEL.<key>`. An app can override it.
219
+ - The base class exposes `bindControl(type)` / `bindValueControl()` (reactive bridge to the
220
+ `value` / `>=` / `<=` query slots), and OnPush-safe `hasValue` / `hasMinValue` / `hasMaxValue`
221
+ computed signals for clear-button visibility.
222
+
223
+ ## ๐ŸŽจ Styling (3-tier)
224
+
225
+ CRUD styling is layered so apps can reach for the lightest tool that does the job:
226
+
227
+ 1. **Tailwind theme (`smart:` prefix).** All CRUD templates use the prefixed Tailwind utilities
228
+ shared with `@smartsoft001/angular`. Theme tokens flow from the host app's Tailwind config.
229
+ 2. **Declarative `cssClass` / `variant` on `CrudFullConfig`.** These are threaded into the page:
230
+ `config.variant` drives `pageOptions().variant` (which `<smart-page>` variant renders) and
231
+ `config.cssClass` is bound as `[class]` on the `<smart-page>` of the list/item screens.
232
+ 3. **`class` on the hand-placed entry points only** โ€” `smart-crud-list-page`,
233
+ `smart-crud-item-page`, `smart-crud-export`. Engine-generated leaf components are mounted
234
+ dynamically and do **not** expose a `class` input; style them through tiers 1โ€“2.
235
+
236
+ ## ๐Ÿงฌ Extending (pro / custom)
237
+
238
+ Every container component is split into a thin `@Directive()` base class (logic only) and a
239
+ concrete implementation, so the **pro** library can extend the logic and supply its own template
240
+ via the base + token precedent from `@smartsoft001/angular`.
241
+
242
+ Exported base classes (from the package barrel):
243
+
244
+ | Base class | Concrete | Extend to customize |
245
+ | ------------------------- | ------------------------- | -------------------------------------------- |
246
+ | `ExportBaseComponent` | `smart-crud-export` | Export trigger + post-export popover logic |
247
+ | `MultiselectBaseComponent`| `smart-crud-multiselect` | Multi-select header / action bar |
248
+ | `FiltersBaseComponent` | `smart-crud-filters` | Filters panel container |
249
+ | `GroupBaseComponent` | `smart-crud-group` | Grouped-list disclosure |
250
+ | `BaseComponent` (filter) | `smart-crud-filter-*` | Per-`FieldType` filter widget logic |
251
+
252
+ The pro library (`@smartsoft001/pro-crud-shell-angular`, FRA-294) provides `smartpro-*` variants
253
+ that `extends` these bases โ€” for example a rich `smartpro-accordion`-backed group โ€” registered
254
+ through the same InjectionToken override pattern used across `@smartsoft001/angular` (the
255
+ `*_STANDARD_COMPONENT_TOKEN` precedent).
256
+
257
+ ## ๐Ÿ…ฐ๏ธ Angular 22 readiness
258
+
259
+ - Components are authored **OnPush**.
260
+ - The form model stays **reactive** (`FormFactory` / `UntypedFormGroup`); signal-forms are a
261
+ planned **additive** step, not a rewrite.
262
+ - `HttpClient` works under the Fetch backend; no XHR-specific assumptions.
263
+
264
+ ## ๐Ÿ“š Storybook
265
+
266
+ ```bash
267
+ nx storybook crud-shell-angular
268
+ ```
269
+
270
+ ## ๐Ÿงช Unit tests
271
+
272
+ ```bash
273
+ nx test crud-shell-angular
274
+ ```
275
+
276
+ ## ๐Ÿค Contributing
277
+
278
+ Contributions are welcome! ๐ŸŽ‰
279
+
280
+ 1. Fork the repository.
281
+ 2. Create a feature branch: git checkout -b feature/my-new-feature.
282
+ 3. Commit your changes: git commit -m 'Add some feature'.
283
+ 4. Push to the branch: git push origin feature/my-new-feature.
284
+ Submit a pull request.
285
+
286
+ For more details, see our [Contributing Guidelines](../../../../CONTRIBUTING.md).
287
+
288
+ ## ๐Ÿ“ Changelog
289
+
290
+ All notable changes to this project will be documented in the [CHANGELOG](../../../../CHANGELOG.md).