# Configurazione
# Configurazione data.js
Il file di configurazione è tutto quello di cui si è bisogno per creare interfaccie admin standard, ha varie tipi di personalizzazioni.
Il file si trova all'interno di ogni componente
# SIDEBAR_DATA
Incominciamo dalla Sidebar, il parametro da configurare è il SIDEBAR_DATA
const SIDEBAR_DATA = [
{
key: 'custom-component', // se si vuole creare un filtro esterno attraverso gli SLOT
componentType: 'custom'
},
{ ... },
{ ... },
{ ... },
]
Abbiamo 4 tipi di tipi che è possibile scegliere per la sidebar e che bisogna andare a settare nel campo componentType:
CUSTOM
Grazie all'utilizzo degli <slot></slot> è possibile andarsi a definire il filtro custom
FILTRO PER LE DATE

{
icon: 'thx-calendar',
componentType: 'date',
dates: [
{
title: 'Date create',
filter: 'filter__date_create'
},
{
title: 'Date last modify',
filter: 'filter__date_last_modify'
}
]
}
| Chiave | Tipo | Descrizione |
|---|---|---|
| icon | String | icona da mostrare nell'accordion |
| componentType | String | Il tipo di componente -> 'date' |
| dates | Array | Le date da inserire nel filtro |
- dates
| Chiave | Tipo | Descrizione |
|---|---|---|
| title | String | Label del componente |
| filter | String | Filtro da mandare giù a backend |
FILTRO SELECT | AUTOCOMPLETE (con lista statica)

{
icon: 'thx-info-empty',
componentType: 'select|autocomplete',
itemName: 'status',
itemPluralName: 'statuses',
filter: 'filter__status__in',
fieldSelectKeys: { id: 'id', name: 'name' },
options: [
{ id: 1, name: 'Enabled' },
{ id: 0, name: 'Disabled' }
]
},
| Chiave | Tipo | Descrizione |
|---|---|---|
| icon | String | icona da mostrare nell'accordion |
| componentType | String | Il tipo di componente -> 'select' o 'autocomplete' |
| title | String | label mostrata nell'accordion |
| itemName | String | nome del filtro (singolare) |
| itemPluralName | String | nome del filtro (plurale) |
| filter | String | che filtro mandare giù a backend quando è stato selezionato il campo |
| fieldSelectKeys | Object | dall'api di lista della select dove andare a prendere i dati per la lista nella select |
| options | Array | lista da inserire nella select |
FILTRO SELECT | AUTOCOMPLETE (con lista presa dal backend)

{
icon: 'thx-building',
componentType: 'select|autocomplete',
itemName: 'carriage',
itemPluralName: 'carriages',
filter: 'filter__carriage__in',
fieldSelectKeys: { id: 'code', name: 'name' },
apiUrl: '/api/v1/carriage/{profile}/carriage',
filterSearch: 'filter__name__icontains',
searchLength: 3
},
| Chiave | Tipo | Descrizione |
|---|---|---|
| icon | String | icona da mostrare nell'accordion |
| componentType | String | Il tipo di componente -> 'select' o 'autocomplete' |
| title | String | label mostrata nell'accordion |
| itemName | String | nome del filtro (singolare) |
| itemPluralName | String | nome del filtro (plurale) |
| filter | String | che filtro mandare giù a backend quando è stato selezionato il campo |
| fieldSelectKeys | Object | dall'api di lista della select dove andare a prendere i dati per la lista nella select |
| apiUrl | String | url dell'api da chiamare |
| filterSearch | String | filtro da mandare a bakend per filtrare la lista della select |
| searchLength | String | dopo quanti caratteri iniziare a chiamare l'api backend |
# LIST_DATA
Passiamo alla lista e alla tabella, il parametro da configurare è il LIST_DATA
const LIST_DATA = {
title: 'Demo',
instanceName: 'Demo',
instancePluralName: 'Demos',
paginationOnTop: true,
buttonSidebarOptions: { label: 'Transactions', icon: 'thx-sidebar-collapse' },
sidebarOptions: { width: 300 },
separator: '/',
buttonAddInfo: { label: 'Add', icon: 'thx-plus' },
mobileGrid: true,
showFooter: true,
showHeader: true,
showSidebar: true,
showPagination: true,
messageEnable: 'Enable',
messageDisable: 'Disable',
breadcrumbs: [...],
searchFields: [...],
fields: [...]
}
| Chiave | Tipo | Descrizione |
|---|---|---|
| title | String | Titolo della lista (di solito al plurale) |
| instanceName | String | Nome dell'istanza al singolare |
| instancePluralName | String | Nome dell'istanza al plurale |
| paginationOnTop | Boolean | Tipo di paginazione che viene posta sopra la tabella |
| buttonSidebarOptions | Object | Opzioni per modificare label e icona del pulsante per aprire la sidebar |
| sidebarOptions | Object | Opzioni grafiche che è possibile dare alla sidebar |
| separator | String | separatore da usare nei breadcrumbs |
| buttonAddInfo | Object | Opzioni per modificare label e icona del pulsante per aprire la pagina di creazione |
| mobileGrid | Boolean | Mostra o no la visualizzazione a griglia da mobile |
| showFooter | Boolean | Mostrare footer pagina |
| showHeader | Boolean | Mostrare header pagina |
| showSidebar | Boolean | Mostrare sidebar |
| messageEnable | String | testo di abilita da mostrare nella modale |
| messageDisable | String | testo di disabilita da mostrare nella modale |
| buttonSidebarOptions | Object | Personalizzare il pulsante che apre e chiude la sidebar |
| routeNameList | String | Nome della route di lista |
| routeNameType | String | Nome della route di lista filtrata per tipo |
| breadcrumbs | Array | I link per i vari redirect tra dettaglio e lista |
| searchFields | Array | Lista dei filtri per la ricerca avanzata |
| fields | Array | Lista dei campi che andranno mostrati nella tabella |
| actions | Array | Lista delle azioni |
# breadcrumbs

const LIST_DATA = {
//...
breadcrumbs: [
{ label: 'Home' },
{ label: 'Demo', to: { name: DEMO_ROUTES.DEMO_LIST } }
],
//...
}
| Chiave | Tipo | Descrizione |
|---|---|---|
| label | String | Nome che verrà mostrato |
| to | Object | route da reindirizzare al click |
# searchFields
I searchField sono i filtri che verranno mostrati nella ricerca avanzata, si possono aggiungere vari tipi di componenti, I vari filtri sono suddivisi per righe.

CUSTOM
Grazie all'utilizzo degli <slot></slot> è possibile andarsi a definire il filtro custom
const LIST_DATA = {
//...
searchFields: [
{
key: '1', // nome della chiave da usare eventualmente come slot
columns: [ // colonne da cui verrà composta la riga
{
key: 'filter__age',
label: 'Age',
col: 6,
componentType: 'input',
options: {
type: 'number',
rules: [
val => (val === null || val === '' || (val > 0 && val < 120)) || 'Please type a real age'
]
}
},
{
key: 'filter__organization_group__in',
label: 'Select',
col: 6,
componentType: 'select|autocomplete',
options: { // per i seguenti tipi di componenti vanno specificati i seguenti parametri (OBBLIGATORI)
fieldSelectKeys: { id: 'id', name: 'name' }, // dal backend quali sono i campi dove andare a prendere le informazioni
noPage: false, // la chiamata api ha paginazione o no
apiUrl: '/api/v1/organization/{profile}/organization-group', // api da chiamare
filterSearch: 'filter__name__icontains', // filtro per filtrare la lista nella ricerca tramite input
}
},
]
},
{
key: '2',
columns: [
{ // Esempio con le choices
key: 'filter__typology',
label: i18n.t('Typology'),
col: 3,
componentType: 'select',
options: {
fieldSelectKeys: { id: '0', name: '1' },
apiUrl: '/api/v1/survey/{profile}/question/typology-choices/'
}
}
]
}
],
//...
}
| Chiave | Tipo | Descrizione |
|---|---|---|
| key | String | Nome della riga (deve essere univoco), personalizzabile tramite slot |
| columns | Array | Composizione e contenuto della riga |
Attenzione!
Per personalizzare i vari componenti bisogna usare le props relative del componente nel parametro options, fare riferimento alle relative documentazioni
I tipi di filtri disponibili sono (stringa da inserire nel parametro componentType):
- input - Qinput (opens new window)
- date/datetime/daterange/time/full - VueFlatpickr (opens new window)
- checkbox - QCheckbox (opens new window)
- checkbox-group QOptionGroup (opens new window)
- select/autocomplete/multiselect Qselect (opens new window)
# columns
| Chiave | Tipo | Descrizione |
|---|---|---|
| key | String | Filtro che verrà mandato giù a backend |
| label | String | Nome del filtro |
| col | Number | Larghezza che il filtro dovrà avere su una dimensione massima di 12 (che occupa tutta riga) |
| componentType | String | Tipo di componente che dovrà essere il filtro |
| options | Object | Le varie personalizzazioni del componente |
# fields
I fields sono i campi che verranno mostrati nella tabella

const LIST_DATA = {
//...
fields: [
{
name: 'status',
label: 'Status',
align: 'center',
type: 'boolean', // text/date/datetime/boolean/currency/percent/function
sorting: 'status',
tdClass: 'text-nowrap',
thClass: 'text-nowrap',
labelClass: '',
hideMobile: false,
field: 'status'
},
{
name: 'date_start',
label: 'Date start',
align: 'left',
type: 'date',
sorting: 'status',
tdClass: 'text-nowrap',
thClass: 'text-nowrap',
labelClass: '',
hideMobile: false,
field: 'date_start'
},
{
name: 'organization',
label: 'Organization',
align: 'left',
type: 'function',
sorting: 'organization__name',
tdClass: 'text-nowrap',
thClass: 'text-nowrap',
labelClass: '',
hideMobile: false,
field: (instance) => instance.organization.name
},
{
name: 'name', // campo custom andrà definito nello slot relativo con la sintassi body-cell-[name]
label: 'Name',
align: 'left',
custom: true
},
{
name: 'actions',
label: 'Actions',
align: 'right',
tdClass: 'text-right text-nowrap',
thClass: 'text-right text-nowrap',
actions: [
'detail', // mostra il pulsante di dettaglio
'edit', // mostra il pulsante di modifica
'status', // mostra il pulsante di cambio status
'delete' // mostra il pulsante di cancellazione
]
}
]
//...
}
| Chiave | Tipo | Descrizione |
|---|---|---|
| name | String | Nome del campo (univoco) in modo da poterlo modificare tramite slot |
| label | String | Nome della colonna di quel campo |
| align | String | In che posizione verrà allineato il campo nella tabella (left, center, right) |
| type | String | Tipo di formattazione del campo |
| sorting | String | Se il campo è ordinabile, inserire il nome del campo da mandare a backend |
| tdClass | String | Eventuale classe che avrà la cella |
| thClass | String | Eventuale classe che avrà la colonna |
| labelClass | String | Eventuale classe che avrà il campo |
| condition | String | Se un campo è formato da un oggetto e si vuole prendere la variabile all'interno dell'oggetto, si usa il seguente parametro inserendo qui il nome dell'oggetto |
| hideMobile | String | mostrare o no il campo da mobile |
| field | String | Inserire il nome del campo tornato da backend da mostrare nella tabella |
| custom | Boolean | Se non vanno bene i campi di default, settando questo parametro a true puoi personalizzarti il campo tramite gli slot |
type
I tipi di formattazione utilizzabile per i campi sono i seguenti:
- text - traduce il campo
- date - mostra la data nel seguente formato DD/MM/YYYY
- datetime - mostra la data nel seguente formato DD/MM/YYYY HH:mm
- boolean - mostra il campo tramite 2 icone per indicare vero e falso
- currency - mostra il campo in formato con la valuta (es 56.000,00 €)
- percent - mostra il campo con la percentuale alla fine (es 20,00%)
- function - esegue una funzione che ritorna il campo
# actions
Le azioni vengono rappresentate nell'apposita select e selezionate varie righe della tabella permette di svolgere azoni su di esse
Tramite il campo actions è possibile definirne la lista
Oppure è possibile lasciare quelle di default e aggiurgerne altre con il campo otherActions
A seconda dei casi andrà ridefinita la funzione doAction oppure doCustomActions
const LIST_DATA = {
// ...
showSelectAllButton: true, // mostra il pulsante per selezionare tutta la lista
actions: [
{ value: null, text: `– ${i18n.t('Select action')}` },
{ value: 'enable', text: i18n.t('Set as enable') },
{ value: 'disable', text: i18n.t('Set as disable') },
{ value: 'delete', text: i18n.t('Delete selected') }
],
otherActions: [
{ value: 'custom', text: i18n.t('custom') }
]
// ...
}
# DETAIL_DATA
Concludiamo con la pagina di dettaglio, il parametro da configurare è il DETAIL_DATA
const DETAIL_DATA = {
pageName: 'Demo',
editMode: true,
breadcrumbs: [...],
fields: [...]
}
| Chiave | Tipo | Descrizione |
|---|---|---|
| pageName | String | Nome della pagina (di solito al singolare) |
| breadcrumbs | Array | I link per i vari redirect tra dettaglio e lista |
| showSidebar | Boolean | Mostro la sidebar nel dettaglio |
| showOnlyEdit | Boolean | Mostro direttamente la modifica senza passare dal dettaglio |
| showCard | Boolean | Mostro la card |
| showHeader | Boolean | Mostro l'header |
| showEditButton | Boolean | Mostro il pulsante di modifica in alto nell'header |
| showCloseButton | Boolean | Mostro il pulsante di chiusura in alto nell'header |
| editMode | Boolean | Mostro la modifica senza passare dal visualizza |
| separator | String | Separatore da inserire nei breadcrumbs |
| sidebarOptions | Object | Opzioni della sidebar, fare riferimento al q-drawer di quasar |
| routeList | Object | Router di reindirizzamento quando si chiude il dettaglio |
| fields | Array | Form che andrà a comporre la nostra pagina |
# breadcrumbs
const DETAIL_DATA = {
//...
breadcrumbs: [
{ label: 'Demo', to: { name: DEMO_ROUTES.DEMO_LIST } },
{ label: 'Demo' }
],
//...
}
# fields
I fields sono le righe che andranno a comporre il nostro form, la struttura è la seguente
const DETAIL_DATA = {
//...
fields: [
{ ... }, // righe che comporranno il form
{ key: 'custom-row' }, // possibilità di crearsi le proprie righe tramite SLOT
{
key: '1',
columns: [
{
key: 'code',
label: 'Code',
col: 3,
componentType: 'input',
rules: {required}
},
{
key: 'customer',
label: 'Customer',
col: 6,
componentType: 'select|autocomplete|multiselect',
options: {
fieldDetailKeys: {id: 'customer', name: 'customer_name'}, // dall'api del dettaglio dove andare a prendere i campi da inserire
fieldSelectKeys: {id: 'id', name: 'name'}, // dall'api di lista della select dove andare a prendere i dati per la lista nella select
apiUrl: '/api/v1/demo/{profile}/demo/', // api da chiamare per visualizzare la lista nella select
noPage: false, // la chiamata api ha paginazione oppure no
filterSearch: 'filter__name__icontains', // filtro per filtrare la lista nella ricerca tramite input
otherFilters: {filter__status: 1}, // se si vogliono aggiungere altri filtri per filtrare la lista nella select
searchLength: 3 // dopo quanti caratteri iniziare a chiamare l'api backend
},
rules: {required}
},
]
},
{ ... },
],
//...
}
| Chiave | Tipo | Descrizione |
|---|---|---|
| key | String | Nome della riga (deve essere univoco), personalizzabile tramite slot |
| columns | Array | Composizione e contenuto della riga |
# columns
| Chiave | Tipo | Descrizione |
|---|---|---|
| key | String | Nome del campo che ritorna dal backend |
| label | String | label del campo da mostrare nel form |
| col | Number | Larghezza che il filtro dovrà avere su una dimensione massima di 12 (che occupa tutta riga) |
| componentType | String | Il tipo di componente, si può scegliere tra vari tipi |
| options | Object | Le varie personalizzazioni del componente |
| rules | Object | Le regole che deve rispettare, fare riferimento a Vuelidate (opens new window) per maggiori informazioni |
Attenzione!
Per personalizzare i vari componenti bisogna usare le props relative del componente nel parametro options, fare riferimento alle relative documentazioni
I tipi di componenti disponibili sono (stringa da inserire nel parametro componentType):
- input/currency - Qinput (opens new window)
- checkbox - QCheckbox (opens new window)
- checkbox-group QOptionGroup (opens new window)
- date/datetime/daterange/time/full - VueFlatpickr (opens new window)
- select/autocomplete/multiselect Qselect (opens new window)
- file Qfile (opens new window)
- json VJsonEditor (opens new window)
- editor Tip tap editor (opens new window)
- text
Seguono alcuni esempi
INPUT

{
key: 'code',
label: 'Code',
col: 6,
componentType: 'input',
rules: { required }
}

{
key: 'code',
label: 'Code',
col: 6,
componentType: 'input',
options: {
type: 'number',
rules: [
val => (val === null || val === '' || (val > 0)) || 'Please type a number greater than 0'
]
}
rules: { required }
}
INPUT CURRENCY

{
key: 'demo',
label: 'Demo',
col: 3,
componentType: 'currency',
rules: { required }
}
TEXT AREA

{
key: 'textarea',
label: 'Textarea',
col: 12,
componentType: 'input',
options: { type: 'textarea' },
rules: {}
},
CHECKBOX

{
key: 'checkbox',
label: 'Status',
col: 3,
componentType: 'checkbox',
options: {
trueValue: 1,
falseValue: 0
},
},
CHECKBOX GROUP

{
key: 'checkbox-group',
label: 'Checkbox group',
col: 6,
componentType: 'checkbox-group',
options: {
options: [
{
label: 'Option 1',
value: 'op1'
},
{
label: 'Option 2',
value: 'op2'
},
{
label: 'Option 3',
value: 'op3'
}
]
}
}
DATE/DATETIME/DATERANGE/TIME

// date
{
key: 'date',
label: 'Date',
col: 3,
componentType: 'date',
options: { minDate: 'date_create' },
rules: {}
},
// daterange
{
key: 'daterange',
label: 'Daterange',
col: 3,
componentType: 'daterange',
options: { maxDate: date.formatDate(new Date(), 'YYYY-MM-DD') },
rules: {}
},
// datetime
{
key: 'datetime',
label: 'Datetime',
col: 3,
componentType: 'datetime',
rules: {}
},
// time
{
key: 'time',
label: 'Time',
col: 3,
componentType: 'time',
rules: {}
}
SELECT/AUTOCOMPLETE/MULTISELECT

// select
{
key: 'select',
label: 'Select',
col: 3,
componentType: 'select',
options: {
fieldDetailKeys: { id: 'code', name: 'name' },
fieldSelectKeys: { id: 'id', name: 'name' },
apiUrl: '/api/v1/organization/administrator/organization-group',
noPage: true
}
},
// autocomplete
{
key: 'autocomplete',
label: 'Autocomplete',
col: 3,
componentType: 'autocomplete',
options: {
apiUrl: '/api/v1/organization/administrator/organization-group',
noPage: true
}
},
// autocomplete
{
key: 'autocomplete_with_vuex',
label: 'Autocomplete with vuex',
col: 3,
componentType: 'autocomplete',
options: {
apiUrl: '/api/v1/organization/administrator/organization-group',
filterSearch: 'filter__name__icontains',
searchLength: 3
}
},
// multiselect
{
key: 'multiselect',
label: 'Multiselect with vuex',
col: 3,
componentType: 'multiselect',
options: {
fieldDetailKeys: { id: 'code', name: 'name' },
fieldSelectKeys: { id: 'id', name: 'name' },
apiUrl: '/api/v1/organization/administrator/organization-group',
filterSearch: 'filter__name__icontains',
searchLength: 3
}
}
{ // Esempio con le choices
key: 'choices',
label: i18n.t('Typology'),
col: 3,
componentType: 'select',
options: {
fieldSelectKeys: { id: '0', name: '1' },
fieldDetailKeys: { id: 'typology', name: 'get_typology_display' },
apiUrl: '/api/v1/survey/{profile}/question/typology-choices/'
}
}
EDITOR

{
key: 'editor',
label: 'Editor',
col: 12,
componentType: 'editor',
rules: {}
}
FILE

{
key: 'file',
label: 'File',
col: 6,
componentType: 'file',
options: {
showImage: true
},
rules: {}
}
JSON

{
key: 'json',
label: 'Json',
col: 12,
componentType: 'json',
rules: {}
},
TEXT

{
key: 'date',
label: 'Date',
col: 6,
componentType: 'text',
options: {
type: 'date'
},
rules: {}
}
// type
I tipi di formattazione utilizzabile per i campi sono i seguenti:
* text - traduce il campo
* date - mostra la data nel seguente formato DD/MM/YYYY
* datetime - mostra la data nel seguente formato DD/MM/YYYY HH:mm
* boolean - mostra il campo tramite 2 icone per indicare vero e falso
* currency - mostra il campo in formato con la valuta (es 56.000,00 €)
* percent - mostra il campo con la percentuale alla fine (es 20,00%)
* function - esegue una funzione che ritorna il campo
# INLINE ROW
È un tipo di riga particolare da inserire nei fields del DETAIL_DATA che permette di modificare una lista di elementi, da usare in particolare per le ManyToManyField di tipo through (opens new window).

{
key: 'row',
title: 'Yard contractor',
type: 'inline',
apiUrl: '/api/v1/yard/{profile}/yard-contractor',
deleteApiUrl: '/api/v1/yard/{profile}/yard-contractor', // api da utilizzare quando si elimina un istanza
updateApiUrl: '/api/v1/yard/{profile}/yard-contractor', // api da utilizzare quando si modifica un istanza
createApiUrl: '/api/v1/yard/{profile}/yard-contractor', // api da utilizzare quando si crea un istanza
optionKey: 'roles', // se settato andrà a prendere la lista da una chiave del dettaglio
noPage: false // Se settato a false andrà ad usare il sistema di paginazione backend
frontendPagination: false, // se settato a true la paginazione verrà gestita a frontend
buttonLabel: // label del pulsante di aggiunta di una nuova riga
otherFilters: { filter__status: 1 },
filter: 'filter__yard',
foreignKeyName: 'yard',
fieldsCol: 11,
actionsCol: 1,
columns: [
{
key: 'contractor',
label: 'Contractor',
col: 6,
componentType: 'autocomplete',
options: {
fieldDetailKeys: { id: 'contractor', name: 'contractor_name' },
fieldSelectKeys: { id: 'id', name: 'name' },
optionValue: 'id',
optionLabel: 'name',
filterSearch: 'filter__name__icontains',
apiUrl: '/api/v1/organization/{profile}/organization'
},
rules: { required }
},
{
key: 'date_yard_entry',
label: 'Date yard entry',
col: 6,
componentType: 'date',
rules: {}
},
{
key: 'editor',
label: 'Editor',
col: 12,
componentType: 'editor'
}
],
actions: [ // i tipi di pulsanti sono remove rimuovere una riga
{
key: 'button_remove',
type: 'remove',
icon: 'thx-remove-empty',
round: true
// altre opzioni <q-btn />
},
{ // È possibile definire dei tasti custom da sovrascrivere negli slot
key: 'custom_button'
}
]
}
| Chiave | Tipo | Descrizione |
|---|---|---|
| key | String | Nome della riga (deve essere univoco), personalizzabile tramite slot |
| title | String | Titolo |
| type | String | Tipo della riga in questo caso sarà 'inline' |
| apiUrl | String | l'api che chiama la ManyToMany di tipo through (opens new window) |
| deleteApiUrl | String | l'api di elimina che chiama la ManyToMany di tipo through (opens new window) |
| updateApiUrl | String | l'api di update che chiama la ManyToMany di tipo through (opens new window) |
| createApiUrl | String | l'api di create che chiama la ManyToMany di tipo through (opens new window) |
| optionKey | String | Se settato andrà a prendere la lista delle inline da una chiave del dettaglio della retrieve |
| noPage | String | Se settato a false andrà ad usare il sistema di paginazione backend |
| frontendPagination | String | Se settato a true la paginazione verrà gestita interamente dal frontend e dal backend ritornerà tutta la lista |
| buttonLabel | String | Label che andrà a comporre il pulsante di aggiunta di una nuova riga |
| foreignKeyName | String | chiave che andrà ad associare la riga al dettaglio |
| otherFilters | Object | altri eventuali filtri da passare all'api |
| filter | String | L'api chiamata andrà filtrata per l'id del dettaglio |
| fieldsCol | Number | Quanto spazio riservare al form (su un max di 12) |
| actionsCol | Number | Quanto spazio riservare ai pulsanti (su un max di 12) |
| columns | Array | Sono identiche a quelle nel dettaglio (columns) |
| actions | Array | Rappresentano i pulsanti da inserire a fianco del form |
# PARENT
Il Parent (genitore) è il componente padre di quello presente nel dettaglio, è utile quando si vuole modificare il componente padre in un dettaglio senza dover cambiare pagina
Nel componente dove si vuole modificare il padre bisognerà aggiungere un nuovo parametro parent

{
key: 'client',
label: 'Client',
col: 6,
componentType: 'autocomplete',
options: { ... },
rules: { ... }
parent: {
key: 'parent_client',
label: 'Organization',
store: useOrganizationStore,
type: 'modal|tooltip', // modal o tooltip -> default modal
options: { fullWidth: true },
fieldsToUpdate: [
{ fieldName: 'id', parentFieldName: 'id' },
{ fieldName: 'name', parentFieldName: 'name' }
],
fields: [...],
actions: [
{
key: 'button_add',
type: 'add',
icon: 'thx-plus',
// altre opzioni <q-btn />
},
{
key: 'button_edit',
type: 'add',
icon: 'thx-edit-pencil',
// altre opzioni <q-btn />
},
{
key: 'button_show',
type: 'show',
icon: 'thx-eye-empty',
// altre opzioni <q-btn />
},
]
},
},
| Chiave | Tipo | Descrizione |
|---|---|---|
| key | String | Nome della riga (deve essere univoco), personalizzabile tramite slot |
| label | String | Titolo |
| store | Object | store dove andare a prendere i dati del componente padre |
| type | String | tipologia del componente (può essere una modale o un tooltip) |
| options | Object | props del componente (solo per modale), fare riferimento alle QDialog (opens new window) |
| fieldsToUpdate | Array | Campi da andare a modificare una volta salvato il nuovo componente padre |
| fields | Array | Form che andrà a comporre la nostra modale o tooltip |
| actions | Array | Pulsanti da mostrare per richiamare il componente padre (aggiungi, modifica, visualizza) |
fieldsToUpdate
- fieldName - campo da aggiornare nel dettaglio
- fieldParentName -> campo del padre da cui prelevare il nuovo dato
Di seguito alcuni esempi
MODAL

{
key: 'client',
label: 'Client',
col: 6,
componentType: 'autocomplete',
options: {
fieldDetailKeys: { id: 'client', name: 'client_name' },
fieldSelectKeys: { id: 'id', name: 'name' },
apiUrl: '/api/v1/organization/administrator/organization',
filterSearch: 'filter__name__icontains',
otherFilters: { filter__status: 1 }
},
rules: { required }
parent: {
key: 'parent_client',
label: 'Organization',
store: useOrganizationStore,
type: 'modal', // modal or tooltip | default modal
options: {
fullWidth: true
},
fieldsToUpdate: [
{ fieldName: 'id', parentFieldName: 'id' },
{ fieldName: 'name', parentFieldName: 'name' }
],
fields: [
{
key: '1',
columns: [
{
key: 'code',
label: 'Code',
col: 4,
componentType: 'input',
rules: { required }
},
{
key: 'name',
label: 'Name',
col: 4,
componentType: 'input',
rules: { required }
},
{
key: 'logo',
label: 'Logo',
col: 4,
componentType: 'file',
rules: {}
},
{
key: 'organization_types',
label: 'Organization types',
col: 12,
componentType: 'multiselect',
options: {
fieldDetailKeys: { id: 'id', name: 'name' },
fieldSelectKeys: { id: 'id', name: 'name' },
optionValue: 'id',
optionLabel: 'name',
apiUrl: '/api/v1/organization/administrator/organization-type',
noPage: true
},
rules: { required }
}
]
}
],
actions: [GET_BUTTON_ADD(), GET_BUTTON_EDIT(), GET_BUTTON_SHOW()]
}
}
TOOLTIP

{
key: 'client',
label: 'Client',
col: 6,
componentType: 'autocomplete',
options: {
fieldDetailKeys: { id: 'client', name: 'client_name' },
fieldSelectKeys: { id: 'id', name: 'name' },
apiUrl: '/api/v1/organization/administrator/organization',
filterSearch: 'filter__name__icontains',
otherFilters: { filter__status: 1 }
},
rules: { required }
parent: {
key: 'parent_client',
label: 'Organization',
store: useOrganizationStore,
type: 'tooltip', // modal or tooltip | default modal
options: {
fullWidth: true
},
fieldsToUpdate: [
{ fieldName: 'id', parentFieldName: 'id' },
{ fieldName: 'name', parentFieldName: 'name' }
],
fields: [
{
key: '1',
columns: [
{
key: 'email',
label: 'Email',
col: 6,
componentType: 'input',
rules: { required }
},
{
key: 'name',
label: 'Name',
col: 6,
componentType: 'input',
rules: { required }
}
]
}
],
actions: [GET_BUTTON_ADD(), GET_BUTTON_EDIT(), GET_BUTTON_SHOW()]
}
},
← Installazione Mixin →