@eqproject/eqp-dynamic-module 2.10.104 → 2.10.105
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/USERGUIDE.md +437 -437
- package/esm2020/lib/components/exported/eqp-dynamic-module-configurator/eqp-dynamic-module-configurator.component.mjs +2 -2
- package/esm2020/lib/components/private/add-form-field/add-form-field.component.mjs +45 -28
- package/esm2020/lib/components/private/add-formula-field/add-formula-field.component.mjs +74 -13
- package/esm2020/lib/components/private/dynamic-module-field-extra-fix/dynamic-module-field-extra-fix.component.mjs +20 -2
- package/esm2020/lib/components/private/field-templates/attachment-field-template/attachment-field-template.component.mjs +1 -1
- package/esm2020/lib/components/private/graphs/graph/graph.component.mjs +3 -3
- package/fesm2015/eqproject-eqp-dynamic-module.mjs +140 -44
- package/fesm2015/eqproject-eqp-dynamic-module.mjs.map +1 -1
- package/fesm2020/eqproject-eqp-dynamic-module.mjs +140 -44
- package/fesm2020/eqproject-eqp-dynamic-module.mjs.map +1 -1
- package/lib/components/private/add-formula-field/add-formula-field.component.d.ts +5 -1
- package/package.json +2 -2
package/USERGUIDE.md
CHANGED
|
@@ -1,437 +1,437 @@
|
|
|
1
|
-
# Guida utente — @eqproject/eqp-dynamic-module
|
|
2
|
-
|
|
3
|
-
> Documento complementare al [README.md](./README.md). Contiene guide pratiche d'uso e prompt AI di esempio.
|
|
4
|
-
> Companion document to [README.md](./README.md). Contains practical usage guides and example AI prompts.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Indice / Table of Contents
|
|
9
|
-
|
|
10
|
-
- [Guida utente (Italiano)](#guida-utente-italiano)
|
|
11
|
-
- [Scenario 1 — Form in sola lettura (VIEW)](#scenario-1--form-in-sola-lettura-view)
|
|
12
|
-
- [Scenario 2 — Compilazione form (COMPILE)](#scenario-2--compilazione-form-compile)
|
|
13
|
-
- [Scenario 3 — Lista risposte con filtri (LIST)](#scenario-3--lista-risposte-con-filtri-list)
|
|
14
|
-
- [Scenario 4 — Configuratore no-code](#scenario-4--configuratore-no-code)
|
|
15
|
-
- [Scenario 5 — Endpoint personalizzati](#scenario-5--endpoint-personalizzati)
|
|
16
|
-
- [Troubleshooting](#troubleshooting)
|
|
17
|
-
- [User Guide (English)](#user-guide-english)
|
|
18
|
-
- [Scenario 1 — Read-only form (VIEW)](#scenario-1--read-only-form-view)
|
|
19
|
-
- [Scenario 2 — Form fill (COMPILE)](#scenario-2--form-fill-compile)
|
|
20
|
-
- [Scenario 3 — Answer list with filters (LIST)](#scenario-3--answer-list-with-filters-list)
|
|
21
|
-
- [Scenario 4 — No-code configurator](#scenario-4--no-code-configurator)
|
|
22
|
-
- [Scenario 5 — Custom endpoints](#scenario-5--custom-endpoints)
|
|
23
|
-
- [Troubleshooting (EN)](#troubleshooting-en)
|
|
24
|
-
- [Utilizzo con AI / AI-assisted Usage](#utilizzo-con-ai--ai-assisted-usage)
|
|
25
|
-
- [Prompt per Claude Code](#prompt-per-claude-code)
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## Guida utente (Italiano)
|
|
30
|
-
|
|
31
|
-
### Prerequisiti
|
|
32
|
-
|
|
33
|
-
1. Angular 15
|
|
34
|
-
2. `npm install @eqproject/eqp-dynamic-module --legacy-peer-deps`
|
|
35
|
-
3. `EqpDynamicModuleModule` importato nel modulo Angular consumer (vedi README)
|
|
36
|
-
4. Un server che espone le API DynamicModule (oppure endpoint custom configurati via `EndPointConfiguration`)
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
### Scenario 1 — Form in sola lettura (VIEW)
|
|
41
|
-
|
|
42
|
-
Mostrare una form compilata senza possibilità di modifica. Tipico caso d'uso: pagina di dettaglio di un record.
|
|
43
|
-
|
|
44
|
-
**Template:**
|
|
45
|
-
```html
|
|
46
|
-
<eqp-dynamic-module
|
|
47
|
-
[dynamicModuleConfig]="configView"
|
|
48
|
-
[starterViewMode]="'VIEW'"
|
|
49
|
-
[formId]="selectedFormId"
|
|
50
|
-
[recordId]="selectedRecordId">
|
|
51
|
-
</eqp-dynamic-module>
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**Componente:**
|
|
55
|
-
```typescript
|
|
56
|
-
import { DynamicModuleConfig, DynamicModuleGeneralConfig, DynamicModuleViewModeEnum } from '@eqproject/eqp-dynamic-module';
|
|
57
|
-
|
|
58
|
-
configView: DynamicModuleConfig = {
|
|
59
|
-
GeneralConfig: {
|
|
60
|
-
baseServerUrl: 'https://your-api-host',
|
|
61
|
-
userToken: this.authService.getToken(),
|
|
62
|
-
context: 'MY_APP'
|
|
63
|
-
} as DynamicModuleGeneralConfig
|
|
64
|
-
} as DynamicModuleConfig;
|
|
65
|
-
|
|
66
|
-
starterViewMode = DynamicModuleViewModeEnum.VIEW;
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
### Scenario 2 — Compilazione form (COMPILE)
|
|
72
|
-
|
|
73
|
-
Permettere all'utente di inserire o modificare una risposta.
|
|
74
|
-
|
|
75
|
-
```html
|
|
76
|
-
<eqp-dynamic-module
|
|
77
|
-
[dynamicModuleConfig]="configCompile"
|
|
78
|
-
[starterViewMode]="'COMPILE'"
|
|
79
|
-
[formId]="formId"
|
|
80
|
-
[recordId]="null"
|
|
81
|
-
(onRecordSaved)="handleSaved($event)">
|
|
82
|
-
</eqp-dynamic-module>
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
- Passa `recordId = null` per una nuova risposta, oppure un ID esistente per modificarla.
|
|
86
|
-
- Ascolta `(onRecordSaved)` per reagire al salvataggio.
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
### Scenario 3 — Lista risposte con filtri (LIST)
|
|
91
|
-
|
|
92
|
-
Visualizzare la lista delle risposte a una form con filtri e paginazione integrati.
|
|
93
|
-
|
|
94
|
-
```html
|
|
95
|
-
<eqp-dynamic-module
|
|
96
|
-
[dynamicModuleConfig]="configList"
|
|
97
|
-
[starterViewMode]="'LIST'"
|
|
98
|
-
[formId]="formId">
|
|
99
|
-
</eqp-dynamic-module>
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Per abilitare i filtri dalla lista imposta `ListConfig.showFilters = true` dentro `DynamicModuleConfig`.
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
### Scenario 4 — Configuratore no-code
|
|
107
|
-
|
|
108
|
-
Permettere a un amministratore di creare o modificare la definizione di una form.
|
|
109
|
-
|
|
110
|
-
```html
|
|
111
|
-
<eqp-dynamic-module-configurator
|
|
112
|
-
[dynamicModuleConfiguratorConfig]="configConfigurator"
|
|
113
|
-
[configuratorMode]="'EDIT'"
|
|
114
|
-
[formId]="formId"
|
|
115
|
-
(onFormSaved)="handleFormSaved($event)">
|
|
116
|
-
</eqp-dynamic-module-configurator>
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
**Modalità disponibili:**
|
|
120
|
-
|
|
121
|
-
| Valore | Comportamento |
|
|
122
|
-
|--------|---------------|
|
|
123
|
-
| `NEW` | Crea una nuova form da zero |
|
|
124
|
-
| `EDIT` | Modifica una form esistente per `formId` |
|
|
125
|
-
| `EXPORT` | Esporta la form come JSON scaricabile |
|
|
126
|
-
| `IMPORT` | Importa una form da JSON |
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
### Scenario 5 — Endpoint personalizzati
|
|
131
|
-
|
|
132
|
-
Quando il server non espone le API al percorso default, configura `EndPointConfiguration`:
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
import { EndPointConfiguration, EndPointData, ParamTypeEnum } from '@eqproject/eqp-dynamic-module';
|
|
136
|
-
|
|
137
|
-
const customEndpoints: EndPointConfiguration = new EndPointConfiguration();
|
|
138
|
-
customEndpoints.Records.GetAll = {
|
|
139
|
-
Url: 'https://custom-host/api/records',
|
|
140
|
-
Token: 'Bearer my-token',
|
|
141
|
-
RequestMethod: 'GET',
|
|
142
|
-
Params: []
|
|
143
|
-
} as EndPointData;
|
|
144
|
-
|
|
145
|
-
// Poi passa customEndpoints in GeneralConfig.EndPointConfiguration
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
Ogni campo di `EndPointConfiguration` è opzionale: puoi sovrascrivere solo gli endpoint che differiscono dai default.
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
### Troubleshooting
|
|
153
|
-
|
|
154
|
-
**Campi non visibili nel configuratore**
|
|
155
|
-
- Verifica che il `formId` sia corretto e che il server risponda su `GET /api/conf/form/{id}`.
|
|
156
|
-
|
|
157
|
-
**Errore CORS**
|
|
158
|
-
- Il server deve restituire `Access-Control-Allow-Origin: *` (o il dominio specifico). In sviluppo puoi usare il proxy Angular.
|
|
159
|
-
|
|
160
|
-
**Form vuota in modalità COMPILE**
|
|
161
|
-
- Controlla che `baseServerUrl` non abbia una barra finale (`/`).
|
|
162
|
-
- Verifica che `userToken` sia valido e non scaduto.
|
|
163
|
-
|
|
164
|
-
**Lista non si aggiorna dopo salvataggio**
|
|
165
|
-
- Chiama `dynamicModuleRef.refreshList()` nell'handler di `(onRecordSaved)` oppure passa `ListConfig.autoRefresh = true`.
|
|
166
|
-
|
|
167
|
-
**Errore di tipo sui campi data**
|
|
168
|
-
- Da v2.10.62 il formato data usa token Luxon (`dd/MM/yyyy`). Se aggiorni da versioni precedenti, verifica i valori salvati in DB.
|
|
169
|
-
|
|
170
|
-
---
|
|
171
|
-
|
|
172
|
-
## User Guide (English)
|
|
173
|
-
|
|
174
|
-
### Prerequisites
|
|
175
|
-
|
|
176
|
-
1. Angular 15
|
|
177
|
-
2. `npm install @eqproject/eqp-dynamic-module --legacy-peer-deps`
|
|
178
|
-
3. `EqpDynamicModuleModule` imported in the consumer Angular module (see README)
|
|
179
|
-
4. A server exposing the DynamicModule API (or custom endpoints configured via `EndPointConfiguration`)
|
|
180
|
-
|
|
181
|
-
---
|
|
182
|
-
|
|
183
|
-
### Scenario 1 — Read-only form (VIEW)
|
|
184
|
-
|
|
185
|
-
Display a completed form without allowing edits. Typical use case: detail page of a record.
|
|
186
|
-
|
|
187
|
-
**Template:**
|
|
188
|
-
```html
|
|
189
|
-
<eqp-dynamic-module
|
|
190
|
-
[dynamicModuleConfig]="configView"
|
|
191
|
-
[starterViewMode]="'VIEW'"
|
|
192
|
-
[formId]="selectedFormId"
|
|
193
|
-
[recordId]="selectedRecordId">
|
|
194
|
-
</eqp-dynamic-module>
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
**Component:**
|
|
198
|
-
```typescript
|
|
199
|
-
import { DynamicModuleConfig, DynamicModuleGeneralConfig, DynamicModuleViewModeEnum } from '@eqproject/eqp-dynamic-module';
|
|
200
|
-
|
|
201
|
-
configView: DynamicModuleConfig = {
|
|
202
|
-
GeneralConfig: {
|
|
203
|
-
baseServerUrl: 'https://your-api-host',
|
|
204
|
-
userToken: this.authService.getToken(),
|
|
205
|
-
context: 'MY_APP'
|
|
206
|
-
} as DynamicModuleGeneralConfig
|
|
207
|
-
} as DynamicModuleConfig;
|
|
208
|
-
|
|
209
|
-
starterViewMode = DynamicModuleViewModeEnum.VIEW;
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
---
|
|
213
|
-
|
|
214
|
-
### Scenario 2 — Form fill (COMPILE)
|
|
215
|
-
|
|
216
|
-
Allow the user to create or edit an answer.
|
|
217
|
-
|
|
218
|
-
```html
|
|
219
|
-
<eqp-dynamic-module
|
|
220
|
-
[dynamicModuleConfig]="configCompile"
|
|
221
|
-
[starterViewMode]="'COMPILE'"
|
|
222
|
-
[formId]="formId"
|
|
223
|
-
[recordId]="null"
|
|
224
|
-
(onRecordSaved)="handleSaved($event)">
|
|
225
|
-
</eqp-dynamic-module>
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
- Pass `recordId = null` for a new answer, or an existing ID to edit it.
|
|
229
|
-
- Listen to `(onRecordSaved)` to react to the save event.
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
### Scenario 3 — Answer list with filters (LIST)
|
|
234
|
-
|
|
235
|
-
Display the list of answers for a form with built-in filters and pagination.
|
|
236
|
-
|
|
237
|
-
```html
|
|
238
|
-
<eqp-dynamic-module
|
|
239
|
-
[dynamicModuleConfig]="configList"
|
|
240
|
-
[starterViewMode]="'LIST'"
|
|
241
|
-
[formId]="formId">
|
|
242
|
-
</eqp-dynamic-module>
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
To enable list filters set `ListConfig.showFilters = true` inside `DynamicModuleConfig`.
|
|
246
|
-
|
|
247
|
-
---
|
|
248
|
-
|
|
249
|
-
### Scenario 4 — No-code configurator
|
|
250
|
-
|
|
251
|
-
Let an administrator create or modify a form definition.
|
|
252
|
-
|
|
253
|
-
```html
|
|
254
|
-
<eqp-dynamic-module-configurator
|
|
255
|
-
[dynamicModuleConfiguratorConfig]="configConfigurator"
|
|
256
|
-
[configuratorMode]="'EDIT'"
|
|
257
|
-
[formId]="formId"
|
|
258
|
-
(onFormSaved)="handleFormSaved($event)">
|
|
259
|
-
</eqp-dynamic-module-configurator>
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
**Available modes:**
|
|
263
|
-
|
|
264
|
-
| Value | Behaviour |
|
|
265
|
-
|-------|-----------|
|
|
266
|
-
| `NEW` | Create a new form from scratch |
|
|
267
|
-
| `EDIT` | Edit an existing form by `formId` |
|
|
268
|
-
| `EXPORT` | Export the form as a downloadable JSON |
|
|
269
|
-
| `IMPORT` | Import a form from a JSON file |
|
|
270
|
-
|
|
271
|
-
---
|
|
272
|
-
|
|
273
|
-
### Scenario 5 — Custom endpoints
|
|
274
|
-
|
|
275
|
-
When the server does not expose APIs at the default paths, configure `EndPointConfiguration`:
|
|
276
|
-
|
|
277
|
-
```typescript
|
|
278
|
-
import { EndPointConfiguration, EndPointData, ParamTypeEnum } from '@eqproject/eqp-dynamic-module';
|
|
279
|
-
|
|
280
|
-
const customEndpoints: EndPointConfiguration = new EndPointConfiguration();
|
|
281
|
-
customEndpoints.Records.GetAll = {
|
|
282
|
-
Url: 'https://custom-host/api/records',
|
|
283
|
-
Token: 'Bearer my-token',
|
|
284
|
-
RequestMethod: 'GET',
|
|
285
|
-
Params: []
|
|
286
|
-
} as EndPointData;
|
|
287
|
-
|
|
288
|
-
// Then pass customEndpoints in GeneralConfig.EndPointConfiguration
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
Each field in `EndPointConfiguration` is optional — only override the endpoints that differ from the defaults.
|
|
292
|
-
|
|
293
|
-
---
|
|
294
|
-
|
|
295
|
-
### Troubleshooting (EN)
|
|
296
|
-
|
|
297
|
-
**Fields not visible in the configurator**
|
|
298
|
-
- Verify that `formId` is correct and that the server responds on `GET /api/conf/form/{id}`.
|
|
299
|
-
|
|
300
|
-
**CORS error**
|
|
301
|
-
- The server must return `Access-Control-Allow-Origin: *` (or the specific domain). In development you can use the Angular proxy.
|
|
302
|
-
|
|
303
|
-
**Empty form in COMPILE mode**
|
|
304
|
-
- Check that `baseServerUrl` does not have a trailing slash (`/`).
|
|
305
|
-
- Verify that `userToken` is valid and not expired.
|
|
306
|
-
|
|
307
|
-
**List does not refresh after save**
|
|
308
|
-
- Call `dynamicModuleRef.refreshList()` in the `(onRecordSaved)` handler, or pass `ListConfig.autoRefresh = true`.
|
|
309
|
-
|
|
310
|
-
**Date field type error**
|
|
311
|
-
- From v2.10.62 dates use Luxon tokens (`dd/MM/yyyy`). If upgrading from older versions, verify DB-saved values.
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## Utilizzo con AI / AI-assisted Usage
|
|
316
|
-
|
|
317
|
-
Questa sezione mostra come usare Claude Code (o un altro assistente AI) per lavorare con `@eqproject/eqp-dynamic-module` in modo efficiente, sia come consumatore della libreria che come manutentore.
|
|
318
|
-
|
|
319
|
-
*This section shows how to use Claude Code (or another AI assistant) to work efficiently with `@eqproject/eqp-dynamic-module`, both as a consumer and as a maintainer.*
|
|
320
|
-
|
|
321
|
-
---
|
|
322
|
-
|
|
323
|
-
### Prompt per Claude Code
|
|
324
|
-
|
|
325
|
-
I prompt seguenti funzionano bene con Claude Code (CLI `claude`) all'interno del repo `DynamicModuleClient`.
|
|
326
|
-
|
|
327
|
-
*The following prompts work well with Claude Code (CLI `claude`) inside the `DynamicModuleClient` repo.*
|
|
328
|
-
|
|
329
|
-
---
|
|
330
|
-
|
|
331
|
-
#### Pubblicazione NPM
|
|
332
|
-
|
|
333
|
-
```
|
|
334
|
-
Pubblica una nuova versione patch del modulo su npm.
|
|
335
|
-
```
|
|
336
|
-
```
|
|
337
|
-
Fai una release minor del modulo dinamico.
|
|
338
|
-
```
|
|
339
|
-
```
|
|
340
|
-
Fai una release major — stiamo rilasciando la versione 3.
|
|
341
|
-
```
|
|
342
|
-
```
|
|
343
|
-
Release patch — ma prima controlla che non ci siano errori TypeScript.
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
Claude eseguirà: analisi diff → aggiornamento README e USERGUIDE → bump versione → build → publish → commit → aggiornamento TMED.
|
|
347
|
-
|
|
348
|
-
---
|
|
349
|
-
|
|
350
|
-
#### Aggiungere un tipo di campo
|
|
351
|
-
|
|
352
|
-
```
|
|
353
|
-
Aggiungi un nuovo tipo di campo chiamato "SignatureField" per la firma digitale.
|
|
354
|
-
Deve comparire nel configuratore come "Firma" e salvare una stringa base64.
|
|
355
|
-
```
|
|
356
|
-
```
|
|
357
|
-
Voglio un campo "RatingField" (stelle 1-5). Mostralo in sola lettura come stelle SVG
|
|
358
|
-
e in compilazione come radio button.
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
Claude creerà: modello in `models/fields/`, template di rendering, template filtro, template trigger, enum, registrazione nel modulo, export da `public-api.ts`.
|
|
362
|
-
|
|
363
|
-
---
|
|
364
|
-
|
|
365
|
-
#### Correzione bug
|
|
366
|
-
|
|
367
|
-
```
|
|
368
|
-
Nella modalità LIST il componente non mostra i risultati quando la lista è vuota.
|
|
369
|
-
Cerca la causa e correggila.
|
|
370
|
-
```
|
|
371
|
-
```
|
|
372
|
-
Gli ActionButton nei form in modalità VIEW sono cliccabili ma non dovrebbero esserlo.
|
|
373
|
-
```
|
|
374
|
-
```
|
|
375
|
-
Il configuratore non salva i trigger quando ci sono più di 5 condizioni.
|
|
376
|
-
Analizza il problema e proponi la correzione.
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
---
|
|
380
|
-
|
|
381
|
-
#### Analisi e spiegazione
|
|
382
|
-
|
|
383
|
-
```
|
|
384
|
-
Spiega come funziona il sistema di trigger nel configuratore.
|
|
385
|
-
```
|
|
386
|
-
```
|
|
387
|
-
Come viene gestita la modalità FILTER? Quali componenti sono coinvolti?
|
|
388
|
-
```
|
|
389
|
-
```
|
|
390
|
-
Quali endpoint chiama il componente in modalità COMPILE? Mostrami il flusso completo.
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
#### Aggiornamento documentazione
|
|
396
|
-
|
|
397
|
-
```
|
|
398
|
-
Il README è obsoleto rispetto al codice. Aggiornalo analizzando i cambiamenti
|
|
399
|
-
dall'ultimo tag git.
|
|
400
|
-
```
|
|
401
|
-
```
|
|
402
|
-
Aggiorna la sezione Changelog del README con le modifiche fatte dall'ultima versione.
|
|
403
|
-
```
|
|
404
|
-
```
|
|
405
|
-
Aggiungi a USERGUIDE.md un esempio per il campo ImageWithMarkers.
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
---
|
|
409
|
-
|
|
410
|
-
#### Task e tracciamento ADO
|
|
411
|
-
|
|
412
|
-
```
|
|
413
|
-
Crea un task ADO per l'implementazione del SignatureField nel modulo dinamico.
|
|
414
|
-
```
|
|
415
|
-
```
|
|
416
|
-
Apri un task per il bug degli ActionButton in VIEW mode — è un fix critico.
|
|
417
|
-
```
|
|
418
|
-
```
|
|
419
|
-
Questo fix tocca sia DynamicModuleClient che DynamicModule. Crea un task per entrambi i progetti e linkali come Related.
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
---
|
|
423
|
-
|
|
424
|
-
#### Workflow multi-step
|
|
425
|
-
|
|
426
|
-
```
|
|
427
|
-
Analizza i cambiamenti dall'ultima release, aggiorna README e USERGUIDE,
|
|
428
|
-
poi fai una release patch.
|
|
429
|
-
```
|
|
430
|
-
```
|
|
431
|
-
C'è un bug in produzione sugli allegati in modalità COMPILE. Analizza la causa,
|
|
432
|
-
crea un task ADO, correggilo e fai una release patch urgente.
|
|
433
|
-
```
|
|
434
|
-
```
|
|
435
|
-
Voglio aggiungere il supporto a un nuovo endpoint per l'esportazione CSV.
|
|
436
|
-
Crea il task ADO, implementa la modifica e poi fai una release minor.
|
|
437
|
-
```
|
|
1
|
+
# Guida utente — @eqproject/eqp-dynamic-module
|
|
2
|
+
|
|
3
|
+
> Documento complementare al [README.md](./README.md). Contiene guide pratiche d'uso e prompt AI di esempio.
|
|
4
|
+
> Companion document to [README.md](./README.md). Contains practical usage guides and example AI prompts.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Indice / Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Guida utente (Italiano)](#guida-utente-italiano)
|
|
11
|
+
- [Scenario 1 — Form in sola lettura (VIEW)](#scenario-1--form-in-sola-lettura-view)
|
|
12
|
+
- [Scenario 2 — Compilazione form (COMPILE)](#scenario-2--compilazione-form-compile)
|
|
13
|
+
- [Scenario 3 — Lista risposte con filtri (LIST)](#scenario-3--lista-risposte-con-filtri-list)
|
|
14
|
+
- [Scenario 4 — Configuratore no-code](#scenario-4--configuratore-no-code)
|
|
15
|
+
- [Scenario 5 — Endpoint personalizzati](#scenario-5--endpoint-personalizzati)
|
|
16
|
+
- [Troubleshooting](#troubleshooting)
|
|
17
|
+
- [User Guide (English)](#user-guide-english)
|
|
18
|
+
- [Scenario 1 — Read-only form (VIEW)](#scenario-1--read-only-form-view)
|
|
19
|
+
- [Scenario 2 — Form fill (COMPILE)](#scenario-2--form-fill-compile)
|
|
20
|
+
- [Scenario 3 — Answer list with filters (LIST)](#scenario-3--answer-list-with-filters-list)
|
|
21
|
+
- [Scenario 4 — No-code configurator](#scenario-4--no-code-configurator)
|
|
22
|
+
- [Scenario 5 — Custom endpoints](#scenario-5--custom-endpoints)
|
|
23
|
+
- [Troubleshooting (EN)](#troubleshooting-en)
|
|
24
|
+
- [Utilizzo con AI / AI-assisted Usage](#utilizzo-con-ai--ai-assisted-usage)
|
|
25
|
+
- [Prompt per Claude Code](#prompt-per-claude-code)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Guida utente (Italiano)
|
|
30
|
+
|
|
31
|
+
### Prerequisiti
|
|
32
|
+
|
|
33
|
+
1. Angular 15
|
|
34
|
+
2. `npm install @eqproject/eqp-dynamic-module --legacy-peer-deps`
|
|
35
|
+
3. `EqpDynamicModuleModule` importato nel modulo Angular consumer (vedi README)
|
|
36
|
+
4. Un server che espone le API DynamicModule (oppure endpoint custom configurati via `EndPointConfiguration`)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### Scenario 1 — Form in sola lettura (VIEW)
|
|
41
|
+
|
|
42
|
+
Mostrare una form compilata senza possibilità di modifica. Tipico caso d'uso: pagina di dettaglio di un record.
|
|
43
|
+
|
|
44
|
+
**Template:**
|
|
45
|
+
```html
|
|
46
|
+
<eqp-dynamic-module
|
|
47
|
+
[dynamicModuleConfig]="configView"
|
|
48
|
+
[starterViewMode]="'VIEW'"
|
|
49
|
+
[formId]="selectedFormId"
|
|
50
|
+
[recordId]="selectedRecordId">
|
|
51
|
+
</eqp-dynamic-module>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Componente:**
|
|
55
|
+
```typescript
|
|
56
|
+
import { DynamicModuleConfig, DynamicModuleGeneralConfig, DynamicModuleViewModeEnum } from '@eqproject/eqp-dynamic-module';
|
|
57
|
+
|
|
58
|
+
configView: DynamicModuleConfig = {
|
|
59
|
+
GeneralConfig: {
|
|
60
|
+
baseServerUrl: 'https://your-api-host',
|
|
61
|
+
userToken: this.authService.getToken(),
|
|
62
|
+
context: 'MY_APP'
|
|
63
|
+
} as DynamicModuleGeneralConfig
|
|
64
|
+
} as DynamicModuleConfig;
|
|
65
|
+
|
|
66
|
+
starterViewMode = DynamicModuleViewModeEnum.VIEW;
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### Scenario 2 — Compilazione form (COMPILE)
|
|
72
|
+
|
|
73
|
+
Permettere all'utente di inserire o modificare una risposta.
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<eqp-dynamic-module
|
|
77
|
+
[dynamicModuleConfig]="configCompile"
|
|
78
|
+
[starterViewMode]="'COMPILE'"
|
|
79
|
+
[formId]="formId"
|
|
80
|
+
[recordId]="null"
|
|
81
|
+
(onRecordSaved)="handleSaved($event)">
|
|
82
|
+
</eqp-dynamic-module>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- Passa `recordId = null` per una nuova risposta, oppure un ID esistente per modificarla.
|
|
86
|
+
- Ascolta `(onRecordSaved)` per reagire al salvataggio.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### Scenario 3 — Lista risposte con filtri (LIST)
|
|
91
|
+
|
|
92
|
+
Visualizzare la lista delle risposte a una form con filtri e paginazione integrati.
|
|
93
|
+
|
|
94
|
+
```html
|
|
95
|
+
<eqp-dynamic-module
|
|
96
|
+
[dynamicModuleConfig]="configList"
|
|
97
|
+
[starterViewMode]="'LIST'"
|
|
98
|
+
[formId]="formId">
|
|
99
|
+
</eqp-dynamic-module>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Per abilitare i filtri dalla lista imposta `ListConfig.showFilters = true` dentro `DynamicModuleConfig`.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### Scenario 4 — Configuratore no-code
|
|
107
|
+
|
|
108
|
+
Permettere a un amministratore di creare o modificare la definizione di una form.
|
|
109
|
+
|
|
110
|
+
```html
|
|
111
|
+
<eqp-dynamic-module-configurator
|
|
112
|
+
[dynamicModuleConfiguratorConfig]="configConfigurator"
|
|
113
|
+
[configuratorMode]="'EDIT'"
|
|
114
|
+
[formId]="formId"
|
|
115
|
+
(onFormSaved)="handleFormSaved($event)">
|
|
116
|
+
</eqp-dynamic-module-configurator>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Modalità disponibili:**
|
|
120
|
+
|
|
121
|
+
| Valore | Comportamento |
|
|
122
|
+
|--------|---------------|
|
|
123
|
+
| `NEW` | Crea una nuova form da zero |
|
|
124
|
+
| `EDIT` | Modifica una form esistente per `formId` |
|
|
125
|
+
| `EXPORT` | Esporta la form come JSON scaricabile |
|
|
126
|
+
| `IMPORT` | Importa una form da JSON |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
### Scenario 5 — Endpoint personalizzati
|
|
131
|
+
|
|
132
|
+
Quando il server non espone le API al percorso default, configura `EndPointConfiguration`:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { EndPointConfiguration, EndPointData, ParamTypeEnum } from '@eqproject/eqp-dynamic-module';
|
|
136
|
+
|
|
137
|
+
const customEndpoints: EndPointConfiguration = new EndPointConfiguration();
|
|
138
|
+
customEndpoints.Records.GetAll = {
|
|
139
|
+
Url: 'https://custom-host/api/records',
|
|
140
|
+
Token: 'Bearer my-token',
|
|
141
|
+
RequestMethod: 'GET',
|
|
142
|
+
Params: []
|
|
143
|
+
} as EndPointData;
|
|
144
|
+
|
|
145
|
+
// Poi passa customEndpoints in GeneralConfig.EndPointConfiguration
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Ogni campo di `EndPointConfiguration` è opzionale: puoi sovrascrivere solo gli endpoint che differiscono dai default.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### Troubleshooting
|
|
153
|
+
|
|
154
|
+
**Campi non visibili nel configuratore**
|
|
155
|
+
- Verifica che il `formId` sia corretto e che il server risponda su `GET /api/conf/form/{id}`.
|
|
156
|
+
|
|
157
|
+
**Errore CORS**
|
|
158
|
+
- Il server deve restituire `Access-Control-Allow-Origin: *` (o il dominio specifico). In sviluppo puoi usare il proxy Angular.
|
|
159
|
+
|
|
160
|
+
**Form vuota in modalità COMPILE**
|
|
161
|
+
- Controlla che `baseServerUrl` non abbia una barra finale (`/`).
|
|
162
|
+
- Verifica che `userToken` sia valido e non scaduto.
|
|
163
|
+
|
|
164
|
+
**Lista non si aggiorna dopo salvataggio**
|
|
165
|
+
- Chiama `dynamicModuleRef.refreshList()` nell'handler di `(onRecordSaved)` oppure passa `ListConfig.autoRefresh = true`.
|
|
166
|
+
|
|
167
|
+
**Errore di tipo sui campi data**
|
|
168
|
+
- Da v2.10.62 il formato data usa token Luxon (`dd/MM/yyyy`). Se aggiorni da versioni precedenti, verifica i valori salvati in DB.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## User Guide (English)
|
|
173
|
+
|
|
174
|
+
### Prerequisites
|
|
175
|
+
|
|
176
|
+
1. Angular 15
|
|
177
|
+
2. `npm install @eqproject/eqp-dynamic-module --legacy-peer-deps`
|
|
178
|
+
3. `EqpDynamicModuleModule` imported in the consumer Angular module (see README)
|
|
179
|
+
4. A server exposing the DynamicModule API (or custom endpoints configured via `EndPointConfiguration`)
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### Scenario 1 — Read-only form (VIEW)
|
|
184
|
+
|
|
185
|
+
Display a completed form without allowing edits. Typical use case: detail page of a record.
|
|
186
|
+
|
|
187
|
+
**Template:**
|
|
188
|
+
```html
|
|
189
|
+
<eqp-dynamic-module
|
|
190
|
+
[dynamicModuleConfig]="configView"
|
|
191
|
+
[starterViewMode]="'VIEW'"
|
|
192
|
+
[formId]="selectedFormId"
|
|
193
|
+
[recordId]="selectedRecordId">
|
|
194
|
+
</eqp-dynamic-module>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Component:**
|
|
198
|
+
```typescript
|
|
199
|
+
import { DynamicModuleConfig, DynamicModuleGeneralConfig, DynamicModuleViewModeEnum } from '@eqproject/eqp-dynamic-module';
|
|
200
|
+
|
|
201
|
+
configView: DynamicModuleConfig = {
|
|
202
|
+
GeneralConfig: {
|
|
203
|
+
baseServerUrl: 'https://your-api-host',
|
|
204
|
+
userToken: this.authService.getToken(),
|
|
205
|
+
context: 'MY_APP'
|
|
206
|
+
} as DynamicModuleGeneralConfig
|
|
207
|
+
} as DynamicModuleConfig;
|
|
208
|
+
|
|
209
|
+
starterViewMode = DynamicModuleViewModeEnum.VIEW;
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### Scenario 2 — Form fill (COMPILE)
|
|
215
|
+
|
|
216
|
+
Allow the user to create or edit an answer.
|
|
217
|
+
|
|
218
|
+
```html
|
|
219
|
+
<eqp-dynamic-module
|
|
220
|
+
[dynamicModuleConfig]="configCompile"
|
|
221
|
+
[starterViewMode]="'COMPILE'"
|
|
222
|
+
[formId]="formId"
|
|
223
|
+
[recordId]="null"
|
|
224
|
+
(onRecordSaved)="handleSaved($event)">
|
|
225
|
+
</eqp-dynamic-module>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
- Pass `recordId = null` for a new answer, or an existing ID to edit it.
|
|
229
|
+
- Listen to `(onRecordSaved)` to react to the save event.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### Scenario 3 — Answer list with filters (LIST)
|
|
234
|
+
|
|
235
|
+
Display the list of answers for a form with built-in filters and pagination.
|
|
236
|
+
|
|
237
|
+
```html
|
|
238
|
+
<eqp-dynamic-module
|
|
239
|
+
[dynamicModuleConfig]="configList"
|
|
240
|
+
[starterViewMode]="'LIST'"
|
|
241
|
+
[formId]="formId">
|
|
242
|
+
</eqp-dynamic-module>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
To enable list filters set `ListConfig.showFilters = true` inside `DynamicModuleConfig`.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
### Scenario 4 — No-code configurator
|
|
250
|
+
|
|
251
|
+
Let an administrator create or modify a form definition.
|
|
252
|
+
|
|
253
|
+
```html
|
|
254
|
+
<eqp-dynamic-module-configurator
|
|
255
|
+
[dynamicModuleConfiguratorConfig]="configConfigurator"
|
|
256
|
+
[configuratorMode]="'EDIT'"
|
|
257
|
+
[formId]="formId"
|
|
258
|
+
(onFormSaved)="handleFormSaved($event)">
|
|
259
|
+
</eqp-dynamic-module-configurator>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Available modes:**
|
|
263
|
+
|
|
264
|
+
| Value | Behaviour |
|
|
265
|
+
|-------|-----------|
|
|
266
|
+
| `NEW` | Create a new form from scratch |
|
|
267
|
+
| `EDIT` | Edit an existing form by `formId` |
|
|
268
|
+
| `EXPORT` | Export the form as a downloadable JSON |
|
|
269
|
+
| `IMPORT` | Import a form from a JSON file |
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
### Scenario 5 — Custom endpoints
|
|
274
|
+
|
|
275
|
+
When the server does not expose APIs at the default paths, configure `EndPointConfiguration`:
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
import { EndPointConfiguration, EndPointData, ParamTypeEnum } from '@eqproject/eqp-dynamic-module';
|
|
279
|
+
|
|
280
|
+
const customEndpoints: EndPointConfiguration = new EndPointConfiguration();
|
|
281
|
+
customEndpoints.Records.GetAll = {
|
|
282
|
+
Url: 'https://custom-host/api/records',
|
|
283
|
+
Token: 'Bearer my-token',
|
|
284
|
+
RequestMethod: 'GET',
|
|
285
|
+
Params: []
|
|
286
|
+
} as EndPointData;
|
|
287
|
+
|
|
288
|
+
// Then pass customEndpoints in GeneralConfig.EndPointConfiguration
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Each field in `EndPointConfiguration` is optional — only override the endpoints that differ from the defaults.
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
### Troubleshooting (EN)
|
|
296
|
+
|
|
297
|
+
**Fields not visible in the configurator**
|
|
298
|
+
- Verify that `formId` is correct and that the server responds on `GET /api/conf/form/{id}`.
|
|
299
|
+
|
|
300
|
+
**CORS error**
|
|
301
|
+
- The server must return `Access-Control-Allow-Origin: *` (or the specific domain). In development you can use the Angular proxy.
|
|
302
|
+
|
|
303
|
+
**Empty form in COMPILE mode**
|
|
304
|
+
- Check that `baseServerUrl` does not have a trailing slash (`/`).
|
|
305
|
+
- Verify that `userToken` is valid and not expired.
|
|
306
|
+
|
|
307
|
+
**List does not refresh after save**
|
|
308
|
+
- Call `dynamicModuleRef.refreshList()` in the `(onRecordSaved)` handler, or pass `ListConfig.autoRefresh = true`.
|
|
309
|
+
|
|
310
|
+
**Date field type error**
|
|
311
|
+
- From v2.10.62 dates use Luxon tokens (`dd/MM/yyyy`). If upgrading from older versions, verify DB-saved values.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Utilizzo con AI / AI-assisted Usage
|
|
316
|
+
|
|
317
|
+
Questa sezione mostra come usare Claude Code (o un altro assistente AI) per lavorare con `@eqproject/eqp-dynamic-module` in modo efficiente, sia come consumatore della libreria che come manutentore.
|
|
318
|
+
|
|
319
|
+
*This section shows how to use Claude Code (or another AI assistant) to work efficiently with `@eqproject/eqp-dynamic-module`, both as a consumer and as a maintainer.*
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
### Prompt per Claude Code
|
|
324
|
+
|
|
325
|
+
I prompt seguenti funzionano bene con Claude Code (CLI `claude`) all'interno del repo `DynamicModuleClient`.
|
|
326
|
+
|
|
327
|
+
*The following prompts work well with Claude Code (CLI `claude`) inside the `DynamicModuleClient` repo.*
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
#### Pubblicazione NPM
|
|
332
|
+
|
|
333
|
+
```
|
|
334
|
+
Pubblica una nuova versione patch del modulo su npm.
|
|
335
|
+
```
|
|
336
|
+
```
|
|
337
|
+
Fai una release minor del modulo dinamico.
|
|
338
|
+
```
|
|
339
|
+
```
|
|
340
|
+
Fai una release major — stiamo rilasciando la versione 3.
|
|
341
|
+
```
|
|
342
|
+
```
|
|
343
|
+
Release patch — ma prima controlla che non ci siano errori TypeScript.
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Claude eseguirà: analisi diff → aggiornamento README e USERGUIDE → bump versione → build → publish → commit → aggiornamento TMED.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
#### Aggiungere un tipo di campo
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
Aggiungi un nuovo tipo di campo chiamato "SignatureField" per la firma digitale.
|
|
354
|
+
Deve comparire nel configuratore come "Firma" e salvare una stringa base64.
|
|
355
|
+
```
|
|
356
|
+
```
|
|
357
|
+
Voglio un campo "RatingField" (stelle 1-5). Mostralo in sola lettura come stelle SVG
|
|
358
|
+
e in compilazione come radio button.
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Claude creerà: modello in `models/fields/`, template di rendering, template filtro, template trigger, enum, registrazione nel modulo, export da `public-api.ts`.
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
#### Correzione bug
|
|
366
|
+
|
|
367
|
+
```
|
|
368
|
+
Nella modalità LIST il componente non mostra i risultati quando la lista è vuota.
|
|
369
|
+
Cerca la causa e correggila.
|
|
370
|
+
```
|
|
371
|
+
```
|
|
372
|
+
Gli ActionButton nei form in modalità VIEW sono cliccabili ma non dovrebbero esserlo.
|
|
373
|
+
```
|
|
374
|
+
```
|
|
375
|
+
Il configuratore non salva i trigger quando ci sono più di 5 condizioni.
|
|
376
|
+
Analizza il problema e proponi la correzione.
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
#### Analisi e spiegazione
|
|
382
|
+
|
|
383
|
+
```
|
|
384
|
+
Spiega come funziona il sistema di trigger nel configuratore.
|
|
385
|
+
```
|
|
386
|
+
```
|
|
387
|
+
Come viene gestita la modalità FILTER? Quali componenti sono coinvolti?
|
|
388
|
+
```
|
|
389
|
+
```
|
|
390
|
+
Quali endpoint chiama il componente in modalità COMPILE? Mostrami il flusso completo.
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
#### Aggiornamento documentazione
|
|
396
|
+
|
|
397
|
+
```
|
|
398
|
+
Il README è obsoleto rispetto al codice. Aggiornalo analizzando i cambiamenti
|
|
399
|
+
dall'ultimo tag git.
|
|
400
|
+
```
|
|
401
|
+
```
|
|
402
|
+
Aggiorna la sezione Changelog del README con le modifiche fatte dall'ultima versione.
|
|
403
|
+
```
|
|
404
|
+
```
|
|
405
|
+
Aggiungi a USERGUIDE.md un esempio per il campo ImageWithMarkers.
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
#### Task e tracciamento ADO
|
|
411
|
+
|
|
412
|
+
```
|
|
413
|
+
Crea un task ADO per l'implementazione del SignatureField nel modulo dinamico.
|
|
414
|
+
```
|
|
415
|
+
```
|
|
416
|
+
Apri un task per il bug degli ActionButton in VIEW mode — è un fix critico.
|
|
417
|
+
```
|
|
418
|
+
```
|
|
419
|
+
Questo fix tocca sia DynamicModuleClient che DynamicModule. Crea un task per entrambi i progetti e linkali come Related.
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
#### Workflow multi-step
|
|
425
|
+
|
|
426
|
+
```
|
|
427
|
+
Analizza i cambiamenti dall'ultima release, aggiorna README e USERGUIDE,
|
|
428
|
+
poi fai una release patch.
|
|
429
|
+
```
|
|
430
|
+
```
|
|
431
|
+
C'è un bug in produzione sugli allegati in modalità COMPILE. Analizza la causa,
|
|
432
|
+
crea un task ADO, correggilo e fai una release patch urgente.
|
|
433
|
+
```
|
|
434
|
+
```
|
|
435
|
+
Voglio aggiungere il supporto a un nuovo endpoint per l'esportazione CSV.
|
|
436
|
+
Crea il task ADO, implementa la modifica e poi fai una release minor.
|
|
437
|
+
```
|