Fixed row filtering
parent
24a0c7aaa7
commit
d15eaff431
|
@ -212,7 +212,7 @@ export default {
|
||||||
},
|
},
|
||||||
ariaSort() {
|
ariaSort() {
|
||||||
if (this.columnProp('sortable')) {
|
if (this.columnProp('sortable')) {
|
||||||
const sortIcon = this.getSortableColumnIcon();
|
const sortIcon = this.sortableColumnIcon;
|
||||||
if (sortIcon[1]['pi-sort-amount-down'])
|
if (sortIcon[1]['pi-sort-amount-down'])
|
||||||
return 'descending';
|
return 'descending';
|
||||||
else if (sortIcon[1]['pi-sort-amount-up-alt'])
|
else if (sortIcon[1]['pi-sort-amount-up-alt'])
|
||||||
|
|
|
@ -9,18 +9,24 @@
|
||||||
:resizableColumns="resizableColumns" @column-resizestart="$emit('column-resizestart', $event)"
|
:resizableColumns="resizableColumns" @column-resizestart="$emit('column-resizestart', $event)"
|
||||||
:sortMode="sortMode" :sortField="sortField" :sortOrder="sortOrder" :multiSortMeta="multiSortMeta"
|
:sortMode="sortMode" :sortField="sortField" :sortOrder="sortOrder" :multiSortMeta="multiSortMeta"
|
||||||
:allRowsSelected="allRowsSelected" :empty="empty" @checkbox-change="$emit('column-change', $event)"
|
:allRowsSelected="allRowsSelected" :empty="empty" @checkbox-change="$emit('column-change', $event)"
|
||||||
:filters="filters" :filtersStore="filtersStore" @filter-change="$emit('filter-change', $event)" @filter-apply="$emit('filter-apply')"
|
:filters="filters" :filterDisplay="filterDisplay" :filtersStore="filtersStore" @filter-change="$emit('filter-change', $event)" @filter-apply="$emit('filter-apply')"
|
||||||
@operator-change="$emit('operator-change',$event)" @matchmode-change="$emit('matchmode-change', $event)" @constraint-add="$emit('constraint-add', $event)"
|
@operator-change="$emit('operator-change',$event)" @matchmode-change="$emit('matchmode-change', $event)" @constraint-add="$emit('constraint-add', $event)"
|
||||||
@constraint-remove="$emit('constraint-remove', $event)" @apply-click="$emit('apply-click',$event)"/>
|
@constraint-remove="$emit('constraint-remove', $event)" @apply-click="$emit('apply-click',$event)"/>
|
||||||
</template>
|
</template>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="filterDisplay === 'row'" role="row">
|
<tr v-if="filterDisplay === 'row'" role="row">
|
||||||
<template v-for="(col,i) of columns" :key="columnProp(col, 'columnKey')||columnProp(col, 'field')||i">
|
<template v-for="(col,i) of columns" :key="columnProp(col, 'columnKey')||columnProp(col, 'field')||i">
|
||||||
<DTHeaderCell v-if="rowGroupMode !== 'subheader' || (groupRowsBy !== columnProp(col, 'field'))" :column="col" :filterColumn="true"
|
<th :style="getFilterColumnHeaderStyle(col)" :class="getFilterColumnHeaderClass(col)">
|
||||||
:allRowsSelected="allRowsSelected" :empty="empty" @checkbox-change="$emit('checkbox-change', $event)"
|
<DTColumnFilter v-if="col.children && col.children.filter" :field="columnProp(col,'filterField')||columnProp(col,'field')" :type="columnProp(col,'dataType')" display="row"
|
||||||
:filters="filters" :filtersStore="filtersStore" @filter-change="$emit('filter-change', $event)" @filter-apply="$emit('filter-apply')"
|
:showMenu="columnProp(col,'showFilterMenu')" :filterElement="col.children && col.children.filter"
|
||||||
@operator-change="$emit('operator-change',$event)" @matchmode-change="$emit('matchmode-change', $event)" @constraint-add="$emit('constraint-add', $event)"
|
:filterHeaderTemplate="col.children && col.children.filterheader" :filterFooterTemplate="col.children && col.children.filterfooter"
|
||||||
@constraint-remove="$emit('constraint-remove', $event)" @apply-click="$emit('apply-click',$event)"/>
|
:filterClearTemplate="col.children && col.children.filterclear" :filterApplyTemplate="col.children && col.children.filterapply"
|
||||||
|
:filters="filters" :filtersStore="filtersStore" @filter-change="$emit('filter-change', $event)" @filter-apply="$emit('filter-apply')" :filterMenuStyle="columnProp(col,'filterMenuStyle')" :filterMenuClass="columnProp(col,'filterMenuClass')"
|
||||||
|
:showOperator="columnProp(col,'showFilterOperator')" :showClearButton="columnProp(col,'showClearButton')" :showApplyButton="columnProp(col,'showApplyButton')"
|
||||||
|
:showMatchModes="columnProp(col,'showFilterMatchModes')" :showAddButton="columnProp(col,'showAddButton')" :matchModeOptions="columnProp(col,'filterMatchModeOptions')" :maxConstraints="columnProp(col,'maxConstraints')"
|
||||||
|
@operator-change="$emit('operator-change',$event)" @matchmode-change="$emit('matchmode-change', $event)"
|
||||||
|
@constraint-add="$emit('constraint-add', $event)" @constraint-remove="$emit('constraint-remove', $event)" @apply-click="$emit('apply-click',$event)"/>
|
||||||
|
</th>
|
||||||
</template>
|
</template>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
@ -31,7 +37,7 @@
|
||||||
@column-click="$emit('column-click', $event)" @column-mousedown="$emit('column-mousedown', $event)"
|
@column-click="$emit('column-click', $event)" @column-mousedown="$emit('column-mousedown', $event)"
|
||||||
:sortMode="sortMode" :sortField="sortField" :sortOrder="sortOrder" :multiSortMeta="multiSortMeta"
|
:sortMode="sortMode" :sortField="sortField" :sortOrder="sortOrder" :multiSortMeta="multiSortMeta"
|
||||||
:allRowsSelected="allRowsSelected" :empty="empty" @checkbox-change="$emit('column-change', $event)"
|
:allRowsSelected="allRowsSelected" :empty="empty" @checkbox-change="$emit('column-change', $event)"
|
||||||
:filters="filters" :filtersStore="filtersStore" @filter-change="$emit('filter-change', $event)" @filter-apply="$emit('filter-apply')"
|
:filters="filters" :filterDisplay="filterDisplay" :filtersStore="filtersStore" @filter-change="$emit('filter-change', $event)" @filter-apply="$emit('filter-apply')"
|
||||||
@operator-change="$emit('operator-change',$event)" @matchmode-change="$emit('matchmode-change', $event)" @constraint-add="$emit('constraint-add', $event)"
|
@operator-change="$emit('operator-change',$event)" @matchmode-change="$emit('matchmode-change', $event)" @constraint-add="$emit('constraint-add', $event)"
|
||||||
@constraint-remove="$emit('constraint-remove', $event)" @apply-click="$emit('apply-click',$event)"/>
|
@constraint-remove="$emit('constraint-remove', $event)" @apply-click="$emit('apply-click',$event)"/>
|
||||||
</template>
|
</template>
|
||||||
|
@ -42,6 +48,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import HeaderCell from './HeaderCell';
|
import HeaderCell from './HeaderCell';
|
||||||
|
import ColumnFilter from './ColumnFilter';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits: ['column-click', 'column-mousedown', 'column-dragstart', 'column-dragover', 'column-dragleave', 'column-drop',
|
emits: ['column-click', 'column-mousedown', 'column-dragstart', 'column-dragover', 'column-dragleave', 'column-drop',
|
||||||
|
@ -110,11 +117,15 @@ export default {
|
||||||
return col.props ? ((col.type.props[prop].type === Boolean && col.props[prop] === '') ? true : col.props[prop]) : null;
|
return col.props ? ((col.type.props[prop].type === Boolean && col.props[prop] === '') ? true : col.props[prop]) : null;
|
||||||
},
|
},
|
||||||
getFilterColumnHeaderClass(column) {
|
getFilterColumnHeaderClass(column) {
|
||||||
return ['p-filter-column', this.columnProp(column, 'filterHeaderClass')];
|
return ['p-filter-column', this.columnProp(column, 'filterHeaderClass'), this.columnProp(column, 'class')];
|
||||||
|
},
|
||||||
|
getFilterColumnHeaderStyle(column) {
|
||||||
|
return [this.columnProp(column, 'filterHeaderStyle'), this.columnProp(column, 'style')];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'DTHeaderCell': HeaderCell
|
'DTHeaderCell': HeaderCell,
|
||||||
|
'DTColumnFilter': ColumnFilter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,15 +10,16 @@
|
||||||
<div class="content-section implementation">
|
<div class="content-section implementation">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<DataTable :value="customers" :paginator="true" class="p-datatable-customers" :rows="10"
|
<DataTable :value="customers" :paginator="true" class="p-datatable-customers" :rows="10"
|
||||||
dataKey="id" :rowHover="true" v-model:selection="selectedCustomers" :filters="filters" :loading="loading"
|
dataKey="id" :rowHover="true" v-model:selection="selectedCustomers" v-model:filters="filters" filterDisplay="menu" :loading="loading"
|
||||||
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[10,25,50]"
|
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[10,25,50]"
|
||||||
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries">
|
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
|
||||||
|
:globalFilterFields="['name','country.name','representative.name','status']">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="table-header">
|
<div class="p-d-flex p-jc-between">
|
||||||
List of Customers
|
<h5 class="p-m-0">Customers</h5>
|
||||||
<span class="p-input-icon-left">
|
<span class="p-input-icon-left">
|
||||||
<i class="pi pi-search" />
|
<i class="pi pi-search" />
|
||||||
<InputText v-model="filters['global']" placeholder="Global Search" />
|
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -28,34 +29,35 @@
|
||||||
<template #loading>
|
<template #loading>
|
||||||
Loading customers data. Please wait.
|
Loading customers data. Please wait.
|
||||||
</template>
|
</template>
|
||||||
<Column selectionMode="multiple" headerStyle="width: 3em"></Column>
|
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
|
||||||
<Column field="name" header="Name" :sortable="true">
|
<Column field="name" header="Name" sortable>
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Name</span>
|
<span class="p-column-title">Name</span>
|
||||||
{{slotProps.data.name}}
|
{{data.name}}
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<InputText type="text" v-model="filters['name']" class="p-column-filter" placeholder="Search by name"/>
|
<InputText type="text" v-model="filterModel.value" class="p-column-filter" placeholder="Search by name"/>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column header="Country" :sortable="true" sortField="country.name" filterField="country.name" filterMatchMode="contains">
|
<Column field="country.name" header="Country" sortable filterMatchMode="contains">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Country</span>
|
<span class="p-column-title">Country</span>
|
||||||
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.data.country.code" width="30" />
|
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + data.country.code" width="30" />
|
||||||
<span class="image-text">{{slotProps.data.country.name}}</span>
|
<span class="image-text">{{data.country.name}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<InputText type="text" v-model="filters['country.name']" class="p-column-filter" placeholder="Search by country"/>
|
<InputText type="text" v-model="filterModel.value" class="p-column-filter" placeholder="Search by country"/>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column header="Representative" :sortable="true" sortField="representative.name" filterField="representative.name" filterMatchMode="in">
|
<Column header="Representative" sortable sortField="representative.name" :showFilterMatchModes="false" :filterMenuStyle="{'width':'14rem'}">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Representative</span>
|
<span class="p-column-title">Agent</span>
|
||||||
<img :alt="slotProps.data.representative.name" :src="'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
|
<img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
|
||||||
<span class="image-text">{{slotProps.data.representative.name}}</span>
|
<span class="image-text">{{data.representative.name}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<MultiSelect v-model="filters['representative.name']" :options="representatives" optionLabel="name" optionValue="name" placeholder="All" class="p-column-filter">
|
<div class="p-mb-3 p-text-bold">Agent Picker</div>
|
||||||
|
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<div class="p-multiselect-representative-option">
|
<div class="p-multiselect-representative-option">
|
||||||
<img :alt="slotProps.option.name" :src="'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
|
<img :alt="slotProps.option.name" :src="'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
|
||||||
|
@ -65,40 +67,56 @@
|
||||||
</MultiSelect>
|
</MultiSelect>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="date" header="Date" :sortable="true" filterMatchMode="custom" :filterFunction="filterDate">
|
<Column field="date" header="Date" sortable dataType="date">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Date</span>
|
<span class="p-column-title">Date</span>
|
||||||
<span>{{slotProps.data.date}}</span>
|
{{formatDate(data.date)}}
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<Calendar v-model="filters['date']" dateFormat="yy-mm-dd" class="p-column-filter" placeholder="Registration Date"/>
|
<Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="status" header="Status" :sortable="true" filterMatchMode="equals">
|
<Column field="balance" header="Balance" sortable dataType="numeric">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Status</span>
|
<span class="p-column-title">Balance</span>
|
||||||
<span :class="'customer-badge status-' + slotProps.data.status">{{slotProps.data.status}}</span>
|
{{formatCurrency(data.balance)}}
|
||||||
|
</template>
|
||||||
|
<template #filter="{filterModel}">
|
||||||
|
<InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="status" header="Status" sortable :filterMenuStyle="{'width':'14rem'}">
|
||||||
|
<template #body="{data}">
|
||||||
|
<span class="p-column-title">Status</span>
|
||||||
|
<span :class="'customer-badge status-' + data.status">{{data.status}}</span>
|
||||||
|
</template>
|
||||||
|
<template #filter="{filterModel}">
|
||||||
|
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
||||||
|
<template #value="slotProps">
|
||||||
|
<span :class="'customer-badge status-' + slotProps.value">{{slotProps.value}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
|
||||||
<Dropdown v-model="filters['status']" :options="statuses" placeholder="Select a Status" class="p-column-filter" :showClear="true">
|
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="activity" header="Activity" :sortable="true" filterMatchMode="gte">
|
<Column field="activity" header="Activity" sortable :showFilterMatchModes="false">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Activity</span>
|
<span class="p-column-title">Activity</span>
|
||||||
<ProgressBar :value="slotProps.data.activity" :showValue="false" />
|
<ProgressBar :value="data.activity" :showValue="false" />
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<InputText type="text" v-model="filters['activity']" class="p-column-filter" placeholder="Minimum"/>
|
<Slider v-model="filterModel.value" range class="p-m-3"></Slider>
|
||||||
|
<div class="p-d-flex p-ai-center p-jc-between p-px-2">
|
||||||
|
<span>{{filterModel.value ? filterModel.value[0] : 0}}</span>
|
||||||
|
<span>{{filterModel.value ? filterModel.value[1] : 100}}</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column headerStyle="width: 8rem; text-align: center" bodyStyle="text-align: center; overflow: visible">
|
<Column headerStyle="width: 8rem; text-align: center" bodyStyle="text-align: center; overflow: visible">
|
||||||
<template #body>
|
<template #body>
|
||||||
<Button type="button" icon="pi pi-cog" class="p-button-secondary"></Button>
|
<Button type="button" icon="pi pi-cog"></Button>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
|
@ -111,6 +129,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CustomerService from '../../service/CustomerService';
|
import CustomerService from '../../service/CustomerService';
|
||||||
|
import {FilterMatchMode,FilterOperator} from 'primevue/api';
|
||||||
import DataTableDoc from './DataTableDoc';
|
import DataTableDoc from './DataTableDoc';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -118,7 +137,17 @@ export default {
|
||||||
return {
|
return {
|
||||||
customers: null,
|
customers: null,
|
||||||
selectedCustomers: null,
|
selectedCustomers: null,
|
||||||
filters: {},
|
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: null, matchMode: FilterMatchMode.BETWEEN},
|
||||||
|
'verified': {value: null, matchMode: FilterMatchMode.EQUALS}
|
||||||
|
},
|
||||||
loading: true,
|
loading: true,
|
||||||
representatives: [
|
representatives: [
|
||||||
{name: "Amy Elsner", image: 'amyelsner.png'},
|
{name: "Amy Elsner", image: 'amyelsner.png'},
|
||||||
|
@ -141,34 +170,22 @@ export default {
|
||||||
this.customerService = new CustomerService();
|
this.customerService = new CustomerService();
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.customerService.getCustomersLarge().then(data => this.customers = data);
|
this.customerService.getCustomersLarge().then(data => {
|
||||||
|
this.customers = data;
|
||||||
|
this.customers.forEach(customer => customer.date = new Date(customer.date));
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
filterDate(value, filter) {
|
formatDate(value) {
|
||||||
if (filter === undefined || filter === null || (typeof filter === 'string' && filter.trim() === '')) {
|
return value.toLocaleDateString('en-US', {
|
||||||
return true;
|
day: '2-digit',
|
||||||
}
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
if (value === undefined || value === null) {
|
});
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value === this.formatDate(filter);
|
|
||||||
},
|
},
|
||||||
formatDate(date) {
|
formatCurrency(value) {
|
||||||
let month = date.getMonth() + 1;
|
return value.toLocaleString('en-US', {style: 'currency', currency: 'USD'});
|
||||||
let day = date.getDate();
|
|
||||||
|
|
||||||
if (month < 10) {
|
|
||||||
month = '0' + month;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (day < 10) {
|
|
||||||
day = '0' + day;
|
|
||||||
}
|
|
||||||
|
|
||||||
return date.getFullYear() + '-' + month + '-' + day;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -193,11 +210,6 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.p-datepicker) {
|
::v-deep(.p-datepicker) {
|
||||||
min-width: 25rem;
|
min-width: 25rem;
|
||||||
|
|
||||||
|
|
|
@ -2520,15 +2520,16 @@ export default {
|
||||||
|
|
||||||
<pre v-code><code><template v-pre>
|
<pre v-code><code><template v-pre>
|
||||||
<DataTable :value="customers" :paginator="true" class="p-datatable-customers" :rows="10"
|
<DataTable :value="customers" :paginator="true" class="p-datatable-customers" :rows="10"
|
||||||
dataKey="id" :rowHover="true" v-model:selection="selectedCustomers" :filters="filters" :loading="loading"
|
dataKey="id" :rowHover="true" v-model:selection="selectedCustomers" v-model:filters="filters" filterDisplay="menu" :loading="loading"
|
||||||
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[10,25,50]"
|
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[10,25,50]"
|
||||||
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries">
|
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
|
||||||
|
:globalFilterFields="['name','country.name','representative.name','status']">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="table-header">
|
<div class="p-d-flex p-jc-between">
|
||||||
List of Customers
|
<h5 class="p-m-0">Customers</h5>
|
||||||
<span class="p-input-icon-left">
|
<span class="p-input-icon-left">
|
||||||
<i class="pi pi-search" />
|
<i class="pi pi-search" />
|
||||||
<InputText v-model="filters['global']" placeholder="Global Search" />
|
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -2538,34 +2539,35 @@ export default {
|
||||||
<template #loading>
|
<template #loading>
|
||||||
Loading customers data. Please wait.
|
Loading customers data. Please wait.
|
||||||
</template>
|
</template>
|
||||||
<Column selectionMode="multiple" headerStyle="width: 3em"></Column>
|
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
|
||||||
<Column field="name" header="Name" :sortable="true">
|
<Column field="name" header="Name" sortable>
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Name</span>
|
<span class="p-column-title">Name</span>
|
||||||
{{slotProps.data.name}}
|
{{data.name}}
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<InputText type="text" v-model="filters['name']" class="p-column-filter" placeholder="Search by name"/>
|
<InputText type="text" v-model="filterModel.value" class="p-column-filter" placeholder="Search by name"/>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column header="Country" :sortable="true" sortField="country.name" filterField="country.name" filterMatchMode="contains">
|
<Column field="country.name" header="Country" sortable filterMatchMode="contains">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Country</span>
|
<span class="p-column-title">Country</span>
|
||||||
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.data.country.code" width="30" />
|
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + data.country.code" width="30" />
|
||||||
<span class="image-text">{{slotProps.data.country.name}}</span>
|
<span class="image-text">{{data.country.name}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<InputText type="text" v-model="filters['country.name']" class="p-column-filter" placeholder="Search by country"/>
|
<InputText type="text" v-model="filterModel.value" class="p-column-filter" placeholder="Search by country"/>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column header="Representative" :sortable="true" sortField="representative.name" filterField="representative.name" filterMatchMode="in">
|
<Column header="Representative" sortable sortField="representative.name" :showFilterMatchModes="false" :filterMenuStyle="{'width':'14rem'}">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Representative</span>
|
<span class="p-column-title">Agent</span>
|
||||||
<img :alt="slotProps.data.representative.name" :src="'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
|
<img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
|
||||||
<span class="image-text">{{slotProps.data.representative.name}}</span>
|
<span class="image-text">{{data.representative.name}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<MultiSelect v-model="filters['representative.name']" :options="representatives" optionLabel="name" optionValue="name" placeholder="All" class="p-column-filter">
|
<div class="p-mb-3 p-text-bold">Agent Picker</div>
|
||||||
|
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<div class="p-multiselect-representative-option">
|
<div class="p-multiselect-representative-option">
|
||||||
<img :alt="slotProps.option.name" :src="'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
|
<img :alt="slotProps.option.name" :src="'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
|
||||||
|
@ -2575,40 +2577,56 @@ export default {
|
||||||
</MultiSelect>
|
</MultiSelect>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="date" header="Date" :sortable="true" filterMatchMode="custom" :filterFunction="filterDate">
|
<Column field="date" header="Date" sortable dataType="date">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Date</span>
|
<span class="p-column-title">Date</span>
|
||||||
<span>{{slotProps.data.date}}</span>
|
{{formatDate(data.date)}}
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<Calendar v-model="filters['date']" dateFormat="yy-mm-dd" class="p-column-filter" placeholder="Registration Date"/>
|
<Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="status" header="Status" :sortable="true" filterMatchMode="equals">
|
<Column field="balance" header="Balance" sortable dataType="numeric">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Status</span>
|
<span class="p-column-title">Balance</span>
|
||||||
<span :class="'customer-badge status-' + slotProps.data.status">{{slotProps.data.status}}</span>
|
{{formatCurrency(data.balance)}}
|
||||||
|
</template>
|
||||||
|
<template #filter="{filterModel}">
|
||||||
|
<InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="status" header="Status" sortable :filterMenuStyle="{'width':'14rem'}">
|
||||||
|
<template #body="{data}">
|
||||||
|
<span class="p-column-title">Status</span>
|
||||||
|
<span :class="'customer-badge status-' + data.status">{{data.status}}</span>
|
||||||
|
</template>
|
||||||
|
<template #filter="{filterModel}">
|
||||||
|
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
||||||
|
<template #value="slotProps">
|
||||||
|
<span :class="'customer-badge status-' + slotProps.value">{{slotProps.value}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
|
||||||
<Dropdown v-model="filters['status']" :options="statuses" placeholder="Select a Status" class="p-column-filter" :showClear="true">
|
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="activity" header="Activity" :sortable="true" filterMatchMode="gte">
|
<Column field="activity" header="Activity" sortable :showFilterMatchModes="false">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Activity</span>
|
<span class="p-column-title">Activity</span>
|
||||||
<ProgressBar :value="slotProps.data.activity" :showValue="false" />
|
<ProgressBar :value="data.activity" :showValue="false" />
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<InputText type="text" v-model="filters['activity']" class="p-column-filter" placeholder="Minimum"/>
|
<Slider v-model="filterModel.value" range class="p-m-3"></Slider>
|
||||||
|
<div class="p-d-flex p-ai-center p-jc-between p-px-2">
|
||||||
|
<span>{{filterModel.value ? filterModel.value[0] : 0}}</span>
|
||||||
|
<span>{{filterModel.value ? filterModel.value[1] : 100}}</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column headerStyle="width: 8rem; text-align: center" bodyStyle="text-align: center; overflow: visible">
|
<Column headerStyle="width: 8rem; text-align: center" bodyStyle="text-align: center; overflow: visible">
|
||||||
<template #body>
|
<template #body>
|
||||||
<Button type="button" icon="pi pi-cog" class="p-button-secondary"></Button>
|
<Button type="button" icon="pi pi-cog"></Button>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
|
@ -2617,13 +2635,24 @@ export default {
|
||||||
|
|
||||||
<pre v-code.script><code>
|
<pre v-code.script><code>
|
||||||
import CustomerService from '../../service/CustomerService';
|
import CustomerService from '../../service/CustomerService';
|
||||||
|
import {FilterMatchMode,FilterOperator} from 'primevue/api';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
customers: null,
|
customers: null,
|
||||||
selectedCustomers: null,
|
selectedCustomers: null,
|
||||||
filters: {},
|
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: null, matchMode: FilterMatchMode.BETWEEN},
|
||||||
|
'verified': {value: null, matchMode: FilterMatchMode.EQUALS}
|
||||||
|
},
|
||||||
loading: true,
|
loading: true,
|
||||||
representatives: [
|
representatives: [
|
||||||
{name: "Amy Elsner", image: 'amyelsner.png'},
|
{name: "Amy Elsner", image: 'amyelsner.png'},
|
||||||
|
@ -2648,136 +2677,26 @@ export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
this.customerService.getCustomersLarge().then(data => {
|
this.customerService.getCustomersLarge().then(data => {
|
||||||
this.customers = data;
|
this.customers = data;
|
||||||
|
this.customers.forEach(customer => customer.date = new Date(customer.date));
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
filterDate(value, filter) {
|
formatDate(value) {
|
||||||
if (filter === undefined || filter === null || (typeof filter === 'string' && filter.trim() === '')) {
|
return value.toLocaleDateString('en-US', {
|
||||||
return true;
|
day: '2-digit',
|
||||||
}
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
if (value === undefined || value === null) {
|
});
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value === this.formatDate(filter);
|
|
||||||
},
|
},
|
||||||
formatDate(date) {
|
formatCurrency(value) {
|
||||||
let month = date.getMonth() + 1;
|
return value.toLocaleString('en-US', {style: 'currency', currency: 'USD'});
|
||||||
let day = date.getDate();
|
|
||||||
|
|
||||||
if (month < 10) {
|
|
||||||
month = '0' + month;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (day < 10) {
|
|
||||||
day = '0' + day;
|
|
||||||
}
|
|
||||||
|
|
||||||
return date.getFullYear() + '-' + month + '-' + day;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<pre v-code.css><code>
|
|
||||||
::v-deep(.p-paginator) {
|
|
||||||
.p-paginator-current {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.p-progressbar) {
|
|
||||||
height: .5rem;
|
|
||||||
background-color: #D8DADC;
|
|
||||||
|
|
||||||
.p-progressbar-value {
|
|
||||||
background-color: #607D8B;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.p-datepicker) {
|
|
||||||
min-width: 25rem;
|
|
||||||
|
|
||||||
td {
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.p-datatable.p-datatable-customers) {
|
|
||||||
.p-datatable-header {
|
|
||||||
padding: 1rem;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-paginator {
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-datatable-thead > tr > th {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-datatable-tbody > tr > td {
|
|
||||||
cursor: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-dropdown-label:not(.p-placeholder) {
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive */
|
|
||||||
.p-datatable-customers .p-datatable-tbody > tr > td .p-column-title {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 960px) {
|
|
||||||
::v-deep(.p-datatable) {
|
|
||||||
&.p-datatable-customers {
|
|
||||||
.p-datatable-thead > tr > th,
|
|
||||||
.p-datatable-tfoot > tr > td {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-datatable-tbody > tr {
|
|
||||||
border-bottom: 1px solid var(--layer-2);
|
|
||||||
|
|
||||||
> td {
|
|
||||||
text-align: left;
|
|
||||||
display: block;
|
|
||||||
border: 0 none !important;
|
|
||||||
width: 100% !important;
|
|
||||||
float: left;
|
|
||||||
clear: left;
|
|
||||||
border: 0 none;
|
|
||||||
|
|
||||||
.p-column-title {
|
|
||||||
padding: .4rem;
|
|
||||||
min-width: 30%;
|
|
||||||
display: inline-block;
|
|
||||||
margin: -.4rem 1rem -.4rem -.4rem;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-progressbar {
|
|
||||||
margin-top: .5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</code></pre>
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabView>
|
</TabView>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2795,15 +2714,16 @@ export default {
|
||||||
<div class="content-section implementation">
|
<div class="content-section implementation">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<DataTable :value="customers" :paginator="true" class="p-datatable-customers" :rows="10"
|
<DataTable :value="customers" :paginator="true" class="p-datatable-customers" :rows="10"
|
||||||
dataKey="id" :rowHover="true" v-model:selection="selectedCustomers" :filters="filters" :loading="loading"
|
dataKey="id" :rowHover="true" v-model:selection="selectedCustomers" v-model:filters="filters" filterDisplay="menu" :loading="loading"
|
||||||
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[10,25,50]"
|
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[10,25,50]"
|
||||||
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries">
|
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
|
||||||
|
:globalFilterFields="['name','country.name','representative.name','status']">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="table-header">
|
<div class="p-d-flex p-jc-between">
|
||||||
List of Customers
|
<h5 class="p-m-0">Customers</h5>
|
||||||
<span class="p-input-icon-left">
|
<span class="p-input-icon-left">
|
||||||
<i class="pi pi-search" />
|
<i class="pi pi-search" />
|
||||||
<InputText v-model="filters['global']" placeholder="Global Search" />
|
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -2813,77 +2733,94 @@ export default {
|
||||||
<template #loading>
|
<template #loading>
|
||||||
Loading customers data. Please wait.
|
Loading customers data. Please wait.
|
||||||
</template>
|
</template>
|
||||||
<Column selectionMode="multiple" headerStyle="width: 3em"></Column>
|
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
|
||||||
<Column field="name" header="Name" :sortable="true">
|
<Column field="name" header="Name" sortable>
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Name</span>
|
<span class="p-column-title">Name</span>
|
||||||
{{slotProps.data.name}}
|
{{data.name}}
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<InputText type="text" v-model="filters['name']" class="p-column-filter" placeholder="Search by name"/>
|
<InputText type="text" v-model="filterModel.value" class="p-column-filter" placeholder="Search by name"/>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column header="Country" :sortable="true" sortField="country.name" filterField="country.name" filterMatchMode="contains">
|
<Column field="country.name" header="Country" sortable filterMatchMode="contains">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Country</span>
|
<span class="p-column-title">Country</span>
|
||||||
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" width="30" />
|
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + data.country.code" width="30" />
|
||||||
<span class="image-text">{{slotProps.data.country.name}}</span>
|
<span class="image-text">{{data.country.name}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<InputText type="text" v-model="filters['country.name']" class="p-column-filter" placeholder="Search by country"/>
|
<InputText type="text" v-model="filterModel.value" class="p-column-filter" placeholder="Search by country"/>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column header="Representative" :sortable="true" sortField="representative.name" filterField="representative.name" filterMatchMode="in">
|
<Column header="Representative" sortable sortField="representative.name" :showFilterMatchModes="false" :filterMenuStyle="{'width':'14rem'}">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Representative</span>
|
<span class="p-column-title">Agent</span>
|
||||||
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" width="32" style="vertical-align: middle" />
|
<img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
|
||||||
<span class="image-text">{{slotProps.data.representative.name}}</span>
|
<span class="image-text">{{data.representative.name}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<MultiSelect v-model="filters['representative.name']" :options="representatives" optionLabel="name" optionValue="name" placeholder="All" class="p-column-filter">
|
<div class="p-mb-3 p-text-bold">Agent Picker</div>
|
||||||
|
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<div class="p-multiselect-representative-option">
|
<div class="p-multiselect-representative-option">
|
||||||
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" width="32" style="vertical-align: middle" />
|
<img :alt="slotProps.option.name" :src="'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
|
||||||
<span class="image-text">{{slotProps.option.name}}</span>
|
<span class="image-text">{{slotProps.option.name}}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</MultiSelect>
|
</MultiSelect>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="date" header="Date" :sortable="true" filterMatchMode="custom" :filterFunction="filterDate">
|
<Column field="date" header="Date" sortable dataType="date">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Date</span>
|
<span class="p-column-title">Date</span>
|
||||||
<span>{{slotProps.data.date}}</span>
|
{{formatDate(data.date)}}
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<Calendar v-model="filters['date']" dateFormat="yy-mm-dd" class="p-column-filter" placeholder="Registration Date"/>
|
<Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="status" header="Status" :sortable="true" filterMatchMode="equals">
|
<Column field="balance" header="Balance" sortable dataType="numeric">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Status</span>
|
<span class="p-column-title">Balance</span>
|
||||||
<span :class="'customer-badge status-' + slotProps.data.status">{{slotProps.data.status}}</span>
|
{{formatCurrency(data.balance)}}
|
||||||
|
</template>
|
||||||
|
<template #filter="{filterModel}">
|
||||||
|
<InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column field="status" header="Status" sortable :filterMenuStyle="{'width':'14rem'}">
|
||||||
|
<template #body="{data}">
|
||||||
|
<span class="p-column-title">Status</span>
|
||||||
|
<span :class="'customer-badge status-' + data.status">{{data.status}}</span>
|
||||||
|
</template>
|
||||||
|
<template #filter="{filterModel}">
|
||||||
|
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
||||||
|
<template #value="slotProps">
|
||||||
|
<span :class="'customer-badge status-' + slotProps.value">{{slotProps.value}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
|
||||||
<Dropdown v-model="filters['status']" :options="statuses" placeholder="Select a Status" class="p-column-filter" :showClear="true">
|
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="activity" header="Activity" :sortable="true" filterMatchMode="gte">
|
<Column field="activity" header="Activity" sortable :showFilterMatchModes="false">
|
||||||
<template #body="slotProps">
|
<template #body="{data}">
|
||||||
<span class="p-column-title">Activity</span>
|
<span class="p-column-title">Activity</span>
|
||||||
<ProgressBar :value="slotProps.data.activity" :showValue="false" />
|
<ProgressBar :value="data.activity" :showValue="false" />
|
||||||
</template>
|
</template>
|
||||||
<template #filter>
|
<template #filter="{filterModel}">
|
||||||
<InputText type="text" v-model="filters['activity']" class="p-column-filter" placeholder="Minimum"/>
|
<Slider v-model="filterModel.value" range class="p-m-3"></Slider>
|
||||||
|
<div class="p-d-flex p-ai-center p-jc-between p-px-2">
|
||||||
|
<span>{{filterModel.value ? filterModel.value[0] : 0}}</span>
|
||||||
|
<span>{{filterModel.value ? filterModel.value[1] : 100}}</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column headerStyle="width: 8rem; text-align: center" bodyStyle="text-align: center; overflow: visible">
|
<Column headerStyle="width: 8rem; text-align: center" bodyStyle="text-align: center; overflow: visible">
|
||||||
<template #body>
|
<template #body>
|
||||||
<Button type="button" icon="pi pi-cog" class="p-button-secondary"></Button>
|
<Button type="button" icon="pi pi-cog"></Button>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
|
@ -2893,14 +2830,25 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CustomerService from '../service/CustomerService';
|
import CustomerService from '../../service/CustomerService';
|
||||||
|
import {FilterMatchMode,FilterOperator} from 'primevue/api';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
customers: null,
|
customers: null,
|
||||||
selectedCustomers: null,
|
selectedCustomers: null,
|
||||||
filters: {},
|
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: null, matchMode: FilterMatchMode.BETWEEN},
|
||||||
|
'verified': {value: null, matchMode: FilterMatchMode.EQUALS}
|
||||||
|
},
|
||||||
loading: true,
|
loading: true,
|
||||||
representatives: [
|
representatives: [
|
||||||
{name: "Amy Elsner", image: 'amyelsner.png'},
|
{name: "Amy Elsner", image: 'amyelsner.png'},
|
||||||
|
@ -2923,34 +2871,22 @@ export default {
|
||||||
this.customerService = new CustomerService();
|
this.customerService = new CustomerService();
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.customerService.getCustomersLarge().then(data => this.customers = data);
|
this.customerService.getCustomersLarge().then(data => {
|
||||||
|
this.customers = data;
|
||||||
|
this.customers.forEach(customer => customer.date = new Date(customer.date));
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
filterDate(value, filter) {
|
formatDate(value) {
|
||||||
if (filter === undefined || filter === null || (typeof filter === 'string' && filter.trim() === '')) {
|
return value.toLocaleDateString('en-US', {
|
||||||
return true;
|
day: '2-digit',
|
||||||
}
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
if (value === undefined || value === null) {
|
});
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value === this.formatDate(filter);
|
|
||||||
},
|
},
|
||||||
formatDate(date) {
|
formatCurrency(value) {
|
||||||
let month = date.getMonth() + 1;
|
return value.toLocaleString('en-US', {style: 'currency', currency: 'USD'});
|
||||||
let day = date.getDate();
|
|
||||||
|
|
||||||
if (month < 10) {
|
|
||||||
month = '0' + month;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (day < 10) {
|
|
||||||
day = '0' + day;
|
|
||||||
}
|
|
||||||
|
|
||||||
return date.getFullYear() + '-' + month + '-' + day;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
|
@ -2970,11 +2906,6 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.p-datepicker) {
|
::v-deep(.p-datepicker) {
|
||||||
min-width: 25rem;
|
min-width: 25rem;
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,8 @@
|
||||||
<template #filter="{filterModel}">
|
<template #filter="{filterModel}">
|
||||||
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
||||||
<template #value="slotProps">
|
<template #value="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.value">{{slotProps.value}}</span>
|
<span :class="'customer-badge status-' + slotProps.value" v-if="slotProps.value">{{slotProps.value}}</span>
|
||||||
|
<span v-else>{{slotProps.placeholder}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
||||||
|
@ -198,7 +199,8 @@
|
||||||
<template #filter="{filterModel,filterCallback}">
|
<template #filter="{filterModel,filterCallback}">
|
||||||
<Dropdown v-model="filterModel.value" @change="filterCallback()" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
<Dropdown v-model="filterModel.value" @change="filterCallback()" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
||||||
<template #value="slotProps">
|
<template #value="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.value">{{slotProps.value}}</span>
|
<span :class="'customer-badge status-' + slotProps.value" v-if="slotProps.value">{{slotProps.value}}</span>
|
||||||
|
<span v-else>{{slotProps.placeholder}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
||||||
|
@ -316,7 +318,8 @@
|
||||||
<template #filter="{filterModel}">
|
<template #filter="{filterModel}">
|
||||||
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
||||||
<template #value="slotProps">
|
<template #value="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.value">{{slotProps.value}}</span>
|
<span :class="'customer-badge status-' + slotProps.value" v-if="slotProps.value">{{slotProps.value}}</span>
|
||||||
|
<span v-else>{{slotProps.placeholder}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
||||||
|
@ -413,7 +416,8 @@
|
||||||
<template #filter="{filterModel,filterCallback}">
|
<template #filter="{filterModel,filterCallback}">
|
||||||
<Dropdown v-model="filterModel.value" @change="filterCallback()" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
<Dropdown v-model="filterModel.value" @change="filterCallback()" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
|
||||||
<template #value="slotProps">
|
<template #value="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.value">{{slotProps.value}}</span>
|
<span :class="'customer-badge status-' + slotProps.value" v-if="slotProps.value">{{slotProps.value}}</span>
|
||||||
|
<span v-else>{{slotProps.placeholder}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
<span :class="'customer-badge status-' + slotProps.option">{{slotProps.option}}</span>
|
||||||
|
|
Loading…
Reference in New Issue