Bonjour,
Qui peut review ma classe ?
https://pastebin.com/PDY8GJ3J
Bah c'est propre. Perso y'a j'aime bien préfixer les variables d'éléments du dom avec un signe particulier pour mieux m'y retrouver mais franchement c'est cool ton truc.
Le 23 juillet 2023 à 09:47:14 :
Bah c'est propre. Perso y'a j'aime bien préfixer les variables d'éléments du dom avec un signe particulier pour mieux m'y retrouver mais franchement c'est cool ton truc.
C'est à dire ?
Petite liste de conseils :
ta méthode "sleep" pourrait être une fonction helper à part, en dehors de ta classe
c'est pas très propre de commenter des bouts de code "morts", c'est mieux de les supprimer. Si tu doutes sur un morceau de code et que tu veux pouvoir revenir en arrière, utilise Git. Même pour des projets perso.
tu pourrais avoir une méthode unique qui gère les fetch() en utilisant les Promise et l'url de ton endpoint en paramètre, ça t'évitera d'avoir de la duplication de code càd des méthodes qui font sensiblement la même chose. Ensuite tes petites méthodes "loadOrganizationsData" ne ferait qu'appeler cette méthode principale.
mieux encore, tu pourrais avoir une classe qui gère la pagination et qui serait abstraite, et une autre classe qui dépendrait de ta classe Pagination et qui l'utiliserait pour faire les fetch() etc.
toujours dans cette idée d'avoir un code modulaire et réutilisable, c'est de faire une classe "EventBus" qui stock et émet des events. Ainsi tu pourrais supprimer tes fonctions "deleteOrgMember" "editRole" "releaseSeat" et tout remplacer par des events. Ainsi dans une certaine partie de ton code, tu n'aurais qu'à enregistrer un évènement et dans ta classe de pagination (ou la classe dépendante) tu n'aurais qu'à appeler ces events. L'avantage, c'est que si plusieurs briques de code doivent réagir à la suppression d'un élément, ils pourront se greffer à l'event et être appeler au bon moment.
tu peux simplifier beaucoup de choses en utilisant les Promises.
Voilà, un bon conseil final ça serait de tout diviser pour simplifier ;-)
c'est pas très propre de commenter des bouts de code "morts", c'est mieux de les supprimer. Si tu doutes sur un morceau de code et que tu veux pouvoir revenir en arrière, utilise Git. Même pour des projets perso.
Ca fait quoi ?
tu pourrais avoir une méthode unique qui gère les fetch() en utilisant les Promise et l'url de ton endpoint en paramètre, ça t'évitera d'avoir de la duplication de code càd des méthodes qui font sensiblement la même chose. Ensuite tes petites méthodes "loadOrganizationsData" ne ferait qu'appeler cette méthode principale.
Ta un exemple ?
mieux encore, tu pourrais avoir une classe qui gère la pagination et qui serait abstraite, et une autre classe qui dépendrait de ta classe Pagination et qui l'utiliserait pour faire les fetch() etc.
Oula comment on fait ca ?
toujours dans cette idée d'avoir un code modulaire et réutilisable, c'est de faire une classe "EventBus" qui stock et émet des events. Ainsi tu pourrais supprimer tes fonctions "deleteOrgMember" "editRole" "releaseSeat" et tout remplacer par des events. Ainsi dans une certaine partie de ton code, tu n'aurais qu'à enregistrer un évènement et dans ta classe de pagination (ou la classe dépendante) tu n'aurais qu'à appeler ces events. L'avantage, c'est que si plusieurs briques de code doivent réagir à la suppression d'un élément, ils pourront se greffer à l'event et être appeler au bon moment.
Aucune idée de comment on fait cela.
Pour l'event bus, je t'invite à chercher sur google : https://www.google.com/search?q=javascript+event+bus+class&oq=javascript+event+bus+class
Tu trouveras assez d'exemple
Je t'invite aussi à te renseigner sur git et son utilisation.
Pour le reste, je te laisse réfléchir à ça, c'est rien de bien compliqué si t'as réussi à coder ta classe Pagination, tu devrais t'en sortir à coder d'autres classes
async loadData(page = 1, container, body, targetDirectory, caller, callback) {
page = parseInt(page, 10);
if (typeof page === 'number' && page > 0) {
this.itemsPerPage = parseInt(this.itemsPerPage, 10);
const loader = container.previousElementSibling;
this.scrollToTarget(container);
container.style.display = "none";
loader.style.display = "";
const controller = new AbortController();
const signal = controller.signal;
const timeoutDuration = 10000;
const timeoutId = setTimeout(() => {
controller.abort();
}, timeoutDuration);
try {
body.append("page", page);
if (typeof this.itemsPerPage === 'number' && this.itemsPerPage > 0) {
body.append("itemsPerPage", this.itemsPerPage);
}
const url = window.location.origin;
const response = await fetch(url + targetDirectory, {
method: "POST",
body,
signal,
});
await this.sleep(500);
clearTimeout(timeoutId);
if (!response.ok) {
displayToastError();
throw new Error(`HTTP error: ${response.status}`);
} else {
const value = await response.text();
if (value) {
container.innerHTML = value;
loader.style.display = "none";
container.style.display = "";
enableTooltipsEverywhere();
this.setupPagination(container, caller, this.setPaginationItemsPerPage.bind(this));
this.setupTableHeader(container, caller, this.sortData.bind(this));
callback();
}
}
} catch (error) {
this.handleError(container, loader, error);
}
}
}
async loadStoreData(page = 1) {
const container = document.getElementById("store-container");
if (!container) {
return;
}
this.sortScope = parseInt(this.sortScope, 10);
const body = new FormData();
if (this.sortCategory) {
body.append("sortCategory", this.sortCategory);
}
if (typeof this.sortScope === 'number' && this.sortScope >= 0) {
body.append("sortScope", this.sortScope);
}
if (this.sortTag) {
body.append("sortTag", this.sortTag);
}
const targetDirectory = "/index.php/Store/loadStore";
this.loadData(page, container, body, targetDirectory, this.loadStoreData.bind(this), () => {});
}
async loadOrganizationsData(page = 1) {
const container = document.getElementById("organizations-container");
if (!container) {
return;
}
const body = new FormData();
if (this.sortField) {
body.append("sortField", this.sortField);
}
if (this.sortOrder) {
body.append("sortOrder", this.sortOrder);
}
const targetDirectory = "/index.php/Organization/loadOrganizations";
this.sortFieldArray = ["name", "type", "nb_members", "project_list", "domain_list", "created"];
this.loadData(page, container, body, targetDirectory, this.loadOrganizationsData.bind(this), () => {
const deleteOrganizations = container.querySelectorAll(".deleteOrganization");
deleteOrganizations.forEach((element) => {
element.addEventListener("click", () => {
deleteOrganization(element);
});
});
});
}
Qu'en pensez vous ?