171 lines
5.7 KiB
JavaScript
171 lines
5.7 KiB
JavaScript
var apx = apx || {};
|
|
apx.adminskull = {};
|
|
|
|
apx.adminskull.show = (id) => {
|
|
document.getElementById("maincontent").innerHTML = `Contenu du wco ${id}`;
|
|
};
|
|
apx.adminskull.genereimg = (alias, size = 100) => {
|
|
const canvas = document.createElement("canvas");
|
|
canvas.width = size;
|
|
canvas.height = size;
|
|
const context = canvas.getContext("2d");
|
|
|
|
// Couleur de fond basée sur les lettres du nom
|
|
const colors = apx.data.tpldata.headnav.colorslist;
|
|
const charCodeSum = alias
|
|
.split("")
|
|
.reduce((acc, char) => acc + char.charCodeAt(0), 0);
|
|
const backgroundColor = colors[charCodeSum % colors.length];
|
|
context.fillStyle = backgroundColor;
|
|
context.fillRect(0, 0, size, size);
|
|
// first and last letter in uppercase
|
|
const initials =
|
|
alias.charAt(0).toUpperCase() +
|
|
alias.charAt(alias.length - 1).toUpperCase();
|
|
context.font = `${size / 2}px Arial`;
|
|
context.fillStyle = "#FFFFFF"; // Couleur du texte
|
|
context.textAlign = "center";
|
|
context.textBaseline = "middle";
|
|
context.fillText(initials, size / 2, size / 2);
|
|
return canvas.toDataURL();
|
|
};
|
|
apx.adminskull.togglesidebarmobile = (eltbtn) => {
|
|
//for mobile need to manage hidden case with other button in headnav
|
|
sidebar=document.getElementById("sidebar");
|
|
sidebar.classList.toggle('w-0');
|
|
sidebar.classList.toggle('w-full'); // Affiche la sidebar sur toute la largeur
|
|
sidebar.classList.toggle('-translate-x-full');
|
|
if (sidebar.classList.contains('w-full')){
|
|
|
|
sidebar.classList.remove('hidden');
|
|
}else{
|
|
sidebar.classList.add('hidden');
|
|
}
|
|
};
|
|
apx.adminskull.toggleheadnav = (icon) => {
|
|
document
|
|
.querySelectorAll(`.dropdown`)
|
|
.forEach((el) => el.classList.add("hidden"));
|
|
document.querySelector(`.dropdown.${icon}`).classList.remove("hidden");
|
|
};
|
|
apx.adminskull.globalevent = () => {
|
|
// add here any
|
|
document.addEventListener("keydown", (e) => {
|
|
if (e.key === "Escape") {
|
|
document
|
|
.querySelectorAll("#headnav .dropdown")
|
|
.forEach((elt) => elt.classList.add("hidden"));
|
|
}
|
|
});
|
|
document.addEventListener("click", (e) => {
|
|
//sidebar open close summary details
|
|
if (e.target.tagName.toLowerCase() === "summary") {
|
|
document.querySelectorAll("#sidebar ul details").forEach((details) => {
|
|
if (details !== e.target.parentNode) {
|
|
details.removeAttribute("open");
|
|
}
|
|
});
|
|
}
|
|
if (!document.getElementById("headnav").contains(e.target)) {
|
|
//if click somewhere else than headnav we close all dropdown that are eventually not hidden
|
|
document
|
|
.querySelectorAll("#headnav .dropdown")
|
|
.forEach((elt) => elt.classList.add("hidden"));
|
|
}
|
|
});
|
|
};
|
|
|
|
apx.adminskull.navigation = () => {
|
|
// test si authentification is valid
|
|
// genere les menu en fonction du contexte
|
|
const sidebar = document.getElementById("sidebar");
|
|
sidebar.querySelectorAll("ul").forEach((e) => e.remove());
|
|
sidebar.innerHTML =
|
|
sidebar.innerHTML +
|
|
Mustache.render(
|
|
apx.data.tpl.adminskullverticalnav,
|
|
apx.data.tpldata.verticalnav
|
|
);
|
|
const headnav = document.getElementById("headnav");
|
|
const datapagan = { alias: apx.data.headers.xalias };
|
|
/* for testing */
|
|
apx.data.itms.notifications = {
|
|
1: {
|
|
id: "1",
|
|
text: "notif 1",
|
|
from: "apxtri script toto.py",
|
|
date: "20250101",
|
|
},
|
|
2: {
|
|
id: "2",
|
|
text: "notif 2",
|
|
from: "apxtri script toto.py",
|
|
date: "20250101",
|
|
},
|
|
3: {
|
|
id: "3",
|
|
text: "notif 3",
|
|
from: "apxtri script toto.py",
|
|
date: "20250101",
|
|
},
|
|
};
|
|
|
|
if (
|
|
apx.data.itms.notifications &&
|
|
Object.keys(apx.data.itms.notifications).length > 0
|
|
) {
|
|
const notifarray = Object.values(apx.data.itms.notifications);
|
|
datapagan.numbernotif = notifarray.length;
|
|
datapagan.notif = notifarray
|
|
.sort((a, b) => b.date.localeCompare(a.date))
|
|
.slice(0, 5);
|
|
datapagan.notifcolor = "green";
|
|
}
|
|
if (
|
|
apx.data.itms.messages &&
|
|
Object.keys(apx.data.itms.messages).length > 0
|
|
) {
|
|
const msgarray = Object.values(apx.data.itms.messages);
|
|
datapagan.numbermsg = msgarray.length;
|
|
datapagan.msg = msgarray
|
|
.sort((a, b) => b.date.localeCompare(a.date))
|
|
.slice(0, 3);
|
|
datapagan.msgcolor = "green";
|
|
}
|
|
datapagan.aliasimg = apx.adminskull.genereimg(datapagan.alias);
|
|
headnav.innerHTML = Mustache.render(
|
|
apx.data.tpl.adminskullheadnav,
|
|
datapagan
|
|
);
|
|
apx.adminskull.globalevent();
|
|
};
|
|
|
|
apx.adminskull.search=(element)=>{
|
|
const input=element.previousElementSibling
|
|
if (!input || input.tagName !== 'INPUT'){
|
|
console.log("Check your component no input avaiilable close to this button")
|
|
return;
|
|
}
|
|
document.getElementById("searchtitle").innerHTML+=" "+input.value
|
|
// analyse search string + - to convert in json search object with common rules to follow to send some action search in an object
|
|
const searchjson={searchtxt:input.value}
|
|
|
|
if (!apx.data.searchfunction || !apx[apx.data.searchfunction]){
|
|
console.log("ERROR: your settings is not correct to use search in your project you must define in apxtri the propertie searchfunction with a value and you must have a function in your project apx[apxtri.searchfunction](search) that return search with in search.results=[{thumbnail,titile,description,..}]")
|
|
return;
|
|
}
|
|
|
|
const result = apx[apx.data.searchfunction](searchjson);
|
|
result.results.forEach(r=>{
|
|
if (!r.thumbnail || r.thumbnail=="") {
|
|
r.thumbnail=apx.adminskull.genereimg(r.title,200)
|
|
}
|
|
})
|
|
document.getElementById("searchresults").innerHTML=Mustache.render(apx.data.tpl.adminskullresult,result)
|
|
|
|
document.getElementById("maincontent").classList.add('hidden')
|
|
document.getElementById("searchcontent").classList.remove('hidden')
|
|
}
|
|
|
|
apx.readyafterupdate(apx.adminskull.navigation);
|