243 lines
11 KiB
Vue
243 lines
11 KiB
Vue
<template>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
Codes EAN
|
|
</div>
|
|
<div class="col-md-6 text-center">
|
|
<transition name="fade">
|
|
<span v-show="processing">
|
|
{{ response }}
|
|
</span>
|
|
</transition>
|
|
</div>
|
|
<div class="col-md-3 text-right">
|
|
<button class="btn btn-primary btn-sm text-white float-right" @click="saveData()" :disabled="processing">
|
|
Sauvegarder
|
|
<div class="spinner-border spinner-border-sm text-light" role="status" v-show="processing">
|
|
<span class="sr-only">Loading...</span>
|
|
</div>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-body">
|
|
<div class="col-md-10 offset-md-1">
|
|
<div class="row">
|
|
<label class="col-form-label col-md-6">Rechercher :</label>
|
|
<input type="text" @keyup="search" v-model="searchText" class="form-control form-control-sm col-md-6">
|
|
</div>
|
|
<hr/>
|
|
<table class="table table-bordered table-sm text-center">
|
|
<thead>
|
|
<tr>
|
|
<th class="w-25" scope="col">Code EAN <span class="required-asterisk">*</span></th>
|
|
<th class="w-50" scope="col">Produit concerné <span class="required-asterisk">*</span></th>
|
|
<th class="w-25" scope="col"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="item in displayedCodes" v-bind:key="item.id">
|
|
<td><input class="form-control form-control-sm" v-model="item.code" type="text" disabled></td>
|
|
<td><input class="form-control form-control-sm" v-model="item.product" type="text" @keyup="updateBaseData(item.code)" required></td>
|
|
<td><button @click="removeItem(item.id)" class="btn btn-danger btn-sm">Supprimer</button></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="form-group text-right">
|
|
<span v-show="filterMode"><i class="fas fa-exclamation-triangle"></i> L'ajout de ligne est désactiver lorsqu'un filtre est actif.</span>
|
|
<button class="btn btn-primary btn-sm text-white" :class="{ disabled: filterMode}" :disabled="filterMode" @click="newItem">Ajouter une ligne</button>
|
|
</div>
|
|
<nav aria-label="Pagination codes EAN">
|
|
<ul class="pagination justify-content-center">
|
|
<li class="page-item" :class="{ disabled: page == 1}">
|
|
<button type="button" class="page-link" :disabled="page == 1" @click="page = 1"> Première </button>
|
|
</li>
|
|
<li class="page-item" :class="{ disabled: page == 1}">
|
|
<button type="button" class="page-link" :disabled="page == 1" @click="page--">
|
|
<span aria-hidden="true">«</span>
|
|
</button>
|
|
</li>
|
|
<li class="page-item" :class="{ active: pageNumber == page}" v-for="pageNumber in resultPagination" @click="page = pageNumber">
|
|
<button type="button" class="page-link"> {{pageNumber}} </button>
|
|
</li>
|
|
<li class="page-item" :class="{ disabled: page == pages.length}">
|
|
<button type="button" @click="page++" :disabled="page == pages.length" class="page-link">
|
|
<span aria-hidden="true">»</span>
|
|
</button>
|
|
</li>
|
|
<li class="page-item" :class="{ disabled: page == pages.length}">
|
|
<button type="button" @click="page = pages.length" :disabled="page == pages.length" class="page-link"> Dernière </button>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
mounted() {
|
|
console.log('CodesEAN Component mounted.');
|
|
this.datas = JSON.parse(this.dbdatas);
|
|
this.baseDatas = JSON.parse(this.dbdatas);
|
|
},
|
|
props: [
|
|
'dbdatas',
|
|
],
|
|
data() {
|
|
return {
|
|
datas: [],
|
|
response: null,
|
|
processing: false,
|
|
page: 1,
|
|
perPage: 10,
|
|
pages: [],
|
|
baseDatas: [],
|
|
searchText: '',
|
|
filterMode: false,
|
|
resultPagination: []
|
|
}
|
|
},
|
|
methods: {
|
|
// Ajoute une ligne au tableau affiché
|
|
newItem() {
|
|
let code = window.prompt('Entrer le code EAN', "");
|
|
let codeOk = false;
|
|
if (code != null) {
|
|
codeOk = this.baseDatas.filter(elem => elem.code == code).length == 0 ? true : false;
|
|
}
|
|
if (codeOk) {
|
|
this.datas.push({id: null, code: code, product: ''});
|
|
this.baseDatas.push({id: null, code: code, product: ''});
|
|
this.setPages();
|
|
this.page = this.pages.length;
|
|
} else {
|
|
Swal.fire({
|
|
text: 'Le code entré existe déjà !',
|
|
icon: 'error'
|
|
})
|
|
}
|
|
},
|
|
// Supprime une ligne dans la base si elle existait déjà
|
|
removeItem(id) {
|
|
if (confirm("Êtes-vous sûr(e) ?")) {
|
|
let i = this.baseDatas.findIndex(element => element.id == id);
|
|
let iDatas = this.datas.findIndex(element => element.id == id);
|
|
if (i !== null && this.baseDatas[i]['id'] !== null) {
|
|
axios.post('/bo/ajax/delete-codes-ean', {
|
|
id: this.baseDatas[i]['id'],
|
|
})
|
|
.catch(function (error) {
|
|
console.log(error);
|
|
});
|
|
this.baseDatas.splice(i, 1);
|
|
this.datas.splice(iDatas, 1);
|
|
} else {
|
|
this.baseDatas.splice(i, 1);
|
|
this.datas.splice(iDatas, 1);
|
|
}
|
|
}
|
|
},
|
|
// Sauvegarde les données dans la base
|
|
saveData() {
|
|
this.processing = true;
|
|
this.response = "En cours de sauvegarde...";
|
|
this.searchText = '';
|
|
axios.post('/bo/ajax/save-codes-ean', {
|
|
codes: this.baseDatas,
|
|
}).then(
|
|
(response) => {
|
|
this.datas = response.data;
|
|
this.baseDatas = JSON.parse(JSON.stringify(this.datas));
|
|
this.response = "Sauvegarde terminée !";
|
|
this.processing = false;
|
|
}
|
|
)
|
|
.catch(function (error) {
|
|
console.log(error);
|
|
this.response = "Erreur lors de la sauvegarde.";
|
|
this.processing = false;
|
|
});
|
|
},
|
|
// Calcul le nombre de page total dans la pagination
|
|
setPages () {
|
|
let numberOfPages = Math.ceil(this.datas.length / this.perPage);
|
|
if (this.pages.length > numberOfPages) {
|
|
this.pages.splice(numberOfPages);
|
|
}
|
|
for (let index = 0; index < numberOfPages; index++) {
|
|
if (!this.pages.includes(index + 1)) {
|
|
this.pages.push(index + 1);
|
|
}
|
|
}
|
|
this.paginationToPrint();
|
|
},
|
|
// S'occupe de la pagination des données affichées dans le tableau
|
|
paginate (datas) {
|
|
let page = this.page;
|
|
let perPage = this.perPage;
|
|
let from = (page * perPage) - perPage;
|
|
let to = (page * perPage);
|
|
return datas.slice(from, to);
|
|
},
|
|
// Recherche dans le tableau les codes ou produit corespondant à la recherche
|
|
search() {
|
|
if (this.page !== 1) {
|
|
this.page = 1;
|
|
}
|
|
if (this.searchText === "") {
|
|
this.filterMode = false;
|
|
} else {
|
|
this.filterMode = true;
|
|
}
|
|
let tmpEAN = this.baseDatas.filter(item => item.code.toString().indexOf(this.searchText) >= 0);
|
|
let tmpProduct = this.baseDatas.filter(item => item.product.toLowerCase().indexOf(this.searchText.toLowerCase()) >= 0);
|
|
this.datas = Object.assign(tmpEAN, tmpProduct);
|
|
},
|
|
// Copie les données du tableau afficher dans le tableau baseDatas qui sert de référence pour sauvegarder, supprimer etc
|
|
updateBaseData(code) {
|
|
this.baseDatas[this.datas.findIndex(element => element.code == code)] = this.datas[this.datas.findIndex(element => element.code == code)];
|
|
},
|
|
// Prépare les pages à afficher a l'écran pour la pagination
|
|
paginationToPrint() {
|
|
this.resultPagination = JSON.parse(JSON.stringify(this.pages));
|
|
if (this.page >= 3) {
|
|
if (this.page <= this.pages.length - 4) {
|
|
this.resultPagination.splice(0, this.page - 4);
|
|
} else {
|
|
this.resultPagination.splice(0, this.pages.length - 8);
|
|
}
|
|
}
|
|
if (this.page <= this.pages.length - 3) {
|
|
this.resultPagination.splice(8);
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
displayedCodes () {
|
|
return this.paginate(this.datas);
|
|
}
|
|
},
|
|
watch: {
|
|
datas () {
|
|
this.setPages();
|
|
},
|
|
page () {
|
|
this.paginationToPrint();
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.fade-enter-active, .fade-leave-active {
|
|
transition: opacity .5s;
|
|
}
|
|
.fade-enter, .fade-leave-to {
|
|
opacity: 0;
|
|
}
|
|
</style>
|