# 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

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

An image

{
  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)

An image

{
  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)

An image

{
  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

An image

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.

An image

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):

# 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

An image

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
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):

Seguono alcuni esempi

INPUT

An image

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

An image

{
  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

An image

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

An image

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

An image

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

An image

{
  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

An image

// 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

An image

// 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

An image

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

An image

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

An image

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

An image

{
  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).

An image

{
  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

An image

{
  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

An image

{
  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

An image

{
  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()]
  }
},