# Slot
Una volta completata la fase di configurazione, se si vuole dare ulteriore personalizzazione alle nostre pagine si possono utilizzare gli slot (opens new window)
Vediamoli nel dettaglio.
# Sidebar
TIP
Lo slot viene inizializzato all'interno del componente con la sintassi <template #nome-slot="props"></template>
Se non ti servono le variabili nello slot basta fare semplicemente <template #nome-slot></template>
Nel file data.js per definire un componente custom nella sidebar bisognerà utilizzare la seguente sintassi
| Slot | Descrizione |
|---|---|
| [key] | Inserendo il nome della chiave messo nel data.js è possibile usare un componente custom |
const SIDEBAR_DATA = [
{
key: 'custom-filter', // il nome deve essere univoco
componentType: 'custom',
},
{
key: 'custom-filter-2', // il nome deve essere univoco
componentType: 'custom',
}
]
Il filtro custom andrà importato nel file CommonFilters.vue nel seguente modo
<template>
<ThuxCommonFilterComponent
:use-common-filters="useCommonFilters"
:fields="fields"
>
<template #custom-filter>
<ComponenteCustom /> <!-- qui andrà il componente custom -->
</template>
<template #custom-filter-2>
<ComponenteCustom2 /> <!-- qui andrà il componente custom -->
</template>
</ThuxCommonFilterComponent>
</template>
# List
Il componente Lista ha diversi slot con cui personalizzarlo:
TIP
Lo slot viene inizializzato all'interno del componente con la sintassi <template #nome-slot="props"></template>
Se non ti servono le variabili nello slot basta fare semplicemente <template #nome-slot></template>
I principali sono:
| Slot | Descrizione |
|---|---|
| header | Il contenuto dell'header della pagina |
| advanced-search | Cosa si apre al click del pulsante della ricerca avanzata |
| detail | Cosa si apre al click del pulsante dettaglio |
| edit | Cosa si apre al click del pulsante modifica |
| body | Il corpo principale della pagina, se non si vuole per esempio usare la tabella ma qualcos'altro |
| table | Definizione del componente tabella |
| sidebar | Il contenuto della Sidebar |
Ci sono slot specifici anche per la sezione dell'Header della pagina
| Slot | Descrizione |
|---|---|
| header-components-top | Eventuali componenti da mostrare sopra la pagina |
| header-components-bottom | Eventuali componenti da mostrare sotto il titolo della pagina |
| header-title | Il titolo della pagina personalizzato |
| header-actions | pulsanti da mostrare a destra del titolo (di default sono la ricerca avanzata, pulsante che apre la sidebar e l'aggiungi) |
| other-header-actions-left | Se si vogliono aggiungere altri pulsanti a sinistra oltre a quelli di default |
| other-header-actions-right | Se si vogliono aggiungere altri pulsanti a destra oltre a quelli di default |
Ci sono slot specifici per la Lista
| Slot | Descrizione |
|---|---|
| header-primary | Cosa mostrare sopra la tabella (di default ci sono le azioni) |
| other-headers-buttons | Se si vogliono aggiungere altri componenti a destra dell'header |
| footer | cosa mostrare sotto la tabella (di default c'è la paginazione) |
<template>
<ThuxListGenericComponent
v-bind="{ ...$attrs }"
:use-list="useList"
:use-advanced-search="useAdvancedSearch"
:reset="reset"
:use-action-select="useActionSelect"
:use-pagination="usePagination"
>
<template #edit>
<Edit
v-if="useList.showEditForm.value"
:id="useList.componentId"
@close-form="useList.closeForm"
/>
</template>
<template #table>
<Table
:list="list"
@open-edit-form="useList.openEditForm"
@open-detail-form="useList.openDetailForm"
/>
</template>
<template #sidebar>
<CommonFilters />
</template>
</ThuxListGenericComponent>
<router-view />
</template>
Di seguito alcuni esempi del funzionamento dei vari slot:
# Esempi principali
header

<template #header>
<div class="row">
<h3 class="q-mr-md">Header personalizzato</h3>
<q-btn color="primary">Pulsante di test</q-btn>
</div>
</template>
advanced-search

<template #advanced-search>
<div v-show="useAdvancedSearch.showAdvancedSearch.value" class="row">
<q-input class="q-mr-md" model-value="">Advanced search personalizzato</q-input>
<q-btn flat color="primary">Salva</q-btn>
</div>
</template>
detail

<template #detail>
<Detail
v-if="useList.showDetailForm.value"
:id="useList.componentId"
@close-form="useList.closeForm"
/>
</template>
edit

<template #edit>
<Edit
v-if="useList.showEditForm.value"
:id="useList.componentId"
@close-form="useList.closeForm"
/>
</template>
body

<template #body>
<PortfolioCards v-show=cards class="q-mb-md" :cards="cards" />
<div class="row q-col-gutter-md">
<div class="col-12 col-md-6">
<DonutApexChart
v-if="Array.isArray(list) && totalAmount !== null"
:list="list"
:total-amount="totalAmount"
/>
</div>
<div class="col-12 col-md-6">
<ProductDataApexChart
v-for="(fund, index) in fundList"
:colors="getFundColor(index)"
:key="fund"
:wallet="fund"
/>
</div>
</div>
</template>
table

<template #table>
<Table
:list="list"
@open-edit-form="useList.openEditForm"
@open-detail-form="useList.openDetailForm"
/>
</template>
sidebar

<template #sidebar>
<TransactionsWidget />
</template>
# Esempi Header
header-components-top

<template #header-components-top>
<q-btn color="primary" class="q-mb-md q-mr-md">{{ i18n.t('Pulsante di prova') }}</q-btn>
<q-btn color="red" class="q-mb-md ">{{ i18n.t('Pulsante di prova 2') }}</q-btn>
</template>
header-components-bottom

<template #header-components-bottom>
<q-btn color="primary" class="q-my-md q-mr-md">{{ i18n.t('Pulsante di prova') }}</q-btn>
<q-btn color="red" class="q-my-md ">{{ i18n.t('Pulsante di prova 2') }}</q-btn>
</template>
header-title

<template #header-title>
<h4 class="text-primary">Titolo personalizzato</h4>
</template>
header-actions

<template #header-actions>
<q-btn color="primary" class="q-my-md q-mr-md">{{ i18n.t('Pulsante di prova') }}</q-btn>
<q-btn color="red" class="q-my-md ">{{ i18n.t('Pulsante di prova 2') }}</q-btn>
</template>
other-header-actions-left

<template #other-header-actions-left>
<q-btn color="primary" class="q-my-md q-mr-md">{{ i18n.t('Pulsante di sinistra') }}</q-btn>
</template>
other-header-actions-right

<template #other-header-actions-right>
<q-btn icon="thx-info-empty" class="btn btn-primary">{{ i18n.t('Pulsante destra') }}</q-btn>
</template>
# Esempi Lista
header-primary
Spostare la paginazione sopra

<template #header-primary>
<ThuxFooterPaginationComponent
:use-pagination="usePagination"
:list="useList.list.value"
:per-page="usePagination.perPage.value"
:page="usePagination.page.value"
@change="usePagination.changePage"
/>
</template>
other-header-buttons

<template #other-header-buttons>
<q-btn icon="thx-info-empty" class="btn btn-primary">{{ i18n.t('Pulsante prova') }}</q-btn>
</template>
footer

<template #footer>
<div class="text-right full-width q-py-md text-bold text-primary">FOOTER PERSONALIZZATO</div>
</template>
# Table
Il componente Tabella ha diversi slot con cui personalizzarlo:
TIP
Lo slot viene inizializzato all'interno del componente con la sintassi <template #nome-slot="props"></template>
Se non ti servono le variabili nello slot basta fare semplicemente <template #nome-slot></template>
<template>
<ThuxTableComponent
:list="list"
:use-table="useTable"
@open-edit-form="$emit('open-edit-form', $event)"
@open-detail-form="$emit('open-detail-form', $event)"
>
<template #other-buttons-actions-left> <!-- Utilizzo degli slot -->
<q-btn icon="thx-info-empty" />
</template>
</ThuxTableComponent>
</template>
I principali sono:
props.item.[name]
Per accedere all'elemento della tabella bisogna usare props.item

<template #body-cell-name="props">
{{ props.item }}
</template>
| Slot | Descrizione |
|---|---|
| header-cell-[name] | Il contenuto della cella dell'header avente quel [name] |
| body-cell-[name] | Il contenuto della cella della tabella avente quel [name] |
| other-buttons-actions-left | pulanti aggiuntivi a sinistra di quelli di default |
| other-buttons-actions-right | pulanti aggiuntivi a destra di quelli di default |
| mobile-row | riga completamente custom (solo per la versione mobile) |
Attenzione!
Lo slot mobile-row funziona solo se nel LIST_DATA nel data.js il campo mobileGrid=true
<template>
<ThuxTableComponent
:list="list"
:use-table="useTable"
@open-edit-form="$emit('open-edit-form', $event)"
@open-detail-form="$emit('open-detail-form', $event)"
>
<template #body-cell-name="props">Custom {{ props.item.name }}</template>
<template #other-buttons-actions-left>
<q-btn icon="thx-info-empty" />
</template>
</ThuxTableComponent>
</template>
# Esempi principali
header-cell-[name]

<template #header-cell-name="props">
{{ props.item }}
</template>
body-cell-[name]

<template #body-cell-name="props">
<div class="fund-table-info">
<div v-if="props.item.image" class="fund-image mr-5">
<img :src="props.item.image" :alt="props.item.name" />
</div>
<div class="fund-name">
<span class="fw-600">{{ props.item.name }}</span>
<span class="fund-desc">{{ props.item.description }}</span>
</div>
</div>
</template>
<template #body-cell-past_annual_return="props">
<span v-if="props.item.past_annual_return" class="tag tag-orange">
{{ props.item.past_annual_return }}% {{ i18n.t('p.a.') }}
</span>
</template>
<template #body-cell-underlying="props">
<span v-if="props.item.underlying">
{{ props.item.underlying }}
</span>
<span v-else>
{{ i18n.t('N.A.') }}
</span>
</template>
<template #body-cell-term="props">
<span v-if="props.item.maturity_date && formatDateDiff(props.item.maturity_date, 'years') > 0">
{{ formatDateDiff(props.item.maturity_date, 'years') }}
<span v-if="formatDateDiff(props.item.maturity_date, 'years') > 1">
{{ i18n.t('years') }}
</span>
<span v-else>{{ i18n.t('year') }}</span>
</span>
<span v-else>-</span>
</template>
<template #body-cell-typology="props">
<span class="text-capitalize">
{{ props.item.typology }}
</span>
</template>
<template #body-cell-automatic_early_redemption="props">
<span v-if="props.item.automatic_early_redemption">
<q-icon name="thx-check" size="16px" class="text-light-green"></q-icon>
</span>
<span v-else>
<q-icon name="thx-cancel" size="16px" class="text-red"></q-icon>
</span>
</template>
other-buttons-actions-left

<template #other-buttons-actions-left>
<q-btn icon="thx-info-empty" />
</template>
other-buttons-actions-right

<template #other-buttons-actions-right="props">
<q-btn
class="btn btn-outline-primary btn-table-cta"
:title="i18n.t('Select Now')"
icon="thx-nav-arrow-right"
@click="$emit('open-detail-form', props.item.id)"
>
{{ i18n.t('Select') }}
</q-btn>
</template>
mobile-row

<template #mobile-row="props">
<div class="mobile-row fund-mobile-row">
<div class="fund-table-info">
<div v-if="props.item.product.image" class="fund-image mr-5">
<img :src="props.item.product.image" :alt="props.item.name" />
</div>
<div class="fund-name">
<span class="fw-600">{{ props.item.product.name }}</span>
<span class="fund-desc">{{ props.item.product.description }}</span>
<span class="fund-desc">{{ }}</span>
</div>
</div>
<div class="fund-value">
<span v-if="props.item.product.product_data_dict.price > 0">
{{ formatCurrency(props.item.product.product_data_dict.price) }}
</span>
<ProfitOrLossBadge
:amount="props.item.product.product_data_dict.price"
:percent="props.item.weight * 100"
:show-amount="false"
/>
</div>
</div>
</template>
# Detail
Il componente Dettaglio ha diversi slot con cui personalizzarlo
Attenzione!
Abbiamo 2 tipi di componenti:
- ThuxDetailPageComponent - È un dettaglio inserito in una pagina nuova (di solito con un routing diverso rispetto alla lista), utile per modelli con molti campi
- ThuxDetailComponent - È invece un form definito sopra la tabella (non ha routing diverso), utile per modelli con pochi campi
Entrambi utilizzano gli stessi slot
TIP
Lo slot viene inizializzato all'interno del componente con la sintassi <template #nome-slot="props"></template>
Se non ti servono le variabili nello slot basta fare semplicemente <template #nome-slot></template>
I principali sono:
| Slot | Descrizione |
|---|---|
| row-[rowKey] | Inserendo il nome della chiave messo nel data.js è possibile creare una riga custom |
| cell-[cellKey] | Inserendo il nome della chiave messo nel data.js è possibile creare una cella custom |
| inline-row-[rowKey] | Inserendo il nome della chiave messo nel data.js è possibile creare una riga custom nell'inline row |
| inline-cell-[cellKey] | Inserendo il nome della chiave messo nel data.js è possibile creare una cella custom nell'inline row |
| parent-row-[parentKey]-[rowKey] | Inserendo il nome della chiave messo nel data.js nel parent e la chiave della relativa riga è possibile creare una riga custom nel componente padre |
| parent-cell-[parentKey]-[cellKey] | Inserendo il nome della chiave messo nel data.js nel parent e la chiave della relativa cella è possibile creare una cella custom nel componente padre |
| inline-parent-row-[parentKey]-[rowKey] | Inserendo il nome della chiave messo nel data.js nel parent e la chiave della relativa riga è possibile creare una riga custom nel componente padre dell'inline row |
| inline-parent-cell-[parentKey]-[cellKey] | Inserendo il nome della chiave messo nel data.js nel parent e la chiave della relativa riga è possibile creare una cella custom nel componente padre nell'inline row |
Ci sono slot specifici anche per la sezione dell'Header della pagina (Solo per ThuxDetailPageComponent)
| Slot | Descrizione |
|---|---|
| header-components-top | Eventuali componenti da mostrare sopra la pagina |
| header-components-bottom | Eventuali componenti da mostrare sotto il titolo della pagina |
| header-title | Il titolo della pagina personalizzato |
| header-actions | pulsanti da mostrare a destra del titolo (di default sono salva e chiudi) |
| other-header-actions-left | Se si vogliono aggiungere altri pulsanti a sinistra oltre a quelli di default |
| other-header-actions-right | Se si vogliono aggiungere altri pulsanti a destra oltre a quelli di default |
Attenzione!
Se si vuole importare in un dettaglio una lista bisogna richiamare il componente lista passando la prop :table-only="true"
esempio
<template #row-fund-transaction-list>
<h4 class="mb-5">{{i18n.t('Movements')}}</h4>
<TransactionList
v-if="useDetail.form.value.id"
:productId="useDetail.form.value.id"
:table-only="true"
/>
</template>
# Esempi principali
row-[rowKey]

<template #row-fund-graph>
<ProductDataApexChart v-if="productDataList" :list="productDataList" />
</template>
<template #row-fund-info>
<FundInfo :fund="useDetail.form" class="my-10" />
</template>
<template #row-fund-transaction-list>
<h4 class="mb-5">{{i18n.t('Movements')}}</h4>
<TransactionList
v-if="useDetail.form.value.id"
:productId="useDetail.form.value.id"
:table-only="true"
/>
</template>
cell-[cellKey]

<template #cell-code>
<q-btn flat color="primary">Pulsante custom</q-btn>
</template>
inline-row-[rowKey]

<template #inline-row-custom-row>
<q-input v-model="test" class="full-width" color="primary">riga custom</q-input>
</template>
inline-cell-[cellKey]

<template #inline-cell-contractor>
<q-input class="col-6" v-model="test" color="primary">cella custom</q-input>
</template>
parent-row-[parentKey]-[rowKey]

<template #parent-row-parent_client-row_1>
<q-input class="full-width q-mb-md" v-model="test" color="primary">riga custom</q-input>
</template>
parent-cell-[parentKey]-[cellKey]

<template #parent-cell-parent_client-cell_1>
<q-input class="col-6 q-mb-md" v-model="test" color="primary">cella custom</q-input>
</template>
inline-parent-row-[parentKey]-[rowKey]

<template #inline-parent-row-parent_client-row_1>
<q-input class="full-width q-mb-md" v-model="test" color="primary">riga inline padre custom</q-input>
</template>
inline-parent-cell-[parentKey]-[cellKey]

<template #inline-parent-cell-parent_client-cell_1>
<q-input class="col-6 q-mb-md" v-model="test" color="primary">cella inline padre custom</q-input>
</template>
# Esempi Header
header-components-top

<template #header-components-top>
<q-btn color="primary" class="q-mb-md q-mr-md">{{ i18n.t('Pulsante di prova') }}</q-btn>
<q-btn color="red" class="q-mb-md ">{{ i18n.t('Pulsante di prova 2') }}</q-btn>
</template>
header-components-bottom

<template #header-components-bottom>
<q-btn color="primary" class="q-my-md q-mr-md">{{ 'Pulsante di prova' }}</q-btn>
<q-btn color="red" class="q-my-md">{{ 'Pulsante di prova 2' }}</q-btn>
</template>
header-title

<template #header-title>
<h4 class="text-primary">Titolo personalizzato</h4>
</template>
header-actions

<template #header-actions>
<q-btn color="primary" class="q-my-md q-mr-md">{{ i18n.t('Pulsante di prova') }}</q-btn>
<q-btn color="red" class="q-my-md ">{{ i18n.t('Pulsante di prova 2') }}</q-btn>
</template>
other-header-actions-left

<template #other-header-actions-left>
<q-btn color="primary" class="q-my-md q-mr-md">{{ i18n.t('Pulsante di sinistra') }}</q-btn>
</template>
other-header-actions-right

<template #other-header-actions-right>
<q-btn icon="thx-info-empty" class="btn btn-primary">{{ i18n.t('Pulsante destra') }}</q-btn>
</template>
# Esempi Dettaglio
body

<template #body>
TEST
</template>
sidebar

<template #sidebar>
<InvestWidget
v-if="useDetail.form && useDetail.form.value.id"
:fund="useDetail.form.value"
:active-tab="route.params.activeTab"
/>
</template>
← Mixin