# Mixin

I mixin sono uno dei principali modi di personalizzare i componenti, grazie ai mixin è possibili andare a ridefinire variabili e funzioni

Vediamoli nel dettaglio

Attenzione!

Per tutti i mixin in questo elenco va passato come parametro lo store del modello in questione

# ThuxCommonFilterMixin

È un mixin utilizzato per la gestione dei filtri laterali sulla sidebar.

definizione

const { useCommonFilters } = ThuxCommonFilterMixin(store)

Ridefinizione dei campi e funzioni

  • SIDEBAR_DATA.[nomecampo] = nuovoCampo
  • SIDEBAR_DATA.[nomeComputed] = () => computed(() => return { // nuova funzione }
  • SIDEBAR_DATA.[nomeFunzione] = () => { // nuova funzione }

oppure se vi servono i dati all'interno del useCommonFilters

  • useCommonFilters.[nomecampo] = nuovoCampo
  • useCommonFilters.[nomeComputed] = () => computed(() => return { // nuova funzione }
  • useCommonFilters.[nomeFunzione] = () => { // nuova funzione }

# - Funzioni

setFilterToComponent

  • type Function

Funzione per settare e mandare giù i filtri per filtrare i campi a backend


cleanComponentFilters

  • type Function

Funzione che rimuove i filtri dei campi che filtravano a backend


resetFilters

  • type Function

Funzione che resetta TUTTI i filtri della sidebar


editComponentFilters

  • type Function

Funzione che richiama la setFilterToComponent o la cleanComponentFilters a seconda dei parametri passati


Esempio
<script setup>
import { useStore as useDemoStore } from './store'
import ThuxCommonFilterMixin from 'components/thux-common-filters/mixins/ThuxCommonFilterMixin'
import ThuxCommonFilterComponent from 'components/thux-common-filters/ThuxCommonFilterComponent'

import { SIDEBAR_DATA } from './data'

const store = useDemoStore()
const { useCommonFilters } = ThuxCommonFilterMixin(store)

const fields = SIDEBAR_DATA
</script>

# List

# ThuxListMixin

definizione

const { useList, useAdvancedSearch, usePagination, useActionSelect } = ThuxListMixin(store, routes, LIST_DATA)

Ridefinizione dei campi e funzioni

  • LIST_DATA.[nomecampo] = nuovoCampo
  • LIST_DATA.[nomeComputed] = () => computed(() => return { // nuova funzione }
  • LIST_DATA.[nomeFunzione] = () => { // nuova funzione }

oppure se vi servono i dati all'interno del useList

  • useList.[nomecampo] = nuovoCampo
  • useList.[nomeComputed] = () => computed(() => return { // nuova funzione }
  • useList.[nomeFunzione] = () => { // nuova funzione }

oppure se vi servono i dati all'interno del useAdvancedSearch

  • useAdvancedSearch.[nomecampo] = nuovoCampo
  • useAdvancedSearch.[nomeComputed] = () => computed(() => return { // nuova funzione }
  • useAdvancedSearch.[nomeFunzione] = () => { // nuova funzione }

oppure se vi servono i dati all'interno del usePagination

  • usePagination.[nomecampo] = nuovoCampo
  • usePagination.[nomeComputed] = () => computed(() => return { // nuova funzione }
  • usePagination.[nomeFunzione] = () => { // nuova funzione }

oppure se vi servono i dati all'interno del useActionSelect

  • useActionSelect.[nomecampo] = nuovoCampo
  • useActionSelect.[nomeComputed] = () => computed(() => return { // nuova funzione }
  • useActionSelect.[nomeFunzione] = () => { // nuova funzione }

# - Campi

title

  • type: String
  • default: ''

Titolo della pagina

Esempio

An image

LIST_DATA.title = i18n.t(LIST_DATA.title)

instanceName

  • type: String
  • default: undefined

Indica il nome della pagina (al singolare)

Esempio
LIST_DATA.instanceName = 'Organization'

instancePluralName

  • type: String
  • default: undefined

Indica il nome della pagina (al plurale)

Esempio
LIST_DATA.instancePluralName = 'Organizations'

breadcrumbs

  • type: Array
  • default: []

Sono dei link di navigazione che riproducono il percorso disegnato dal sito web e consentono all'utente di capire dove si trova

Esempio

An image

LIST_DATA.breadcrumbs = [
    { label: 'Home' },
    { label: 'Demo', to: { name: DEMO_ROUTES.DEMO_LIST } }
]

layoutOptions

  • type: Object
  • default: { class: 'layout-fixed' }

Personalizzazioni da dare al layout della pagina (Ad esempio la pagina rimane con il titolo e i pulsanti fissati in alto anche se si scorre in basso)


sidebarOptions

  • type: Object
  • default: { width: '300' }

Personalizzazioni da dare alla sidebar (fare riferimento al componente Qdrawer (opens new window) per conoscere le prop relative)


buttonSidebarOptions

  • type: Object
  • default: { label: 'Filters', icon: 'thx-filter', hide: false }

Pulsante per aprire e chiudere la sidebar nella lista

Esempio

An image

LIST_DATA.buttonSidebarOptions = { label: 'Transactions', icon: 'thx-sidebar-collapse', hide: false }

separator

  • type: String
  • default: '/'

Stringa che separa i vari breadcrumb tra loro

Esempio

An image

LIST_DATA.separator = '>'

routeNameList

  • type: String
  • default: ''

Nome della route del componente lista


showEditForm

  • type: Boolean
  • default: false

Booleano per mostrare o no l'Edit


showDetailForm

  • type: Boolean
  • default: false

Booleano per mostrare o no il Detail


showFooter

  • type: Boolean
  • default: true

Booleano per mostrare o no il Footer (di default il footer è la paginazione)


showHeader

  • type: Boolean
  • default: true

Booleano per mostrare o no l'Header (di default l'header è il titolo e i pulsanti a lato)


showSidebar

  • type: Boolean
  • default: true

Booleano per mostrare o no la Sidebar


# - Computed

showList

  • type: Computed

Mostra o no la lista (utile quando si va nel dettaglio di una pagina, quindi si nasconde la lista)

Esempio

Mostra la lista finche non si è nel dettaglio (quando si cambia route)

LIST_DATA.showList = computed(() => {
  return route.name === DEMO_ROUTES.DEMO_LIST
})

canAddInstance

  • type: Computed

Mostra o no il pulsante di creazione (utile per differenziare i vari permessi, es 'manager' può creare invece 'staff' no)

Esempio
LIST_DATA.canAddInstance = computed(() => {
  return profile === 'manager'
})

# - Funzioni

openEditForm

  • type: Function

Funzione che si attiva quando clicco il pulsante modifica sulla tabella

Esempio

Di default apro il componente Edit

LIST_DATA.openEditForm = (id) => {
    componentId.value = id
    showEditForm.value = true
    showDetailForm.value = false
}

openDetailForm

  • type: Function

Funzione che si attiva quando clicco il pulsante dettaglio sulla tabella

Esempio

Di default apro il componente Detail

LIST_DATA.openDetailForm = (id) => {
    componentId.value = id
    showEditForm.value = true
    showDetailForm.value = false
}

closeForm

  • type: Function

Funzione che si attiva alla chiusura o del Detail o dell'Edit

Esempio
LIST_DATA.closeForm = () => {
    showEditForm.value = false
    showDetailForm.value = false
}

init

  • type: Function

Funzione che si attiva alla creazione del componente

Esempio

Alla creazione caricami la lista

LIST_DATA.init = (filters = {}) => {
    store.setFilters(filters)
}

initNestedComponent

  • type: Function

Funzione che si attiva alla creazione del componente (serve per evitare di chiamare l'api di lista nel dettaglio)

Esempio
useList.initNestedComponent = (filters = {}) => {
    isCreated.value = true
    if (isCreated.value && (route.name === routes.LIST || route.name === routes.LIST_TYPE)) {
      useList.init(filters)
      isCreated.value = false
    }
}

# ThuxAdvancedSearchMixin

Questo mixin è utilizzato per la gestione dell'Advanced Search

# - Campi

showAdvancedSearch

  • type: Boolean
  • default: false

Booleano per mostrare o no l'Advanced Search


searchFields

  • type: Array
  • default: []

Lista dei campi da mostrare nell'Advanced Search


# - Funzioni

openOrCloseAdvancedSearch

  • type: Function

Apertura e chiusura Advanced Search

Esempio
LIST_DATA.openOrCloseAdvancedSearch = () => {
    showAdvancedSearch.value = !showAdvancedSearch.value
}

getCustomFiltersToAdd

  • type: Function

Funzione usata se voglio aggiungere dei filtri custom

Esempio
useAdvancedSearch.getCustomFiltersToAdd = (filters) => {
    return filters
}

getCustomFiltersToRemove

  • type: Function

Funzione usata se voglio rimuovere dei filtri custom

Esempio
useAdvancedSearch.getCustomFiltersToRemove = (filters) => {
    return filters
}

addFiltersToList

  • type: Function

Setta i filtri della lista e chiama il backend

Esempio
useAdvancedSearch.addFiltersToList = (filtersToAdd) => {
    let filters = { ...store.filters.value }
    if (filtersToAdd) {
      Object.keys(filtersToAdd).forEach((key) => {
        filters[key] = filtersToAdd[key]
      })
    }
    filters = useAdvancedSearch.getCustomFiltersToAdd(filters)
    store.setExcludedList([])
    store.setFilters(filters).then(() => { useAdvancedSearch.updateSelectedList() })
}

removeFiltersFromList

  • type: Function

Rimuove tutti i filtri dall'Advanced Search e chiama il backend

Esempio
useAdvancedSearch.removeFiltersFromList = (filtersToRemove) => {
    filtersToRemove = useAdvancedSearch.getCustomFiltersToRemove(filtersToRemove)
    store.removeFilters(filtersToRemove).then(() => { useAdvancedSearch.updateSelectedList() })
}

# ThuxActionSelectMixin

Mixin utilizzato per la gestione delle azioni

# - Campi

action

  • type: Object
  • default: { value: null, text:– ${i18n.t('Select action')}}

Valore di default da mostrare nella select della action


actions

  • type: Array
  • default: (azioni di default: abilita e disabilita)
Esempio
LIST_DATA.actions = [
    { value: null, text: '– ${i18n.t("Select action")}' },
    {
      value: 'enable',
      text: i18n.t('Set as enable')
    },
    {
      value: 'disable',
      text: i18n.t('Set as disable')
    }
  ]

Lista delle azioni


otherActions

  • type: Array
  • default: []

Se si vogliono tenere le azioni di default e aggiungerne di nuove

Esempio
LIST_DATA.otherActions = [
    {
      value: 'action',
      text: i18n.t('Action')
    }
]

# - Computed

canSeeActionSelect

  • type: Computed

Mostra o no la select delle azioni (utile per differenziare i vari permessi, es 'manager' può fare azioni invece 'staff' no)

Esempio
LIST_DATA.canSeeActionSelect = computed(() => {
  return profile === 'manager'
})

showSelectAllButton

  • type: Computed

Mostra o no il pulsante seleziona tutto (utile quando si vuole selezionare tutto il queryset, es per fare un esportazione in excel)

Esempio
LIST_DATA.showSelectAllButton = computed(() => {
  return action.value.value === 'export_csv'
})

showCancelSelectionButton

  • type: Computed

Mostra o no il pulsante per deselezionare tutte le righe selezionate

Esempio
LIST_DATA.showCancelSelectionButton = computed(() => {
  return selectedList.value.length > 0
})

# - Funzioni

selectOrDeselectAllQueryset

  • type: Function

Mostra o no il pulsante per deselezionare tutte le righe della tabella selezionate

Esempio
LIST_DATA.showCancelSelectionButton = computed(() => {
    store.setSelectAll(isSelectAll)
    store.setSelectedList([])
})

selectAction

  • type: Function

La funzione si attiva quando viene selezionato un elemento dalla select delle azioni

Esempio
LIST_DATA.selectAction = (item) => {
    store.setSelectAll(false)
    action.value = actions.value.find((action) => action.value === item)
}

doAction

  • type: Function

La funzione si attiva quando viene premuto il pulsante esegui

  • Il fieldName è il nome della chiave primaria
Esempio
useActionSelect.doAction = (actionType) => {
    actionType = actionType.value
    if ((useActionSelect.selectedList.value.length !== 0 || useActionSelect.isSelectAll.value) && actionType) {
      const selectedListFiltered = useActionSelect.selectedList.value.filter((instance) => {
        if (actionType !== 'disable' && actionType !== 'enable') return instance
        const status = actionType === 'disable' ? 0 : 1
        return instance.status.toString() !== status.toString()
      })
      const idList = selectedListFiltered.map((instance) => instance[useActionSelect.fieldName.value])
      if (idList.length === 0) return
      const promises = []
      if (actionType === 'enable' || actionType === 'disable' || actionType === 'delete') {
        idList.forEach((id) => {
          let promise
          if (actionType === 'enable' || actionType === 'disable') {
            promise = store.setStatus({ id, status: actionType === 'disable' ? 0 : 1 })
          } else {
            promise = store.delete({ id })
          }
          promises.push(promise)
        })
        Promise.all(promises).then(() => {
          store.getList()
          store.setSelectedList([])
        })
      } else {
        useActionSelect.doCustomActions(actionType, idList)
      }
    }
}

doCustomActions

  • type: Function

Se oltre alle azioni di default (abilita e disabilita) ne ho aggiunte altre custom (viene eseguita quando clicco su esegui)

Esempio
LIST_DATA.doCustomActions = (actionType, idList) => {
    if (actionType === 'exportToCsv') {
        exportToCsv(idList)
    }
}

# ThuxPaginationMixin

Mixin per la gestione della paginazione

# - Campi

perPage

  • type: Number
  • default: 10

Quanti elementi per pagina mostrare in tabella

perPageOptions

  • type: Number
  • default: [10, 25, 50]

Lista di possibili numero di elementi per pagina

page

  • type: Number
  • default: 1

Pagina corrente all'interno della lista

# - Funzioni

changePerPage

  • type: Function

Funzione che viene chiamata quando viene selezionato un elemento della select per cambiare gli elementi per pagina

changePage

  • type: Function

Funzione che viene chiamata quando si cambia pagina nella tabella

# Table

# ThuxTableMixin

Mixin utilizzato per la gestione della tabella

# - Campi

instance

  • type: Object
  • default: {}

Istanza selezionata (es tramite pulsanti) e salvata in questo campo


instanceName

  • type: String
  • default: '''

Nome del modello


mobileGrid

  • type: Boolean
  • default: true

Booleano per mostrare o no la visualizzazione a griglia della tabella da mobile


# - Computed

canSeeInstance

  • type: Computed

Mostra o no il pulsante di dettaglio (utile per differenziare i vari permessi, es 'manager' può creare invece 'staff' no)

Esempio
LIST_DATA.canSeeInstance = computed(() => {
  return profile === 'manager' && profile === 'staff'
})

canEditInstance

  • type: Computed

Mostra o no il pulsante di modifica (utile per differenziare i vari permessi, es 'manager' può modificare invece 'staff' no)

Esempio
LIST_DATA.canEditInstance = computed(() => {
  return profile === 'manager'
})

canChangeStatusInstance

  • type: Computed

Mostra o no il pulsante di cambio stato (utile per differenziare i vari permessi, es 'manager' può cambiare stato invece 'staff' no)

Esempio
LIST_DATA.canChangeStatusInstance = computed(() => {
  return profile === 'manager'
})

canDeleteInstance

  • type: Computed

Mostra o no il pulsante di elimina (utile per differenziare i vari permessi, es 'manager' può eliminare invece 'staff' no)

Esempio
LIST_DATA.canDeleteInstance = computed(() => {
  return profile === 'manager'
})

canSeeChecks

  • type: Computed

Mostra o no le checkbox sulla tabella per le azioni (utile per differenziare i vari permessi, es 'manager' può creare invece 'staff' no)

Esempio
LIST_DATA.canSeeChecks = computed(() => {
  return profile === 'manager'
})

# - Funzioni

selectRow

  • type: Function

La funzione viene attivata quando seleziono una riga sulla tabella


applyOrderToTable

  • type: Function

La funzione viene attivata quando clicco su una colonna per aggiungere l'ordinamento a un campo


removeOrderFromTable

  • type: Function

La funzione viene attivata quando clicco su una colonna per rimuovere l'ordinamento di un campo


changeStatusInstance

  • type: Function

Funzione usata per il cambio di stato (attivo o disattivo) di una singola instanza


deleteInstance

  • type: Function

Funzione usata per l'eliminazione di una singola instanza


# Detail

# ThuxDetailMixin

Mixin usato per la gestione del dettaglio di una istanza

# - Campi

id

  • type: String|Number
  • default: route.params.id

Id del dettaglio dell'istanza


routeList

  • type: Object
  • default: { name: routes.LIST }

Route che ti riporta dal dettaglio alla lista


form

  • type: Object
  • default: {}

Campo che contiene il contenuto del dettaglio


formEditable

  • type: Boolean
  • default: false

Booleano che ti dice se puoi modificare il form oppure no


pageName

  • type: String
  • default: ''

Nome della pagina


fields

  • type: Array
  • default: []

Array di campi del data.js per popolare il form


breadcrumbs

  • type: Array
  • default: []

Sono dei link di navigazione che riproducono il percorso disegnato dal sito web e consentono all'utente di capire dove si trova


forceClose

  • type: Boolean
  • default: false

Se settato a true forza la chiusura del dettaglio al submit del form


editMode

  • type: Boolean
  • default: true

Il form è sempre modificabile, non c'è bisogno di passare dal visualizza


sidebarOptions

  • type: Object
  • default: { width: '300' }

Personalizzazioni da dare alla sidebar (fare riferimento al componente Qdrawer (opens new window) per conoscere le prop relative)


showSidebar

  • type: Boolean
  • default: false

Mostra o meno la sidebar nel dettaglio


showHeader

  • type: Boolean
  • default: true

Mostra o meno l'header nel dettaglio


showEditButton

  • type: Boolean
  • default: true

Mostra o meno il pulsante di modifica nel dettaglio


showCloseButton

  • type: Boolean
  • default: true

Mostra o meno il pulsante di chiusura nel dettaglio


separator

  • type: String
  • default: '/'

Stringa che separa i vari breadcrumb tra loro


routeNameList

  • type: String
  • default: ''

Nome della route del componente dettaglio


# - Computed

title

  • type: Computed

Titolo della pagina


# - Funzioni

init

  • type: Function

Funziona eseguita alla create del componente, di default fa la retrieve del componente


initFields

  • type: Function

Funziona aggiuntiva eseguita alla create del componente (usata se si vogliono inizializzare dei campi ulteriori e non si vuole riscrivere tutta la init), di default non fa niente


setForm

  • type: Function

Funziona aggiuntiva eseguita alla create del componente (usata se si vogliono inizializzare dei campi ulteriori e non si vuole riscrivere tutta la init), di default non fa niente