Various fixes and improvements
This commit is contained in:
parent
8cc15870d8
commit
9c54bd1025
@ -31,6 +31,4 @@ h1 {
|
||||
#app {
|
||||
max-width: 1600px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
@ -4,15 +4,25 @@ import Chart from 'primevue/chart';
|
||||
import Fieldset from 'primevue/fieldset';
|
||||
import MeterGroup from 'primevue/metergroup';
|
||||
import Carousel from 'primevue/carousel';
|
||||
import { getProducts,getWarehouses } from '../api.js';
|
||||
import { getProducts,getWarehouses, modifyProduct } from '../api.js';
|
||||
import Tag from 'primevue/tag';
|
||||
import AutoComplete from 'primevue/autocomplete';
|
||||
import InputNumber from 'primevue/inputnumber';
|
||||
import IftaLabel from 'primevue/iftalabel';
|
||||
import Button from 'primevue/button'
|
||||
|
||||
const products = ref();
|
||||
const warehouses = ref();
|
||||
|
||||
const selectedRef = ref()
|
||||
const filteredRef = ref();
|
||||
const newValue = ref();
|
||||
|
||||
const chartProductsData = ref();
|
||||
const chartWarehousesData = ref();
|
||||
const chartOptions = {plugins:{legend:{labels:{usePointStyle:true,}}}};
|
||||
const productColors = {};
|
||||
const warehouseColors ={};
|
||||
const colorsSchemes = [
|
||||
"#40407a", "#706fd3", "#f7f1e3", "#34ace0",
|
||||
"#33d9b2", "#2c2c54", "#474787", "#aaa69d",
|
||||
@ -38,6 +48,13 @@ const getColorForProduct = (productName) => {
|
||||
}
|
||||
return productColors[productName];
|
||||
};
|
||||
const getColorForWarehouse = (warehouseName) => {
|
||||
if (!warehouseColors[warehouseName]) {
|
||||
warehouseColors[warehouseName] = colorsSchemes[Object.keys(warehouseColors).length % colorsSchemes.length];
|
||||
}
|
||||
return warehouseColors[warehouseName];
|
||||
};
|
||||
|
||||
|
||||
|
||||
const setChartProductsData = () => {
|
||||
@ -61,8 +78,8 @@ const setChartWarehousesData = () =>{
|
||||
datasets: [
|
||||
{
|
||||
label: 'Capacité',
|
||||
backgroundColor: products.value.map(product => `${getColorForProduct(product.name)}80`),
|
||||
borderColor : products.value.map(product => getColorForProduct(product.name)),
|
||||
backgroundColor: warehouses.value.map(warehouse => `${getColorForWarehouse(warehouse.name)}80`),
|
||||
borderColor : warehouses.value.map(warehouse => getColorForWarehouse(warehouse.name)),
|
||||
data: warehouses.value.map(warehouse => warehouse.max_capacity),
|
||||
borderWidth: 1
|
||||
}
|
||||
@ -70,15 +87,45 @@ const setChartWarehousesData = () =>{
|
||||
}
|
||||
};
|
||||
|
||||
const search = (event) => {
|
||||
filteredRef.value = products.value.filter(product =>
|
||||
product.reference.toLowerCase().includes(event.query.toLowerCase())
|
||||
);
|
||||
}
|
||||
onMounted(async () => {
|
||||
warehouses.value = await getWarehouses();
|
||||
products.value = await getProducts();
|
||||
chartProductsData.value = setChartProductsData();
|
||||
chartWarehousesData.value = setChartWarehousesData();
|
||||
})
|
||||
|
||||
const productValueModifier = async () => {
|
||||
if (!selectedRef.value || !newValue.value) return;
|
||||
|
||||
const product = products.value.find(p => p.reference === selectedRef.value.reference);
|
||||
if (product) {
|
||||
const newQuantity = product.quantity + newValue.value
|
||||
try{
|
||||
await modifyProduct({
|
||||
quantity: newQuantity,
|
||||
warehouses: product.warehouses
|
||||
}, product.id);
|
||||
warehouses.value = await getWarehouses();
|
||||
products.value = await getProducts();
|
||||
chartProductsData.value = setChartProductsData();
|
||||
chartWarehousesData.value = setChartWarehousesData();
|
||||
} catch (error){
|
||||
console.error(error)
|
||||
}
|
||||
} else {
|
||||
console.error("no product found")
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<Fieldset legend="Produits stockés" style="max-width: 600px; margin: auto; padding:20px" toggleable>
|
||||
<Chart type="pie" :data="chartProductsData" :options="chartOptions"></Chart>
|
||||
</Fieldset>
|
||||
@ -94,6 +141,20 @@ onMounted(async () => {
|
||||
</ul>
|
||||
</Fieldset>
|
||||
<Fieldset legend="Products" style="max-width: 600px; margin: auto; padding:20px" toggleable>
|
||||
<form @submit.prevent="productValueModifier">
|
||||
<IftaLabel>
|
||||
<AutoComplete inputId="reference" name="reference" optionLabel="reference" variant="filled" :suggestions="filteredRef" v-model="selectedRef" @complete="search"></AutoComplete>
|
||||
<label for="reference">Reference</label>
|
||||
</IftaLabel>
|
||||
<IftaLabel>
|
||||
<InputNumber inputId="number-value" showButtons v-model="newValue" mode="decimal"></InputNumber>
|
||||
<label for="number-value">Ajouter/Soustraire</label>
|
||||
</IftaLabel>
|
||||
<Button
|
||||
label="update"
|
||||
type="submit"
|
||||
class="p-button-primary"> </Button>
|
||||
</form>
|
||||
<Carousel :value="products"
|
||||
:numVisible="3"
|
||||
:numScroll="1"
|
||||
@ -106,6 +167,7 @@ onMounted(async () => {
|
||||
<Tag severity="info" value="STOCK OK" rounded> </Tag>
|
||||
</span>
|
||||
<p>{{ slotProps.data.name }}</p>
|
||||
<p>{{ slotProps.data.reference }}</p>
|
||||
<p>{{ slotProps.data.quantity }}</p>
|
||||
<img :src="slotProps.data.image" alt="" style="border-radius: 8px; width: 150px;">
|
||||
</template>
|
||||
|
@ -29,7 +29,8 @@ const productDescription = ref('');
|
||||
const productQuantity = ref(0);
|
||||
const productAlert = ref(false);
|
||||
const productStockLimit = ref(null);
|
||||
const base64Image = ref(null);
|
||||
const b64Img = ref(null);
|
||||
const b64Modif = ref(null);
|
||||
const selectedWarehouses = ref([]);
|
||||
|
||||
const registerErrors = ref({});
|
||||
@ -51,7 +52,7 @@ async function create_product() {
|
||||
quantity: productQuantity.value,
|
||||
alert_enabled: productAlert.value,
|
||||
stock_limit: productStockLimit.value,
|
||||
image: base64Image.value,
|
||||
image: b64Img.value,
|
||||
warehouses: selectedWarehouses.value.map((warehouse) => warehouse.id),
|
||||
});
|
||||
warehouses.value = await getWarehouses();
|
||||
@ -88,10 +89,19 @@ function resetForms() {
|
||||
productQuantity.value = 0;
|
||||
productAlert.value = false;
|
||||
productStockLimit.value = null;
|
||||
base64Image.value = null;
|
||||
b64Img.value = null;
|
||||
b64Modif.value = null;
|
||||
selectedWarehouses.value = [];
|
||||
};
|
||||
|
||||
function resetImg(modifImg = false){
|
||||
if (modifImg){
|
||||
b64Modif.value = null;
|
||||
return
|
||||
}
|
||||
b64Img.value = null;
|
||||
};
|
||||
|
||||
async function onRowEditSave(event) {
|
||||
if (event && event.data) {
|
||||
let {newData, index} = event;
|
||||
@ -103,17 +113,30 @@ async function onRowEditSave(event) {
|
||||
return;
|
||||
}
|
||||
modifyErrors.value[newData.id] = {};
|
||||
let tableDatas = {}
|
||||
console.log(b64Modif)
|
||||
try {
|
||||
await modifyProduct({
|
||||
id: newData.id,
|
||||
name: newData.name,
|
||||
reference: newData.reference,
|
||||
description: newData.description,
|
||||
quantity: newData.quantity,
|
||||
image: base64Image.value,
|
||||
warehouses: newData.warehouse.map((warehouse) => warehouse.id),
|
||||
},
|
||||
newData.id);
|
||||
if (b64Modif.value){
|
||||
tableDatas = {
|
||||
id: newData.id,
|
||||
name: newData.name,
|
||||
reference: newData.reference,
|
||||
description: newData.description,
|
||||
quantity: newData.quantity,
|
||||
image: b64Modif.value,
|
||||
warehouses: newData.warehouse.map((warehouse) => warehouse.id),
|
||||
}
|
||||
} else {
|
||||
tableDatas = {
|
||||
id: newData.id,
|
||||
name: newData.name,
|
||||
reference: newData.reference,
|
||||
description: newData.description,
|
||||
quantity: newData.quantity,
|
||||
warehouses: newData.warehouse.map((warehouse) => warehouse.id),
|
||||
}
|
||||
}
|
||||
await modifyProduct(tableDatas,newData.id);
|
||||
warehouses.value = await getWarehouses();
|
||||
products.value = await getProducts();
|
||||
products.value = enrichProducts();
|
||||
@ -199,12 +222,16 @@ const truncate = (text, length) => {
|
||||
}
|
||||
return text;
|
||||
};
|
||||
const handleFileUpload = (event) => {
|
||||
const handleFileUpload = (event, iscreated) => {
|
||||
const file = event.files[0];
|
||||
if (!file) return;
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
base64Image.value = reader.result;
|
||||
if (iscreated){
|
||||
b64Img.value = reader.result;
|
||||
} else {
|
||||
b64Modif.value = reader.result;
|
||||
}
|
||||
toast.add({ severity: 'success', life: 2500, summary: 'Image ajouté avec succès.' });
|
||||
};
|
||||
reader.onerror = () => {
|
||||
@ -328,17 +355,21 @@ try {
|
||||
<div class="form">
|
||||
<InputGroup >
|
||||
<InputGroupAddon>Image :</InputGroupAddon>
|
||||
<FileUpload
|
||||
name="productImage"
|
||||
accept="image/*"
|
||||
mode="basic"
|
||||
customUpload
|
||||
:auto="true"
|
||||
:multiple="false"
|
||||
:maxFileSize="1000000"
|
||||
:chooseLabel="'Choisir une image'"
|
||||
@uploader="handleFileUpload"
|
||||
/>
|
||||
<InputGroupAddon v-if="b64Img">
|
||||
<img :src="b64Img" alt="Image" style="width: 6rem">
|
||||
<Button icon="pi pi-times" severity="secondary" @click="resetForms()"/>
|
||||
</InputGroupAddon>
|
||||
<FileUpload
|
||||
name="productImage"
|
||||
accept="image/*"
|
||||
mode="basic"
|
||||
customUpload
|
||||
:auto="true"
|
||||
:multiple="false"
|
||||
:maxFileSize="1000000"
|
||||
:chooseLabel="'Choisir une image'"
|
||||
@uploader="handleFileUpload($event,true)"
|
||||
/>
|
||||
</InputGroup>
|
||||
</div>
|
||||
<div class="form">
|
||||
@ -423,7 +454,7 @@ try {
|
||||
style="width: 6rem"
|
||||
/>
|
||||
</template>
|
||||
<template #editor>
|
||||
<template #editor="slotProps">
|
||||
<FileUpload
|
||||
name="editProductImage"
|
||||
accept="image/*"
|
||||
@ -433,10 +464,17 @@ try {
|
||||
:multiple="false"
|
||||
:maxFileSize="1000000"
|
||||
:chooseLabel='"modifier image"'
|
||||
@uploader="handleFileUpload"
|
||||
@uploader="handleFileUpload($event,false)"
|
||||
>
|
||||
</FileUpload>
|
||||
</template>
|
||||
<div v-if="b64Modif">
|
||||
<img :src="b64Modif" alt="Image" style="width: 6rem">
|
||||
<Button icon="pi pi-times" severity="secondary" @click="resetImg(true)"/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<img :src="slotProps.data.image" alt="Image" style="width: 6rem;">
|
||||
</div>
|
||||
</template>
|
||||
</Column>
|
||||
|
||||
<Column field="is_stock_low" header="Stock" sortable>
|
||||
|
Loading…
x
Reference in New Issue
Block a user