This commit is contained in:
Philippe Torrel
2026-07-24 13:31:30 +02:00
parent c118892017
commit e5c2f47063
19 changed files with 1380 additions and 659 deletions

View File

@@ -1,9 +1,344 @@
(() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
try {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
} catch (e) {
throw mod = 0, e;
}
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// node_modules/toastify-js/src/toastify.js
var require_toastify = __commonJS({
"node_modules/toastify-js/src/toastify.js"(exports, module) {
(function(root, factory) {
if (typeof module === "object" && module.exports) {
module.exports = factory();
} else {
root.Toastify = factory();
}
})(exports, function(global) {
var Toastify2 = function(options) {
return new Toastify2.lib.init(options);
}, version = "1.12.0";
Toastify2.defaults = {
oldestFirst: true,
text: "Toastify is awesome!",
node: void 0,
duration: 3e3,
selector: void 0,
callback: function() {
},
destination: void 0,
newWindow: false,
close: false,
gravity: "toastify-top",
positionLeft: false,
position: "",
backgroundColor: "",
avatar: "",
className: "",
stopOnFocus: true,
onClick: function() {
},
offset: { x: 0, y: 0 },
escapeMarkup: true,
ariaLive: "polite",
style: { background: "" }
};
Toastify2.lib = Toastify2.prototype = {
toastify: version,
constructor: Toastify2,
// Initializing the object with required parameters
init: function(options) {
if (!options) {
options = {};
}
this.options = {};
this.toastElement = null;
this.options.text = options.text || Toastify2.defaults.text;
this.options.node = options.node || Toastify2.defaults.node;
this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify2.defaults.duration;
this.options.selector = options.selector || Toastify2.defaults.selector;
this.options.callback = options.callback || Toastify2.defaults.callback;
this.options.destination = options.destination || Toastify2.defaults.destination;
this.options.newWindow = options.newWindow || Toastify2.defaults.newWindow;
this.options.close = options.close || Toastify2.defaults.close;
this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify2.defaults.gravity;
this.options.positionLeft = options.positionLeft || Toastify2.defaults.positionLeft;
this.options.position = options.position || Toastify2.defaults.position;
this.options.backgroundColor = options.backgroundColor || Toastify2.defaults.backgroundColor;
this.options.avatar = options.avatar || Toastify2.defaults.avatar;
this.options.className = options.className || Toastify2.defaults.className;
this.options.stopOnFocus = options.stopOnFocus === void 0 ? Toastify2.defaults.stopOnFocus : options.stopOnFocus;
this.options.onClick = options.onClick || Toastify2.defaults.onClick;
this.options.offset = options.offset || Toastify2.defaults.offset;
this.options.escapeMarkup = options.escapeMarkup !== void 0 ? options.escapeMarkup : Toastify2.defaults.escapeMarkup;
this.options.ariaLive = options.ariaLive || Toastify2.defaults.ariaLive;
this.options.style = options.style || Toastify2.defaults.style;
if (options.backgroundColor) {
this.options.style.background = options.backgroundColor;
}
return this;
},
// Building the DOM element
buildToast: function() {
if (!this.options) {
throw "Toastify is not initialized";
}
var divElement = document.createElement("div");
divElement.className = "toastify on " + this.options.className;
if (!!this.options.position) {
divElement.className += " toastify-" + this.options.position;
} else {
if (this.options.positionLeft === true) {
divElement.className += " toastify-left";
console.warn("Property `positionLeft` will be depreciated in further versions. Please use `position` instead.");
} else {
divElement.className += " toastify-right";
}
}
divElement.className += " " + this.options.gravity;
if (this.options.backgroundColor) {
console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
}
for (var property in this.options.style) {
divElement.style[property] = this.options.style[property];
}
if (this.options.ariaLive) {
divElement.setAttribute("aria-live", this.options.ariaLive);
}
if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
divElement.appendChild(this.options.node);
} else {
if (this.options.escapeMarkup) {
divElement.innerText = this.options.text;
} else {
divElement.innerHTML = this.options.text;
}
if (this.options.avatar !== "") {
var avatarElement = document.createElement("img");
avatarElement.src = this.options.avatar;
avatarElement.className = "toastify-avatar";
if (this.options.position == "left" || this.options.positionLeft === true) {
divElement.appendChild(avatarElement);
} else {
divElement.insertAdjacentElement("afterbegin", avatarElement);
}
}
}
if (this.options.close === true) {
var closeElement = document.createElement("button");
closeElement.type = "button";
closeElement.setAttribute("aria-label", "Close");
closeElement.className = "toast-close";
closeElement.innerHTML = "✖";
closeElement.addEventListener(
"click",
function(event) {
event.stopPropagation();
this.removeElement(this.toastElement);
window.clearTimeout(this.toastElement.timeOutValue);
}.bind(this)
);
var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
divElement.insertAdjacentElement("afterbegin", closeElement);
} else {
divElement.appendChild(closeElement);
}
}
if (this.options.stopOnFocus && this.options.duration > 0) {
var self = this;
divElement.addEventListener(
"mouseover",
function(event) {
window.clearTimeout(divElement.timeOutValue);
}
);
divElement.addEventListener(
"mouseleave",
function() {
divElement.timeOutValue = window.setTimeout(
function() {
self.removeElement(divElement);
},
self.options.duration
);
}
);
}
if (typeof this.options.destination !== "undefined") {
divElement.addEventListener(
"click",
function(event) {
event.stopPropagation();
if (this.options.newWindow === true) {
window.open(this.options.destination, "_blank");
} else {
window.location = this.options.destination;
}
}.bind(this)
);
}
if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
divElement.addEventListener(
"click",
function(event) {
event.stopPropagation();
this.options.onClick();
}.bind(this)
);
}
if (typeof this.options.offset === "object") {
var x = getAxisOffsetAValue("x", this.options);
var y = getAxisOffsetAValue("y", this.options);
var xOffset = this.options.position == "left" ? x : "-" + x;
var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
}
return divElement;
},
// Displaying the toast
showToast: function() {
this.toastElement = this.buildToast();
var rootElement;
if (typeof this.options.selector === "string") {
rootElement = document.getElementById(this.options.selector);
} else if (this.options.selector instanceof HTMLElement || typeof ShadowRoot !== "undefined" && this.options.selector instanceof ShadowRoot) {
rootElement = this.options.selector;
} else {
rootElement = document.body;
}
if (!rootElement) {
throw "Root element is not defined";
}
var elementToInsert = Toastify2.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
rootElement.insertBefore(this.toastElement, elementToInsert);
Toastify2.reposition();
if (this.options.duration > 0) {
this.toastElement.timeOutValue = window.setTimeout(
function() {
this.removeElement(this.toastElement);
}.bind(this),
this.options.duration
);
}
return this;
},
hideToast: function() {
if (this.toastElement.timeOutValue) {
clearTimeout(this.toastElement.timeOutValue);
}
this.removeElement(this.toastElement);
},
// Removing the element from the DOM
removeElement: function(toastElement) {
toastElement.className = toastElement.className.replace(" on", "");
window.setTimeout(
function() {
if (this.options.node && this.options.node.parentNode) {
this.options.node.parentNode.removeChild(this.options.node);
}
if (toastElement.parentNode) {
toastElement.parentNode.removeChild(toastElement);
}
this.options.callback.call(toastElement);
Toastify2.reposition();
}.bind(this),
400
);
}
};
Toastify2.reposition = function() {
var topLeftOffsetSize = {
top: 15,
bottom: 15
};
var topRightOffsetSize = {
top: 15,
bottom: 15
};
var offsetSize = {
top: 15,
bottom: 15
};
var allToasts = document.getElementsByClassName("toastify");
var classUsed;
for (var i = 0; i < allToasts.length; i++) {
if (containsClass(allToasts[i], "toastify-top") === true) {
classUsed = "toastify-top";
} else {
classUsed = "toastify-bottom";
}
var height = allToasts[i].offsetHeight;
classUsed = classUsed.substr(9, classUsed.length - 1);
var offset2 = 15;
var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
if (width <= 360) {
allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
offsetSize[classUsed] += height + offset2;
} else {
if (containsClass(allToasts[i], "toastify-left") === true) {
allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
topLeftOffsetSize[classUsed] += height + offset2;
} else {
allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
topRightOffsetSize[classUsed] += height + offset2;
}
}
}
return this;
};
function getAxisOffsetAValue(axis, options) {
if (options.offset[axis]) {
if (isNaN(options.offset[axis])) {
return options.offset[axis];
} else {
return options.offset[axis] + "px";
}
}
return "0px";
}
function containsClass(elem, yourClass) {
if (!elem || typeof yourClass !== "string") {
return false;
} else if (elem.className && elem.className.trim().split(/\s+/gi).indexOf(yourClass) > -1) {
return true;
} else {
return false;
}
}
Toastify2.lib.init.prototype = Toastify2.lib;
return Toastify2;
});
}
});
// node_modules/@popperjs/core/lib/index.js
var lib_exports = {};
@@ -5164,6 +5499,65 @@
enableDismissTrigger(Toast);
defineJQueryPlugin(Toast);
// dev/scripts/modules/Toast.js
var import_toastify_js = __toESM(require_toastify(), 1);
var Toast2 = (text = "", variant = "primary") => {
const getColorByName = (variant2 = "") => {
let color;
switch (variant2.trim().toLowerCase()) {
case "primary":
color = "#0d6efd";
break;
case "secondary":
color = "#6c757d";
break;
case "warning":
color = "#ffc720";
break;
case "success":
color = "#13653f";
break;
case "info":
color = "#25cff2";
break;
case "error":
case "danger":
color = "#a52834";
break;
case "light":
color = "#babbbc";
break;
case "dark":
color = "#373b3e";
break;
default:
console.warn("variant not found");
color: "white";
}
return color;
};
const show = () => {
(0, import_toastify_js.default)({
text,
duration: 2e3,
className: variant,
gravity: "top",
// `top` or `bottom`
position: "center",
// `left`, `center` or `right`
stopOnFocus: true,
// Prevents dismissing of toast on hover
style: {
background: getColorByName(variant)
}
}).showToast();
};
return {
show
};
};
var Toast_default = Toast2;
// dev/scripts/modules/ProductManager.js
var ProductManager = (el = null) => {
const BASE_URL = "http://127.0.0.1:8000";
@@ -5177,25 +5571,41 @@
inputPrice: module.querySelector(".input-product-price"),
btnAdd: module.querySelector(".button-product-add"),
templateRow: module.querySelector(".template-row"),
// Modal
// Modal Edit
modalEdit: module.querySelector(".modal-edit"),
formEdit: module.querySelector(".form-product-edit"),
inputEditName: module.querySelector(".input-edit-name"),
inputEditPrice: module.querySelector(".input-edit-price"),
inputEditId: module.querySelector(".input-edit-id"),
inputEditPosition: module.querySelector(".input-edit-position")
inputEditPosition: module.querySelector(".input-edit-position"),
btnUpdate: module.querySelector(".button-product-update"),
// Modal Delete
modalDelete: module.querySelector(".modal-delete"),
productName: module.querySelector("strong.product-name"),
btnConfirmDelete: module.querySelector(".button-confirm-delete")
};
console.log(DOM);
const bsModalEdit = new Modal(DOM.modalEdit, {
backdrop: "static",
// true
keyboard: true
});
console.log(DOM);
const bsModalDelete = new Modal(DOM.modalDelete, {
backdrop: "static",
// true
keyboard: true
});
const init = () => {
console.log("init");
initProducts();
DOM.btnAdd.addEventListener("click", onClickAdd);
DOM.btnAdd.disabled = true;
DOM.btnConfirmDelete.addEventListener("click", onClickConfirmDelete);
DOM.formEdit.addEventListener("submit", onSubmitEdit);
window.addEventListener("keyup", onKeyUp);
};
const onKeyUp = (e) => {
DOM.btnAdd.disabled = DOM.inputName.value === "" || DOM.inputPrice.value === "";
};
const onSubmitEdit = (e) => {
e.preventDefault();
@@ -5205,11 +5615,17 @@
_id: DOM.inputEditId.value,
position: DOM.inputEditPosition.value
};
DOM.btnUpdate.querySelector("i").classList.add("fa-spin");
updateProduct(product).then((data) => {
console.log(data);
if (data.success) {
Toast_default(data.msg, "success").show();
DOM.btnUpdate.querySelector("i").classList.remove("fa-spin");
loadProducts();
resetFields();
bsModalEdit.hide();
} else {
Toast_default(data.msg, "error").show();
}
});
};
@@ -5223,7 +5639,9 @@
console.log(data);
if (data.success) {
console.log("add");
Toast_default(data.msg, "success").show();
loadProducts();
resetFields();
}
});
disableNonFunctionalButtons();
@@ -5238,9 +5656,25 @@
};
const onClickRemove = (e) => {
const btnEl = e.currentTarget;
const currentRowEl = parents(btnEl, "tr")[0];
currentRowEl.remove();
disableNonFunctionalButtons();
const currentRow = parents(btnEl, "tr")[0];
const id = currentRow.dataset.id;
const productName = currentRow.querySelector(".td-name").textContent.trim();
DOM.btnConfirmDelete.dataset.id = id;
DOM.productName.textContent = productName;
};
const onClickConfirmDelete = (e) => {
const btnEl = e.currentTarget;
const id = btnEl.dataset.id;
deleteProduct(id).then((data) => {
if (data.success) {
Toast_default(data.msg, "success").show();
bsModalDelete.hide();
loadProducts();
} else {
Toast_default(data.msg, "error").show();
console.error(data);
}
});
};
const onClickMoveUp = (e) => {
const btnEl = e.currentTarget;
@@ -5307,6 +5741,7 @@
const data = await response.json();
return data;
} catch (error) {
Toast_default(error, "error").show();
console.error(error);
return error;
}
@@ -5356,11 +5791,30 @@
return error;
}
};
const deleteProduct = async (id) => {
try {
const response = await fetch(`${BASE_URL}/api/products/${id}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json"
}
});
if (!response.ok) {
throw new Error("Fetch went wrong.");
}
const data = await response.json();
return data;
} catch (error) {
console.error(error);
return error;
}
};
const initProducts = () => {
getProducts().then((products) => {
products.forEach((product) => {
addProduct(product);
});
Toast_default("Init products").show();
disableNonFunctionalButtons();
});
};
@@ -5405,6 +5859,12 @@
DOM.inputEditId.value = id;
DOM.inputEditPosition.value = position;
};
const resetFields = () => {
DOM.btnAdd.disabled = true;
DOM.inputPrice.value = "";
DOM.inputName.value = "";
DOM.formEdit.reset();
};
const disableNonFunctionalButtons = () => {
Array.from(DOM.tBody.querySelectorAll("tr")).forEach((tr) => {
const btnMoveUp = tr.querySelector(".button-product-move-up");
@@ -5423,7 +5883,8 @@
init();
return {
init,
initProducts
initProducts,
resetFields
};
};
var ProductManager_default = ProductManager;
@@ -5456,6 +5917,15 @@
})();
/*! Bundled license information:
toastify-js/src/toastify.js:
(*!
* Toastify js 1.12.0
* https://github.com/apvarun/toastify-js
* @license MIT licensed
*
* Copyright (C) 2018 Varun A P
*)
bootstrap/dist/js/bootstrap.esm.js:
(*!
* Bootstrap v5.3.8 (https://getbootstrap.com/)

File diff suppressed because one or more lines are too long