<template> <DocSectionText v-bind="$attrs"> <p>DataTable with selection, pagination, filtering, sorting and templating.</p> </DocSectionText> <div class="card"> <DataTable v-model:filters="filters" v-model:selection="selectedCustomers" :value="customers" paginator :rows="10" dataKey="id" filterDisplay="menu" :globalFilterFields="['name', 'country.name', 'representative.name', 'balance', 'status']"> <template #header> <div class="flex justify-content-between"> <Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" /> <span class="p-input-icon-left"> <i class="pi pi-search" /> <InputText v-model="filters['global'].value" placeholder="Keyword Search" /> </span> </div> </template> <template #empty> No customers found. </template> <Column selectionMode="multiple" headerStyle="width: 3rem"></Column> <Column field="name" header="Name" sortable style="min-width: 14rem"> <template #body="{ data }"> {{ data.name }} </template> <template #filter="{ filterModel }"> <InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" /> </template> </Column> <Column header="Country" sortable sortField="country.name" filterField="country.name" style="min-width: 14rem"> <template #body="{ data }"> <div class="flex align-items-center gap-2"> <img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" /> <span>{{ data.country.name }}</span> </div> </template> <template #filter="{ filterModel }"> <InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" /> </template> </Column> <Column header="Agent" sortable sortField="representative.name" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem"> <template #body="{ data }"> <div class="flex align-items-center gap-2"> <img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" /> <span>{{ data.representative.name }}</span> </div> </template> <template #filter="{ filterModel }"> <MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter"> <template #option="slotProps"> <div class="flex align-items-center gap-2"> <img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" /> <span>{{ slotProps.option.name }}</span> </div> </template> </MultiSelect> </template> </Column> <Column field="date" header="Date" sortable filterField="date" dataType="date" style="min-width: 10rem"> <template #body="{ data }"> {{ formatDate(data.date) }} </template> <template #filter="{ filterModel }"> <Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" /> </template> </Column> <Column field="balance" header="Balance" sortable filterField="balance" dataType="numeric" style="min-width: 10rem"> <template #body="{ data }"> {{ formatCurrency(data.balance) }} </template> <template #filter="{ filterModel }"> <InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" /> </template> </Column> <Column header="Status" sortable field="status" :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem"> <template #body="{ data }"> <Tag :value="data.status" :severity="getSeverity(data.status)" /> </template> <template #filter="{ filterModel }"> <Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear> <template #option="slotProps"> <Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" /> </template> </Dropdown> </template> </Column> <Column field="activity" header="Activity" sortable :showFilterMatchModes="false" style="min-width: 12rem"> <template #body="{ data }"> <ProgressBar :value="data.activity" :showValue="false" style="height: 6px"></ProgressBar> </template> <template #filter="{ filterModel }"> <Slider v-model="filterModel.value" range class="m-3"></Slider> <div class="flex align-items-center justify-content-between px-2"> <span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span> <span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span> </div> </template> </Column> <Column headerStyle="width: 5rem; text-align: center" bodyStyle="text-align: center; overflow: visible"> <template #body> <Button type="button" icon="pi pi-cog" rounded /> </template> </Column> </DataTable> </div> <DocSectionCode :code="code" :service="['CustomerService']" /> </template> <script> import { CustomerService } from '@/service/CustomerService'; import { FilterMatchMode, FilterOperator } from 'primevue/api'; export default { data() { return { customers: null, selectedCustomers: null, filters: null, representatives: [ { name: 'Amy Elsner', image: 'amyelsner.png' }, { name: 'Anna Fali', image: 'annafali.png' }, { name: 'Asiya Javayant', image: 'asiyajavayant.png' }, { name: 'Bernardo Dominic', image: 'bernardodominic.png' }, { name: 'Elwin Sharvill', image: 'elwinsharvill.png' }, { name: 'Ioni Bowcher', image: 'ionibowcher.png' }, { name: 'Ivan Magalhaes', image: 'ivanmagalhaes.png' }, { name: 'Onyama Limba', image: 'onyamalimba.png' }, { name: 'Stephen Shaw', image: 'stephenshaw.png' }, { name: 'XuXue Feng', image: 'xuxuefeng.png' } ], statuses: ['unqualified', 'qualified', 'new', 'negotiation', 'renewal', 'proposal'], code: { basic: ` <DataTable v-model:filters="filters" v-model:selection="selectedCustomers" :value="customers" paginator :rows="10" dataKey="id" filterDisplay="menu" :globalFilterFields="['name', 'country.name', 'representative.name', 'balance', 'status']"> <template #header> <div class="flex justify-content-between"> <Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" /> <span class="p-input-icon-left"> <i class="pi pi-search" /> <InputText v-model="filters['global'].value" placeholder="Keyword Search" /> </span> </div> </template> <template #empty> No customers found. </template> <Column selectionMode="multiple" headerStyle="width: 3rem"></Column> <Column field="name" header="Name" sortable style="min-width: 14rem"> <template #body="{ data }"> {{ data.name }} </template> <template #filter="{ filterModel }"> <InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" /> </template> </Column> <Column header="Country" sortable sortField="country.name" filterField="country.name" style="min-width: 14rem"> <template #body="{ data }"> <div class="flex align-items-center gap-2"> <img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="\`flag flag-\${data.country.code}\`" style="width: 24px" /> <span>{{ data.country.name }}</span> </div> </template> <template #filter="{ filterModel }"> <InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" /> </template> </Column> <Column header="Agent" sortable sortField="representative.name" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem"> <template #body="{ data }"> <div class="flex align-items-center gap-2"> <img :alt="data.representative.name" :src="\`https://primefaces.org/cdn/primevue/images/avatar/\${data.representative.image}\`" style="width: 32px" /> <span>{{ data.representative.name }}</span> </div> </template> <template #filter="{ filterModel }"> <MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter"> <template #option="slotProps"> <div class="flex align-items-center gap-2"> <img :alt="slotProps.option.name" :src="\`https://primefaces.org/cdn/primevue/images/avatar/\${slotProps.option.image}\`" style="width: 32px" /> <span>{{ slotProps.option.name }}</span> </div> </template> </MultiSelect> </template> </Column> <Column field="date" header="Date" sortable filterField="date" dataType="date" style="min-width: 10rem"> <template #body="{ data }"> {{ formatDate(data.date) }} </template> <template #filter="{ filterModel }"> <Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" /> </template> </Column> <Column field="balance" header="Balance" sortable filterField="balance" dataType="numeric" style="min-width: 10rem"> <template #body="{ data }"> {{ formatCurrency(data.balance) }} </template> <template #filter="{ filterModel }"> <InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" /> </template> </Column> <Column header="Status" field="status" sortable :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem"> <template #body="{ data }"> <Tag :value="data.status" :severity="getSeverity(data.status)" /> </template> <template #filter="{ filterModel }"> <Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear> <template #option="slotProps"> <Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" /> </template> </Dropdown> </template> </Column> <Column field="activity" header="Activity" sortable :showFilterMatchModes="false" style="min-width: 12rem"> <template #body="{ data }"> <ProgressBar :value="data.activity" :showValue="false" style="height: 6px"></ProgressBar> </template> <template #filter="{ filterModel }"> <Slider v-model="filterModel.value" range class="m-3"></Slider> <div class="flex align-items-center justify-content-between px-2"> <span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span> <span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span> </div> </template> </Column> <Column headerStyle="width: 5rem; text-align: center" bodyStyle="text-align: center; overflow: visible"> <template #body> <Button type="button" icon="pi pi-cog" rounded /> </template> </Column> </DataTable>`, options: ` <template> <div class="card"> <DataTable v-model:filters="filters" v-model:selection="selectedCustomers" :value="customers" paginator :rows="10" dataKey="id" filterDisplay="menu" :globalFilterFields="['name', 'country.name', 'representative.name', 'balance', 'status']"> <template #header> <div class="flex justify-content-between"> <Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" /> <span class="p-input-icon-left"> <i class="pi pi-search" /> <InputText v-model="filters['global'].value" placeholder="Keyword Search" /> </span> </div> </template> <template #empty> No customers found. </template> <Column selectionMode="multiple" headerStyle="width: 3rem"></Column> <Column field="name" header="Name" sortable style="min-width: 14rem"> <template #body="{ data }"> {{ data.name }} </template> <template #filter="{ filterModel }"> <InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" /> </template> </Column> <Column header="Country" sortable sortField="country.name" filterField="country.name" style="min-width: 14rem"> <template #body="{ data }"> <div class="flex align-items-center gap-2"> <img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="\`flag flag-\${data.country.code}\`" style="width: 24px" /> <span>{{ data.country.name }}</span> </div> </template> <template #filter="{ filterModel }"> <InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" /> </template> </Column> <Column header="Agent" sortable sortField="representative.name" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem"> <template #body="{ data }"> <div class="flex align-items-center gap-2"> <img :alt="data.representative.name" :src="\`https://primefaces.org/cdn/primevue/images/avatar/\${data.representative.image}\`" style="width: 32px" /> <span>{{ data.representative.name }}</span> </div> </template> <template #filter="{ filterModel }"> <MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter"> <template #option="slotProps"> <div class="flex align-items-center gap-2"> <img :alt="slotProps.option.name" :src="\`https://primefaces.org/cdn/primevue/images/avatar/\${slotProps.option.image}\`" style="width: 32px" /> <span>{{ slotProps.option.name }}</span> </div> </template> </MultiSelect> </template> </Column> <Column field="date" header="Date" sortable filterField="date" dataType="date" style="min-width: 10rem"> <template #body="{ data }"> {{ formatDate(data.date) }} </template> <template #filter="{ filterModel }"> <Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" /> </template> </Column> <Column field="balance" header="Balance" sortable filterField="balance" dataType="numeric" style="min-width: 10rem"> <template #body="{ data }"> {{ formatCurrency(data.balance) }} </template> <template #filter="{ filterModel }"> <InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" /> </template> </Column> <Column header="Status" field="status" sortable :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem"> <template #body="{ data }"> <Tag :value="data.status" :severity="getSeverity(data.status)" /> </template> <template #filter="{ filterModel }"> <Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear> <template #option="slotProps"> <Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" /> </template> </Dropdown> </template> </Column> <Column field="activity" header="Activity" sortable :showFilterMatchModes="false" style="min-width: 12rem"> <template #body="{ data }"> <ProgressBar :value="data.activity" :showValue="false" style="height: 6px"></ProgressBar> </template> <template #filter="{ filterModel }"> <Slider v-model="filterModel.value" range class="m-3"></Slider> <div class="flex align-items-center justify-content-between px-2"> <span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span> <span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span> </div> </template> </Column> <Column headerStyle="width: 5rem; text-align: center" bodyStyle="text-align: center; overflow: visible"> <template #body> <Button type="button" icon="pi pi-cog" rounded /> </template> </Column> </DataTable> </div> </template> <script> import { CustomerService } from '@/service/CustomerService'; import { FilterMatchMode, FilterOperator } from 'primevue/api'; export default { data() { return { customers: null, selectedCustomers: null, filters: null, representatives: [ { name: 'Amy Elsner', image: 'amyelsner.png' }, { name: 'Anna Fali', image: 'annafali.png' }, { name: 'Asiya Javayant', image: 'asiyajavayant.png' }, { name: 'Bernardo Dominic', image: 'bernardodominic.png' }, { name: 'Elwin Sharvill', image: 'elwinsharvill.png' }, { name: 'Ioni Bowcher', image: 'ionibowcher.png' }, { name: 'Ivan Magalhaes', image: 'ivanmagalhaes.png' }, { name: 'Onyama Limba', image: 'onyamalimba.png' }, { name: 'Stephen Shaw', image: 'stephenshaw.png' }, { name: 'XuXue Feng', image: 'xuxuefeng.png' } ], statuses: ['unqualified', 'qualified', 'new', 'negotiation', 'renewal', 'proposal'] }; }, created() { this.initFilters(); }, mounted() { CustomerService.getCustomersLarge().then((data) => { this.customers = this.getCustomers(data); }); }, methods: { formatDate(value) { return value.toLocaleDateString('en-US', { day: '2-digit', month: '2-digit', year: 'numeric' }); }, formatCurrency(value) { return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' }); }, clearFilter() { this.initFilters(); }, initFilters() { this.filters = { global: { value: null, matchMode: FilterMatchMode.CONTAINS }, name: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] }, 'country.name': { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] }, representative: { value: null, matchMode: FilterMatchMode.IN }, date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] }, balance: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }, status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }, activity: { value: [0, 100], matchMode: FilterMatchMode.BETWEEN }, verified: { value: null, matchMode: FilterMatchMode.EQUALS } }; }, getCustomers(data) { return [...(data || [])].map((d) => { d.date = new Date(d.date); return d; }); }, getSeverity(status) { switch (status) { case 'unqualified': return 'danger'; case 'qualified': return 'success'; case 'new': return 'info'; case 'negotiation': return 'warning'; case 'renewal': return null; } } } }; <\/script>`, composition: ` <template> <div class="card"> <DataTable v-model:filters="filters" v-model:selection="selectedCustomers" :value="customers" paginator :rows="10" dataKey="id" filterDisplay="menu" :globalFilterFields="['name', 'country.name', 'representative.name', 'balance', 'status']"> <template #header> <div class="flex justify-content-between"> <Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" /> <span class="p-input-icon-left"> <i class="pi pi-search" /> <InputText v-model="filters['global'].value" placeholder="Keyword Search" /> </span> </div> </template> <template #empty> No customers found. </template> <Column selectionMode="multiple" headerStyle="width: 3rem"></Column> <Column field="name" header="Name" sortable style="min-width: 14rem"> <template #body="{ data }"> {{ data.name }} </template> <template #filter="{ filterModel }"> <InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" /> </template> </Column> <Column header="Country" sortable sortField="country.name" filterField="country.name" style="min-width: 14rem"> <template #body="{ data }"> <div class="flex align-items-center gap-2"> <img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="\`flag flag-\${data.country.code}\`" style="width: 24px" /> <span>{{ data.country.name }}</span> </div> </template> <template #filter="{ filterModel }"> <InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" /> </template> </Column> <Column header="Agent" sortable sortField="representative.name" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem"> <template #body="{ data }"> <div class="flex align-items-center gap-2"> <img :alt="data.representative.name" :src="\`https://primefaces.org/cdn/primevue/images/avatar/\${data.representative.image}\`" style="width: 32px" /> <span>{{ data.representative.name }}</span> </div> </template> <template #filter="{ filterModel }"> <MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter"> <template #option="slotProps"> <div class="flex align-items-center gap-2"> <img :alt="slotProps.option.name" :src="\`https://primefaces.org/cdn/primevue/images/avatar/\${slotProps.option.image}\`" style="width: 32px" /> <span>{{ slotProps.option.name }}</span> </div> </template> </MultiSelect> </template> </Column> <Column field="date" header="Date" sortable filterField="date" dataType="date" style="min-width: 10rem"> <template #body="{ data }"> {{ formatDate(data.date) }} </template> <template #filter="{ filterModel }"> <Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" /> </template> </Column> <Column field="balance" header="Balance" sortable filterField="balance" dataType="numeric" style="min-width: 10rem"> <template #body="{ data }"> {{ formatCurrency(data.balance) }} </template> <template #filter="{ filterModel }"> <InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" /> </template> </Column> <Column header="Status" field="status" sortable :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem"> <template #body="{ data }"> <Tag :value="data.status" :severity="getSeverity(data.status)" /> </template> <template #filter="{ filterModel }"> <Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear> <template #option="slotProps"> <Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" /> </template> </Dropdown> </template> </Column> <Column field="activity" header="Activity" sortable :showFilterMatchModes="false" style="min-width: 12rem"> <template #body="{ data }"> <ProgressBar :value="data.activity" :showValue="false" style="height: 6px"></ProgressBar> </template> <template #filter="{ filterModel }"> <Slider v-model="filterModel.value" range class="m-3"></Slider> <div class="flex align-items-center justify-content-between px-2"> <span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span> <span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span> </div> </template> </Column> <Column headerStyle="width: 5rem; text-align: center" bodyStyle="text-align: center; overflow: visible"> <template #body> <Button type="button" icon="pi pi-cog" rounded /> </template> </Column> </DataTable> </div> </template> <script setup> import { ref, onMounted } from 'vue'; import { CustomerService } from '@/service/CustomerService'; import { FilterMatchMode, FilterOperator } from 'primevue/api'; const customers = ref(); const selectedCustomers = ref(); const filters = ref(); const representatives = ref([ { name: 'Amy Elsner', image: 'amyelsner.png' }, { name: 'Anna Fali', image: 'annafali.png' }, { name: 'Asiya Javayant', image: 'asiyajavayant.png' }, { name: 'Bernardo Dominic', image: 'bernardodominic.png' }, { name: 'Elwin Sharvill', image: 'elwinsharvill.png' }, { name: 'Ioni Bowcher', image: 'ionibowcher.png' }, { name: 'Ivan Magalhaes', image: 'ivanmagalhaes.png' }, { name: 'Onyama Limba', image: 'onyamalimba.png' }, { name: 'Stephen Shaw', image: 'stephenshaw.png' }, { name: 'XuXue Feng', image: 'xuxuefeng.png' } ]); const statuses = ref(['unqualified', 'qualified', 'new', 'negotiation', 'renewal', 'proposal']); onMounted(() => { CustomerService.getCustomersLarge().then((data) => { customers.value = getCustomers(data); }); }); const initFilters = () => { filters.value = { global: { value: null, matchMode: FilterMatchMode.CONTAINS }, name: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] }, 'country.name': { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] }, representative: { value: null, matchMode: FilterMatchMode.IN }, date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] }, balance: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }, status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }, activity: { value: [0, 100], matchMode: FilterMatchMode.BETWEEN }, verified: { value: null, matchMode: FilterMatchMode.EQUALS } }; }; initFilters(); const formatDate = (value) => { return value.toLocaleDateString('en-US', { day: '2-digit', month: '2-digit', year: 'numeric' }); }; const formatCurrency = (value) => { return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' }); }; const clearFilter = () => { initFilters(); }; const getCustomers = (data) => { return [...(data || [])].map((d) => { d.date = new Date(d.date); return d; }); }; const getSeverity = (status) => { switch (status) { case 'unqualified': return 'danger'; case 'qualified': return 'success'; case 'new': return 'info'; case 'negotiation': return 'warning'; case 'renewal': return null; } }; <\/script>`, data: ` { id: 1000, name: 'James Butt', country: { name: 'Algeria', code: 'dz' }, company: 'Benton, John B Jr', date: '2015-09-13', status: 'unqualified', verified: true, activity: 17, representative: { name: 'Ioni Bowcher', image: 'ionibowcher.png' }, balance: 70663 }, ...` } }; }, created() { this.initFilters(); }, mounted() { CustomerService.getCustomersLarge().then((data) => { this.customers = this.getCustomers(data); }); }, methods: { formatDate(value) { return value.toLocaleDateString('en-US', { day: '2-digit', month: '2-digit', year: 'numeric' }); }, formatCurrency(value) { return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' }); }, clearFilter() { this.initFilters(); }, initFilters() { this.filters = { global: { value: null, matchMode: FilterMatchMode.CONTAINS }, name: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] }, 'country.name': { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] }, representative: { value: null, matchMode: FilterMatchMode.IN }, date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] }, balance: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }, status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }, activity: { value: [0, 100], matchMode: FilterMatchMode.BETWEEN }, verified: { value: null, matchMode: FilterMatchMode.EQUALS } }; }, getCustomers(data) { return [...(data || [])].map((d) => { d.date = new Date(d.date); return d; }); }, getSeverity(status) { switch (status) { case 'unqualified': return 'danger'; case 'qualified': return 'success'; case 'new': return 'info'; case 'negotiation': return 'warning'; case 'renewal': return null; } } } }; </script>