Various fixes and improvements

This commit is contained in:
Léo 2025-02-06 18:17:16 +01:00
parent 8cc15870d8
commit 9c54bd1025
3 changed files with 132 additions and 34 deletions

View File

@ -31,6 +31,4 @@ h1 {
#app { #app {
max-width: 1600px; max-width: 1600px;
margin: 0 auto; margin: 0 auto;
padding: 2rem;
text-align: center;
} }

View File

@ -4,15 +4,25 @@ import Chart from 'primevue/chart';
import Fieldset from 'primevue/fieldset'; import Fieldset from 'primevue/fieldset';
import MeterGroup from 'primevue/metergroup'; import MeterGroup from 'primevue/metergroup';
import Carousel from 'primevue/carousel'; import Carousel from 'primevue/carousel';
import { getProducts,getWarehouses } from '../api.js'; import { getProducts,getWarehouses, modifyProduct } from '../api.js';
import Tag from 'primevue/tag'; 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 products = ref();
const warehouses = ref(); const warehouses = ref();
const selectedRef = ref()
const filteredRef = ref();
const newValue = ref();
const chartProductsData = ref(); const chartProductsData = ref();
const chartWarehousesData = ref(); const chartWarehousesData = ref();
const chartOptions = {plugins:{legend:{labels:{usePointStyle:true,}}}}; const chartOptions = {plugins:{legend:{labels:{usePointStyle:true,}}}};
const productColors = {}; const productColors = {};
const warehouseColors ={};
const colorsSchemes = [ const colorsSchemes = [
"#40407a", "#706fd3", "#f7f1e3", "#34ace0", "#40407a", "#706fd3", "#f7f1e3", "#34ace0",
"#33d9b2", "#2c2c54", "#474787", "#aaa69d", "#33d9b2", "#2c2c54", "#474787", "#aaa69d",
@ -38,6 +48,13 @@ const getColorForProduct = (productName) => {
} }
return productColors[productName]; return productColors[productName];
}; };
const getColorForWarehouse = (warehouseName) => {
if (!warehouseColors[warehouseName]) {
warehouseColors[warehouseName] = colorsSchemes[Object.keys(warehouseColors).length % colorsSchemes.length];
}
return warehouseColors[warehouseName];
};
const setChartProductsData = () => { const setChartProductsData = () => {
@ -61,8 +78,8 @@ const setChartWarehousesData = () =>{
datasets: [ datasets: [
{ {
label: 'Capacité', label: 'Capacité',
backgroundColor: products.value.map(product => `${getColorForProduct(product.name)}80`), backgroundColor: warehouses.value.map(warehouse => `${getColorForWarehouse(warehouse.name)}80`),
borderColor : products.value.map(product => getColorForProduct(product.name)), borderColor : warehouses.value.map(warehouse => getColorForWarehouse(warehouse.name)),
data: warehouses.value.map(warehouse => warehouse.max_capacity), data: warehouses.value.map(warehouse => warehouse.max_capacity),
borderWidth: 1 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 () => { onMounted(async () => {
warehouses.value = await getWarehouses(); warehouses.value = await getWarehouses();
products.value = await getProducts(); products.value = await getProducts();
chartProductsData.value = setChartProductsData(); chartProductsData.value = setChartProductsData();
chartWarehousesData.value = setChartWarehousesData(); 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> </script>
<template> <template>
<Fieldset legend="Produits stockés" style="max-width: 600px; margin: auto; padding:20px" toggleable> <Fieldset legend="Produits stockés" style="max-width: 600px; margin: auto; padding:20px" toggleable>
<Chart type="pie" :data="chartProductsData" :options="chartOptions"></Chart> <Chart type="pie" :data="chartProductsData" :options="chartOptions"></Chart>
</Fieldset> </Fieldset>
@ -94,6 +141,20 @@ onMounted(async () => {
</ul> </ul>
</Fieldset> </Fieldset>
<Fieldset legend="Products" style="max-width: 600px; margin: auto; padding:20px" toggleable> <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" <Carousel :value="products"
:numVisible="3" :numVisible="3"
:numScroll="1" :numScroll="1"
@ -106,6 +167,7 @@ onMounted(async () => {
<Tag severity="info" value="STOCK OK" rounded> </Tag> <Tag severity="info" value="STOCK OK" rounded> </Tag>
</span> </span>
<p>{{ slotProps.data.name }}</p> <p>{{ slotProps.data.name }}</p>
<p>{{ slotProps.data.reference }}</p>
<p>{{ slotProps.data.quantity }}</p> <p>{{ slotProps.data.quantity }}</p>
<img :src="slotProps.data.image" alt="" style="border-radius: 8px; width: 150px;"> <img :src="slotProps.data.image" alt="" style="border-radius: 8px; width: 150px;">
</template> </template>

View File

@ -29,7 +29,8 @@ const productDescription = ref('');
const productQuantity = ref(0); const productQuantity = ref(0);
const productAlert = ref(false); const productAlert = ref(false);
const productStockLimit = ref(null); const productStockLimit = ref(null);
const base64Image = ref(null); const b64Img = ref(null);
const b64Modif = ref(null);
const selectedWarehouses = ref([]); const selectedWarehouses = ref([]);
const registerErrors = ref({}); const registerErrors = ref({});
@ -51,7 +52,7 @@ async function create_product() {
quantity: productQuantity.value, quantity: productQuantity.value,
alert_enabled: productAlert.value, alert_enabled: productAlert.value,
stock_limit: productStockLimit.value, stock_limit: productStockLimit.value,
image: base64Image.value, image: b64Img.value,
warehouses: selectedWarehouses.value.map((warehouse) => warehouse.id), warehouses: selectedWarehouses.value.map((warehouse) => warehouse.id),
}); });
warehouses.value = await getWarehouses(); warehouses.value = await getWarehouses();
@ -88,10 +89,19 @@ function resetForms() {
productQuantity.value = 0; productQuantity.value = 0;
productAlert.value = false; productAlert.value = false;
productStockLimit.value = null; productStockLimit.value = null;
base64Image.value = null; b64Img.value = null;
b64Modif.value = null;
selectedWarehouses.value = []; selectedWarehouses.value = [];
}; };
function resetImg(modifImg = false){
if (modifImg){
b64Modif.value = null;
return
}
b64Img.value = null;
};
async function onRowEditSave(event) { async function onRowEditSave(event) {
if (event && event.data) { if (event && event.data) {
let {newData, index} = event; let {newData, index} = event;
@ -103,17 +113,30 @@ async function onRowEditSave(event) {
return; return;
} }
modifyErrors.value[newData.id] = {}; modifyErrors.value[newData.id] = {};
let tableDatas = {}
console.log(b64Modif)
try { try {
await modifyProduct({ if (b64Modif.value){
id: newData.id, tableDatas = {
name: newData.name, id: newData.id,
reference: newData.reference, name: newData.name,
description: newData.description, reference: newData.reference,
quantity: newData.quantity, description: newData.description,
image: base64Image.value, quantity: newData.quantity,
warehouses: newData.warehouse.map((warehouse) => warehouse.id), image: b64Modif.value,
}, warehouses: newData.warehouse.map((warehouse) => warehouse.id),
newData.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(); warehouses.value = await getWarehouses();
products.value = await getProducts(); products.value = await getProducts();
products.value = enrichProducts(); products.value = enrichProducts();
@ -199,12 +222,16 @@ const truncate = (text, length) => {
} }
return text; return text;
}; };
const handleFileUpload = (event) => { const handleFileUpload = (event, iscreated) => {
const file = event.files[0]; const file = event.files[0];
if (!file) return; if (!file) return;
const reader = new FileReader(); const reader = new FileReader();
reader.onload = () => { 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.' }); toast.add({ severity: 'success', life: 2500, summary: 'Image ajouté avec succès.' });
}; };
reader.onerror = () => { reader.onerror = () => {
@ -328,17 +355,21 @@ try {
<div class="form"> <div class="form">
<InputGroup > <InputGroup >
<InputGroupAddon>Image :</InputGroupAddon> <InputGroupAddon>Image :</InputGroupAddon>
<FileUpload <InputGroupAddon v-if="b64Img">
name="productImage" <img :src="b64Img" alt="Image" style="width: 6rem">
accept="image/*" <Button icon="pi pi-times" severity="secondary" @click="resetForms()"/>
mode="basic" </InputGroupAddon>
customUpload <FileUpload
:auto="true" name="productImage"
:multiple="false" accept="image/*"
:maxFileSize="1000000" mode="basic"
:chooseLabel="'Choisir une image'" customUpload
@uploader="handleFileUpload" :auto="true"
/> :multiple="false"
:maxFileSize="1000000"
:chooseLabel="'Choisir une image'"
@uploader="handleFileUpload($event,true)"
/>
</InputGroup> </InputGroup>
</div> </div>
<div class="form"> <div class="form">
@ -423,7 +454,7 @@ try {
style="width: 6rem" style="width: 6rem"
/> />
</template> </template>
<template #editor> <template #editor="slotProps">
<FileUpload <FileUpload
name="editProductImage" name="editProductImage"
accept="image/*" accept="image/*"
@ -433,10 +464,17 @@ try {
:multiple="false" :multiple="false"
:maxFileSize="1000000" :maxFileSize="1000000"
:chooseLabel='"modifier image"' :chooseLabel='"modifier image"'
@uploader="handleFileUpload" @uploader="handleFileUpload($event,false)"
> >
</FileUpload> </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>
<Column field="is_stock_low" header="Stock" sortable> <Column field="is_stock_low" header="Stock" sortable>