Transition complète vers jQuery

This commit is contained in:
FyloZ 2020-02-26 21:02:25 -05:00
parent 54b4751eb6
commit 43ae9f1222
21 changed files with 123 additions and 331 deletions

View File

@ -180,23 +180,16 @@ function showConfirm(value, prompt = false, continueCallback = () => {
}) {
const filter = $("#filter");
const node = prompt ? $(promptMsg) : $(confirmMsg);
const nodeInput = prompt ? node.find("#confirmInput") : $("");
const nodeInput = prompt ? node.find("#confirmInput") : undefined;
if (prompt) {
nodeInput.val("");
// Ne fonctionne pas sans
setTimeout(function () {
nodeInput.focus();
}, 0);
}
if (prompt) nodeInput.val("");
showMessage(node, value, false);
filter.show();
filter.animate({opacity: 0.5}, messageBoxesAnimationTime);
setTimeout(() => {
nodeInput.on({
$("body").on({
keyup: function (e) {
if (e.which === 13) { // Enter
confirmContinue(node, continueCallback);
@ -215,6 +208,8 @@ function showConfirm(value, prompt = false, continueCallback = () => {
confirmCancel(node, cancelCallback)
}
});
if (nodeInput) nodeInput.focus();
}, 100);
}

View File

@ -1,4 +1,4 @@
import * as bpac from "/js/bpac.js";
import * as bpac from "/js/libs/bpac.js";
export class PtouchPrinter {
constructor(object) {

View File

@ -1,64 +1,72 @@
(() => {
document.querySelectorAll(".recipeRow").forEach(e => {
if (e.dataset.approbationdate === undefined) {
e.classList.add("unapproved");
e.title = recipeNotApproved;
$(() => {
$(".recipeRow").each(function () {
if (!$(this).data("approbationdate")) {
$(this).addClass("unapproved");
$(this).attr({title: recipeNotApproved})
}
});
})();
});
function closeTabs() {
document.querySelectorAll(".recipesList").forEach(l => l.style.display = "none");
$(".recipesList").each(function () {
$(this).hide();
});
}
function openTabs() {
document.querySelectorAll(".recipesList").forEach(l => l.style.display = "");
$(".recipesList").each(function () {
$(this).show();
});
}
const companyRows = document.querySelectorAll(".companyTab");
const companyRows = $(".companyTab");
function performSearch(searchString) {
let found = false;
let emptySearch = false;
const recipesContainer = document.querySelector(".recipesContainer:not(.researchEnabled)");
if (recipesContainer !== undefined && recipesContainer !== null) {
recipesContainer.classList.add("researchEnabled");
}
const recipesContainer = $(".recipesContainer:not(.researchEnabled)");
if (recipesContainer) recipesContainer.addClass("researchEnabled");
document.querySelectorAll(".researchResult").forEach(t => {
t.classList.remove("researchResult");
});
companyRows.forEach(c => {
const recipeRows = c.querySelectorAll(".recipeRow");
companyRows.each(function () {
const company = $(this);
const recipeRows = company.find(".recipeRow");
if (!searchString || !searchString.replace(/\s/g, '').length) {
c.classList.add("researchResult");
if (!searchString || !searchString.replace(/\s/g, '').length) { // Si la recherche est vide
company.addClass("researchResult");
recipeRows.forEach(r => {
r.classList.add("researchResult");
recipeRows.each(function () {
$(this).addClass("researchResult");
});
found = true;
emptySearch = true;
} else if (searchIn(searchString, company.find("h2").text())) { // Si la recherche correspondant à une bannière
company.addClass("researchResult");
recipeRows.each(function () {
$(this).addClass("researchResult");
});
found = true;
} else { // Sinon on fait une recherche dans les recettes
recipeRows.each(function () {
const recipe = $(this);
$(this).find(".descriptionCell").each(function () {
if (searchIn(searchString, $(this).text())) {
company.addClass("researchResult");
recipe.addClass("researchResult");
found = true;
}
});
found = true;
emptySearch = true;
} else if (searchIn(searchString, c.querySelector("h2").textContent)) {
c.classList.add("researchResult");
recipeRows.forEach(r => r.classList.add("researchResult"));
found = true;
} else {
recipeRows.forEach(r => {
r.querySelectorAll(".descriptionCell").forEach(d => {
if (searchIn(searchString, d.textContent)) {
r.classList.add("researchResult");
c.classList.add("researchResult");
found = true;
}
});
});
}
});
}
);
});
if (!found) showMessage(warningMsg, researchNotFound, false);
else hideMessage(warningMsg);

View File

@ -22,6 +22,5 @@
<!-- Fragment du pied de page -->
<footer th:include="fragments.html :: footer(null, true)"></footer>
</body>
</html>

View File

@ -151,90 +151,79 @@
const defaultLowQuantity = 100;
(() => {
const materialRows = $(".materialRow");
$(() => {
// Rajoute un événement sur les boutons pour modifier les produits pour rediriger l'utilisateur vers la page de modification
document.querySelectorAll(".modifyMaterial").forEach(e => {
e.addEventListener("click", () => {
window.location.href = `/material/editor/${e.dataset.materialid}`;
});
$(".modifyMaterial").on({
click: function () {
window.location.href = `/material/editor/${$(this).data("materialid")}`;
}
});
document.querySelector("#lowQuantity").value = defaultLowQuantity;
checkLowQuantity(defaultLowQuantity)
})();
$("#lowQuantity").val(defaultLowQuantity);
checkLowQuantity(defaultLowQuantity);
});
// Ajoute la classe "lowQuantity" au produits qui ont une quantité en inventaire inférieur à la quantité limite définie
function checkLowQuantity(value) {
document.querySelectorAll(".materialRow").forEach(e => {
if (parseFloat(e.querySelector(".inventoryQuantity").innerHTML) < value) {
e.classList.add("lowQuantity");
} else {
e.classList.remove("lowQuantity");
}
hide(document.querySelector("#hideOthers").checked);
materialRows.each(function () {
if (parseFloat($(this).find(".inventoryQuantity").text()) < value) $(this).addClass("lowQuantity");
else $(this).removeClass("lowQuantity");
});
hide($("#hideOthers").attr("checked"));
}
// Cache ou dévoile les produits qui ont la classe "lowQuantity", dépendamment du paramètre "checked"
function hide(checked) {
if (checked) {
document.querySelectorAll(".materialRow").forEach(e => {
if (!e.classList.contains("lowQuantity")) {
e.classList.add("hidden");
} else {
e.classList.remove("hidden");
}
materialRows.each(function () {
if ($(this).hasClass("lowQuantity")) $(this).addClass("hidden");
else $(this).removeClass("hidden");
});
} else {
document.querySelectorAll(".hidden").forEach(e => {
e.classList.remove("hidden");
$(".hidden").each(function () {
$(this).removeClass("hidden");
});
}
}
// Cache les produits qui ne sont pas du type de produit spécifié dans le paramètre "select", si le type de produit n'est pas "Aucun"
function hideMaterialTypes(select) {
const value = select.value;
const anyValue = document.querySelector("#anyTypeId").value;
select = $(select);
document.querySelectorAll(".materialRow").forEach(e => {
if (value !== anyValue && e.dataset.materialtype !== value) {
e.classList.add("hiddenWrongType");
} else {
e.classList.remove("hiddenWrongType");
}
const value = parseInt(select.val());
const anyValue = parseInt($("#anyTypeId").val());
materialRows.each(function () {
if (value !== anyValue && parseInt($(this).data("materialtype")) !== value) $(this).addClass("hiddenWrongType");
else $(this).removeClass("hiddenWrongType");
});
}
const materialRows = document.querySelectorAll(".materialRow");
function performSearch(searchString) {
let found = false;
const recipesContainer = document.querySelector(".materialsContainer:not(.researchEnabled)");
if (recipesContainer !== undefined && recipesContainer !== null) {
recipesContainer.classList.add("researchEnabled");
const materialsContainer = $(".materialsContainer:not(.researchEnabled)");
if (materialsContainer) {
materialsContainer.addClass("researchEnabled");
}
document.querySelectorAll(".researchResult").forEach(t => {
t.classList.remove("researchResult");
$(".researchResult").each(function () {
$(this).removeClass("researchResult");
});
materialRows.forEach(row => {
materialRows.each(function () {
if (!searchString || !searchString.replace(/\s/g, '').length) {
row.classList.add("researchResult");
$(this).addClass("researchResult");
found = true;
} else {
const materialCode = row.querySelector(".materialCode").textContent;
const materialType = row.querySelector(".materialType").textContent;
const materialCode = $(this).find(".materialCode").text();
const materialType = $(this).find(".materialType").text();
if (searchIn(searchString, materialCode) || searchIn(searchString, materialType)) {
row.classList.add("researchResult");
$(this).addClass("researchResult");
found = true;
}
}

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html lang="fr" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="fragments.html :: head(#{material.add.title}, null)"></th:block>
<link href="/css/main.css" rel="stylesheet"/>
</head>
<body>
<!-- Fragment de l'entête -->
<header th:include="fragments.html :: header(false)"></header>
<!-- Corps de la page -->
<section>
<p th:text="#{material.success.created(${name})}"></p>
<h1 th:text="#{material.add.title}"></h1>
<button class="returnButton" th:text="#{keyword.back}"></button>
</section>
<!-- Fragment du pied de page -->
<footer th:include="fragments.html :: footer(null, true)"></footer>
</body>
</html>

View File

@ -87,9 +87,11 @@
<script>
function switchUnits(unitSelect) {
const quantityElem = document.querySelector("#quantity");
quantityElem.dataset.unit = unitSelect.value;
calculateMilliliters(quantityElem.value, unitSelect.value);
unitSelect = $(unitSelect);
const quantityElem = $("#quantity");
quantityElem.data({unit: unitSelect.val()});
calculateMilliliters(quantityElem.val(), unitSelect.val());
}
function calculateMilliliters(quantity, unit) {
@ -106,7 +108,7 @@
break;
}
document.querySelector("#inventoryQuantity").value = convertedQuantity;
$("#inventoryQuantity").val(convertedQuantity);
}
</script>
</body>

View File

@ -48,12 +48,10 @@
<script>
/*<![CDATA[*/
(() => {
document.querySelectorAll(".editor").forEach((e) => {
e.addEventListener("click", () => {
const materialId = e.getAttribute("data-materialId");
window.location.href = "/material/editor/" + materialId;
});
$(".editor").on({
click: function () {
window.location.href = `/material/editor/${$(this).data("materialid")}`;
}
});
})();
/*]]>*/

View File

@ -49,6 +49,5 @@
<!-- Fragment du pied de page -->
<footer th:include="fragments.html :: footer('/material/remover', true)"></footer>
</body>
</html>

View File

@ -30,6 +30,5 @@
<!-- Fragment du pied de page -->
<footer th:include="fragments.html :: footer(null, true)"></footer>
</body>
</html>

View File

@ -58,6 +58,5 @@
<!-- Fragment du pied de page -->
<footer th:include="fragments.html :: footer(null, true)"></footer>
</body>
</html>

View File

@ -59,6 +59,5 @@
<!-- Fragment du pied de page -->
<footer th:include="fragments.html :: footer(null, true)"></footer>
</body>
</html>

View File

@ -46,12 +46,10 @@
<script>
/*<![CDATA[*/
(() => {
document.querySelectorAll(".editor").forEach((e) => {
e.addEventListener("click", () => {
const materialTypeId = e.getAttribute("data-materialTypeId");
window.location.href = "/materialType/editor/" + materialTypeId;
});
$(".editor").on({
click: function () {
window.location.href = `/materialType/editor/${$(this).data("materialtypeid")}`;
}
});
})();
/*]]>*/

View File

@ -49,6 +49,5 @@
<!-- Fragment du pied de page -->
<footer th:include="fragments.html :: footer('/materialType/remover', true)"></footer>
</body>
</html>

View File

@ -1,155 +0,0 @@
<div class="form">
<form th:action="@{/recipe/editor}" th:object="${recipe}" class="requireAuth" method="POST">
<input type="hidden" th:field="*{id}"/>
<table class="mainTable">
<tr>
<td>
<table>
<tr>
<td><b th:text="#{keyword.id} + ':'"></b></td>
<td th:text="${recipe.id}"></td>
</tr>
<tr th:include="fragments.html :: separator"></tr>
<tr>
<td><b><label th:for="${#ids.next('name')}"
th:text="#{recipe.color} + ':'"></label></b></td>
<td><input type="text" th:field="*{name}"></td>
</tr>
<tr th:include="fragments.html :: separator"></tr>
<tr>
<td><b><label th:for="${#ids.next('company')}"
th:text="#{keyword.company} + ':'"></label></b>
</td>
<td>
<select th:field="*{company}">
<option th:each="company : ${companies}"
th:selected="${recipe.company.equals(company)}"
th:text="${company.name}"
th:value="${company.id}"></option>
</select>
</td>
</tr>
<tr th:include="fragments.html :: separator"></tr>
<tr>
<td><b><label th:for="${#ids.next('description')}"
th:text="#{recipe.description} + ':'"></label></b></td>
<td><input type="text" th:field="*{description}"/></td>
</tr>
<tr th:include="fragments.html :: separator"></tr>
<tr>
<td><b><label th:for="${#ids.next('sample')}" th:text="#{recipe.sample} + ':'"></label></b>
</td>
<td><input type="number" th:field="*{sample}"/></td>
</tr>
<tr th:include="fragments.html :: separator"></tr>
<tr>
<td><b><label th:for="${#ids.next('approbationDate')}"
th:text="#{recipe.approbationDate} + ':'"></label></b></td>
<td><input type="date" th:field="*{approbationDate}"/></td>
</tr>
<tr th:include="fragments.html :: separator"></tr>
<tr>
<td><b><label th:for="${#ids.next('remark')}" th:text="#{recipe.remark} + ':'"></label></b>
</td>
<td><textarea cols="20" rows="2" th:field="*{remark}"></textarea>
</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td colspan="2" style="height: 40px; text-align: right">
<button id="newMix" type="button" th:text="#{recipe.edit.addMix}"></button>
</td>
</tr>
<th:block th:each="mix : ${mixes}">
<tr>
<td class="mixNameColumn">
<b th:text="${mix.mixType.name} + ':'"></b>
<br/>
<th:block th:if="${mix != null}">
<button class="mixEditor" th:data-mixId="${mix.id}" type="button"
th:text="#{keyword.edit}"></button>
</th:block>
</td>
<td>
<div class="recipe">
<table style="margin-left: 50px">
<!-- Produits -->
<tr>
<th th:text="#{keyword.material}"></th>
<th th:text="#{keyword.type}"></th>
<th th:text="#{keyword.quantity}"></th>
</tr>
<tr th:each="mixQuantity : ${mix.mixQuantities}"
th:with="material = ${mixQuantity.material}">
<td th:classappend="${material.isMixType()} ? '' : name"
th:data-materialId="${material.id}"
th:text="${material.name}"></td>
<td>
<p th:text="${material.materialType.name}"></p>
</td>
<td th:text="${mixQuantity.quantity} + ' ' + ${material.materialType.usePercentages ? '%' : 'mL'}"></td>
</tr>
</table>
</div>
</td>
</tr>
<tr th:include="fragments.html :: separator"></tr>
</th:block>
</table>
</td>
</tr>
<tr>
<td>
<!-- Images -->
<table>
<tr th:each="image : ${images}">
<td class="centerTD">
<img alt="Image supprimée ou corrompue" th:src="'/images/' + ${image}"
height="250px"/>
</td>
<td style="text-align: left; padding-left: 50px">
<button class="deleteImg" th:data-image="${image}" type="button"
style="height: 250px">
<span th:text="#{keyword.delete}"
style="display: inline-block; transform: rotate(90deg); font-weight: bolder"></span>
</button>
</td>
</tr>
</table>
</td>
<td>
<!-- Étapes -->
<table>
<tr>
<td style="text-align: center">
<h3 th:text="#{recipe.steps}"></h3>
</td>
<td style="text-align: left; vertical-align: middle; padding-left: 20px">
<button id="addStep" type="button">+</button>
</td>
<td style="width: 100%"></td>
</tr>
<tr>
<td colspan="3">
<table id="steps" style="width:100%">
<tbody></tbody>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<button id="addImg" th:data-recipeId="${recipe.id}" type="button"
th:text="#{recipe.edit.addImage}"></button>
</td>
</tr>
<tr th:include="fragments.html :: mainTableButtons"></tr>
</table>
</form>
</div>

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html lang="fr" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="fragments.html :: head(#{recipe.add.title}, null)"></th:block>
</head>
<body>
<!-- Fragment de l'entête -->
<header th:include="fragments.html :: header"></header>
<!-- Corps de la page -->
<section>
<div th:include="fragments.html :: messages"></div>
<h1 th:text="#{recipe.add.title}"></h1>
<p th:text="#{recipe.sucess.saved(${recipe.recipeCode})}"></p>
<button th:onclick="'document.location.href=\'/recipe/editor/' + ${recipe.recipeID} + '\''"
th:text="#{keyword.continue}"></button>
</section>
<!-- Fragment du pied de page -->
<footer th:include="fragments.html :: footer(null, true)"></footer>
</body>
</html>

View File

@ -67,6 +67,5 @@
<!-- Fragment du pied de page -->
<footer th:include="fragments.html :: footer(null, true)"></footer>
</body>
</html>

View File

@ -260,7 +260,7 @@
.attr({
for: input.attr("id")
})
.text(`${stepNbr + 1}`);
.text(`${stepNbr + 1}. `);
const deleteButton = $("<button></button>")
.attr({

View File

@ -25,20 +25,17 @@
<!-- Fragment du pied de page -->
<footer th:include="fragments.html :: footer(null, true)"></footer>
<script>
/*<![CDATA[*/
window.addEventListener("load", e => {
$(() => {
axios.get("updates/get")
.then(r => {
document.querySelector("#markdown").innerHTML = r.data;
$("#markdown").html(r.data);
})
.catch(e => {
showMessage(errorMsg, generalErrorText);
console.log(e);
});
});
/*]]>*/
</script>
</body>
</html>

View File

@ -1,8 +1,23 @@
# v1.3.0 (Optimisations back-end)
### Note: Cette mise à jour n'est pas compatible avec les anciennes versions.
### Corrections
* Réusinage des modèles. (Empêche la compatibilité avec les anciennes versions)
* Réusinage des contrôleurs et des services (Améliore la maintenabilité)
* Réusinage des modèles. (Améliore la maintenabilité, empêche la compatibilité avec les anciennes versions)
* Réusinage des contrôleurs et des services. (Améliore la maintenabilité et permet d'avoir des messages d'erreur plus précis)
* La recherche de produit dans les sélecteurs de produits dans l'éditeur de mélange est fonctionnelle.
* Correction de quelques bugs visuels dans les menus et l'éditeur de mélange.
* Les caractères spéciaux sont maintenant affichés correctement dans les PDFs et les étiquettes P-touch.
### Ajouts
* Les boites de texte des boites de confirmation prennent le focus automatiquement.
* Appuyez sur Entrer (Enter) lorsqu'une boite de confirmation est présente aura le même effet qu'appuyer sur Continuer.
* Appuyez sur Échapper (Esc) lorsqu'un boite de confirmation est présente aura le même effet qu'appuyer sur Annuler.
* Il n'est plus possible de créer des mélanges dont le type est le même qu'un produit. (Permet d'éviter les conflits)
* Ajout des types de produit par défaut.
* Ceux-ci ne peuvent pas être modifiés ou supprimés.
* Ils peuvent être configurés dans les propriétés du serveur.
### Dépendances
* Transition complète vers jQuery.
# v1.2.0 (Imprimante P-touch)
### Corrections
@ -30,7 +45,7 @@
### Dépendances
* Ajout de jQuery, début de la transition.
* Migration vers Java 11
* Migration vers Java 11.
# v1.1.3
### Corrections