Correzione report produzione

Riscrittura paginazione su singolo componente
Colorazione grafico e relativo aggiornamento dei dati al cambio di indicatore tra frequenza e quantità
Posizionamento tooltip grafico
This commit is contained in:
Giacomo Canonico
2019-03-27 14:31:25 +01:00
parent 5940c5daf7
commit 56ccecab58
8 changed files with 383 additions and 303 deletions
+58 -113
View File
@@ -2269,8 +2269,9 @@
table {
table-layout: fixed;
width: 100%;
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.4);
border-radius: 2px;
border-collapse: collapse;
border: solid 1px @color-label-grey;
}
thead {
@@ -2279,7 +2280,7 @@
line-height: 1.29;
color: @color-darkish-blue;
display: block;
width: 1431px;
width: 100%;
}
thead tr th {
@@ -2307,76 +2308,13 @@
width: auto;
}
// th:nth-child(1), td:nth-child(1){
// width:162px;
// max-width: 162px;
// text-align: center;
// }
// th:nth-child(2), td:nth-child(2){
// width:139px;
// max-width: 139px;
// text-align: center;
// }
// th:nth-child(3), td:nth-child(3){
// width:83px;
// max-width:83px;
// text-align: center;
// }
// th:nth-child(4), td:nth-child(4){
// width:83px;
// max-width:83px;
// text-align: center;
// }
// th:nth-child(5), td:nth-child(5){
// width:83px;
// max-width:83px;
// text-align: center;
// }
// th:nth-child(6), td:nth-child(6){
// width:83px;
// max-width:83px;
// text-align: center;
// }
// th:nth-child(7), td:nth-child(7){
// width:97px;
// max-width:97px;
// text-align: center;
// }
// th:nth-child(8), td:nth-child(8){
// width:97px;
// max-width:97px;
// text-align: center;
// }
// th:nth-child(9), td:nth-child(9){
// width:97px;
// max-width:97px;
// text-align: center;
// }
// th:nth-child(10), td:nth-child(10){
// width:115px;
// max-width:115px;
// text-align: center;
// }
// th:nth-child(11), td:nth-child(11){
// width:97px;
// max-width:97px;
// text-align: center;
// }
// th:nth-child(12), td:nth-child(12){
// width:148px;
// max-width:148px;
// text-align: center;
// }
// th:nth-child(13), td:nth-child(13){
// width:97px;
// max-width:97px;
// text-align: center;
// }
th:last-child {
display: flex;
align-items: center;
float: right;
font-size: 23px;
width: 16px;
padding: 0px 18px;
font-weight: bold;
cursor: pointer;
}
@@ -2393,25 +2331,28 @@
tbody {
display: block;
height: 552px;
width: 1420px;
overflow-y: auto;
padding-right: 10px;
height: 554px;
width: 1410px;
overflow-y: scroll;
padding-right: 20px;
&.without-footer {
height: 620px
}
&::-webkit-scrollbar{
&::-webkit-scrollbar {
width: 16px;
}
&::-webkit-scrollbar-track{
margin-bottom: 4px;
margin-top: 4px;
&::-webkit-scrollbar-track {
margin: 20px 0px;
background-color: #E5E5E5;
border-radius: 15px;
box-shadow: inset 0 1px 3px 0 #9F9F9F;
}
&::-webkit-scrollbar-thumb{
&::-webkit-scrollbar-thumb {
width: 16px;
background: #9F9F9F;
border: 4px solid #E5E5E5;
@@ -2446,6 +2387,7 @@
td:last-child {
width: 16px;
display: flex;
// padding: 0px 18px;
}
&.selected {
@@ -2459,52 +2401,55 @@
tfoot {
width: 100%;
bottom: 0;
}
tr {
width: 100%;
display: table;
}
tfoot tr td {
height: 64px;
width: 100%;
font-size: 18px;
color: @color-darkish-blue;
position: relative;
bottom: 0;
border-top: solid 2px @color-silver;
td {
padding: 0;
text-align: center;
&.hidden{
display: none;
visibility: hidden;
}
div.group-label-button {
text-align: center;
margin: 8px 0 8px 0;
tr {
width: 100%;
display: table;
button {
width: 60px;
padding: 0px;
&.disabled {
opacity: .65;
cursor: default;
box-shadow: none !important;
pointer-events: none;
td {
height: 64px;
width: 100%;
font-size: 18px;
color: @color-darkish-blue;
position: relative;
bottom: 0;
border-top: solid 2px @color-silver;
padding: 0;
text-align: center;
i.fa {
color: #838383;
div.group-label-button {
text-align: center;
margin: 8px 0 8px 0;
button {
width: 60px;
padding: 0px;
&.disabled {
opacity: .65;
cursor: default;
box-shadow: none !important;
pointer-events: none;
i.fa {
color: #838383;
}
}
}
.freespace {
width: 60px;
display: inline-block;
margin: 0 8px;
}
}
}
.freespace {
width: 60px;
display: inline-block;
margin: 0 8px;
}
}
}
+18 -11
View File
@@ -8766,8 +8766,9 @@ footer .container button.big:before {
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container table {
table-layout: fixed;
width: 100%;
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.4);
border-radius: 2px;
border-collapse: collapse;
border: solid 1px #979797;
}
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container thead {
border-bottom: solid 2px #979797;
@@ -8775,7 +8776,7 @@ footer .container button.big:before {
line-height: 1.29;
color: #002680;
display: block;
width: 1431px;
width: 100%;
}
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container thead tr th {
height: 48px;
@@ -8798,6 +8799,8 @@ footer .container button.big:before {
align-items: center;
float: right;
font-size: 23px;
width: 16px;
padding: 0px 18px;
font-weight: bold;
cursor: pointer;
}
@@ -8812,17 +8815,19 @@ footer .container button.big:before {
}
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container tbody {
display: block;
height: 552px;
width: 1420px;
overflow-y: auto;
padding-right: 10px;
height: 554px;
width: 1410px;
overflow-y: scroll;
padding-right: 20px;
}
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container tbody.without-footer {
height: 620px;
}
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container tbody::-webkit-scrollbar {
width: 16px;
}
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container tbody::-webkit-scrollbar-track {
margin-bottom: 4px;
margin-top: 4px;
margin: 20px 0px;
background-color: #E5E5E5;
border-radius: 15px;
box-shadow: inset 0 1px 3px 0 #9F9F9F;
@@ -8865,7 +8870,11 @@ footer .container button.big:before {
width: 100%;
bottom: 0;
}
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container tr {
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container tfoot.hidden {
display: none;
visibility: hidden;
}
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container tfoot tr {
width: 100%;
display: table;
}
@@ -8877,8 +8886,6 @@ footer .container button.big:before {
position: relative;
bottom: 0;
border-top: solid 2px #bbbcbc;
}
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container tfoot tr td td {
padding: 0;
text-align: center;
}
@@ -1,12 +1,8 @@
<template>
<div class="user-info">
<button class="dark-blue"
@click="sendMessage('show-help')"
:title="'header_tooltip_btn_help' | localize('Show Machine Help')"
>
?
</button>
<button class="dark-blue" @click="sendMessage('show-help')" :title="'header_tooltip_btn_help' | localize('Show Machine Help')">
<i class="fa fa-question"></i>
</button>
<button class="dark-blue"
@click="sendMessage('show-machine-info')" :title="'header_tooltip_btn_mchinfo' | localize('Show Machine Info')">
<img src="assets/icons/png/machine-info.png" width="28px">
@@ -15,22 +11,10 @@
<small>{{state.machineInfo.machineSerialNumber}}</small>
</div>
</button>
<button class="profile dark-blue"
v-if="currentUser"
@click="sendMessage('show-user-info')"
:title="'header_tooltip_btn_usrinfo' | localize('Show User Info')"
:class="{'colorWhite':isDarkColor(getColor(currentUser.lastName,currentUser.firstName))}"
:style="{'background-color':getColor(currentUser.lastName,currentUser.firstName) }"
>
<button class="profile dark-blue" v-if="currentUser" @click="sendMessage('show-user-info')" :title="'header_tooltip_btn_usrinfo' | localize('Show User Info')" :class="{'colorWhite':isDarkColor(getColor(currentUser.lastName,currentUser.firstName))}" :style="{'background-color':getColor(currentUser.lastName,currentUser.firstName) }">
<i class="fa fa-user"></i>
</button>
<button class="profile dark-blue colorWhite"
v-if="!currentUser"
@click="sendMessage('show-user-info')"
:title="'header_tooltip_btn_usrinfo' | localize('Show User Info')"
>
<button class="profile dark-blue colorWhite" v-else @click="sendMessage('show-user-info')" :title="'header_tooltip_btn_usrinfo' | localize('Show User Info')">
<i class="fa fa-user"></i>
</button>
<time :title="date" >
@@ -14,40 +14,78 @@ import { Watch } from "vue-property-decorator";
import Chart from "chart.js";
import { reportService } from "src/services/reportService";
import { DoughnutChart } from "src/components/doughnut-chart";
import { CustomPagination } from "src/components/pagination";
declare let $: any;
@Component({ components: { datePicker: DatePicker, cardReport: cardReport, accordionDropdown: accordionDropdown, accordion: Accordion, DoughnutChart } })
export default class CardReportProduction extends Vue {
lang = {
days: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
pickers: ['next 7 days', 'next 30 days', 'previous 7 days', 'previous 30 days'],
placeholder: {
date: 'Select Date',
dateRange: 'Select Date Range'
}
@Component({
components: {
datePicker: DatePicker,
cardReport: cardReport,
accordionDropdown: accordionDropdown,
accordion: Accordion,
DoughnutChart,
CustomPagination
}
})
export default class CardReportProduction extends Vue {
lang = {
days: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
months: [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
pickers: [
"next 7 days",
"next 30 days",
"previous 7 days",
"previous 30 days"
],
placeholder: {
date: "Select Date",
dateRange: "Select Date Range"
}
};
filter: {
interval?: Date[],
multiUser: Array<any>,
nameProgram: string,
yAxis: string
interval?: Date[];
multiUser: Array<any>;
nameProgram: string;
yAxis: string;
} = {
multiUser: [],
interval: [new Date(new Date().setDate(new Date().getDate() - 6)), new Date(new Date().setDate(new Date().getDate() + 1))],
nameProgram: "",
yAxis: "quantity"
};
multiUser: [],
interval: [
new Date(new Date().setDate(new Date().getDate() - 6)),
new Date(new Date().setDate(new Date().getDate() + 1))
],
nameProgram: "",
yAxis: "quantity"
};
filterName: string = "";
public searchText: string = "";
visibleColumns: string[] = [
"ProgramName",
"Deviation",
"EffectiveTime",
"Quantity",
"AverageTime",
"StartDate",
"TheoreticalTime",
"EndDate"
];
visibleColumns: string[] = ["ProgramName","Deviation","EffectiveTime","Quantity","AverageTime","StartDate","TheoreticalTime","EndDate",];
isVisible(value){
isVisible(value) {
return this.visibleColumns.some(c => c == value);
}
@@ -57,68 +95,54 @@ export default class CardReportProduction extends Vue {
selectTable: boolean = true;
myBarChart: any = null;
users: Array<any> = [];
selectedPage = 1;
visiblePages = 3;
paginationData: { firstDate: any, pages: number } = {firstDate: new Date(), pages: 0};
currentPage: number = 0;
itemsPerPage: number = 10;
totalPages: number = 1;
resultPrograms: any = [];
get programs() : server.programTableData[]{
get programs(): server.programTableData[] {
return (this.$store.getters as ReportGetters).getProgramsReportProd();
}
get dataPieces() : server.reportData{
get dataPieces(): server.reportData {
return (this.$store.getters as ReportGetters).getReportData();
}
get paginator() {
let min = Math.max(this.selectedPage - 4, 0);
let max = Math.min(this.selectedPage + 5, this.paginationData.pages);
return { min: min, max: max, count: (max - min) }
}
get freeSpaseMinus() {
if(this.selectedPage - (this.visiblePages + 1) < 0)
return ((this.selectedPage - (this.visiblePages + 1)) * (-1));
return 0;
}
get freeSpasePlus() {
if(!this.paginationData || !this.paginationData.pages)
return 0;
if(this.paginationData.pages - this.selectedPage <= this.visiblePages)
return (this.visiblePages - (this.paginationData.pages - this.selectedPage))
return 0;
}
get currentUser() {
return this.$store.state.currentUser;
}
@Watch("currentPage", { deep: true })
@Watch("filter", { deep: true })
async filterChanged(n, o) {
this.resultPrograms = await reportService.ProgramsReport(9,this.selectedPage,this.filter.nameProgram, this.filter.interval);
this.paginationData.pages = this.resultPrograms.pages;
this.resultPrograms = await reportService.ProgramsReport(
this.itemsPerPage,
this.currentPage + 1,
this.filter.nameProgram,
this.filter.interval
);
this.totalPages = this.resultPrograms.pages;
this.buildChart();
}
async mounted() {
this.users = await loginService.getAllUsers();
this.users.unshift({ id: -1, username: this.$options.filters.localize("alarm_history_users_not_user", "Nessun utente") });
this.users.unshift({
id: -1,
username: this.$options.filters.localize(
"alarm_history_users_not_user",
"Nessun utente"
)
});
this.filter.multiUser.push(this.currentUser.username);
// this.resultPrograms = await reportService.ProgramsReport(9,this.selectedPage,this.filter.nameProgram, this.filter.interval);
// this.paginationData.pages = this.resultPrograms.pages;
this.buildChart();
}
public selectTab(value) {
this.selectedTab = value;
}
timeformat() {
return (moment() as any)._locale._longDateFormat.LT;
}
@@ -140,128 +164,136 @@ export default class CardReportProduction extends Vue {
viewMoreFilter() {
if (!this.selectMoreFilter) {
this.selectMoreFilter = true;
}
else {
} else {
this.selectMoreFilter = false;
}
}
async openModalSelectField() {
this.visibleColumns = await ModalHelper.ShowModalAsync(modalReportSelectColumn, this.visibleColumns);
this.visibleColumns = await ModalHelper.ShowModalAsync(
modalReportSelectColumn,
this.visibleColumns
);
}
public openSelectStateU() {
if (!$('.checkboxesU').hasClass('checkboxesViewUser'))
$('.checkboxesU').addClass('checkboxesViewUser');
else
$('.checkboxesU').removeClass('checkboxesViewUser');
if (!$(".checkboxesU").hasClass("checkboxesViewUser"))
$(".checkboxesU").addClass("checkboxesViewUser");
else $(".checkboxesU").removeClass("checkboxesViewUser");
}
public selectPage(page) {
this.selectedPage = Math.min(Math.max(page,1), this.paginationData.pages);
}
hideTooltip : boolean = true;
hideTooltip: boolean = true;
buildChart() {
let _self = this;
let dataNumber: Array<number> = [];
let dataString: Array<string> = [];
let _chartData: Array<number> = [];
let _chartXaxis: Array<string> = [];
let _chartBackgroundColor: Array<string> = [];
let _chartBorderColor: Array<string> = [];
this.programs.forEach(element => {
if(element){
dataString.push(element.progName);
if(_self.filter.yAxis == 'quantity'){
dataNumber.push(element.quantity);
}
else{
dataNumber.push(element.frequency);
}
this.programs.forEach((element, index) => {
if (element) {
_chartXaxis.push(element.progName);
_chartBackgroundColor.push(
index % 2 === 0 ? "rgba(0, 38, 128, 0.7)" : "rgba(55, 160, 255, 0.7)"
);
_chartBorderColor.push(
index % 2 === 0 ? "rgba(0, 38, 128, 1)" : "rgba(55, 160, 255, 1)"
);
if (_self.filter.yAxis == "quantity") _chartData.push(element.quantity);
else _chartData.push(element.frequency);
}
});
if(this.myBarChart != null){
this.myBarChart.data.labels.pop();
this.myBarChart.data.datasets.pop();
this.myBarChart = null;
}
let canvas = document.getElementById("myBarChart") as HTMLCanvasElement;
if(canvas){
if (canvas) {
let options = {
barPercentage: 0.9,
responsive: false,
categoryPercentage: 0.8,
events: ["click"],
hover: {
mode: 'nearest'
},
tooltips:{
hover: { mode: "nearest" },
tooltips: {
enabled: false,
custom: function (tooltip) {
let barSelected = _self.programs.find(x => x.progName == tooltip.title);
custom: function(tooltip) {
let barSelected = _self.programs.find(
x => x.progName == tooltip.title
);
if(barSelected == null)
{
if (barSelected == null) {
_self.hideTooltip = true;
return;
}
_self.hideTooltip = false;
let tooltipEl = document.getElementById("chartjs-tooltip");
(_self.$refs.tooltip_title as HTMLElement).innerHTML = barSelected.progName;
(_self.$refs.tooltip_executed as HTMLElement).innerHTML = barSelected.quantity.toString();
(_self.$refs.tooltip_frequency as HTMLElement).innerHTML = barSelected.frequency.toString();
(_self.$refs.tooltip_title as HTMLElement).innerHTML =
barSelected.progName;
(_self.$refs
.tooltip_executed as HTMLElement).innerHTML = barSelected.quantity.toString();
(_self.$refs
.tooltip_frequency as HTMLElement).innerHTML = barSelected.frequency.toString();
debugger;
var positionY = this._chart.canvas.offsetTop;
var positionX = this._chart.canvas.offsetLeft;
if(tooltip.caretY > 350){
tooltipEl.style.top = [(positionY + window.pageYOffset + tooltip.caretY) - (tooltipEl.offsetHeight)] + 'px';
}
else{
tooltipEl.style.top = positionY + window.pageYOffset + tooltip.caretY + 'px';
}
tooltipEl.style.left = positionX + window.pageXOffset + tooltip.caretX - (tooltipEl.offsetWidth / 2) + 'px';
tooltipEl.style.opacity = '1';
tooltipEl.style.position = 'absolute';
tooltipEl.style.fontFamily = tooltip._bodyFontFamily;
tooltipEl.style.fontSize = tooltip.bodyFontSize + 'px';
tooltipEl.style.fontStyle = tooltip._bodyFontStyle;
tooltipEl.style.pointerEvents = 'none';
var position = this._chart.canvas.getBoundingClientRect();
let _top =
Math.ceil(
position.top +
window.pageYOffset +
tooltip.caretY -
(tooltip.caretY > 350 ? tooltipEl.offsetHeight : 0)
) - 12;
tooltipEl.style.top = `${_top}px`;
let _left = Math.ceil(
position.left +
window.pageXOffset +
tooltip.caretX -
tooltipEl.offsetWidth / 2
);
tooltipEl.style.left = `${_left}px`;
tooltipEl.style.position = "absolute";
tooltipEl.style.pointerEvents = "none";
}
}
}
let data = {
labels: dataString,
datasets: [{
label: _self.filter.yAxis,
data: dataNumber,
borderWidth: 1
}]
}
this.myBarChart = new Chart(canvas, {
type: 'bar',
data: data,
options: options
});
};
let _chartDataSet = {
label: _self.filter.yAxis,
data: _chartData,
backgroundColor: _chartBackgroundColor,
borderColor: _chartBorderColor,
borderWidth: 1
};
if (this.myBarChart != null) {
this.myBarChart.data.labels = _chartXaxis;
this.myBarChart.data.datasets = [_chartDataSet];
this.myBarChart.update();
} else {
this.myBarChart = new Chart(canvas, {
type: "bar",
data: {
labels: _chartXaxis,
datasets: [[_chartDataSet]]
},
options: options
});
}
}
}
close(){
close() {
this.hideTooltip = true;
}
colorDeviation(deviation){
if(deviation.startsWith("+")){
colorDeviation(deviation) {
if (deviation.startsWith("+")) {
return "red";
}
else if(deviation.startsWith("-")){
} else if (deviation.startsWith("-")) {
return "green";
}
else{
} else {
return "grey";
}
}
@@ -72,7 +72,7 @@
<th @click="openModalSelectField()"><i class="fa fa-angle-double-right"></i></th>
</tr>
</thead>
<tbody>
<tbody :class="{'without-footer': totalPages <= 1}">
<tr v-for="(p, idx) in programs" :key="idx">
<td :style="{width:(100/visibleColumns.length)+'%'}" v-if="isVisible('ProgramName')">{{p.progName}}</td>
<td :style="{width:(100/visibleColumns.length)+'%'}" v-if="isVisible('Quantity')">{{p.quantity}}</td>
@@ -85,29 +85,16 @@
<td></td>
</tr>
</tbody>
<tfoot>
<tfoot :class="{'hidden': totalPages <= 1}">
<tr>
<td colspan="4">
<div class="group-label-button" v-if="programs && programs.length > 0">
<button class="btn" :class="{'disabled': paginator.count <= 1}" @click="selectPage(paginator.min)"><i class="fa fa-angle-double-left"></i></button>
<div class="freespace" v-for="(p, idx) in freeSpaseMinus" :key="'fakeMinus' + idx" >&nbsp;</div>
<button class="btn" :class="{'btn-success': selectedPage == paginator.min + p}"
v-for="(p, idx) in paginator.count" :key="'page' + idx"
@click="selectPage(paginator.min + p)">{{paginator.min + p}}</button>
<div class="freespace" v-for="(p, idx) in freeSpasePlus" :key="'fakePlus' + idx" >&nbsp;</div>
<button class="btn" :class="{'disabled': paginator.count <= 1}" @click="selectPage(paginator.max)"><i class="fa fa-angle-double-right"></i></button>
<div class="group-label-button">
<custom-pagination v-model="currentPage" :items-per-page="itemsPerPage" :total-pages="totalPages"></custom-pagination>
</div>
</td>
</tr>
</tfoot>
</table>
<!-- <div class="pagination">
<button @click="selectPage(selectedPage-1)"><i class="fa fa-angle-double-left"></i></button>
<button class="page" :class="{active: selectedPage == paginator.min + p}"
v-for="(p, idx) in paginator.count" :key="'page' + idx"
@click="selectPage(paginator.min + p)">{{paginator.min + p}}</button>
<button @click="selectPage(selectedPage+1)"><i class="fa fa-angle-double-right"></i></button>
</div> -->
</div>
</div>
<div class="body-left-center" :class="{'hideDiagram': !selectDiagram}">
@@ -132,7 +119,7 @@
</div>
</div>
<div class="body-left-center-container">
<canvas ref="barChart" id="myBarChart" width="1405px" height="681px"></canvas>
<canvas ref="barChart" id="myBarChart" width="1448px" height="671px" style="border-radius: 2px; box-shadow: 0px 1px 3px 0 rgba(0, 0, 0, 0.4);"></canvas>
</div>
</div>
</div>
@@ -0,0 +1,105 @@
import Vue from "vue";
import { Component, Watch, Prop } from "vue-property-decorator";
@Component({})
export default class CustomPagination extends Vue {
@Prop({ required: true, default: 0 })
value: number;
@Prop({ required: false, default: 10 })
itemsPerPage: number;
@Prop({ required: false, default: 1 })
totalPages: number;
@Prop({ required: false, default: 3 })
maxVisiblePages: number;
currentPage: number = this.value;
@Watch("currentPage", { deep: true })
async currentPageChange(n, o) {
if (n != o) this.$emit("input", n);
}
get totalPagesArrays(): number[] {
let result = [];
for (let index = 0; index < this.totalPages; index++) {
result.push(index);
}
return result;
}
get pages() {
let filteredPages = this.filteredPages;
let pages = this.totalPagesArrays as any[];
if (filteredPages)
pages = [
0,
filteredPages[0] - 1 === 1 ? 1 : "...",
...filteredPages,
filteredPages[filteredPages.length - 1] + 1 === this.totalPages - 2
? this.totalPages - 2
: "...",
this.totalPages - 1
];
return [this.currentPage - 1, ...pages, this.currentPage + 1];
}
get filteredPages() {
let diff = this.maxVisiblePages / 2;
let toFilterPages = this.totalPagesArrays.slice(2, -2);
if (toFilterPages.length > this.maxVisiblePages) {
let diffFirst = this.currentPage - toFilterPages[0];
let diffLast = this.currentPage - toFilterPages[toFilterPages.length - 1];
if (diffFirst < diff) {
return toFilterPages.slice(0, this.maxVisiblePages);
} else if (diffLast >= -diff) {
return toFilterPages.slice(-this.maxVisiblePages);
} else {
return toFilterPages.filter(page => {
let diffPage = this.currentPage - page;
return diffPage < 0 ? Math.abs(diffPage) <= diff : diffPage < diff;
});
}
}
}
get buttons() {
return this.pages.map((page, key) => {
return {
page,
active: page === this.currentPage,
disabled: this.disabled(page, key),
html: this.html(page, key)
};
});
}
html(page, key) {
if (key === 0) {
return '<i class="fa fa-angle-left"></i>';
}
if (key === this.pages.length - 1) {
return '<i class="fa fa-angle-right"></i>';
}
if (page === "...") {
return page;
}
return page + 1 + "";
}
disabled(page, key) {
return (
(key === 0 && this.currentPage === 0) ||
(key === this.pages.length - 1 &&
this.currentPage === this.totalPages - 1) ||
page === "..."
);
}
}
@@ -0,0 +1,15 @@
<template>
<div>
<button
v-for="(button, index) in buttons"
:key="index"
class="btn"
:class="{'btn-success': button.active && !button.disabled}"
:disabled="button.disabled"
@click="currentPage = button.page"
>
<span v-html="button.html"/>
</button>
</div>
</template>
<script src="./custom-pagination.ts" lang="ts"></script>
@@ -0,0 +1,5 @@
import CustomPagination from "./custom-pagination.vue";
export {
CustomPagination
}