@eqproject/eqp-dynamic-module
v2.10.98
Published
Dynamic module component - Angular Material based
Downloads
6,797
Readme
@eqproject/eqp-dynamic-module
Libreria Angular 15 per la creazione, visualizzazione e gestione di form dinamiche con configuratore no-code.
Angular 15 library for building, rendering and managing dynamic forms with a no-code configurator.
Changelog
v2.10.87
- Bugfix configurator — sezione "Generale" assente per 5 tipi di campo: durante il lavoro di potenziamento grafico (v2.10.68–v2.10.70), i tipi
ActionButtonField,ImageField,ImageWithMarkersField,ListValueFieldeImageSelectorFieldavevano ricevuto la sezione "Grafica" nel tab "Stile Compilazione" del configuratore, ma la sezione "Generale" (Larghezza campo, Visibile, VisibleIf, Tooltip, Tipo di invisibilità, Mantieni il valore) era stata rimossa per errore. Ripristinata per tutti e 5 i tipi. - Bugfix configurator — "Generale" section missing for 5 field types: during the graphical enhancement work (v2.10.68–v2.10.70),
ActionButtonField,ImageField,ImageWithMarkersField,ListValueFieldandImageSelectorFieldreceived the "Grafica" section in the configurator's "Stile Compilazione" tab, but the "Generale" section (field width, visibility, VisibleIf, tooltip, invisibility type, maintain value) was accidentally removed. Restored for all 5 field types.
v2.10.86
- Bugfix loop infinito
ListValueField:FormControl.setValue()notificava il callback_onChangedelNgModelregistrato tramite[formControlName]sulmat-checkbox, causandongModelChange→updateSelected()→setFormControlValue()in ricorsione infinita. Aggiunto{ emitModelToViewChange: false }asetFormControlValue()per interrompere il ciclo. Fix correlati:updateSelected()ora restituiscenull(non[]) per campi single-choice senza selezione, evitando instabilità Angular CD da[] !== [];resetArrayData()chiamaupdateSelected(false)per non emettererecordChangedurante il rebuild delle opzioni;updateField()distingue formula-per-valore da formula-per-opzioni nei campiDataGetterType=Formula. - Bugfix loop infinito
onRecordChange: aggiunta guardia di rientranza_recordChangingcontry/finallyinadd-form-record.onRecordChange()per prevenire ricorsione da campi formula concatenati (es. campo numerico → campo elenco valorizzato dalla formula del primo). - Bugfix loop in anteprima —
DynAttachment.ButtonKeynull: nei templateimage-field-templateeimage-with-markers-field-template, la valutazione difield.DynAttachment.ButtonKeyin*ngIflanciava eccezione quandoDynAttachmenteranull(campo senza immagine caricata), innescando un loop di Angular CD. Sostituito confield.DynAttachment?.ButtonKey. - Fix posizione dialog DataGetter: la modale del Query Editor aperta con "Modifica" nel configuratore compariva a metà pagina. Aggiunti
position: { top: '20px' }emaxHeight: '90vh'per allinearla al comportamento di tutte le altre dialog. - Bugfix infinite loop
ListValueField:FormControl.setValue()was notifying the_onChangecallback of theNgModelregistered via[formControlName]onmat-checkbox, causingngModelChange→updateSelected()→setFormControlValue()in infinite recursion. Added{ emitModelToViewChange: false }tosetFormControlValue()to break the cycle. Related fixes:updateSelected()now returnsnull(not[]) for single-choice fields with no selection, preventing Angular CD instability from[] !== [];resetArrayData()callsupdateSelected(false)to avoid emittingrecordChangeduring option rebuild;updateField()now distinguishes formula-for-value from formula-for-options inDataGetterType=Formulafields. - Bugfix infinite loop
onRecordChange: added_recordChangingre-entrancy guard withtry/finallyinadd-form-record.onRecordChange()to prevent recursion from chained formula fields (e.g. numeric field → list field driven by the first field's formula). - Bugfix preview loop —
DynAttachment.ButtonKeynull: inimage-field-templateandimage-with-markers-field-template, evaluatingfield.DynAttachment.ButtonKeyin*ngIfthrew an exception whenDynAttachmentwasnull(field with no image loaded), triggering an Angular CD loop. Replaced withfield.DynAttachment?.ButtonKey. - Fix DataGetter dialog position: the Query Editor modal opened via "Modifica" in the configurator was appearing at mid-page. Added
position: { top: '20px' }andmaxHeight: '90vh'to align it with all other dialogs.
v2.10.85
- Bugfix loop infinito (approccio corretto): il loop di v2.10.84 era asincrono:
setValuechiamawriteValuesui ControlValueAccessor di Angular Material che emettono eventi nel tick successivo, quando la guardia di rientranza era già rilasciata. Soluzione definitiva: il validatorrequiredora legge direttamente darecord[field.Name]tramite closure (anziché dacontrol.value); inonRecordChange()viene chiamatoupdateValueAndValidity({ emitEvent: false })— che ri-esegue i validator senza invocarewriteValue— eliminando alla radice ogni possibilità di cascade. - Bugfix infinite loop (correct approach): the v2.10.84 loop was asynchronous:
setValuecallswriteValueon Angular Material ControlValueAccessors which emit events on the next tick, after the re-entrancy guard was already released. Definitive fix: therequiredvalidator now reads directly fromrecord[field.Name]via closure (instead ofcontrol.value);onRecordChange()callsupdateValueAndValidity({ emitEvent: false })— which re-runs validators without invokingwriteValue— eliminating any cascade at the root.
v2.10.84
- Bugfix loop infinito
onRecordChange: la sincronizzazione deiFormControlintrodotta in v2.10.83 causava un loop:setValueinvocawriteValuesui ControlValueAccessor (es.mat-datepicker), che emettono(dateChange)/(ngModelChange)→recordChange→onRecordChangedi nuovo, all'infinito. Aggiunta una guardia di rientranza (_isInRecordChange) contry/finallyche interrompe il ciclo. La sincronizzazione dei FormControl resta attiva e la validazione required funziona correttamente. - Bugfix infinite loop
onRecordChange: the FormControl sync introduced in v2.10.83 caused an infinite loop:setValuecallswriteValueon ControlValueAccessors (e.g.mat-datepicker), which emit(dateChange)/(ngModelChange)→recordChange→onRecordChangeagain, endlessly. Added a re-entrancy guard (_isInRecordChange) withtry/finallythat breaks the cycle. FormControl sync remains active and required validation works correctly.
v2.10.83
- Bugfix validazione form — campi obbligatori valorizzati via formula/ActionButton: quando un campo con
requiredveniva impostato tramite formula o ActionButton, il valore compariva visivamente ma ilFormControlAngular rimaneva non aggiornato, lasciando il form invalido finché l'utente non interagiva manualmente col campo. OraonRecordChange()risincronizza tutti iFormControldal record dopo ogni aggiornamento formula, rendendo la validazione coerente con il valore visualizzato. - Bugfix form validation — required fields set via formula/ActionButton: when a required field was populated by a formula or ActionButton, the value appeared visually but the Angular
FormControlwas never updated, keeping the form invalid until the user manually interacted with the field.onRecordChange()now re-syncs allFormControlvalues from the record after every formula update, making validation consistent with the displayed value.
v2.10.81
- Bugfix configurator —
DataGetternull dopo decode Base64: quando il campoDataGetterValueBase64Stringdecodifica in un JSON conDataGetter: null, viene ora creato un oggettoDataGettervuoto anziché proseguire connull, evitando errori a runtime nel configuratore. - Bugfix
add-form-record—actionButtonsnull: se l'inputactionButtonsarrivanullal componente, viene ora inizializzato a un array vuoto prima del filtraggio, prevenendo un'eccezione al caricamento del record. - Bugfix configurator —
DataGetternull after Base64 decode: whenDataGetterValueBase64Stringdecodes to a JSON withDataGetter: null, a new emptyDataGetterobject is now created instead of proceeding withnull, preventing runtime errors in the configurator. - Bugfix
add-form-record—actionButtonsnull: if theactionButtonsinput arrives asnull, it is now initialized to an empty array before filtering, preventing an exception on record load.
v2.10.79
- DataGetter V2 — selezione automatica colonna singola: quando il flusso V2 genera una sola
columnKey, essa viene assegnata automaticamente aDataGetterColumnForcesenza che l'utente debba selezionarla manualmente dalla dropdown. - DataGetter V2 — single column auto-selection: when the V2 flow produces exactly one
columnKey, it is automatically assigned toDataGetterColumnForcewithout requiring manual selection from the dropdown.
v2.10.77
- DataGetter V2 —
DataGetterColumnForcecome stringa:onAiDataGetterOutora salvaDataGetterColumnForcecome stringa chiave (non come oggetto), allineandosi al formato atteso daeqp-select. Il valore pre-selezionato nella dropdown compare automaticamente dopo il flusso AI. - DataGetter V2 —
DataGetterColumnForceas string:onAiDataGetterOutnow storesDataGetterColumnForceas a key string (not as an object), matching the format expected byeqp-select. The pre-selected value in the dropdown appears automatically after the AI flow.
v2.10.76
- DataGetter V2 —
createColumnKeysretrocompatibile:add-form-fieldora rilevaDataGetterCodeVersion=2e leggeselectedFieldsdaqueryCommandDatabaseConfiguration.selectedFieldsinvece che dal livello radice; fallback suPropertyNameseCurrentTranslateè assente. - DataGetter V2 —
createColumnKeysbackward-compatible:add-form-fieldnow detectsDataGetterCodeVersion=2and readsselectedFieldsfromqueryCommandDatabaseConfiguration.selectedFieldsinstead of the root level; falls back toPropertyNamewhenCurrentTranslateis missing.
v2.10.74 / v2.10.75
- DataGetter AI — nuova modalità "Da database" (DataGetterType=3): aggiunto campo
DataGetterSpeechTextnel modelloDataGetter. Il configurator AI può creare campi con recupero dati da database impostando un prompt testuale: al caricamento del form, il componente QueryEditor esterno viene invocato silenziosamente, elabora il prompt via AI e popola automaticamenteDataGetterValue,DataGetterCardinality=1,DataGetterHasResetButton=trueeDataGetterColumnForce(se il risultato ha un solo campo selezionato). - DataGetterCodeVersion V2 — retrocompatibilità in lettura: il
DbgetterComponentrileva automaticamente i campi conDataGetterCodeVersion=2(formato Omnisearch AI) ed esegue un unwrap trasparente della strutturaqueryCommandDatabaseConfigurational formato V1, senza impatto sui campi legacy. IlDataGetterCodeVersion=2viene propagato al componente QueryEditor esterno tramiteconfig.DataGetterCodeVersionper consentire al client ospitante di attivare il flusso V2 in lettura. - AI DataGetter — new "Da database" mode (DataGetterType=3): added
DataGetterSpeechTextfield to theDataGettermodel. The AI configurator can create database-getter fields with a natural-language prompt: on form load, the external QueryEditor component is invoked silently, processes the prompt via AI and automatically populatesDataGetterValue,DataGetterCardinality=1,DataGetterHasResetButton=trueandDataGetterColumnForce(if a single output field is returned). - DataGetterCodeVersion V2 — backward-compatible read flow:
DbgetterComponentnow auto-detects fields withDataGetterCodeVersion=2(Omnisearch AI format) and transparently unwraps thequeryCommandDatabaseConfigurationstructure to the V1 format, with zero impact on legacy fields.DataGetterCodeVersion=2is forwarded to the external QueryEditor component viaconfig.DataGetterCodeVersionto enable the V2 read flow on the host application side.
v2.10.70
- Theming configurator — nuovi input: aggiunto
[configuratorThemeCss]che accetta direttamente il testo di un file CSS con le dichiarazioni delle variabili--conf-*. Permette di portare il tema dall'esterno come file statico senza hardcodare valori TypeScript. Se entrambi gli input sono presenti,configuratorThemesovrascriveconfiguratorThemeCssper le chiavi in conflitto. - Theming configurator — nuove variabili CSS:
--conf-stepper-header-bg(sfondo zona step superiore),--conf-stepper-content-bg(sfondo zona inferiore),--conf-step-icon-edit-bg(sfondo pallini step completati),--conf-hint-btn-bg/--conf-hint-btn-hover-bg(bottone suggerimento rapido),--conf-btn-color(colore testo bottoni con sfondo gradiente). - Theming configurator — forzatura
!important: tutti i valori iniettati tramite tema esterno sono ora applicati con!important, rendendo il sistema di theming l'unico canale valido per sovrascrivere i colori. - Theming configurator —
--conf-btn-color: il colore del testo dei bottoni attivi (sfondo gradiente) è ora templatizzabile e forzato con!importantper resistere a override CSS provenienti dall'applicazione ospitante. - New theming input: added
[configuratorThemeCss]accepting a CSS text string with--conf-*variable declarations. Enables external theme files without TypeScript hardcoding. When both inputs are present,configuratorThemeoverridesconfiguratorThemeCssfor conflicting keys. - New CSS variables:
--conf-stepper-header-bg,--conf-stepper-content-bg,--conf-step-icon-edit-bg,--conf-hint-btn-bg,--conf-hint-btn-hover-bg,--conf-btn-color. !importantenforcement: all externally-injected theme values are now set with!important, making the theming system the sole valid override channel.
v2.10.65
- TextField — icona opzionale: aggiunta la possibilità di associare un'icona Material Icons al campo di testo. Le nuove proprietà
IconName(stringa) eIconPosition(enum:1=Sinistra/prefix,2=Destra/suffix) sono opzionali e retrocompatibili (null sui form esistenti). Configurabili nel builder tramite il toggle "Icona" nella sezione Specifiche del campo. - TextField — optional icon: added support for a Material Icons icon on text fields. New properties
IconName(string) andIconPosition(enum:1=Left/prefix,2=Right/suffix) are optional and backward-compatible (null on existing forms). Configurable in the builder via the "Icona" toggle in the field's Specifiche section.
v2.10.64
- Bugfix configurator: se il campo
Codedel form risultanullal momento del salvataggio (scenario: form creato con AI senza salvataggio intermedio), ora viene generato automaticamente daNameprima dell'invio al server.
v2.10.63
- README riscritto in formato bilingue (italiano completo + inglese completo).
- Aggiunto
USERGUIDE.mdcon guida pratica per scenari d'uso comuni e sezione prompt AI di esempio. USERGUIDE.mdincluso nel pacchetto npm tramiteng-package.jsonassets.
v2.10.62
- Migrazione da
tmw-picker1.0.x a 1.1.0: NgModule → standalone components, moment.js → Luxon, aggiornamento di tutti i token formato data (DD/MM/YYYY→dd/MM/yyyy). - Rimossi input inutilizzati:
answerToDuplicateIddaeqp-dynamic-module,ProjectNamedaeqp-dynamic-module-configurator. - Documentazione NPM riscritta completamente (bilingue IT/EN).
v2.10.60
- Aggiornamenti interni e correzioni bug.
Versione italiana
- Panoramica
- Prerequisiti
- Installazione
- Configurazione del modulo
- Componenti
- Modelli di configurazione
- Modalità di visualizzazione
- Configurazione endpoint
- Modelli dati
- Tipi di campo
Panoramica
@eqproject/eqp-dynamic-module espone due componenti pubblici:
| Componente | Scopo |
|-----------|-------|
| <eqp-dynamic-module> | Visualizzatore, compilatore, lista, filtro e grafici a runtime |
| <eqp-dynamic-module-configurator> | Builder no-code per creare e modificare le definizioni form |
Le form sono strutture JSON salvate lato server e recuperate a runtime. La libreria gestisce rendering, validazione, recupero dati, operazioni CRUD e funzionalità avanzate come formule, trigger, action button e speech-to-text.
Prerequisiti
npm install @angular/cdk@^15.1.2 @angular/material@^15.1.2 @angular/material-luxon-adapter@^15.2.9 --legacy-peer-deps
npm install @angular-material-components/datetime-picker@^15.0.0 @angular-material-components/moment-adapter@^15.0.0 --legacy-peer-deps
npm install moment@^2.29.4 sweetalert2@^11.4.24 --legacy-peer-depsTutti i comandi
npm installper questa libreria richiedono il flag--legacy-peer-deps.
Installazione
npm install @eqproject/eqp-dynamic-module --legacy-peer-depsConfigurazione del modulo
import { EqpDynamicModuleModule } from '@eqproject/eqp-dynamic-module';
@NgModule({
imports: [
EqpDynamicModuleModule
]
})
export class AppModule {}In angular.json, aggiungi il tema Material agli stili:
"styles": [
"node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.css"
]Componenti
eqp-dynamic-module — Visualizzatore form
Visualizza una form dinamica in una delle modalità disponibili.
Utilizzo base
import { DynamicModuleGeneralConfig, DynamicModuleViewModeEnum } from '@eqproject/eqp-dynamic-module';
generalConfig = new DynamicModuleGeneralConfig(
'https://tua-api.esempio.it/api',
this.userToken,
this.context,
null
);<eqp-dynamic-module
[configurations]="generalConfig"
[formID]="'id-del-form'"
[starterViewMode]="DynamicModuleViewModeEnum.LIST"
[userID]="currentUser.id"
(saveRecord)="onSalvataggio($event)"
(afterSaveRecord)="dopoSalvataggio($event)">
</eqp-dynamic-module>Input
| Input | Tipo | Default | Descrizione |
|-------|------|---------|-------------|
| configurations | DynamicModuleGeneralConfig | — | Obbligatorio. Configurazione connessione server. |
| formID | string | — | Obbligatorio. ID del form da visualizzare. |
| starterViewMode | DynamicModuleViewModeEnum | LIST | Modalità iniziale. |
| userID | string | "0" | ID utente per il salvataggio record. |
| orgaID | string | "0" | ID organizzazione. |
| showTitle | boolean | true | Mostra/nasconde il nome del form. |
| showBackButton | boolean | true | Mostra/nasconde il pulsante indietro. |
| showSaveButton | boolean | true | Mostra/nasconde il pulsante salva. |
| values | Record[] | null | Record pre-caricati per la modalità LIST. |
| FormJSON | string | "" | JSON del form per la modalità REPAIR. |
| formulaObject | any | {} | Oggetto contesto per le formule (es. { role, user }). |
| selectedRecord | Record \| string | null | Record pre-selezionato (oggetto o ID). |
| externalButtons | RecordButton[] | [] | Pulsanti extra nel menu azioni record. |
| actionButtons | ActionButton[] | [] | Pulsanti azione per i campi di tipo Bottone. |
| defaultListActions | DynamicModuleListFormRecordActionsDefault | tutti true | Azioni default lista: add, view, edit, duplicate, delete, graphs. |
| listViewRecordTitle | string[] | [] | Chiavi dei campi che compongono il titolo accordion. |
| defaultListViewFunction | Function | null | Funzione custom al caricamento della lista. |
| onSaveBackToList | boolean | false | Torna alla LIST dopo il salvataggio. |
| onBackTo | DynamicModuleViewModeEnum | null | Modalità di destinazione del pulsante indietro. |
| numberOfColumns | number | 3 | Numero di colonne del layout. |
| showHiddenFields | boolean | true | Mostra/nasconde i campi marcati come nascosti. |
| filterResultViewMode | DynamicModuleFilterResultViewModeEnum | INTERNAL_EQPTABLE | Modalità visualizzazione risultati filtro. |
| additionalParams | any | null | Parametri extra per le chiamate filtro server. |
| additionalInfo | any | null | Dati extra per operazioni client-side. |
| prefilterParams | any | null | Parametri pre-filtro. |
| updateInfo | any | null | Dati per aggiornare i valori delle risposte. |
| contestualizationParams | any | null | Parametri di contestualizzazione della lista risultati. |
| showNewSearchButton | boolean | true | Mostra/nasconde il pulsante "nuova ricerca". |
| highlightFilter | any | — | Configurazione evidenziazione righe/campi. |
| isDraggableListView | boolean | true | Abilita drag-and-drop nella lista. |
| Statistic | FilterStatistic | null | Configurazione statistiche e filtri. |
| QueryEditorComponent | any | — | Componente query editor custom per i lookup. |
| debugMode | boolean | false | Abilita log dettagliati in console. |
Output
| Output | Payload | Descrizione |
|--------|---------|-------------|
| (saveRecord) | Record | Emesso al salvataggio senza endpoint configurato. |
| (afterSaveRecord) | Record | Emesso dopo la chiamata server di salvataggio. |
| (deleteRecord) | Record | Emesso all'eliminazione senza endpoint configurato. |
| (afterDeleteRecord) | Record | Emesso dopo la chiamata server di eliminazione. |
| (SaveJSON) | string | Emesso all'esportazione del JSON del form. |
| (afterFilter) | DynRecord[] | Emesso dopo l'applicazione di un filtro. |
| (dragStarted) | Record | Emesso all'inizio di un drag. |
| (dragReleased) | void | Emesso al rilascio del drag. |
| (clickDragIndicator) | Record | Emesso al click sull'icona drag. |
| (out) | eventOut | Output generico per comunicazione esterna. |
| (fireTrigger) | FireTrigger | Emesso quando scatta un trigger. |
| (afterOutputExternalFilters) | FilterStatistic | Emesso dopo filtri esterni applicati. |
eqp-dynamic-module-configurator — Builder form
Designer no-code per creare e modificare definizioni form.
Modalità d'uso
// Nuovo form
const specific = new DynamicModuleConfiguratorSpecificConfig();
specific.UserID = this.currentUser.id;
specific.orgaID = this.currentOrga.id;
const general = new DynamicModuleGeneralConfig(this.baseServerUrl, this.userToken, this.context, null);
this.config = new DynamicModuleConfiguratorConfig(general, specific);<!-- Nuovo form -->
<eqp-dynamic-module-configurator
*ngIf="config"
[configurations]="config"
(saveFormEvent)="onSalvaForm($event)">
</eqp-dynamic-module-configurator>
<!-- Modifica form esistente -->
<eqp-dynamic-module-configurator
*ngIf="config"
[configurations]="config"
[formID]="formID"
(saveFormEvent)="onSalvaForm($event)">
</eqp-dynamic-module-configurator>
<!-- Esportazione -->
<eqp-dynamic-module-configurator
[configurations]="config"
[formID]="formID"
[viewMode]="'Export'"
(saveFormEvent)="onSalvaForm($event)">
</eqp-dynamic-module-configurator>
<!-- Importazione da JSON -->
<eqp-dynamic-module-configurator
[configurations]="config"
[formID]="null"
[viewMode]="'Export'"
(saveFormEvent)="onSalvaForm($event)">
</eqp-dynamic-module-configurator>Input
| Input | Tipo | Default | Descrizione |
|-------|------|---------|-------------|
| configurations | DynamicModuleConfiguratorConfig | — | Obbligatorio. Contenitore configurazione. |
| formID | string | null | ID del form da modificare. null crea un nuovo form. |
| viewMode | string | "addOrEdit" | "addOrEdit" per creare/modificare, "Export" per esportare/importare. |
| fieldsExtraConfig | FieldExtraConfig[] | — | Configurazione extra per campi specifici. |
| triggers | any | — | Definizioni trigger disponibili nell'editor. |
| actionButtons | any | — | Definizioni action button disponibili. |
| contestualization | Contestualization[] | — | Opzioni di contestualizzazione per lookup e filtri. |
| formulaObject | any | — | Contesto per l'anteprima delle formule. |
| QueryEditorComponent | DynamicLoaderDirectiveData | — | Componente query editor custom. |
| debugMode | boolean | false | Abilita log dettagliati. |
| configuratorTheme | Record<string, string> \| null | null | Override delle variabili CSS del tema tramite oggetto TypeScript. |
| configuratorThemeCss | string \| null | null | Override delle variabili CSS del tema tramite stringa CSS (es. contenuto di un file .css). |
Output
| Output | Payload | Descrizione |
|--------|---------|-------------|
| (saveFormEvent) | Form | Emesso al salvataggio senza endpoint configurato. |
| (afterSaveFormEvent) | Form | Emesso dopo la chiamata server di salvataggio. |
| (out) | eventOut | Output generico per comunicazione esterna. |
| (fireTrigger) | FireTrigger | Emesso quando scatta un trigger. |
Theming
Il configurator espone un sistema di temi basato su CSS custom properties. Tutti i valori iniettati tramite tema sono applicati con !important e non possono essere sovrascritti dall'esterno se non attraverso questi input.
<!-- Opzione A: oggetto TypeScript -->
<eqp-dynamic-module-configurator
[configurations]="config"
[configuratorTheme]="{ '--conf-gradient': 'linear-gradient(to right, #1565c0, #0288d1)', '--conf-bg-page': '#f0f6fb' }">
</eqp-dynamic-module-configurator>
<!-- Opzione B: file CSS caricato come stringa -->
<eqp-dynamic-module-configurator
[configurations]="config"
[configuratorThemeCss]="themeCssString">
</eqp-dynamic-module-configurator>Formato del file CSS per configuratorThemeCss (nessun selettore richiesto):
--conf-gradient: linear-gradient(to right, #1565c0, #0288d1);
--conf-bg-page: #f0f6fb;
--conf-btn-color: #ffffff;Variabili disponibili:
| Variabile | Default | Descrizione |
|-----------|---------|-------------|
| --conf-gradient | gradiente viola-blu | Sfondo bottoni e header |
| --conf-bg-page | #f5f5f5 | Sfondo generale pagina/stepper |
| --conf-radius | 10px | Border radius bottoni |
| --conf-modal-radius | 12px | Border radius modali |
| --conf-accent | #693DDA | Colore accento (bordi, focus) |
| --conf-primary | #1E31EB | Colore primario |
| --conf-step-selected | #643cda | Freccia step selezionato |
| --conf-step-edit | #3034e7 | Freccia step completato |
| --conf-stepper-header-bg | ereditato da --conf-bg-page | Sfondo zona superiore (header stepper) |
| --conf-stepper-content-bg | ereditato da --conf-bg-page | Sfondo zona inferiore (form e bottoni) |
| --conf-step-icon-edit-bg | ereditato da --conf-step-edit | Sfondo pallini step completati |
| --conf-btn-color | #ffffff | Colore testo bottoni attivi (sfondo gradiente) |
| --conf-hint-btn-bg | #2563eb | Sfondo bottone suggerimento rapido (lampadina) |
| --conf-hint-btn-hover-bg | #1d4ed8 | Sfondo lampadina al hover |
| --conf-table-header-bg | variabile SCSS | Sfondo header tabella campi |
| --conf-search-bg | variabile SCSS | Sfondo campo di ricerca |
| --conf-table-bg | #ffffff | Sfondo righe tabella |
| --conf-card-bg | #ffffff | Sfondo card |
| --conf-font-family | inherit | Font dell'intero configurator |
Modelli di configurazione
DynamicModuleGeneralConfig
const general = new DynamicModuleGeneralConfig(
'https://api.esempio.it/api', // baseServerUrl
userToken, // token autenticazione
context, // oggetto Context
null // EndPointConfiguration (null = usa default)
);| Proprietà | Tipo | Descrizione |
|-----------|------|-------------|
| baseServerUrl | string | URL base API. Usato per costruire automaticamente gli endpoint se endPointConfiguration è null. |
| userToken | string | Token di autenticazione inviato con ogni chiamata. |
| endPointConfiguration | EndPointConfiguration \| null | Override completo degli endpoint. null usa le rotte standard. |
| context | Context | Contesto applicativo. |
DynamicModuleListFormRecordActionsDefault
const actions = new DynamicModuleListFormRecordActionsDefault();
actions.add = true; // Pulsante "Aggiungi" nell'header lista
actions.view = true; // Visualizza record (solo lettura)
actions.edit = true; // Modifica record
actions.duplicate = false; // Duplica record
actions.delete = true; // Elimina record
actions.graphs = false; // Grafici recordModalità di visualizzazione
import { DynamicModuleViewModeEnum } from '@eqproject/eqp-dynamic-module';
enum DynamicModuleViewModeEnum {
NONE = 0, // Nessuna visualizzazione
VIEW = 1, // Sola lettura
COMPILE = 2, // Compilazione / modifica
LIST = 3, // Lista record
REPAIR = 4, // Revisione form
LISTWIEW = 5, // Lista compatta alternativa
FILTER = 6, // Filtro / ricerca
GRAPHS = 7, // Statistiche e grafici
HLIST = 8, // Lista orizzontale
EXTERNAL_FILTER = 9 // Filtro guidato dal componente padre
}Configurazione endpoint
Per default la libreria costruisce tutti gli URL dagli endpoint a partire da baseServerUrl. Passa un EndPointConfiguration custom per sovrascrivere singole rotte.
import { EndPointConfiguration, EndPointData, RequestMethodEnum, ParamTypeEnum } from '@eqproject/eqp-dynamic-module';
const endPoints = new EndPointConfiguration();
endPoints.Records.SaveEndPoint = new EndPointData();
endPoints.Records.SaveEndPoint.Url = 'https://custom-api.esempio.it/records/save';
endPoints.Records.SaveEndPoint.RequestMethod = RequestMethodEnum.POST;
endPoints.Records.SaveEndPoint.Params = [{
ParamName: 'orgId',
ParamValue: this.orgaId,
ParamType: ParamTypeEnum['Query param']
}];Endpoint Records disponibili: GetWithContextualizationByFormCodeEndPoint, GetByFormIDEndPoint, GetByFormCodeEndPoint, GetAllByEntAndUserIDEndPoint, GetByIDEndPoint, SaveEndPoint, DuplicateEndPoint, DeleteEndPoint, RepairEndPoint, ApplyFilter, GetAllAttachmentsEndPoint.
Endpoint Forms disponibili: GetByIDEndPoint, GetAllFormEndPoint, GetByIDAndVersionEndPoint, SaveEndPoint, SaveAttachmentEndPoint, ExportByIDEndPoint, GetAttachmentWithBases64, SpeechToFormEditEndPoint.
Modelli dati
Record
| Proprietà | Tipo | Descrizione |
|-----------|------|-------------|
| ID | string | Identificatore unico. |
| EntID | string | ID del form (entità) di appartenenza. |
| Version | number | Versione del form al momento della compilazione. |
| userID | string | ID utente che ha creato il record. |
| AnswerDate | string | Data di compilazione (ISO). |
| HTMLreadableValues | string | Valori in formato HTML leggibile. |
| AdditionalParams | any | Parametri aggiuntivi. |
| AdditionalInfo | any | Informazioni aggiuntive. |
Tipi di campo
| Valore | Chiave | Descrizione |
|--------|--------|-------------|
| 1 | Campo di testo | Input testo singola riga. |
| 2 | Area di testo | Textarea multiriga. |
| 3 | Booleano | Checkbox / toggle. |
| 4 | Data e/ora | Selettore data e/o ora. |
| 5 | Campo numerico | Input numerico con maschera. |
| 6 | Allegato | Upload file. |
| 7 | Immagine | Upload immagine con crop. |
| 8 | Elenco generico | Dropdown / selezione multipla. |
| 9 | Lookup | Lookup server-side con query configurabile. |
| 10 | Form di dettaglio | Form di dettaglio annidato. |
| 11 | Elenco immagini | Selettore lista immagini. |
| 12 | Etichetta | Solo visualizzazione. |
| 13 | Immagine con markers | Immagine con annotazioni interattive. |
| 14 | Bottone | Campo pulsante azione. |
English version
- Overview
- Prerequisites
- Installation
- Module Setup
- Components
- Configuration Models
- View Modes
- Endpoint Configuration
- Data Models
- Field Types Reference
Overview
@eqproject/eqp-dynamic-module exposes two public components:
| Component | Purpose |
|-----------|---------|
| <eqp-dynamic-module> | Runtime form viewer, filler, list, filter and graphs |
| <eqp-dynamic-module-configurator> | No-code form builder (create, edit, import, export) |
Forms are defined as JSON structures stored server-side and fetched at runtime. The library handles rendering, validation, data retrieval, CRUD operations and advanced features like formulas, triggers, action buttons and speech-to-text.
Prerequisites
npm install @angular/cdk@^15.1.2 @angular/material@^15.1.2 @angular/material-luxon-adapter@^15.2.9 --legacy-peer-deps
npm install @angular-material-components/datetime-picker@^15.0.0 @angular-material-components/moment-adapter@^15.0.0 --legacy-peer-deps
npm install moment@^2.29.4 sweetalert2@^11.4.24 --legacy-peer-depsAll
npm installcommands for this library require--legacy-peer-deps.
Installation
npm install @eqproject/eqp-dynamic-module --legacy-peer-depsModule Setup
import { EqpDynamicModuleModule } from '@eqproject/eqp-dynamic-module';
@NgModule({
imports: [EqpDynamicModuleModule]
})
export class AppModule {}Add Angular Material theme to angular.json styles:
"styles": [
"node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.css"
]Components
eqp-dynamic-module — Form Viewer/Filler
Basic usage
import { DynamicModuleGeneralConfig, DynamicModuleViewModeEnum } from '@eqproject/eqp-dynamic-module';
generalConfig = new DynamicModuleGeneralConfig(
'https://your-api.example.com/api',
this.userToken,
this.context,
null
);<eqp-dynamic-module
[configurations]="generalConfig"
[formID]="'your-form-id'"
[starterViewMode]="DynamicModuleViewModeEnum.LIST"
[userID]="currentUser.id"
(saveRecord)="onSave($event)"
(afterSaveRecord)="onAfterSave($event)">
</eqp-dynamic-module>Inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| configurations | DynamicModuleGeneralConfig | — | Required. Server connection configuration. |
| formID | string | — | Required. ID of the form to display. |
| starterViewMode | DynamicModuleViewModeEnum | LIST | Initial view mode. |
| userID | string | "0" | User ID stamped on saved records. |
| orgaID | string | "0" | Organization ID. |
| showTitle | boolean | true | Show/hide the form name. |
| showBackButton | boolean | true | Show/hide the back button. |
| showSaveButton | boolean | true | Show/hide the save button. |
| values | Record[] | null | Pre-loaded records for LIST mode. |
| FormJSON | string | "" | Form JSON string for REPAIR mode. |
| formulaObject | any | {} | Context object for formula evaluation. |
| selectedRecord | Record \| string | null | Pre-select a record by object or ID. |
| externalButtons | RecordButton[] | [] | Extra buttons in the record action menu. |
| actionButtons | ActionButton[] | [] | Action buttons for Bottone field type. |
| defaultListActions | DynamicModuleListFormRecordActionsDefault | all true | Toggle default list actions. |
| listViewRecordTitle | string[] | [] | Field keys composing the accordion title. |
| defaultListViewFunction | Function | null | Custom function called on list load. |
| onSaveBackToList | boolean | false | Return to LIST after save. |
| onBackTo | DynamicModuleViewModeEnum | null | View mode for the back button. |
| numberOfColumns | number | 3 | Number of layout columns. |
| showHiddenFields | boolean | true | Show/hide hidden fields. |
| filterResultViewMode | DynamicModuleFilterResultViewModeEnum | INTERNAL_EQPTABLE | Filter results display mode. |
| additionalParams | any | null | Extra params for server filter calls. |
| additionalInfo | any | null | Extra data for client-side operations. |
| prefilterParams | any | null | Pre-filter parameters. |
| updateInfo | any | null | Data to update response values after load. |
| contestualizationParams | any | null | Contextualisation parameters. |
| showNewSearchButton | boolean | true | Show/hide the new search button. |
| highlightFilter | any | — | Row/field highlighting configuration. |
| isDraggableListView | boolean | true | Enable drag-and-drop in list view. |
| Statistic | FilterStatistic | null | Statistics and filter configuration. |
| QueryEditorComponent | any | — | Custom query editor component for lookups. |
| debugMode | boolean | false | Enable verbose console logging. |
Outputs
| Output | Payload | Description |
|--------|---------|-------------|
| (saveRecord) | Record | Emitted on save when no save endpoint is configured. |
| (afterSaveRecord) | Record | Emitted after server save call completes. |
| (deleteRecord) | Record | Emitted on delete when no delete endpoint is configured. |
| (afterDeleteRecord) | Record | Emitted after server delete call completes. |
| (SaveJSON) | string | Emitted when form JSON is exported. |
| (afterFilter) | DynRecord[] | Emitted after filter operation with result set. |
| (dragStarted) | Record | Emitted when drag starts. |
| (dragReleased) | void | Emitted when drag ends. |
| (clickDragIndicator) | Record | Emitted when drag handle is clicked. |
| (out) | eventOut | General-purpose external output. |
| (fireTrigger) | FireTrigger | Emitted when a trigger fires. |
| (afterOutputExternalFilters) | FilterStatistic | Emitted after external filters applied. |
eqp-dynamic-module-configurator — Form Builder
Usage modes
<!-- Create new form -->
<eqp-dynamic-module-configurator
*ngIf="config"
[configurations]="config"
(saveFormEvent)="onFormSaved($event)">
</eqp-dynamic-module-configurator>
<!-- Edit existing form -->
<eqp-dynamic-module-configurator
[configurations]="config"
[formID]="formID"
(saveFormEvent)="onFormSaved($event)">
</eqp-dynamic-module-configurator>
<!-- Export form -->
<eqp-dynamic-module-configurator
[configurations]="config"
[formID]="formID"
[viewMode]="'Export'"
(saveFormEvent)="onFormSaved($event)">
</eqp-dynamic-module-configurator>
<!-- Import from JSON -->
<eqp-dynamic-module-configurator
[configurations]="config"
[formID]="null"
[viewMode]="'Export'"
(saveFormEvent)="onFormSaved($event)">
</eqp-dynamic-module-configurator>Inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| configurations | DynamicModuleConfiguratorConfig | — | Required. Configuration container. |
| formID | string | null | Form ID to edit. null creates a new form. |
| viewMode | string | "addOrEdit" | "addOrEdit" or "Export". |
| fieldsExtraConfig | FieldExtraConfig[] | — | Extra configuration for specific fields. |
| triggers | any | — | Trigger definitions for the editor. |
| actionButtons | any | — | Action button definitions. |
| contestualization | Contestualization[] | — | Contextualisation options. |
| formulaObject | any | — | Context for formula preview. |
| QueryEditorComponent | DynamicLoaderDirectiveData | — | Custom query editor component. |
| debugMode | boolean | false | Enable verbose logging. |
| configuratorTheme | Record<string, string> \| null | null | CSS variable overrides via TypeScript object. |
| configuratorThemeCss | string \| null | null | CSS variable overrides via CSS text string (e.g. contents of a .css file). |
Outputs
| Output | Payload | Description |
|--------|---------|-------------|
| (saveFormEvent) | Form | Emitted on save when no save endpoint is configured. |
| (afterSaveFormEvent) | Form | Emitted after server save call completes. |
| (out) | eventOut | General-purpose external output. |
| (fireTrigger) | FireTrigger | Emitted when a trigger fires. |
Theming
The configurator exposes a theming system based on CSS custom properties. All values injected via the theme inputs are applied with !important and cannot be overridden externally except through these inputs.
<!-- Option A: TypeScript object -->
<eqp-dynamic-module-configurator
[configurations]="config"
[configuratorTheme]="{ '--conf-gradient': 'linear-gradient(to right, #1565c0, #0288d1)' }">
</eqp-dynamic-module-configurator>
<!-- Option B: CSS file loaded as string -->
<eqp-dynamic-module-configurator
[configurations]="config"
[configuratorThemeCss]="themeCssString">
</eqp-dynamic-module-configurator>CSS file format for configuratorThemeCss (no selector required):
--conf-gradient: linear-gradient(to right, #1565c0, #0288d1);
--conf-bg-page: #f0f6fb;
--conf-btn-color: #ffffff;Available variables:
| Variable | Default | Description |
|----------|---------|-------------|
| --conf-gradient | purple-blue gradient | Button and header background |
| --conf-bg-page | #f5f5f5 | General page/stepper background |
| --conf-radius | 10px | Button border radius |
| --conf-modal-radius | 12px | Modal border radius |
| --conf-accent | #693DDA | Accent colour (borders, focus) |
| --conf-primary | #1E31EB | Primary colour |
| --conf-step-selected | #643cda | Selected step arrow |
| --conf-step-edit | #3034e7 | Completed step arrow |
| --conf-stepper-header-bg | inherited from --conf-bg-page | Upper zone background (stepper header) |
| --conf-stepper-content-bg | inherited from --conf-bg-page | Lower zone background (form and buttons) |
| --conf-step-icon-edit-bg | inherited from --conf-step-edit | Completed step icon background |
| --conf-btn-color | #ffffff | Active button text colour (gradient background) |
| --conf-hint-btn-bg | #2563eb | Quick-suggestion button (lightbulb) background |
| --conf-hint-btn-hover-bg | #1d4ed8 | Lightbulb button hover background |
| --conf-table-header-bg | SCSS variable | Field table header background |
| --conf-search-bg | SCSS variable | Search field background |
| --conf-table-bg | #ffffff | Table row background |
| --conf-card-bg | #ffffff | Card background |
| --conf-font-family | inherit | Configurator-wide font family |
Configuration Models
DynamicModuleGeneralConfig
const general = new DynamicModuleGeneralConfig(
baseServerUrl, // string — e.g. "https://api.example.com/api"
userToken, // string — auth token
context, // Context
endPointConfiguration // EndPointConfiguration | null
);DynamicModuleListFormRecordActionsDefault
const actions = new DynamicModuleListFormRecordActionsDefault();
actions.add = true;
actions.view = true;
actions.edit = true;
actions.duplicate = false;
actions.delete = true;
actions.graphs = false;View Modes
enum DynamicModuleViewModeEnum {
NONE = 0,
VIEW = 1,
COMPILE = 2,
LIST = 3,
REPAIR = 4,
LISTWIEW = 5,
FILTER = 6,
GRAPHS = 7,
HLIST = 8,
EXTERNAL_FILTER = 9
}Endpoint Configuration
const endPoints = new EndPointConfiguration();
endPoints.Records.SaveEndPoint = new EndPointData();
endPoints.Records.SaveEndPoint.Url = 'https://custom-api.example.com/records/save';
endPoints.Records.SaveEndPoint.RequestMethod = RequestMethodEnum.POST;
endPoints.Records.SaveEndPoint.Params = [{
ParamName: 'orgId',
ParamValue: this.orgaId,
ParamType: ParamTypeEnum['Query param']
}];
const general = new DynamicModuleGeneralConfig(baseUrl, token, context, endPoints);Available Records endpoints: GetWithContextualizationByFormCodeEndPoint, GetByFormIDEndPoint, GetByFormCodeEndPoint, GetAllByEntAndUserIDEndPoint, GetByIDEndPoint, SaveEndPoint, DuplicateEndPoint, DeleteEndPoint, RepairEndPoint, ApplyFilter, GetAllAttachmentsEndPoint.
Available Forms endpoints: GetByIDEndPoint, GetAllFormEndPoint, GetByIDAndVersionEndPoint, SaveEndPoint, SaveAttachmentEndPoint, ExportByIDEndPoint, GetAttachmentWithBases64, SpeechToFormEditEndPoint.
Data Models
Record
| Property | Type | Description |
|----------|------|-------------|
| ID | string | Unique record identifier. |
| EntID | string | ID of the form this record belongs to. |
| Version | number | Form version at compilation time. |
| userID | string | ID of the user who created the record. |
| AnswerDate | string | ISO date string of compilation. |
| HTMLreadableValues | string | Pre-rendered HTML of field values. |
| AdditionalParams | any | Extra parameters. |
| AdditionalInfo | any | Extra information. |
Field Types Reference
| Value | Key | Description |
|-------|-----|-------------|
| 1 | Campo di testo | Single-line text input. |
| 2 | Area di testo | Multi-line textarea. |
| 3 | Booleano | Checkbox / boolean toggle. |
| 4 | Data e/ora | Date and/or time picker. |
| 5 | Campo numerico | Numeric input with mask. |
| 6 | Allegato | File attachment upload. |
| 7 | Immagine | Image upload with optional cropping. |
| 8 | Elenco generico | Dropdown / multi-select list. |
| 9 | Lookup | Server-side lookup with configurable query. |
| 10 | Form di dettaglio | Embedded detail (inner) form. |
| 11 | Elenco immagini | Image selector list. |
| 12 | Etichetta | Display-only label. |
| 13 | Immagine con markers | Image with interactive annotation markers. |
| 14 | Bottone | Action button field. |
