1
0
mirror of https://git.topisto.net/tibo/template.git synced 2026-03-31 21:39:10 +00:00

initialisation with SMETI code

This commit is contained in:
Thibaud
2024-09-13 17:26:06 +02:00
commit 2030381b45
118 changed files with 5779 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
// Create a function that will handle any intersection between some elements and the viewport.
const handleFooterIntersection = function (entries) {
// Loop through all the observed elements
for (let entry of entries) {
// Check if the element is intersecting the viewport
if (entry.isIntersecting) {
console.log("The footer is visible in the viewport");
if (typeof footerIsNowVisible === 'function') footerIsNowVisible(entry);
} else {
console.log("The footer is invisible in the viewport");
if (typeof footerIsNowInvisible === 'function') footerIsNowInvisible(entry);
}
}
}
const footer = document.querySelector("#footer");
if (footer) {
const footerObserver = new IntersectionObserver(handleFooterIntersection);
footerObserver.observe(footer);
}

View File

@@ -0,0 +1,12 @@
const headerObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (typeof headerIsVisible === 'function') headerIsVisible(entry.isIntersecting);
});
});
const header = document.querySelector("header");
if (header) headerObserver.observe(header);
else myLog('No header to observe');

View File

@@ -0,0 +1,17 @@
const synthesisTopObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
// Check if the element is intersecting the viewport
if (entry.isIntersecting) {
myLog("The synthesis is visible in the viewport");
if (typeof synthesisTopIsNowVisible === 'function') synthesisTopIsNowVisible(entry);
} else {
myLog("The synthesis is invisible in the viewport");
if (typeof synthesisTopIsNowInvisible === 'function') synthesisTopIsNowInvisible(entry);
}
});
});
const synthesis_top = document.querySelector("#synthesis_top");
if (synthesis_top) synthesisTopObserver.observe(synthesis_top);
else myLog('No #synthesis_top to obseve');

View File

@@ -0,0 +1,855 @@
// Affichage une colonne par intervenant
//function afficher_planning_atos_2(unModeAffichage) {
function ajouterClientColonne(client, colonne, indexCol) {
if (colonne[indexCol].indexOf(client) == -1) {
colonne[indexCol] += '/' + client;
}
}
datagrid_hooks['calendar_intervenants'] = function(){
let element = document.querySelector("#datagrid");
let filtre = getTrigrammeCollaborateur(getContexteValeur('intervenant'));
let lebreak = 0;
let annee = new Date().getFullYear();
let ladate = dateGetPrevMonday(new Date(annee, 0, 1));
let ladateToString;
let intervenants = [];
let jours_semaine = ["D", "L", "M", "M", "J", "V", "S"];
let lastWeekNumber = 99;
let tamponWeek = "";
let tamponWeekFlag = false;
let header = '';
let jours_feries = [];
let contenu = '';
// Tout le calendirer est encapsulé dans une cellule d'un tableau
// Permet de garantir le comportement du scroll avec le sticky des thead et tfoot
/*
contenu += '<table width="100vw">';
contenu += '<thead><tr><th>Calendrier</th></tr></thead>';
contenu += '<tr><td align="center" style="background:#aaaaaa">';
*/
sortItemsByStartDate();
setItemsVisibility();
if (getContexteValeur('debut'))
{
ladate = stringdateToDate(getContexteValeur('debut'));
ladate = dateGetPrevMonday(ladate);
}
ladateToString = formatDatetoStringDate(ladate);
// Se limiter à un an
annee = ladate.getFullYear() + 1;
annee += 1;
// Et à 2 ans si calendrier glissant
// TODO : ajouter un contexte qui indique si on est en calendrier annuel ou glissant
//if (select_date_debut == 2) annee += 1;
// Définir la liste des intervenants
items.forEach(element => {
let item = getItemFromElement(element);
let debut = item['debut'].substring(0,8);
let fin = item['fin'].substring(0,8);
// On ne s'occupe que des feuilles
if (item.childs.length != 0) return true;
// Au passage alimenter les jours fériés , mais ne pas les compter
if (item['client'] == 'FER') {
jours_feries.push(item['fin'].substring(0,8));
return true;
}
// On élimine ce qui est masqué
if (!item["visible"]) return true;
// On élimine les items non affectés
if (parseInt(item["intervenant"]) == 0) return true;
// Ne pas compter les Releases
if (item['client'] == 'REL') return true;
// Appliquer le filtre
if (filtre != 'ANO')
if (getTrigrammeCollaborateur(item['intervenant']) != filtre) return true;
// On ne compte pas ce qui n'est pas dans la période concernée
if (fin < ladateToString ) return true;
if (fin == '99999999' ) return true;
if (debut > (annee+'1231') ) return true;
if (intervenants.indexOf(item["intervenant"]) == -1) {
intervenants.push(item["intervenant"]);
}
});
intervenants.sort();
header += ' <th colspan="3">Calendrier</th>';
intervenants.forEach((intervenant) => {
let trigramme = getTrigrammeCollaborateur(intervenant);
header += '<th colspan="11"><center>' + trigramme + "</center></th>";
});
contenu += '<table width="100vw">';
contenu += " <thead><tr>" + header +"</tr></thead>";
contenu += " <tbody>";
let semaine_vide = "";
let semaine_paire = false;
let couleur = '';
semaine_vide += '<tr class="calendrier" style="background:#777777">';
semaine_vide += '<td width="30px" style="border-top:1px solid black;font-size:2vh">SXX</td>';
semaine_vide += '<td colspan="' + ( 2 + (11 * intervenants.length)) + '" align="center" style="border-top:1px solid black;font-size:2vh">&nbsp;</td>';
semaine_vide += "</tr>";
while (annee > ladate.getFullYear()) {
let bgcolor = "white";
let font_weight = 'normal';
let jour = ladate.getDay();
let jour_courant = formatDatetoStringDate(ladate);
let weekNumber = stringdateGetWeekOfYear(jour_courant)%100;
let colonnes = [];
let colonnes_bw = []; // Before Work
let colonnes_am = []; // Matin
let colonnes_md = []; // Midi
let colonnes_pm = []; // Après-Midi
let colonnes_aw = []; // After Work
let style_tr = '';
let style_td = '';
let jour_libelle = '';
intervenants.forEach((intervenant) => {
colonnes.push("");
colonnes_bw.push("");
colonnes_am.push("");
colonnes_md.push("");
colonnes_pm.push("");
colonnes_aw.push("");
});
// On change de semaine
// Si la semaine est vide, tamponWeekFlag == false
if (weekNumber != lastWeekNumber) {
let semaine = '';
if (lastWeekNumber != 99) semaine = semaine_vide.replace("SXX", "S" + stringDatePadDigits(lastWeekNumber,2));
if (tamponWeekFlag) {
semaine = tamponWeek;
semaine_paire = !semaine_paire;
}
contenu += semaine;
tamponWeek = "";
tamponWeekFlag = false;
}
// Couleur pour les samedi et dimanche
if (jour == 0 || jour == 6) bgcolor = "#f1d4af";
// Couleur pour les lundi et vendredi
if (jour == 1 || jour == 5) bgcolor = "#eeeeee";
// Couleur pour les jours fériés
if (jours_feries.includes(jour_courant)) bgcolor = "#f1d4af";
// Couleur d'aujourd'hui
if (jour_courant == todayStringDate){
bgcolor='#87cefa';
font_weight='bold';
tamponWeekFlag = true;
}
items.forEach((element) => {
let item = getItemFromElement(element);
let debut = item["debut"];
let fin = item["fin"];
let jour_debut;
let jour_fin;
let ajout = false;
if (isDebugItem(item)){
myLog('item ICI');
}
if (!item["visible"]) return true; // Invisible
if (item["intervenant"] == 0) return true; // Non affecté
if (item.childs.length != 0) return true; // Noeud
if ((fin.substring(8,12) == '0000')||(fin.substring(8,12) == '9999')) fin = fin.substring(0,8)+'2000';
if (item['type'] == 'TODO') debut = fin; // Un TODO est un jalon
jour_debut = debut.substring(0,8);
jour_fin = fin.substring(0,8);
// if (jour_debut > jour_courant) return false;
// Ceci n'est pas réellement planifié
if ((jour_debut == '00000000') && (jour_fin.substring(0,8) == (1+parseInt(todayStringDate.substring(0,4))+'1231'))) {
return true;
}
// L'item débute ou finit le jour courant
if (jour_debut == jour_courant) ajout = true;
if (jour_fin == jour_courant) ajout = true;
// Le jour courant est entièrement contenu dans l'item
if (jour_debut < jour_courant && jour_fin > jour_courant) ajout = true;
if (ajout) {
let indexCol = intervenants.indexOf(item["intervenant"]);
let client = item["client"];
let horaire_debut = 0;
let horaire_fin = 20;
let colonne = null;
tamponWeekFlag = true;
if (jour_courant == jour_debut) horaire_debut = parseInt(debut.substring(8, 10));
if (jour_courant == jour_fin) horaire_fin = parseInt(fin.substring(8, 10));
// Pour les releases et les jour fériés, on affiche le libellé
if ((client == 'REL')||(client == 'FER')) {
jour_libelle = item['libelle'];
return true;
}
if (client == 'REL') return true;
if (client == 'FER') return true;
//if (client == "ABS") bgcolor = "#f1d4af";
//if (client == "CGI") font_weight += ";color:blue";
if (indexCol == -1) {
myLog(item["intervenant"] + " inconnu");
return true;
}
if ((horaire_debut <= 9) && (horaire_fin<=9)) ajouterClientColonne(client, colonnes_bw, indexCol);
if ((horaire_debut >= 12) && (horaire_fin<=14)) ajouterClientColonne(client, colonnes_md, indexCol);
if ((horaire_debut >= 17) && (horaire_fin<=21)) ajouterClientColonne(client, colonnes_aw, indexCol);
if ((horaire_debut < 12) && (horaire_fin > 9)) ajouterClientColonne(client, colonnes_am, indexCol);
if ((horaire_debut < 17) && (horaire_fin > 14)) ajouterClientColonne(client ,colonnes_pm, indexCol);
}
});
style_tr = 'background:'+bgcolor+';font-weight:'+font_weight;
tamponWeek += '<tr style="'+style_tr+'" class="js-open-modal-trigger" data-modal-info="type=calendrier:jour=' + jour_courant + '">';
if (weekNumber != lastWeekNumber) {
if (semaine_paire) couleur = '#eeeeee';
else couleur = 'white';
lastWeekNumber = weekNumber;
/*
tamponWeek += '<td class="calendrier" width="10px" style="font-family: fixed; width: 30px;background: ' + couleur + '; font-weight: bold" rowspan="7" align="center">';
tamponWeek += "S" + lastWeekNumber.toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += "</td>";
*/
}
if (jour == 1) style_td = 'border-top:1px solid black'; // Le lundi
tamponWeek += '<td style="font-family: fixed; width: 30px; background:'+couleur+';text-align:center;border-right:1px solid;font-size:2vh;'+style_td+'">';
if (jour == 4) tamponWeek += 'S'+lastWeekNumber.toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += '&nbsp;</td>';
tamponWeek += '<td style="font-family: fixed;font-size:2vh; width: 20px;background:'+bgcolor+';font-weight:bold;'+style_td+'">'+jours_semaine[jour]+'</td>';
if (jour_libelle != '' ) {
tamponWeek += '<td style="font-family: fixed;font-size:2vh;width:80px;background:'+bgcolor+';color:red;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-right:1px solid black;'+style_td+'"><small>'+ jour_libelle +'</small></td>';
} else {
tamponWeek += '<td style="font-family: fixed;font-size:2vh;width: 80px;background:'+bgcolor+';font-weight:bold;border-right:1px solid;'+style_td+'">';
tamponWeek +=
ladate.getDate().toLocaleString(undefined, { minimumIntegerDigits: 2 }) +
" / " +
(ladate.getMonth() + 1).toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += "</td>";
}
intervenants.forEach((intervenant) => {
let index = intervenants.indexOf(intervenant);
let aligne = "center";
let colonne = colonnes[index].substring(1);
let colonne_bw = colonnes_bw[index];
let colonne_am = colonnes_am[index];
let colonne_md = colonnes_md[index];
let colonne_pm = colonnes_pm[index];
let colonne_aw = colonnes_aw[index];
let style_am = "";
let style_pm = "";
let style_tr_td = "";
// if (colonne_bw != '' || colonne_am != '' || colonne_md != '' || colonne_pm != '' || colonne_aw != '') {
//tamponWeekFlag = true;
if (colonne != '') {
let tempo = colonne.replace('</span>','');
let valeurs = tempo.split('/');
valeurs.forEach(valeur => {
if (!colonne_am.includes(valeur)) colonne_am += '/'+valeur+'</span>';
if (!colonne_pm.includes(valeur)) colonne_pm += '/'+valeur+'</span>';
// if (!colonne_aw.includes(valeur)) colonne_aw += '/'+valeur+'</span>';
})
}
colonne_bw = colonne_bw.substring(1);
colonne_am = colonne_am.substring(1);
colonne_md = colonne_md.substring(1);
colonne_pm = colonne_pm.substring(1);
colonne_aw = colonne_aw.substring(1);
if (jour == 0 || jour ==6) {
colonne_bw = "";
colonne_am = "";
colonne_md = "";
colonne_pm = "";
colonne_aw = "";
}
style_tr = 'overflow: hidden;white-space: nowrap;text-overflow:ellipsis';
style_tr += ';border-color:black;border-width:1px';
style_tr += ';padding-left: 5px; padding-right: 5px';
style_tr += ';background:' + bgcolor;
style_tr_td = style_tr+";"+style_td;
if (colonne_am.includes("ABS")) style_am+=";background:#f004";
if (colonne_pm.includes("ABS")) style_pm+=";background:#f004";
if (colonne_am.includes("CGI")) style_am+=";color:blue";
if (colonne_pm.includes("CGI")) style_pm+=";color:blue";
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5" align="' + aligne + '"><center>' + colonne_bw + "</center></td>";
tamponWeek += '<td colspan="4" style="width:80px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_tr_td+';'+style_am + '"' + aligne + '"><center>' + colonne_am + "</center></td>";
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5" align="' + aligne + '"><center>' + colonne_md + "</center></td>";
tamponWeek += '<td colspan="4" style="width:80px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_tr_td+';'+style_pm+ ';" align="' + aligne + '"><center>' + colonne_pm + "</center></td>";
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5;border-right: 1px solid" align="' + aligne + '"><center>' + colonne_aw + "</center></td>";
/*} else {
//if (colonne != '') tamponWeekFlag = true;
tamponWeek += '<td colspan="5" style="background:' + bgcolor + ';min-width: 60px;padding-left: 5px; padding-right: 5px" align="' + aligne + '"><center>' + colonne + "</center></td>";
}
*/
});
tamponWeek += "</tr>";
// Pour ne pas boucler indéfiniment
if (++lebreak > 400) break;
/*
if (select_date_debut == 1) {
// Planning glissant
// Stop au dimanche suivant anniversaire
if (intJourCourant > intValToDay + 10000) if (jour == 0) break;
}
*/
ladate.setDate(ladate.getDate() + 1);
}
contenu += tamponWeek;
contenu += " <tfoot><tr>" + header +"</tr></tfoot>";
contenu += "</table>";
/*
contenu += "</td></tr>";
contenu += "<tfoot><tr><th>Calendrier</th></tr></tfoot>";
contenu += "</table>";
*/
//element.innerHTML = '<div align="center" style="background:#aaaaaa">'+contenu+'</div>';
element.innerHTML = contenu;
}
datagrid_hooks['calendar_clients'] = function(){
let element = document.querySelector("#datagrid");
let filtre = getContexteValeur('client');
let lebreak = 0;
let annee = new Date().getFullYear();
let ladate = dateGetPrevMonday(new Date(annee, 0, 1));
let ladateToString;
let entetes = [];
let jours_semaine = ["D", "L", "M", "M", "J", "V", "S"];
let lastWeekNumber = 99;
let tamponWeek = "";
let tamponWeekFlag = false;
let header = '';
let jours_feries = [];
let contenu = '';
sortItemsByStartDate();
setItemsVisibility();
if (getContexteValeur('debut'))
{
ladate = stringdateToDate(getContexteValeur('debut'));
ladate = dateGetPrevMonday(ladate);
}
ladateToString = formatDatetoStringDate(ladate);
// Se limiter à un an
annee = ladate.getFullYear() + 1;
annee += 1;
// Et à 2 ans si calendrier glissant
// TODO : ajouter un contexte qui indique si on est en calendrier annuel ou glissant
//if (select_date_debut == 2) annee += 1;
// Définir la liste des intervenants
items.forEach(element => {
let item = getItemFromElement(element);
let debut = item['debut'].substring(0,8);
let fin = item['fin'].substring(0,8);
// On ne s'occupe que des feuilles
if (item.childs.length != 0) return true;
// Au passage alimenter les jours fériés , mais ne pas les compter
if (item['client'] == 'FER') {
jours_feries.push(item['fin'].substring(0,8));
return true;
}
// Ne pas compter les Releases
if (item['client'] == 'REL') return true;
if (filtre != '')
if (item['client'] != filtre) return true;
// On élimine ce qui est masqué
if (!item["visible"]) return true;
// On élimine les items non affectés
if (parseInt(item["client"]) == 0) return true;
// On ne compte pas ce qui n'est pas dans la période concernée
if (fin < ladateToString ) return true;
if (fin == '99999999' ) return true;
if (debut > (annee+'1231') ) return true;
if (entetes.indexOf(item['client']) == -1) {
entetes.push(item['client']);
}
});
entetes.sort();
header += ' <th colspan="3">Calendrier</th>';
entetes.forEach((entete) => {
header += '<th colspan="11"><center>' + entete + "</center></th>";
});
contenu += '<table width="100vw">';
contenu += " <thead><tr>" + header +"</tr></thead>";
contenu += " <tbody>";
let semaine_vide = "";
let semaine_paire = false;
let couleur = '';
semaine_vide += '<tr class="calendrier" style="background:#777777">';
semaine_vide += '<td width="30px" style="border-top:1px solid black;font-size:2vh">SXX</td>';
semaine_vide += '<td colspan="' + ( 2 + (11 * entetes.length)) + '" align="center" style="border-top:1px solid black;font-size:2vh">&nbsp;</td>';
semaine_vide += "</tr>";
while (annee > ladate.getFullYear()) {
let bgcolor = "white";
let font_weight = 'normal';
let jour = ladate.getDay();
let jour_courant = formatDatetoStringDate(ladate);
let weekNumber = stringdateGetWeekOfYear(jour_courant)%100;
let colonnes = [];
let colonnes_bw = []; // Before Work
let colonnes_am = []; // Matin
let colonnes_md = []; // Midi
let colonnes_pm = []; // Après-Midi
let colonnes_aw = []; // After Work
let style_tr = '';
let style_td = '';
let jour_libelle = '';
entetes.forEach((intervenant) => {
colonnes.push("");
colonnes_bw.push("");
colonnes_am.push("");
colonnes_md.push("");
colonnes_pm.push("");
colonnes_aw.push("");
});
// On change de semaine
// Si la semaine est vide, tamponWeekFlag == false
if (weekNumber != lastWeekNumber) {
let semaine = '';
if (lastWeekNumber != 99) semaine = semaine_vide.replace("SXX", "S" + stringDatePadDigits(lastWeekNumber,2));
if (tamponWeekFlag) {
semaine = tamponWeek;
semaine_paire = !semaine_paire;
}
contenu += semaine;
tamponWeek = "";
tamponWeekFlag = false;
}
// Couleur pour les samedi et dimanche
if (jour == 0 || jour == 6) bgcolor = "#f1d4af";
// Couleur pour les lundi et vendredi
if (jour == 1 || jour == 5) bgcolor = "#eeeeee";
// Couleur pour les jours fériés
if (jours_feries.includes(jour_courant)) bgcolor = "#f1d4af";
// Couleur d'aujourd'hui
if (jour_courant == todayStringDate){
bgcolor='#87cefa';
font_weight='bold';
tamponWeekFlag = true;
}
items.forEach((element) => {
let item = getItemFromElement(element);
let debut = item["debut"];
let fin = item["fin"];
let jour_debut;
let jour_fin;
let ajout = false;
if (isDebugItem(item)){
myLog('item ICI');
}
if (!item["visible"]) return true; // Invisible
if (item["client"] == 0) return true; // Non affecté
if (item.childs.length != 0) return true; // Noeud
if ((fin.substring(8,12) == '0000')||(fin.substring(8,12) == '9999')) fin = fin.substring(0,8)+'2000';
if (item['type'] == 'TODO') debut = fin; // Un TODO est un jalon
jour_debut = debut.substring(0,8);
jour_fin = fin.substring(0,8);
// if (jour_debut > jour_courant) return false;
// Ceci n'est pas réellement planifié
if ((jour_debut == '00000000') && (jour_fin.substring(0,8) == (1+parseInt(todayStringDate.substring(0,4))+'1231'))) {
return true;
}
// L'item débute ou finit le jour courant
if (jour_debut == jour_courant) ajout = true;
if (jour_fin == jour_courant) ajout = true;
// Le jour courant est entièrement contenu dans l'item
if (jour_debut < jour_courant && jour_fin > jour_courant) ajout = true;
if (ajout) {
let indexCol = entetes.indexOf(item["client"]);
let intervenant = getTrigrammeCollaborateur(item["intervenant"]);
let client = item["client"];
let horaire_debut = 0;
let horaire_fin = 20;
let colonne = null;
tamponWeekFlag = true;
if (jour_courant == jour_debut) horaire_debut = parseInt(debut.substring(8, 10));
if (jour_courant == jour_fin) horaire_fin = parseInt(fin.substring(8, 10));
// Pour les releases et les jour fériés, on affiche le libellé
if ((client == 'REL')||(client == 'FER')) {
jour_libelle = item['libelle'];
return true;
}
if (client == 'REL') return true;
if (client == 'FER') return true;
if (client == "ABS") bgcolor = "#f1d4af";
if (client == "CGI") font_weight += ";color:blue";
if (indexCol == -1) {
myLog(item["client"] + " inconnu");
return true;
}
if ((horaire_debut <= 9) && (horaire_fin<=9)) ajouterClientColonne(intervenant, colonnes_bw, indexCol);
if ((horaire_debut >= 12) && (horaire_fin<=14)) ajouterClientColonne(intervenant, colonnes_md, indexCol);
if ((horaire_debut >= 17) && (horaire_fin<=21)) ajouterClientColonne(intervenant, colonnes_aw, indexCol);
if ((horaire_debut < 12) && (horaire_fin > 9)) ajouterClientColonne(intervenant, colonnes_am, indexCol);
if ((horaire_debut < 17) && (horaire_fin > 14)) ajouterClientColonne(intervenant ,colonnes_pm, indexCol);
}
});
style_tr = 'background:'+bgcolor+';font-weight:'+font_weight;
tamponWeek += '<tr style="'+style_tr+'" class="js-open-modal-trigger" data-modal-info="type=calendrier:jour=' + jour_courant + '">';
if (weekNumber != lastWeekNumber) {
if (semaine_paire) couleur = '#eeeeee';
else couleur = 'white';
lastWeekNumber = weekNumber;
/*
tamponWeek += '<td class="calendrier" width="10px" style="font-family: fixed; width: 30px;background: ' + couleur + '; font-weight: bold" rowspan="7" align="center">';
tamponWeek += "S" + lastWeekNumber.toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += "</td>";
*/
}
if (jour == 1) style_td = 'border-top:1px solid black'; // Le lundi
tamponWeek += '<td style="font-family: fixed; width: 30px; background:'+couleur+';text-align:center;border-right:1px solid;font-size:2vh;'+style_td+'">';
if (jour == 4) tamponWeek += 'S'+lastWeekNumber.toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += '&nbsp;</td>';
tamponWeek += '<td style="font-family: fixed;font-size:2vh; width: 20px;background:'+bgcolor+';font-weight:bold;'+style_td+'">'+jours_semaine[jour]+'</td>';
if (jour_libelle != '' ) {
tamponWeek += '<td style="font-family: fixed;font-size:2vh;width:80px;background:'+bgcolor+';color:red;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-right:1px solid black;'+style_td+'"><small>'+ jour_libelle +'</small></td>';
} else {
tamponWeek += '<td style="font-family: fixed;font-size:2vh;width: 80px;background:'+bgcolor+';font-weight:bold;border-right:1px solid;'+style_td+'">';
tamponWeek +=
ladate.getDate().toLocaleString(undefined, { minimumIntegerDigits: 2 }) +
" / " +
(ladate.getMonth() + 1).toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += "</td>";
}
entetes.forEach((entete) => {
let index = entetes.indexOf(entete);
let aligne = "center";
let colonne = colonnes[index].substring(1);
let colonne_bw = colonnes_bw[index];
let colonne_am = colonnes_am[index];
let colonne_md = colonnes_md[index];
let colonne_pm = colonnes_pm[index];
let colonne_aw = colonnes_aw[index];
// if (colonne_bw != '' || colonne_am != '' || colonne_md != '' || colonne_pm != '' || colonne_aw != '') {
//tamponWeekFlag = true;
if (colonne != '') {
let tempo = colonne.replace('</span>','');
let valeurs = tempo.split('/');
valeurs.forEach(valeur => {
if (!colonne_am.includes(valeur)) colonne_am += '/'+valeur+'</span>';
if (!colonne_pm.includes(valeur)) colonne_pm += '/'+valeur+'</span>';
// if (!colonne_aw.includes(valeur)) colonne_aw += '/'+valeur+'</span>';
})
}
colonne_bw = colonne_bw.substring(1);
colonne_am = colonne_am.substring(1);
colonne_md = colonne_md.substring(1);
colonne_pm = colonne_pm.substring(1);
colonne_aw = colonne_aw.substring(1);
style_tr = 'overflow: hidden;white-space: nowrap;text-overflow:ellipsis';
style_tr += ';border-color:black;border-width:1px';
style_tr += ';padding-left: 5px; padding-right: 5px';
style_tr += ';background:' + bgcolor;
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5" align="' + aligne + '"><center>' + colonne_bw + "</center></td>";
tamponWeek += '<td colspan="4" style="width:80px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_tr+';'+style_td + '"' + aligne + '"><center>' + colonne_am + "</center></td>";
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5" align="' + aligne + '"><center>' + colonne_md + "</center></td>";
tamponWeek += '<td colspan="4" style="width:80px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_tr+';'+style_td + ';" align="' + aligne + '"><center>' + colonne_pm + "</center></td>";
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5;border-right: 1px solid" align="' + aligne + '"><center>' + colonne_aw + "</center></td>";
/*} else {
//if (colonne != '') tamponWeekFlag = true;
tamponWeek += '<td colspan="5" style="background:' + bgcolor + ';min-width: 60px;padding-left: 5px; padding-right: 5px" align="' + aligne + '"><center>' + colonne + "</center></td>";
}
*/
});
tamponWeek += "</tr>";
// Pour ne pas boucler indéfiniment
if (++lebreak > 400) break;
/*
if (select_date_debut == 1) {
// Planning glissant
// Stop au dimanche suivant anniversaire
if (intJourCourant > intValToDay + 10000) if (jour == 0) break;
}
*/
ladate.setDate(ladate.getDate() + 1);
}
contenu += tamponWeek;
contenu += " <tfoot><tr>" + header +"</tr></tfoot>";
contenu += "</table>";
element.innerHTML = contenu;
}
modal_hooks['calendrier'] = function(parametres){
let jour_courant='00000000';
let paramSplit = parametres.split(':');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0]==='jour') jourInfo(elemSplit[1].substring(0,8));
});
};
function testDateItem(item, jour_courant)
{
let retour = false;
let jour_debut = item["debut"].substring(0,8);
let jour_fin = item["fin"].substring(0,8);
// Les TODO sont des jalons
if (item['type']=='TODO') jour_debut = jour_fin;
// Se limiter aux items réellement entièrement plannifiés
if ((jour_debut != '00000000') && (jour_fin != (1+parseInt(todayStringDate.substring(0,4))+'1231'))) {
// L'item débute ou finit le jour courant
if (jour_debut == jour_courant) retour = true;
if (jour_fin == jour_courant) retour = true;
// Le jour courant est entièrement contenu dans l'item
if (jour_debut < jour_courant && jour_fin > jour_courant) retour = true;
}
return retour;
}
function jourInfo(jour_courant) {
let modal_header='Détail <b>'+formatLocaleDateFromStringDate(jour_courant)+'</b>';
let modal_body='TODO inconnu !';
let modal_footer='';
let start = 7; // Mettre un contexte ...
let finish = 14; // Mettre un contexte ...
let horaires = [];
for(i=0;i<finish;i++){
horaires[(i*2)] = '';
horaires[(i*2)+1] = '';
}
items.forEach(element => {
let resultat = getItemFromElement(element);
let debut = resultat["debut"];
let fin = resultat["fin"];
let jour_debut;
let jour_fin;
let heure_debut;
let heure_fin;
if (isDebugItem(resultat)){
myLog('item ICI');
}
// L'item concerne-t-il bien la date courante ?
if (!testDateItem(resultat, jour_courant)) return true;
heure_fin=fin.substring(8,12);
if (heure_fin =='0000') fin=fin.substring(0,8)+'2000';
// Les TODO sont des jalons
if (resultat.type=='TODO') debut = fin;
jour_debut = debut.substring(0,8);
jour_fin = fin.substring(0,8);
heure_debut = parseInt(debut.substring(8,12));
heure_fin = parseInt(fin.substring(8,12));
// L'item commence avant le jour courant
if (jour_debut < jour_courant) heure_debut = '0900';
// L'item termine après le jour courant
if (jour_fin > jour_courant) heure_fin = '1800';
// Recalibrer les heures de debut et de fin
if (heure_debut=='0000') heure_debut='0900';
if (heure_fin=='0000') heure_fin='2000';
for(i=0;i<finish;i++) {
let cur_debut, cur_fin;
let flag;
cur_debut = parseInt((start+i)+'00');
cur_fin = parseInt((start+i)+'30');
flag = false;
if ((heure_debut <= cur_debut)&&(heure_fin >= cur_fin)) flag = true;
if ((heure_debut >= cur_debut)&&(heure_fin <= cur_fin)) flag = true;
if ((heure_debut == heure_fin)&&(heure_fin == cur_fin)) flag = false;
// Cas particulier de la pause de midi
if (cur_debut == '1300')
if ((heure_debut<'1230')&&(heure_fin>'1330')) flag = false;
if (flag) horaires[(i*2)] += resultat.libelle+'<br>';
cur_debut = parseInt((start+i)+'30');
cur_fin = parseInt((start+i)+1+'00');
flag = false;
if ((heure_debut <= cur_debut)&&(heure_fin >= cur_fin)) flag = true;
if ((heure_debut >= cur_debut)&&(heure_fin <= cur_fin)) flag = true;
if ((heure_debut == heure_fin)&&(heure_fin == cur_fin)) flag = false;
// Cas particulier de la pause de midi
if (cur_debut == '1230')
if ((heure_debut<'1230')&&(heure_fin>'1330')) flag = false;
if (flag) horaires[(i*2)+1] += resultat.libelle+'<br>';
}
});
modal_body = '<table class="modal_table">';
for(i=0;i<finish;i++) {
let debut;
let fin;
let style_tr;
debut = stringDatePadDigits((i+start),2)+':00';
fin = stringDatePadDigits((i+start),2)+':30';
style_tr=' class="tr1"';
if (debut < '09:00') style_tr=' class="tr2"';
if (fin > '18:00') style_tr=' class="tr2"';
if (debut == '13:00') style_tr=' class="tr2"';
modal_body += '<tr'+style_tr+'>';
modal_body += '<td style="width:40px">'+debut+' - '+fin+'</td>';
modal_body += '<td>'+horaires[i*2]+'</td></tr>';
modal_body += '</tr>';
debut = stringDatePadDigits((i+start),2)+':30';
fin = stringDatePadDigits((i+start)+1,2)+':00';
style_tr=' class="tr1"';
if (debut < '09:00') style_tr=' class="tr2"';
if (fin > '18:00') style_tr=' class="tr2"';
if (debut == '12:30') style_tr=' class="tr2"';
modal_body += '<tr'+style_tr+'>';
modal_body += '<td style="width:40px">'+debut+' - '+fin+'</td>';
modal_body += '<td>'+horaires[(i*2)+1]+'</td></tr>';
modal_body += '</tr>';
}
modal_body += '</table>';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}

View File

@@ -0,0 +1,147 @@
// ---------------------------------------------------------------------------------------
// ---- Fonctions pour charger des lignes identiques dans le tableau
// ---------------------------------------------------------------------------------------
function datagridLignesIdentiques(nblignes, valeur) {
let element = document.querySelector('#datagrid');
let contenu='';
contenu += '<table>';
contenu += ' <thead>';
contenu += ' <tr>';
contenu += ' <th>&nbsp;</th>';
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
for(let i=0; i<nblignes; i++)
{
contenu += ' <tr>';
contenu += ' <td align="center">'+valeur+'</td>';
contenu += ' </tr>';
}
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th>&nbsp;</th>';
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
element.innerHTML = contenu;
}
// ---------------------------------------------------------------------------------------
// ---- Fonctions pour charger des lignes vides
// ---------------------------------------------------------------------------------------
function datagridEmptyLines(nblignes) {
return datagridLignesIdentiques(nblignes,'&nbsp;');
}
// ---------------------------------------------------------------------------------------
// ---- Fonctions utilitaires
// ---------------------------------------------------------------------------------------
function datagridLoading() {
let nblignes = 25 + Math.floor(Math.random() * 475); // Nbre entre ntre 25 et 500
return datagridLignesIdentiques(nblignes, 'Loading data ..');
}
// ---------------------------------------------------------------------------------------
// ---- Fonctions pour charger des données au hasard dans le datagrid
// ---------------------------------------------------------------------------------------
var nbCols = 5;
function setDatagridRandomValues(element, nbcols, nblignes)
{
let contenu='';
contenu += '<table>';
contenu += ' <thead>';
contenu += ' <tr>';
contenu += ' <th>ID HEAD</th>';
for(let i= 0; i<nbcols; i++)
{
contenu += ' <th>HEAD'+i+'</th>';
}
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
for(let i=0; i<nblignes; i++)
{
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="random:idligne='+i+'">';
contenu += ' <td>ID</td>';
for(let ii= 0; ii<nbcols; ii++)
{
contenu += ' <td> VALUE '+i+' '+ii+'</td>';
}
contenu += ' </tr>';
}
// Rejouter 2 lignes vides
for(let i=0; i<2; i++)
{
contenu += ' <tr>';
contenu += ' <td>&nbsp;</td>';
for(let ii= 0; ii<nbcols; ii++)
{
contenu += ' <td>&nbsp;</td>';
}
contenu += ' </tr>';
}
contenu += ' </body>';
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th>ID FOOT</th>';
for(let i= 0; i<nbcols; i++)
{
contenu += ' <th>FOOT'+i+'</th>';
}
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
element.innerHTML = contenu;
init_modal();
nbCols = nbcols;
}
modal_hooks['random'] = function(parametres){
let paramSplit = parametres.split(',');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0] === 'idligne') {
let ligne = elemSplit[1];
let modal_header='Détail de la ligne '+ligne;
let modal_body='';
let modal_footer='<button>Enregistrer</button';
modal_body += '<table class="modal_table">';
for(i=0;i<nbCols; i++)
{
modal_body += '<tr>';
modal_body += '<td> PARAM '+i+'</td>';
modal_body += '<td> VALUE '+ligne+' '+i+'</td>';
modal_body += '</tr>';
}
modal_body += '</table>';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}
});
};
// --------------------------------------------------------------------------------------------
// ---- Tableau de hooks pour alimenter le datagrid
// --------------------------------------------------------------------------------------------
var datagrid_hooks = [];
datagrid_hooks['random'] = function(){
let element = document.querySelector('#datagrid');
let nblignes = 25 + Math.floor(Math.random() * 475); // Nbre entre ntre 25 et 500
setDatagridRandomValues(element, nbCols, nblignes)
};

View File

@@ -0,0 +1,154 @@
class Modal {
// TODO : industrialiser en créant une classe
}
const modalDialog = document.getElementById('fiche');
var modal_hooks = [];
function disableScrolling(){
/*
document.body.style.position = 'fixed';
document.body.style.top = `-${window.scrollY}px`;
*/
/*
var x=window.scrollX;
var y=window.scrollY;
window.onscroll=function(){window.scrollTo(x, y);};
*/
// Ne marche pas :
// supprime la scrollbar (déplacement du body vers la droite)
// document.body.style.overflow='hidden';
// Ne marche pas :
// la modal ne propage pas le scroll
// modalDialog.scroll = function(e) {e.stopPropagation();}
}
function enableScrolling(){
/*
const scrollY = document.body.style.top;
document.body.style.position = '';
document.body.style.top = '';
window.scrollTo(0, parseInt(scrollY || '0') * -1);
*/
// Ne marche pas :
// au retour, certains élements de la page ne sont plus clickables
//document.body.style.overflow='scroll';
// window.onscroll=function(){};
}
function showDialog(){
modalDialog.showModal();
disableScrolling()
}
function show_modal(data_modal) {
showDialog();
if (typeof open_modal_hook === 'function') open_modal_hook(data_modal);
};
function close_modal()
{
modalDialog.close();
enableScrolling();
}
function init_modal()
{
let testElements = document.getElementsByClassName('js-open-modal-trigger');
let testDivs = Array.prototype.filter.call(testElements, function(testElement){
return true;
});
testDivs.forEach(function(item){
item.onclick = function(ev) {
show_modal(this.getAttribute("data-modal-info"));
};
});
testElements = document.getElementsByClassName('js-close-modal-trigger');
testDivs = Array.prototype.filter.call(testElements, function(testElement){
return true;
});
testDivs.forEach(function(item){
item.onclick = function(ev) {
close_modal(this.getAttribute("data-modal-info"));
};
});
return true;
}
function close_modal_hook()
{
console.log("close_modal_hook");
modalSetInnerHtml('modal_header', '');
modalSetInnerHtml('modal_body', '');
modalSetInnerHtml('modal_footer', '');
}
function modalSetInnerHtml(className, valeur)
{
var testElements = document.getElementsByClassName(className);
var testDivs = Array.prototype.filter.call(testElements, function(testElement){
return true;
});
testDivs.forEach(function(element){
element.scrollTop = 0;
element.innerHTML = valeur;
});
}
function modalSetChildren(className, children)
{
var testElements = document.getElementsByClassName(className);
var testDivs = Array.prototype.filter.call(testElements, function(testElement){
return true;
});
modalSetInnerHtml(className, '');
testDivs.forEach(function(element){
element.scrollTop = 0;
element.appendChild(children);
});
}
function modalSetHeader(valeur)
{
modalSetInnerHtml('modal_header', valeur);
}
function modalSetBody(valeur)
{
modalSetInnerHtml('modal_body', valeur);
}
function modalSetFooter(valeur)
{
modalSetInnerHtml('modal_footer', valeur);
}
/*
* Format du paramètre : methode:p1=v1,p2=v2
*/
function open_modal_hook(parametre)
{
console.log("open_modal_hook pour "+parametre);
let hook = null;
let paramSplit = parametre.split(':');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0] === 'type') {
hook = modal_hooks[elemSplit[1]];
}
});
if ((hook===null)||(hook===undefined)) hook = modal_hooks['ITEM'];
return hook(parametre);
}
init_modal();

View File

@@ -0,0 +1,83 @@
datagrid_hooks['planning'] = function() {
let element = document.querySelector("#datagrid");
let filtre = getTrigrammeCollaborateur(getContexteValeur('intervenant'));
let contenu = "";
let nbLignes = 1;
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
let retour = 0;
/*
if (item_a['client'] < item_b['client']) retour = -1;
if (item_a['client'] > item_b['client']) retour = 1;
*/
if (retour == 0 ) {
retour = sort2ItemsByDates(item_a, item_b);
}
return retour;
});
setItemsVisibility();
contenu += "<table>";
contenu += " <thead>";
contenu += " <tr>";
contenu += ' <th style="width:50px;text-align:center">Client</td>';
contenu += ' <th style="width:50px;text-align:center">Intervenant</td>';
contenu += ' <th style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">Libellé</th>';
contenu += ' <th style="width:100px;text-align:center">Début</td>';
contenu += ' <th style="width:100px;text-align:center">fin</td>';
contenu += " </tr>";
contenu += " </thead>";
contenu += " <tbody>";
items.forEach((element) => {
let item = getItemFromElement(element);
let texte = getNonNullTextValeur(item.libelle);
let debut = formatLocaleDateFromStringDate(item.debut);
let heureDebut= formatTimeFromStringDate(item.debut);
let fin = formatLocaleDateFromStringDate(item.fin);
let heureFin= formatTimeFromStringDate(item.fin);
// On n'affiche pas la racine
if (item["idlignes"] == 1) return true;
// On n'affiche que ce qui est marqué comme visible
if (!item["visible"]) return true;
// On n'affiche que les feuilles
if (item.childs.length != 0) return true;
// On n'affiche que ce qui est plannifié
if((debut=='-')&&(fin=='-')) return true;
// Appliquer le filtre
if (filtre != 'ANO')
if (getTrigrammeCollaborateur(item['intervenant']) != filtre) return true;
if (item.status == 3) texte = "<strike>" + texte + "</strike>";
if (item.status == 2) texte = "<strike>" + texte + "</strike>";
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="type='+item.type+':id=' + getNonNullTextValeur(item.idlignes) + '">';
contenu += ' <td style="width:50px;text-align:center">' + getNonNullTextValeur(item.client) + "</td>";
contenu += ' <td style="width:50px;text-align:center">' + getTrigrammeCollaborateur(item['intervenant']) + "</td>";
contenu += ' <td style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">'+ texte + "</td>";
contenu += ' <td style="width:100px;text-align:center">' + debut + "<br>" + heureDebut + "</td>";
contenu += ' <td style="width:100px;text-align:center">' + fin + "<br>" + heureFin + "</td>";
contenu += " </tr>";
nbLignes += 1;
});
contenu += " </tbody>";
contenu += " <tfoot>";
contenu += " <tr>";
contenu += ' <th colspan="5">'+setLevelPadding(2)+''+(nbLignes-1)+' tâches</th>';
contenu += " </tr>";
contenu += " </foot>";
contenu += "</table>";
element.innerHTML = contenu;
}

View File

@@ -0,0 +1,74 @@
function lancerPomodoroItem(id) {
let cur_type=null;
let modal_header='';
let modal_body='';
let modal_footer='';
items.filter(item => item.idlignes == id).forEach(resultat => {
let flagDisabled='disabled';
modal_header = getItemDialogHeader(resultat, cur_type);
modal_body += resultat.client+' > '+getTrigrammeCollaborateur(resultat.intervenant)+' : '+resultat.libelle+'<br>';
modal_body += '<textarea id="notes" data-aatribute="'+resultat.id+'" ';
modal_body += 'style="width: 100%;height: 100%;overflow: hidden;border: none;outline: none" placeholder="Saisir vos notes...">';
modal_body += '</textarea>';
modal_footer += '<div align="left" width="50%" style="float:left;padding-top:2vh">';
modal_footer += '<button onclick="todo()">Notes</button>';
modal_footer += '<button onclick="todo()">RIDA</button>';
modal_footer += '<button onclick="todo()">Documents</button>';
modal_footer += '<button onclick="todo()">Conversation</button>';
modal_footer += '</div>';
modal_footer += '<div align="right" width="50%" style="float:right;padding-top:2vh">';
modal_footer += '<button onclick="enregistrerNotes('+resultat.idlignes+')">Sauver</button>';
modal_footer += '<button onclick="arreterPomodoroItem('+resultat.idlignes+')">Fermer</button>';
modal_footer += '</div>';
});
modal_footer += '<div style="clear:both">';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
lireNotes(id);
}
function arreterPomodoroItem(id) {
// STOP le chrono
// enregistrer la saisie en cours
enregistrerNotes(id);
// Aficher les infos
itemInfo(id);
}
function enregistrerNotes(_id){
let _notes=document.getElementById('notes').value;
postData("../backend/notes.php", {id: _id, action: 'write', notes: _notes}).then((data) => {
console.log(data); // JSON data parsed by `data.json()` call
});
}
function lireNotes(_id){
postData("../backend/notes.php", {id: _id, action: 'read', notes: ''}).then((data) => {
document.getElementById('notes').value = data.notes;
});
}
/*
* Ajouter la prise en charge de "Ctrl + S" dans la textarea
*/
document.onkeydown = function(e) {
if (e.ctrlKey && e.key === 's') {
let notes = document.getElementById('notes');
if (notes) {
enregistrerNotes(notes.getAttribute('data-attribute'));
}
return false;
}
};

View File

@@ -0,0 +1,163 @@
function settingsInitModal(){
let template = document.querySelector('#settings_header');
modalSetHeader('');
modalSetBody('');
modalSetFooter('');
template = document.querySelector('#settings_header');
if (template) {
let contenu = document.importNode(template.content, true);
if (contenu) modalSetChildren('modal_header',contenu);
}
}
modal_hooks['settings'] = function(parametres){
settingsSetModeInfo();
};
modal_hooks['login'] = function(parametres){
settingsSetModeLogin();
};
function settingsSetModeInfo()
{
let template = document.querySelector('#settings_body');
settingsInitModal();
if (template) {
let contenu = document.importNode(template.content, true);
if (contenu) modalSetChildren('modal_body',contenu);
}
modalSetFooter('');
}
function settingsSetModeLogin()
{
let intervenant=getContexteValeur('intervenant');
let profil=getContexteValeur('profil');
let profils=getContexteValeur('profils');
let modal_body='';
let modal_footer='';
let profil_selector=profil;
if (profils) {
let tableau=profils.split(',');
profil_selector='<select style="width: 100%;font-size: 1em">';
tableau.forEach(element => {
let s=(element == profil) ? 'selected' : '';
profil_selector+='<option '+s+'>'+element+'</option>';
});
profil_selector+='</select>';
}
settingsInitModal();
modalSetBody(modal_body);
modalSetFooter(modal_footer);
modal_body+='<div style="height:100%;background: url(\'images/LoginBanner.jpg\');background-size: cover;display: flex;justify-content: center;align-items: center;">';
modal_body+=' <div style="background-color: rgba(255, 255, 255, 0.4); border-radius: 5px;min-width: 25%;backdrop-filter: blur(3px);display: flex;flex-direction: column;justify-content: center;align-items: center;">';
if (intervenant=='Anonymous') {
modal_body+=' <input id="login_username" type="text" placeholder="Username" style="margin: 5px;font-size: 1em;width: 200px"></input>';
modal_body+=' <input id="login_password" type="password" style="margin: 5px;font-size: 1em;width: 200px"></input>';
modal_body+=' <button style="border:none;background-color: #2196F3;width: 200px;border-radius: 5px;margin: 5px;color: white; font-size: 1em; font-weight: bold; cursor: pointer" onclick="connectUser()">Log In</button>';
} else {
modal_body+=' <h2 style="width: 200px;display: flex;text-align : center;justify-content: center;align-items: center;margin: 2px;">'+intervenant+'</h2>';
modal_body+=' <h3 style="width: 200px;display: flex;text-align : center;justify-content: center;align-items: center;margin: 5px;">'+getTrigrammeCollaborateur(intervenant)+'<h3>';
modal_body+=' <div style=""width: 200px;display: flex;text-align : center;justify-content: center;align-items: center;margin: 5px;">'+profil_selector+'</div>';
modal_body+=' <button style="border:none;background-color: grey;width: 200px;border-radius: 5px;margin: 5px;color: white; font-size: 1em; font-weight: bold; cursor: pointer" onclick="deconnectUser()">Log Out</button>';
}
modal_body+=' </div>';
modal_body+='<div>';
modalSetBody(modal_body);
}
function connectUser()
{
let username = document.getElementById('login_username').value;
let password = document.getElementById('login_password').value;
// C'est un POC donc on n'a pas de base utilisateur
if ((username!='')&&(password==username))
{
setContexteValeur('intervenant', username);
setContexteValeur('profils', 'Utilisateur');
setContexteValeur('profil', 'Utilisateur');
if (username=='TME')
{
setContexteValeur('intervenant', 'Thibaud MEUNIER');
setContexteValeur('profils', 'Utilisateur,Admin');
setContexteValeur('profil', 'Utilisateur');
}
document.getElementById('username').innerHTML=username;
}
settingsSetModeLogin();
}
function deconnectUser()
{
setContexteValeur('intervenant', 'Anonymous');
settingsSetModeLogin();
document.getElementById('username').innerHTML='Log In';
}
function settingsSetModeFilter()
{
let modal_body='';
let modal_footer='';
settingsInitModal();
modalSetBody(modal_body);
modalSetFooter(modal_footer);
modal_body+='<div style="height:100%;display: flex;justify-content: center;align-items: center;flex-direction: column;">';
modal_body+='<h2>Mode Filter</h2>';
modal_body+='<div>';
modalSetBody(modal_body);
}
function settingsSetModeSetup()
{
let modal_body='';
let modal_footer='';
settingsInitModal();
modalSetBody(modal_body);
modalSetFooter(modal_footer);
modal_body+='<div style="height:100%;width:100%;display: flex;justify-content: center;align-items: center;flex-direction: column;">';
modal_body+=' <h2>Thèmes</h2>';
modal_body+=' <div style="display:flex;">';
modal_body+=' <div style="flex: 1;border: 1px solid black;text-align: center;cursor: pointer">';
modal_body+=' <a onclick="settingsSetTheme(\'default\')">Default</a>';
modal_body+=' </div>';
modal_body+=' <div style="flex:1;border: 1px solid black;text-align: center;cursor: pointer">';
modal_body+=' <a onclick="settingsSetTheme(\'red\')" style="color:#FA0000">Red</a>';
modal_body+=' </div>';
modal_body+=' <div style="flex:1;border: 1px solid black;text-align: center;cursor: pointer">';
modal_body+=' <a onclick="settingsSetTheme(\'blue\')" style="color:#0000FA">Blue</a>';
modal_body+=' </div>';
modal_body+=' </div>';
modal_body+='<div>';
modalSetBody(modal_body);
}
function settingsSetTheme(valeur)
{
switch(valeur){
case 'blue':
CSSsetClair(245,245,240);
CSSsetSombre(0,0,245);
break;
case 'red':
CSSsetClair(245,245,240);
CSSsetSombre(245,0,0);
break;
default:
CSSsetClair(245,245,240);
CSSsetSombre(0,0,0);
}
}

View File

@@ -0,0 +1,77 @@
var clients;
function setClients(data){
clients = data;
}
getEntities('client', setClients);
function initDatagridClients() {
setClients(null);
datagridLoading();
getEntities('client', __initDatagridClients);
}
function __initDatagridClients(data) {
let element = document.querySelector('#datagrid');
let contenu='';
setClients(data);
contenu += '<table>';
contenu += ' <thead>';
contenu += ' <tr>';
contenu += ' <th>Id</th>';
contenu += ' <th>Code</th>';
contenu += ' <th>Client</th>';
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
clients.forEach(client => {
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="client:id='+client.idclient+'">';
contenu += ' <td>'+client.idclient+'</td>';
contenu += ' <td>'+client.code+'</td>';
contenu += ' <td>'+client.nom+'</td>';
contenu += ' </tr>';
});
contenu += ' </body>';
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th colspan="3">&nbsp;</th>';
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
element.innerHTML = contenu;
init_modal();
}
modal_hooks['client'] = function(parametres){
let paramSplit = parametres.split(',');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0] === 'id') {
let id = elemSplit[1];
let modal_header='Fiche client ['+id+']';
let modal_body='Client inconnu !';
let modal_footer='<button>Enregistrer</button';
clients.filter(client => client.idclient == id)
.forEach(resultat => {
modal_body = '<table class="modal_table">';
modal_body += '<tr><td style="width:30%">Id</td><td>'+resultat.idclient+'</td></tr>';
modal_body += '<tr><td style="width:30%">Code</td><td>'+resultat.code+'</td></tr>';
modal_body += '<tr><td style="width:30%">Nom</td><td>'+resultat.nom+'</td></tr>';
modal_body += '</table>';
});
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}
});
};

View File

@@ -0,0 +1,98 @@
var collaborateurs = [];
function setCollaborateurs(data){
collaborateurs = data;
}
getEntities('collaborateur', setCollaborateurs);
function getTrigrammeCollaborateur(intervenant) {
let trigramme = intervenant;
collaborateurs.forEach((collaborateur) => {
if (collaborateur.nom == intervenant) trigramme = collaborateur.trigramme;
});
return trigramme;
}
async function addCollaborateurs(collaborateur) {
let url = '../backend/api.php?entity=collaborateur';
let response = await fetch(url, {
method: "POST",
body: JSON.stringify(collaborateur),
headers: {
"Content-Type": "application/json",
},
});
let data = await response.json(); //extract JSON from the http response
}
function initDatagridCollaborateurs() {
let element = document.querySelector('#datagrid');
element.innerHTML= '<center>Loading colaborateurs ...</center>'
setCollaborateurs(null);
getEntities('collaborateur', __initDatagridCollaborateurs);
}
function __initDatagridCollaborateurs(data) {
let element = document.querySelector('#datagrid');
let contenu='';
setCollaborateurs(data);
contenu += '<table>';
contenu += ' <thead>';
contenu += ' <tr>';
contenu += ' <th>Id</th>';
contenu += ' <th>Nom</th>';
contenu += ' <th>Trigramme</th>';
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
collaborateurs.forEach(collaborateur => {
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="collaborateur:id='+collaborateur.idcollaborateur+'">';
contenu += ' <td>'+collaborateur.idcollaborateur+'</td>';
contenu += ' <td>'+collaborateur.nom+'</td>';
contenu += ' <td>'+collaborateur.trigramme+'</td>';
contenu += ' </tr>';
});
contenu += ' </body>';
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th colspan="3">&nbsp;</th>';
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
element.innerHTML = contenu;
init_modal();
}
modal_hooks['collaborateur'] = function(parametres){
let paramSplit = parametres.split(',');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0] === 'id') {
let id = elemSplit[1];
let modal_header='Fiche collaborateur ['+id+']';
let modal_body='Collaborateur inconnu !';
let modal_footer='<button>Enregistrer</button';
collaborateurs.filter(collaborateur => collaborateur.idcollaborateur == id)
.forEach(resultat => {
modal_body = '<table class="modal_table">';
modal_body += '<tr><td style="width:30%">Id</td><td>'+resultat.idcollaborateur+'</td></tr>';
modal_body += '<tr><td style="width:30%">Nom</td><td>'+resultat.nom+'</td></tr>';
modal_body += '<tr><td style="width:30%">Trigramme</td><td>'+resultat.trigramme+'</td></tr>';
modal_body += '</table>';
});
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}
});
};

View File

@@ -0,0 +1,5 @@
function getEntities(entity, callback) {
return fetch('../backend/api.php?entity='+entity)
.then(response => response.json())
.then(data => callback(data));
}

View File

@@ -0,0 +1,728 @@
var items = null;
var items_max_level = 0;
var padding_end_char = '0';
var padding_start_char = '0';
var padding_length = 8;
var useClone = true;
var itemFields = [];
var debug_item = -1;
function isDebugItem(item) {
return (item.idlignes == debug_item);
}
function getItemFromElement(element)
{
if (useClone) return (element?.clone ?? null);
return element;
}
function AddCloneToElement(element)
{
if (useClone) element.clone = Object.assign({}, element);
return useClone;
}
function setLevelPadding(level)
{
let retour = '';
if (level > 0)
for(i=0;i<level;i++) retour += '&nbsp;&nbsp;&nbsp;&nbsp;';
return retour;
}
function itemGetParentItem(item) {
return getItemFromElement(items.filter(ee => ee.idlignes == item.parent)[0]);
}
function setItems(data) {
items = data;
items_max_level = 0;
// Ajouter une copie de lui-même à chaque item
items.forEach(element => AddCloneToElement(element));
// Trouver le niveau de l'item et mettre à jour le niveau max
items.forEach(element => {
let item = getItemFromElement(element);
let parent = getItemFromElement(items.filter(ee => ee.idlignes == item.parent)[0]);
if (isDebugItem(item)){
myLog("ICI");
}
// gestion du rang vide
if (item['rank'] == '') item['rank'] = '0';
// Recherche du niveau, des ancêtres et des enfants
item['level']=0;
item['parents'] = [];
while(parent != null){
item['level'] += 1;
item['parents'].push(parent['idlignes']);
parent = getItemFromElement(items.filter(ee => ee.idlignes == parent.parent)[0]);
}
item['childs'] = [];
items.forEach(ee => {if (ee['parent'] == item['idlignes']) item['childs'].push(ee['idlignes']) });
if (items_max_level < item['level']) items_max_level = item['level']+1;
item['debut'] = item['debut']?.padEnd(12,'0') ?? '000000000000';
item['fin'] = item['fin']?.padEnd(12,'0') ?? '999999990000';
if (item['debut']=='000000000000') item['debut']=item['fin'];
item['visible'] = true;
// En mode feuille, seules les feuilles sont visibles
if (getParametreValeur(['mode_feuille']))
if (item['childs'].length != 0)
item['visible'] = false;
});
// Gestion de l'héritage des propriétés
// On en profite pour calculer le chemin de l'item
// Et pour calculer une valeur qui permette le tri dans l'affiche tree
// ie
let heritage = ['contrat','projet','intervenant','client'];
for(i=0;i<items_max_level+1;i++) {
items.forEach(element => {
let item = getItemFromElement(element);
if (item['level']==i) {
let parent = getItemFromElement(items.filter(ee => ee.idlignes == item.parent)[0]);
item['path'] = item['rank'].padStart(3,padding_start_char)+item['idlignes'].padStart(padding_length,padding_start_char);
item['tritree']=item['path'];
if (parent != null) {
item['tritree']=parent['tritree']+item['debut']+item['tritree'];
item['path'] = parent['path']+item['path'];
for(var field in parent)
if (heritage.indexOf(field) !== -1)
if ((item[field] == null)||(item[field]==''))
item[field] = parent[field];
}
}
});
}
// Gestion de la remontée des propriétés
for(i=items_max_level+1;i>=0;i--) {
items.forEach(element => {
let item = getItemFromElement(element);
if (item['level']==i) {
if (item.childs.length != 0) {
item.jours_commandes = 0.0;
item.jours_planifies = 0.0;
item.jours_realises = 0.0;
item.childs.forEach(child => {
let childElement = items.filter(ee => ee.idlignes == child)[0];
let enfant = getItemFromElement(childElement);
if (isDebugItem(item)){
myLog("ICI");
}
item.jours_commandes += customParseFloat(enfant.jours_commandes);
item.jours_planifies += customParseFloat(enfant.jours_planifies);
item.jours_realises += customParseFloat(enfant.jours_realises);
});
}
}
// L'element porte une commande, on annule le calcul
if (customParseFloat(element.jours_commandes) > 0) item.jours_commandes = element.jours_commandes;
});
}
}
// -----------------------------------------------------------------------------
// ---- Cette fonction détermine la visibilité des item
// -----------------------------------------------------------------------------
function setItemsVisibility(){
let mode_affichage=getContexteValeur('mode_affichage');
let termine=getContexteValeur('termine');
let client = getContexteValeur('client');
let level = parseInt(getContexteValeur('level'));
let idfiltre = stringDatePadDigits(parseInt(getContexteValeur('parent')),8);
/*
TODO : Faire la part des choses entre "contexte" et "filtre"
A priori :
Un filtre dépend des données exemples
- filtrer parmi les clients
- filtrer parmi les niveaux
Un contexte dépend de l'appli, exemples
- utilistaeur connecté
- mode d'affichage courant
*/
client = getFiltreValeur('client');
level = parseInt(getFiltreValeur('level'));
if (idfiltre != '00000000'){
let itemFiltre = getItemFromElement(items.filter(ee => ee.idlignes == parseInt(idfiltre))[0]);
if (itemFiltre) level += itemFiltre['level'];
}
// Gestion de la visibilité individuelle
// Que l'on va appeler 'filtre'
items.forEach(element => {
let item = getItemFromElement(element);
if (isDebugItem(item)){
myLog("ICI");
}
item['visible'] = true;
// Contrôle du statut
if ((item['status'] != 0)&&(item['status'] != 3)) item['visible'] = false;
// Contrôle du client courant
if ((client != '') && (client != item['client'])) item['visible'] = false;
// Contrôle du niveau courant
if (item['level'] > level) item['visible'] = false;
// Cas particulier
// ABS = Absences
// FER = Fériés
// REL = Releases de version
// RDV = Rendez-Vous
switch(mode_affichage){
case 'absences':
if (item['client'] != 'ABS') item['visible'] = false;
break;
case 'releases':
if (item['client'] != 'REL') item['visible'] = false;
break;
case 'feries':
if (item['client'] != 'FER') item['visible'] = false;
break;
case 'rdv':
if (item['client'] != 'RDV') item['visible'] = false;
break;
case 'planning':
case 'calendar_intervenants':
case 'calendar_clients':
break;
default:
//if (item['client'] == 'ABS') item['visible'] = false;
if (item['client'] == 'RDV') item['visible'] = false;
if (item['client'] == 'FER') item['visible'] = false;
if (item['client'] == 'REL') item['visible'] = false;
}
// Appliquer le filtre
if ((idfiltre != '00000000') && (!item['path'].includes(idfiltre))) item['visible'] = false;
if ((termine=='non')&&(item['status']!=0)) item['visible']=false;
// La racine est toujours visible
// if (item['idlignes'] == 1) item['visible'] = true;
});
// Gestion des statuts hérités
// Si un parent est terminé alors ses enfants aussi
for(i=0; i<items_max_level+1;i++) {
items.forEach(element => {
let item = getItemFromElement(element);
if (item['level']==i) {
let parent = itemGetParentItem(item);
if (parent != null)
if (parent['status'] != 0) {
item['visible'] = false;
}
}
});
}
// Gestion de la visibilité héritée
// Si un enfant est visible alors ses parents aussi
for(i=items_max_level+1;i>=0;i--) {
items.forEach(element => {
let item = getItemFromElement(element);
if (item['level']==i) {
if (item['visible']) {
let parent = itemGetParentItem(item);
if (parent != null)
parent['visible'] = true;
}
}
});
}
}
// -----------------------------------------------------------------------------
// ---- foncttons de tri des items
// -----------------------------------------------------------------------------
function sort2ItemsByField(item_a, item_b, field){
let retour = 0;
if (item_a[field] < item_b[field]) retour = -1;
if (item_a[field] > item_b[field]) retour = 1;
return retour;
}
function sort2ItemsByDates(item_a, item_b){
let retour = 0;
let maintenant = formatDatetoStringDateTime(new Date);
// Par défaut, on trie par date de début
let val_a = item_a['debut']?.padEnd(12,'0');
let val_b = item_b['debut']?.padEnd(12,'0');
// Sauf si l'item est en cours.
if ((item_a.debut < maintenant)&&(item_a.fin>=maintenant))
val_a = item_a['fin']?.padEnd(12,'0');
if ((item_b.debut < maintenant)&&(item_b.fin>=maintenant))
val_b = item_b['fin']?.padEnd(12,'0');
// Ce qui n'est pas planifié est plus tard que le reste
if (val_a == '') val_a = '999999999999';
if (val_b == '') val_b = '999999999999';
if (val_a < val_b) return -1;
if (val_a > val_b) return 1;
// retour = sort2ItemsByField(item_a, item_b, 'debut');
// if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'rank');
if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'idlignes');
if (retour != 0) return retour;
return retour;
}
function sort2ItemsByStartDates(item_a, item_b){
retour = sort2ItemsByField(item_a, item_b, 'debut');
if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'fin');
if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'idlignes');
if (retour != 0) return retour;
return 0;
}
function sort2ItemsByEndDates(item_a, item_b){
retour = sort2ItemsByField(item_a, item_b, 'fin');
if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'debut');
if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'idlignes');
if (retour != 0) return retour;
return 0;
}
function sortItemsByDate(){
let maintenant = formatDatetoStringDateTime(new Date);
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
// Par défaut, on trie par date de début
let val_a = item_a['debut'];
let val_b = item_b['debut'];
// Sauf si l'item est en cours.
if ((item_a.debut < maintenant)&&(item_a.fin>=maintenant))
val_a = item_a['fin'];
if ((item_b.debut < maintenant)&&(item_b.fin>=maintenant))
val_b = item_b['fin'];
if (val_a < val_b) return -1;
if (val_a > val_b) return 1;
return sort2ItemsByStartDates(item_a, item_b);
});
}
function sortItemsByEndDate() {
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
return sort2ItemsByEndDates(item_a, item_b);
});
}
function sortItemsByStartDate() {
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
return sort2ItemsByStartDates(item_a, item_b);
});
}
/* TO DELETE
function sortItemsByPath() {
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
return sort2ItemsByField(item_a, item_b, 'path');
});
}
*/
function sortItemsByTriTreeValue() {
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
return sort2ItemsByField(item_a, item_b,'tritree');
});
}
function sortItemsByPathDates() {
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
let retour = 0;
// Les 2 items sont des feuilles du même parent
// On les trie par rang puis par dates
if ((item_a.childs.length == 0)&&(item_b.childs.length == 0)){
if (item_a.parent === item_b.parent){
retour = sort2ItemsByField(item_a, item_b,'rank');
if (retour == 0) retour = sort2ItemsByDates(item_a, item_b);
}
}
if (retour == 0) retour = sort2ItemsByField(item_a, item_b,'path');
return retour;
});
}
function sortItemsByClientParentDates() {
return sortItemsByTriTreeValue();
}
/* TO DELETE
function sortItemsModeTasks() {
sortItemsByPath();
}
*/
// -----------------------------------------------------------------------------
// ---- Cette fonction charge les items
// -----------------------------------------------------------------------------
function initDatagridItems() {
datagridLoading();
return getEntities(getContexteValeur('items_type'), __initDatagridItems);
}
function __initDatagridItems(data) {
setItems(data);
return afficherItems();
}
// -----------------------------------------------------------------------------
// ---- Placer un filtre
// -----------------------------------------------------------------------------
function filtrerItem(id){
items.filter(item => item.idlignes == id).forEach(element => {
let item=getItemFromElement(element);
setContexteValeur('parent',id);
setContexteValeur('client',item['client']);
setContexteValeur('parent_level',item['level']);
});
gotoTop();
afficherItems();
}
// -----------------------------------------------------------------------------
// ---- Cette fonction détermine l'entité à afficher en fonction du contexte
// -----------------------------------------------------------------------------
function clearElement(idElement){
let element = document.querySelector(idElement);
if (element) element.innerHTML = '';
}
function afficherItems() {
let callback_affichage = datagrid_hooks[getContexteValeur('mode_affichage')];
clearElement("#datagrid");
clearElement("#calendrier");
setItemsVisibility();
if (callback_affichage === null) callback_affichage = datagrid_hooks['items'];
callback_affichage();
init_modal();
}
// -------------------------------------------------------------------------------------------------
// ---- Édition générique des items
// -------------------------------------------------------------------------------------------------
var items_edit_hooks = [];
var item_save_hooks = [];
function editerItem(id,libelle){
let callback_edition=items_edit_hooks[getContexteValeur('type_courant')];
items.filter(item => item.idlignes == id).forEach(resultat => {
callback_edition = items_edit_hooks[resultat.type];
});
if ((callback_edition===null)||(callback_edition===undefined)) {
callback_edition = items_edit_hooks['ITEM'];
}
return callback_edition(id, libelle);
}
function itemAPI(idlignes, bodyJSON) {
let url = '../backend/api.php?entity=lignes';
if (idlignes != 1) // On ne sauve pas la racine
{
if (idlignes != -1) url += '&id='+idlignes;
fetch(url, {
method: 'POST',
body: bodyJSON, // string or object
headers: {
'Content-Type': 'application/json'
}
}).then((response) => response.json()).then((objet) => {
initDatagridItems()
.then(() => {
if (idlignes != -1) itemInfo(idlignes);
else close_modal();
});
});
}
}
function itemInfo(id){
let cur_type='ITEM';
items.filter(item => item.idlignes == id).forEach(resultat => {
cur_type=resultat.type;
});
return modal_hooks['ITEM']('type='+cur_type+':id='+id);
}
function itemSave(type, id){
return item_save_hooks[type](id);
}
function itemChangeAttribut(id, attribut, valeur) {
let bodyJSON = '{"idlignes":'+id+', "'+attribut+'": "'+valeur+'"}';
return itemAPI(id, bodyJSON, itemInfo);
}
function eventItemChangeType(id, event) {
return itemChangeAttribut(id, 'type',event.target.value);
}
function eventItemChangeStatus(id, event) {
return itemChangeAttribut(id, 'status',event.target.value);
}
// -------------------------------------------------------------------------------------------------
// ---- Gestion générique des items
// -------------------------------------------------------------------------------------------------
itemFields['ITEM'] = ['parent','type','client','intervenant','libelle'];
let last_path='';
let last_path_retour;
function explodePath(path, id)
{
let retour = '';
let start = 0;
const nb_numeros = 3;
if (!last_path.includes(path)) last_path=path;
if (last_path.length > nb_numeros*8) {
start = (last_path.length - (nb_numeros*11));
retour = '... > ';
}
for(let i=start;i<last_path.length;i+=11){
let split = parseInt(last_path.substring(i,i+11));
if (split != 1) {
if (id == split) split = '<b>'+split+'</b>';
if (i>start) retour += ' > ';
retour += '<span onclick="itemInfo('+split+')" style="cursor: pointer">'+split+'</span>';
}
else retour = '...';
}
return retour ;
}
datagrid_hooks['items'] = function(){
let element = document.querySelector("#datagrid");
let contenu = "";
sortItemsByTriTreeValue();
contenu += '<table width="100vw">';
contenu += " <thead>";
contenu += " <tr>";
contenu += ' <th style="width:50px"><span class="nouveau" onclick="editerItem(-1,\'\')">Nouveau</span></th>';
contenu += ' <th colspan="2">&nbsp;</th>';
contenu += ' <th><span class="filtrer">Filtre</span></th>';
contenu += " </tr>";
contenu += " <tr>";
contenu += ' <th style="width:50px">Client</th>';
contenu += " <th>Libelle</th>";
contenu += " <th><center>Type</center></th>";
contenu += " <th><center>État</center></th>";
contenu += " </tr>";
contenu += " </thead>";
contenu += " <tbody>";
items.forEach((element) => {
let item = getItemFromElement(element);
let texte = getNonNullTextValeur(item.libelle);
if (item.status == 3) texte = "<strike>" + texte + "</strike>";
// On n'affiche pas la racine
if (item["idlignes"] == 1) return true;
// On n'affiche que ce qui est marqué comme visible
if (!item["visible"]) return true;
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="'+item.type+':id=' + item.idlignes + '">';
contenu += ' <td style="width:50px">' + item.client + '</td>';
contenu += " <td>" + setLevelPadding(item["level"]) + texte + "</td>";
contenu += ' <td><center>' + item.type + "</center></td>";
contenu += " <td><center>" + getStatusLibelleFromId(item.status) + "</center></td>";
contenu += " </tr>";
});
contenu += " </body>";
contenu += " <tfoot>";
contenu += " <tr>";
contenu += ' <th colspan="4">&nbsp;</th>';
contenu += " </tr>";
contenu += " </foot>";
contenu += "</table>";
element.innerHTML = contenu;
}
function getItemDialogHeader(item){
let retour='';
let liste_select_types = ['TODO','TACHE','PRESTATION','ITEM'];
retour += '<select onchange="eventItemChangeType('+item.idlignes+',event)">';
liste_select_types.forEach((valeur)=>{
let selected = '';
if (valeur == item.type) selected='selected';
retour += '<option value="'+valeur+'" '+selected+'>'+valeur+'</opton>';
});
retour += '</select><br>';
retour += ' n°'+explodePath(item.clone.path,item.idlignes);
return retour;
}
modal_hooks['ITEM'] = function(parametres){
let cur_type=null;
let cur_id=null;
let modal_header='';
let modal_body='item inconnu !';
let modal_footer='';
let paramSplit = parametres.split(':');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0]==='type') cur_type=elemSplit[1];
if (elemSplit[0]==='id') cur_id=elemSplit[1];
});
if (itemFields[cur_type]===undefined) cur_type='ITEM';
items.filter(item => item.idlignes == cur_id).forEach(resultat => {
let liste_status = ['Planifié', 'Supprimé', 'Annulé', 'Terminé','Reporté'];
modal_header = getItemDialogHeader(resultat);
modal_body = '<table class="modal_table">';
itemFields[cur_type].forEach(attribut => {
let valeur = getNonNullTextValeur(resultat[attribut]);
if (attribut =='libelle') valeur = '<b>'+valeur+'</b>';
modal_body += '<tr class="tr1"><td>'+attribut+'</td><td>'+valeur+'</td></tr>';
});
modal_body += '</table>';
modal_footer += '<div align="left" width="50%" style="float:left;padding-top:2vh">';
modal_footer += '<button onclick="editerItem('+resultat.idlignes+',null)">Modifier</button>';
modal_footer += '<button onclick="filtrerItem('+resultat.idlignes+')">Filtrer</button> ';
modal_footer += '</div>';
modal_footer += '<div align="right" width="50%" style="float:right;padding-top:2vh">';
modal_footer += '<button onclick="lancerPomodoroItem('+resultat.idlignes+')">Lancer</button>';
modal_footer += '<select onchange="eventItemChangeStatus('+resultat.idlignes+',event)">';
liste_status.forEach((valeur,index)=>{
let selected = '';
if (index == resultat.status) selected='selected';
modal_footer += '<option value="'+index+'" '+selected+'>'+valeur+'</option>';
});
modal_footer += '</select><br>';
modal_footer += '</div>';
});
modal_footer += '<div style="clear:both">';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}
items_edit_hooks['ITEM'] = function (id, libelle) {
let modal_header='';
let modal_body='Item inconnu !';
let modal_footer='<div align="right" width="100%" style="padding-top:2vh"><button onclick="itemSave('+id+')">Enregistrer</button></div>';
let local_values = [];
let local_placeholder = [];
local_values['parent']=getContexteValeur('parent');
local_values['type']=getContexteValeur('type_courant');
local_values['client']=getContexteValeur('client');
local_values['intervenant']=getContexteValeur('intervenant');
local_values['libelle']=libelle;
if (local_values['client']=='') local_values['client']=getTrigrammeCollaborateur(local_values['intervenant']);
items.filter(item => item.idlignes == id).forEach(resultat => {
local_values['type']=resultat['type'];
itemFields[local_values['type']].forEach(attribut => {
local_values[attribut]=resultat[attribut];
local_placeholder[attribut]=resultat.clone[attribut];
});
});
modal_header=local_values['type'];
if (id != -1) modal_header+=' n°<b>'+id+'</b>';
modal_body = '<table class="modal_table"><form id="formulaire_lignes">';
itemFields[local_values['type']].forEach(attribut => {
modal_body += '<tr><td>'+attribut+'</td><td>'+getInputLabel(attribut,local_values[attribut], local_placeholder[attribut])+'</td></tr>';
});
modal_body += '</form></table>';
modal_footer='<div align="left" width="100%" style="padding-top:2vh"><button onclick="itemSave(\''+local_values['type']+'\','+id+')">Enregistrer</button></div>';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
if (!modalDialog.open) modalDialog.showModal();
}

View File

@@ -0,0 +1,118 @@
itemFields['PRESTATION'] = ['libelle','parent','rank','client','intervenant','debut','fin','contrat','projet','jours_commandes','jours_planifies','jours_realises'];
datagrid_hooks['prestations'] = function() {
let element = document.querySelector("#datagrid");
let contenu = "";
let nbLignes = 1;
let parentLevel=getContexteValeur('parent_level');
let showPrestationsOnly=(getContexteValeur('prestation')=='oui');
if (parentLevel == 0) parentLevel=1;
sortItemsByClientParentDates();
contenu += "<table>";
contenu += " <thead>";
contenu += " <tr>";
contenu += ' <th colspan="6" onchange="updateValue(event)"><input id="newitem_input" type="text" placeholder="Nouvel item" style="width: 98%;outline: none"></th>';
contenu += " </tr>";
contenu += " <tr>";
// contenu += " <th><center>Id</center></th>";
contenu += ' <th style="width:50px;text-align:center"><span onclick="openFiltrePopup(\'client\')">Client</span></th>';
contenu += ' <th style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'libelle\')">Libellé</span></th>';
contenu += ' <th style="max-width:150px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'contrat\')">Contrat</span></th>';
contenu += ' <th style="max-width:150px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'libelle\')">Commandés</span></th>';
contenu += ' <th style="max-width:150px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'libelle\')">Prévus</span></th>';
contenu += ' <th style="max-width:150px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'libelle\')">Réalisés</span></th>';
// contenu += " <th><center>État</center></th>";
contenu += " </tr>";
contenu += " </thead>";
contenu += " <tbody>";
items.forEach((element) => {
let item = getItemFromElement(element);
let texte = getNonNullTextValeur(item.libelle);
let commandes = "-";
let planifies = "-";
let realises = "-";
// On n'affiche pas la racine
if (item["idlignes"] == 1) return true;
// On n'affiche que ce qui est marqué comme visible
if (!item["visible"]) return true;
if ((showPrestationsOnly)&&((item.jours_commandes + item.jours_realises+item.jours_planifies) == 0)) return true;
if (item.status == 3) texte = "<strike>" + texte + "</strike>";
if (item.status == 2) texte = "<strike>" + texte + "</strike>";
if (item.jours_commandes > 0)
commandes = convertJourHeure(getNonNullTextValeur(item.jours_commandes));
if (item.jours_realises > 0)
realises = convertJourHeure(getNonNullTextValeur(item.jours_realises));
if (item.jours_planifies > 0)
planifies = convertJourHeure(getNonNullTextValeur(item.jours_planifies));
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="type='+item.type+':id=' + getNonNullTextValeur(item.idlignes) + '">';
//contenu += " <td><center>" + getNonNullTextValeur(item.idlignes) + "</center></td>";
contenu += ' <td style="width:50px;text-align:center">' + getNonNullTextValeur(item.client) + '</td>';
contenu += ' <td style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + setLevelPadding(item["level"]-parentLevel) + texte + '</td>';
contenu += ' <td style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + getNonNullTextValeur(item.contrat) + '</td>';
contenu += ' <td style="width:50px;text-align:center">' + commandes + '</td>';
contenu += ' <td style="width:100px;text-align:center">' + planifies + '</td>';
contenu += ' <td style="width:100px;text-align:center">' + realises + '</td>';
//contenu += " <td>" + getStatusLibelleFromId(item.status) + '</td>';
contenu += " </tr>";
nbLignes += 1;
});
contenu += " </tbody>";
contenu += " <tfoot>";
contenu += " <tr>";
contenu += ' <th colspan="6">'+setLevelPadding(2)+''+(nbLignes-1)+' tâches</th>';
contenu += " </tr>";
contenu += " </foot>";
contenu += "</table>";
element.innerHTML = contenu;
// Ne marche pas , ça enlève le stick du header du tableau ...
// document.getElementById('newitem_input').focus({preventScroll: true});
}
function prestationSave(idlignes) {
let bodyJSON = JSON.stringify(getCurrentPRESTATION(idlignes));
return itemAPI(idlignes, bodyJSON, itemInfo);
}
item_save_hooks['PRESTATION'] = prestationSave;
function getCurrentPRESTATION(idlignes)
{
let result = new Object();
if (idlignes > 1) {
result['idlignes'] = idlignes;
} else {
result['type']=getContexteValeur('type_courant');
}
itemFields['PRESTATION'].forEach(attribut => {
result[attribut] = documentGetElementById('item_'+attribut);
});
if (result['parent']=='') result['parent']=1;
if (result['client']=='') result['client']==getTrigrammeCollaborateur(result['intervenant']);
if (result['libelle']=='') result['libelle']='xxxxxxxxxxxx';
if (result['intervevant']=='') result['intervenant']=getContexteValeur('intervenant');;
if (result['debut']=='') result['debut']=0;
if (result['fin']=='') result['fin']=0;
if (result['status']=='') result['status']=0;
return result;
}

View File

@@ -0,0 +1,106 @@
itemFields['TACHE'] = ['libelle','parent','rank','client','intervenant','debut','fin'];
datagrid_hooks['taches'] = function() {
let element = document.querySelector("#datagrid");
let contenu = "";
let nbLignes = 1;
let parentLevel=getContexteValeur('parent_level');
if (parentLevel == 0) parentLevel=1;
sortItemsByClientParentDates();
contenu += "<table>";
contenu += " <thead>";
contenu += " <tr>";
contenu += ' <th colspan="4" onchange="updateValue(event)"><input id="newitem_input" type="text" placeholder="Nouvel item" style="width: 98%;outline: none"></th>';
contenu += " </tr>";
contenu += " <tr>";
// contenu += " <th><center>Id</center></th>";
contenu += ' <th style="width:50px;text-align:center"><span onclick="openFiltrePopup(\'client\')">Client</span></th>';
contenu += ' <th style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'libelle\')">Libellé</span></th>';
contenu += ' <th style="width:100px;text-align:center"><span onclick="openFiltrePopup(\'debut\')">Début</span></th>';
contenu += ' <th style="width:100px;text-align:center"><span onclick="openFiltrePopup(\'fin\')">Fin</span></th>';
// contenu += " <th><center>État</center></th>";
contenu += " </tr>";
contenu += " </thead>";
contenu += " <tbody>";
items.forEach((element) => {
let item = getItemFromElement(element);
let texte = getNonNullTextValeur(item.libelle);
if (item.status == 3) texte = "<strike>" + texte + "</strike>";
if (item.status == 2) texte = "<strike>" + texte + "</strike>";
// On n'affiche pas la racine
if (item["idlignes"] == 1) return true;
// On n'affiche que ce qui est marqué comme visible
if (!item["visible"]) return true;
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="type='+item.type+':id=' + getNonNullTextValeur(item.idlignes) + '">';
//contenu += " <td><center>" + getNonNullTextValeur(item.idlignes) + "</center></td>";
contenu += ' <td style="width:50px;text-align:center">' + getNonNullTextValeur(item.client) + "</td>";
contenu += ' <td style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + setLevelPadding(item["level"]-parentLevel) + texte + "</td>";
contenu += ' <td style="width:100px;text-align:center">' + formatLocaleDateFromStringDate(item.debut) + "</td>";
contenu += ' <td style="width:100px;text-align:center">' + formatLocaleDateFromStringDate(item.fin) + "</td>";
//contenu += " <td>" + getStatusLibelleFromId(item.status) + "</td>";
contenu += " </tr>";
nbLignes += 1;
});
contenu += " </tbody>";
contenu += " <tfoot>";
contenu += " <tr>";
contenu += ' <th colspan="4">'+setLevelPadding(2)+''+(nbLignes-1)+' tâches</th>';
contenu += " </tr>";
contenu += " </foot>";
contenu += "</table>";
element.innerHTML = contenu;
// Ne marche pas , ça enlève le stick du header du tableau ...
// document.getElementById('newitem_input').focus({preventScroll: true});
}
// on affiche ces éléments comme des tâches
datagrid_hooks['absences'] = datagrid_hooks['taches'];
datagrid_hooks['releases'] = datagrid_hooks['taches'];
datagrid_hooks['feries'] = datagrid_hooks['taches'];
datagrid_hooks['rdv'] = datagrid_hooks['taches'];
function taskSave(idlignes) {
let bodyJSON = JSON.stringify(getCurrentTASK(idlignes));
return itemAPI(idlignes, bodyJSON, itemInfo);
}
item_save_hooks['TACHE'] = taskSave;
function getCurrentTASK(idlignes)
{
let result = new Object();
if (idlignes > 1) {
result['idlignes'] = idlignes;
} else {
result['type']=getContexteValeur('type_courant');
}
itemFields['TACHE'].forEach(attribut => {
result[attribut] = documentGetElementById('item_'+attribut);
});
if (result['parent']=='') result['parent']=1;
if (result['client']=='') result['client']==getTrigrammeCollaborateur(result['intervenant']);
if (result['libelle']=='') result['libelle']='xxxxxxxxxxxx';
if (result['intervevant']=='') result['intervenant']=getContexteValeur('intervenant');;
if (result['debut']=='') result['debut']=0;
if (result['fin']=='') result['fin']=0;
if (result['status']=='') result['status']=0;
return result;
}

View File

@@ -0,0 +1,525 @@
itemFields['TODO'] = ['libelle','parent','client','intervenant','fin'];
function todoListLigne(item, style)
{
let retour = '';
let client = getNonNullTextValeur(item.client);
let intervenant = getTrigrammeCollaborateur(item.intervenant);
let texte = getNonNullTextValeur(item.libelle);
let date = item.fin;
let classe = 'class="js-open-modal-trigger" data-modal-info="type='+item.type+':id='+item.idlignes+'"';
let maintenant = formatDatetoStringDateTime(new Date);
let localStyle=style;
if (item.status == 3) localStyle = 'text-decoration: line-through';
// Si l'item n'est pas un jalon
// Si son début est dans le futur
// On affiche le début
if (item.type != 'TODO')
if (item.debut > maintenant)
date = item.debut;
// Ce qui est prévu pour aujourd'hui ou demain
// On affiche l'heure
if ((date.substring(0,8) == todayStringDate.substring(0,8))||(date.substring(0,8) == tomorrowStringDate.substring(0,8))) {
date = formatTimeFromStringDate(date)
} else {
date = formatLocaleDateFromStringDate(date);
}
if (intervenant != '')
if (intervenant != client)
texte = ' ['+intervenant+'] '+texte;
if (client != '') texte = '['+client+'] '+texte;
if (item.type == 'TODO')
texte = '[&diams;] '+texte;
else
texte = '[&curren;] '+texte;
retour += ' <tr '+classe+' style="'+localStyle+'">';
retour += ' <td style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-left:15px">'+texte+'</td>';
retour += ' <td style="width:100px;text-align:center">'+date+'</td>';
retour += ' </tr>';
return retour;
}
function todoListSection(section, style)
{
let retour = '';
retour += ' <tr style="'+style+'">';
retour += ' <td colspan="3" style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-left:5px">'+section+'</td>';
retour += ' </tr>';
return retour;
}
function getNonNullTextValeur(valeur){
let val = valeur;
if ((val===null)||(val===undefined)) val = '';
return val;
}
function getNonNullDateValeur(valeur){
if (valeur === null) return '';
if (valeur == 0) return '';
return valeur;
}
function getInputLabel(nom, valeur, placeholder) {
return '<input style="width:99%;border:none" type="text" name="'+nom+'" id="item_'+nom+'" value="'+getNonNullTextValeur(valeur)+'" placeholder="'+getNonNullTextValeur(placeholder)+'"></input>';
}
function todoTermine(idlignes) {
myError('Fonction Obsolète : '+arguments.callee.name);
return itemTermine(idlignes,'TODO');
}
function todoSave(idlignes) {
let bodyJSON = JSON.stringify(getCurrentTODO(idlignes));
return itemAPI(idlignes, bodyJSON, itemInfo);
}
function getCurrentTODO(idlignes)
{
let result = new Object();
if (idlignes > 1) {
result['idlignes'] = idlignes;
} else {
result['type']=getContexteValeur('type_courant');
}
itemFields['TODO'].forEach(attribut => {
result[attribut] = documentGetElementById('item_'+attribut);
});
if (result['parent']=='') result['parent']=1;
if (result['client']=='') result['client']=getTrigrammeCollaborateur(result['intervenant']);
if (result['libelle']=='') result['libelle']='xxxxxxxxxxxx';
if (result['intervevant']=='') result['intervenant']=getContexteValeur('intervenant');;
if (result['fin']=='') result['fin']=0;
if (result['status']=='') result['status']=0;
return result;
}
datagrid_hooks['todos'] = function(){
let datagrid = document.querySelector('#datagrid');
let synthesis = document.querySelector('#synthesis_body');
let thisWeek = parseInt(stringdateGetWeekOfYear(todayStringDate));
let thisMonth = parseInt(todayStringDate.substring(0,6));
let thisYear = parseInt(todayStringDate.substring(0,4));
let client = getContexteValeur('client');
let termine = getContexteValeur('termine');
let nextWeek = thisWeek + 1;
let nextMonth = thisMonth + 1;
let nextYear = thisYear + 1;
let contenu='';
let synthese1='';
let synthese2='';
let nb_lignes=0;
let lignes_vides=0;
let liste_retard='';
let liste_today='';
let liste_tomorrow='';
let liste_thisWeek='';
let liste_nextWeek='';
let liste_thisMonth='';
let liste_nextMonth='';
let liste_thisYear='';
let liste_nextYear='';
let liste_noplanning = '';
let liste_before='';
let liste_finished='';
let liste_encours='';
let liste_todo='';
let tableau_before=[];
let tableau_finished=[];
let tableau_encours=[];
let tableau_todo=[];
let tableau_retard=[];
let tableau_today=[];
let tableau_tomorrow=[];
let tableau_thisWeek=[];
let tableau_nextWeek=[];
let tableau_thisMonth=[];
let tableau_nextMonth=[];
let tableau_thisYear=[];
let tableau_nextYear=[];
let tableau_noplanning=[];
let stats = 0;
// Gérer les fins d'année
if (nextWeek > parseInt(stringdateGetWeek(thisYear+'12310000'))) nextWeek = parseInt(nextYear+'01');
if (nextMonth > parseInt(thisYear+'12')) nextMonth = parseInt(nextYear+'01');
sortItemsByDate();
contenu += '<table>';
contenu += ' <thead>';
contenu += " <tr>";
contenu += ' <th colspan="2" onchange="updateValue(event)"><input id="newitem_input" type="text" placeholder="Nouvel item" style="width: 98%;outline: none"></th>';
contenu += " </tr>";
contenu += ' <tr>';
contenu += ' <th style="padding-left:5px"><span onclick="openFiltrePopup(\'libelle\')">Libellé</span></th>';
contenu += ' <th style="width:100px;text-align:center"><span onclick="openFiltrePopup(\'fin\')">Échéance</span></th>';
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
liste = '';
items.forEach(element => {
let item = getItemFromElement(element);
let itemWeek = parseInt(stringdateGetWeekOfYear(item.fin.substring(0,8)));
let itemMonth = parseInt(item.fin.substring(0,6));
let itemYear = parseInt(item.fin.substring(0,4));
// On n'affiche pas la racine
if (item['idlignes']==1) return true;
// On n'affiche que ce qui est marqué comme visible
if (!item['visible']) return true;
// On n'affiche que les feuilles
if (item.childs.length>0) return true;
if (item.status == 1) return true;
if (item.status == 2) return true;
if (termine=='non')
if (item['status']==3) return true;
if (client!='')
if (item['client']!=client) return true;
// Ce qui est non planifié
if ((item.fin.substring(0,8) == '00000000')&&(item.status == 0)) {
tableau_noplanning.push(todoListLigne(item,'color:var(--nuance-sombre-06)'));
return true;
}
// Ce qui était pour avant cette année
if (item.fin.substring(0,8) < thisYear+'0101')
tableau_before.push(todoListLigne(item,''));
// Ce qui est terminé
if (item.status == 3)
tableau_finished.push(todoListLigne(item,''));
else
tableau_todo.push(todoListLigne(item,''));
// Ce qui est en retard
if ((item.status == 0)&&(item.fin < todayStringDate)) {
tableau_retard.push(todoListLigne(item,''));
return true;
}
// Ce qui est prévu pour aujourd'hui
if (((item.status == 0)||(item.status == 3))&&(item.fin.substr(0,8) == todayStringDate.substr(0,8))) {
tableau_today.push(todoListLigne(item,'font-weight:bold'));
return true;
}
// Ce qui est prévu pour demain
if (((item.status == 0)||(item.status == 3))&&(item.fin.substr(0,8) == tomorrowStringDate.substr(0,8))) {
tableau_tomorrow.push(todoListLigne(item,'font-weight:bold'));
return true;
}
// Ce qui est prévu cette semaine
if (item.fin.substring(0,8) > thisYear+'0101')
if (itemWeek == thisWeek) {
tableau_thisWeek.push(todoListLigne(item,'font-weight:bold'));
return true;
}
if (item.status != 0) return true;
// Les tâches qui ont commencé et qui ne sont pas finies
if (item.debut.substr(0,8) < todayStringDate.substr(0,8))
if (item.fin.substr(0,8) > todayStringDate.substr(0,8)) {
if (item.type != 'TODO') tableau_encours.push(todoListLigne(item,'font-weight:bold'));
return true;
}
// Ce qui est prévu la semaine prochaine
if (itemWeek == nextWeek) {
tableau_nextWeek.push(todoListLigne(item,'color:var(--nuance-sombre-09)'));
return true;
}
// Ce qui est prévu ce mois-ci
if (itemMonth == thisMonth) {
tableau_thisMonth.push(todoListLigne(item,'color:var(--nuance-sombre-09)'));
return true;
}
// Ce qui est prévu le mois prochain
if (itemMonth == nextMonth) {
tableau_nextMonth.push(todoListLigne(item,'color:var(--nuance-sombre-09)'));
return true;
}
// Ce qui est prévu cette année
if (itemYear == thisYear) {
tableau_thisYear.push(todoListLigne(item,'color:var(--nuance-sombre-09)'));
return true;
}
// Ce qui est prévu l'année prochaine
if (itemYear == nextYear) {
tableau_nextYear.push(todoListLigne(item,'color:var(--nuance-sombre-06)'));
return true;
}
return true;
});
if (tableau_before.length!=0){
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox2">Avant<br>'+tableau_before.length+'</div>';
}
if (tableau_today.length!=0){
liste_today += tableau_today.join('');
nb_lignes += tableau_today.length;
}
stats=tableau_today.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox1">Aujourd\'hui<br>'+stats+'</div>';
if (tableau_tomorrow.length!=0){
liste_tomorrow += tableau_tomorrow.join('');
nb_lignes += tableau_tomorrow.length;
}
stats+=tableau_tomorrow.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox1">Demain<br>'+tableau_tomorrow.length+'</div>';
if (tableau_thisWeek.length!=0){
liste_thisWeek += tableau_thisWeek.join('');
nb_lignes += tableau_thisWeek.length;
}
stats+=tableau_thisWeek.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox1">Cette semaine<br>'+stats+'</div>';
if (tableau_nextWeek.length!=0){
liste_nextWeek += tableau_nextWeek.join('');
nb_lignes += tableau_nextWeek.length;
}
stats+=tableau_nextWeek.length;
if (tableau_thisMonth.length!=0){
liste_thisMonth += tableau_thisMonth.join('');
nb_lignes += tableau_thisMonth.length;
}
stats+=tableau_thisMonth.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox2">Ce mois-ci<br>'+stats+'</div>';
if (tableau_nextMonth.length!=0){
liste_nextMonth += tableau_nextMonth.join('');
nb_lignes += tableau_nextMonth.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox2">Mois Prochain<br>'+tableau_nextMonth.length+'</div>';
}
stats+=tableau_nextMonth.length;
if (tableau_thisYear.length!=0){
liste_thisYear += tableau_thisYear.join('');
nb_lignes += tableau_thisYear.length;
}
stats+=tableau_thisYear.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox2">Cette année<br>'+stats+'</div>';
if (tableau_nextYear.length!=0){
liste_nextYear += tableau_nextYear.join('');
nb_lignes += tableau_nextYear.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox2">Après<br>'+tableau_nextYear.length+'</div>';
}
if (tableau_finished.length != 0){
liste_finished += tableau_retard.join('');
if (synthese2=='') synthese2+='<div class="statrow" style="margin-top: 5px">';
synthese2+='<div class="statbox1">Terminé<br>'+tableau_finished.length+'</div>';
}
if (tableau_retard.length != 0){
liste_retard += tableau_retard.join('');
nb_lignes += tableau_retard.length;
if (synthese2=='') synthese2+='<div class="statrow" style="margin-top: 5px">';
synthese2+='<div class="statbox1">En retard<br>'+tableau_retard.length+'</div>';
}
if (tableau_encours.length != 0){
liste_encours += tableau_encours.join('');
if (synthese2=='') synthese2+='<div class="statrow" style="margin-top: 5px">';
synthese2+='<div class="statbox1">En cours<br>'+tableau_encours.length+'</div>';
}
if (tableau_todo.length != 0){
liste_todo += tableau_todo.join('');
if (synthese2=='') synthese2+='<div class="statrow" style="margin-top: 5px">';
synthese2+='<div class="statbox1">A faire<br>'+tableau_todo.length+'</div>';
}
if (tableau_noplanning.length !=0) {
liste_noplanning += tableau_noplanning.join('');
nb_lignes += tableau_noplanning.length;
if (synthese2=='') synthese2+='<div class="statrow" style="margin-top: 5px">';
synthese2+='<div class="statbox2">Non-Planifiés<br>'+tableau_noplanning.length+'</div>';
}
if (synthese1!='') synthese1+='</div>';
if (synthese2!='') synthese2+='</div>';
lignes_vides = nb_lignes;
if (liste_retard != '')
{
contenu += todoListSection('En retard', '');
contenu += liste_retard;
lignes_vides += 1;
}
if (liste_encours != '')
{
contenu += todoListSection('En cours', 'font-weight:bold');
contenu += liste_encours;
lignes_vides += 1;
}
if (liste_today != '')
{
contenu += todoListSection('Aujourd\'hui', 'font-weight:bold');
contenu += liste_today;
lignes_vides += 1;
}
if (liste_tomorrow != '')
{
contenu += todoListSection('Demain', 'font-weight:bold');
contenu += liste_tomorrow;
lignes_vides += 1;
}
if (liste_thisWeek != '')
{
contenu += todoListSection('Cette semaine', 'font-weight:bold');
contenu += liste_thisWeek;
lignes_vides += 1;
}
if (liste_nextWeek != '')
{
contenu += todoListSection('La semaine prochaine', 'color:var(--nuance-sombre-09)');
contenu += liste_nextWeek;
lignes_vides += 1;
}
if (liste_thisMonth != '')
{
contenu += todoListSection('Ce mois-ci', 'color:var(--nuance-sombre-09)');
contenu += liste_thisMonth;
lignes_vides += 1;
}
if (liste_nextMonth != '')
{
contenu += todoListSection('Le mois prochain', 'color:var(--nuance-sombre-09)');
contenu += liste_nextMonth;
lignes_vides += 1;
}
if (liste_thisYear != '')
{
contenu += todoListSection('Cette année', 'color:var(--nuance-sombre-09)');
contenu += liste_thisYear;
lignes_vides += 1;
}
if (liste_nextYear != '')
{
contenu += todoListSection('L\'année prochaine', 'color:var(--nuance-sombre-06)');
contenu += liste_nextYear;
lignes_vides += 1;
}
if (liste_noplanning != '')
{
// On ne place un titre de section que s'il existe des tâches planifiées ...
if (nb_lignes != lignes_vides)
contenu += todoListSection('Non planifié', 'color:var(--nuance-sombre-06)');
contenu += liste_noplanning;
lignes_vides += 1;
}
while(lignes_vides < 30)
{
contenu += ' <tr>';
contenu += ' <td colspan="3">&nbsp;</td>';
contenu += ' </tr>';
lignes_vides += 1;
}
contenu += ' </tbody>';
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th colspan="3">'+setLevelPadding(2)+''+(nb_lignes-1)+' tâches</th>';
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
synthesis.innerHTML = synthese1+synthese2;
datagrid.innerHTML = contenu;
// Ne marche pas , ça enlève le stick du header du tableau ...
// document.getElementById('newitem_input').focus({preventScroll: true});
}
item_save_hooks['TODO'] = todoSave;
items_edit_hooks['TODO_OLD'] = function (id, libelle) {
let modal_header='Todo n°<b>'+id+'</b>';
let modal_body='TODO inconnu !';
let modal_footer='<div align="right" width="100%" style="padding-top:2vh"><button onclick="todoSave('+id+')">Enregistrer</button></div>';
let local_values = [];
local_values['parent']=getContexteValeur('parent');
local_values['type']=getContexteValeur('type_courant');
local_values['intervenant']=getContexteValeur('intervenant');
local_values['client']=getTrigrammeCollaborateur(local_values['intervenant']);
local_values['libelle']=libelle;
items.filter(item => item.idlignes == id).forEach(resultat => {
local_values['type']=resultat['type'];
itemFields[local_values['type']].forEach(attribut => {
local_values[attribut]=resultat[attribut];
});
});
modal_body = '<table class="modal_table"><form id="formulaire_lignes">';
itemFields[local_values['type']].forEach(attribut => {
modal_body += '<tr><td>'+attribut+'</td><td>'+getInputLabel(attribut,local_values[attribut])+'</td></tr>';
});
modal_body += '</form></table>';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
if (!modalDialog.open) modalDialog.showModal();
}

View File

@@ -0,0 +1,79 @@
var allStatus;
function getStatusLibelleFromId(idstatus){
let filtre = allStatus.filter(status => status.idstatus == idstatus);
return (filtre[0]?.libelle ?? "Inconnu");
}
function setStatus(data){
allStatus = data;
}
getEntities('status', setStatus);
function initDatagridStatus() {
setStatus(null);
datagridLoading();
getEntities('status', __initDatagridStatus);
}
function __initDatagridStatus(data) {
let element = document.querySelector('#datagrid');
let contenu='';
setStatus(data);
contenu += '<table>';
contenu += ' <thead>';
contenu += ' <tr>';
contenu += ' <th>Id</th>';
contenu += ' <th>Status</th>';
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
allStatus.forEach(status => {
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="status:id='+status.idstatus+'">';
contenu += ' <td>'+status.idstatus+'</td>';
contenu += ' <td>'+status.libelle+'</td>';
contenu += ' </tr>';
});
contenu += ' </body>';
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th colspan="2">&nbsp;</th>';
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
element.innerHTML = contenu;
init_modal();
}
modal_hooks['status'] = function(parametres){
let paramSplit = parametres.split(',');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0] === 'id') {
let id = elemSplit[1];
let modal_header='Fiche status ['+id+']';
let modal_body='status inconnu !';
let modal_footer='<button>Enregistrer</button';
statuss.filter(status => status.idstatus == id)
.forEach(resultat => {
modal_body = '<table class="modal_table">';
modal_body += '<tr><td style="width:30%">Id</td><td>'+resultat.idstatus+'</td></tr>';
modal_body += '<tr><td style="width:30%">Code</td><td>'+resultat.libelle+'</td></tr>';
modal_body += '</table>';
});
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}
});
};

View File

@@ -0,0 +1,11 @@
function setFilAriane(ariane){
let contenant = document.querySelector('nav>#ariane>#fil');
if (contenant != null) {
let fil = '';
ariane.forEach(element => {
fil += ' <span><a onclick="activeMenu(this)">'+element+'</a></span> >';
});
contenant.innerHTML = fil.slice(0,-2);
}
return true;
}

View File

@@ -0,0 +1,15 @@
// ----------------------------------------------------------------------
// ---- Le contexte contient un ensemble de paramétres
// ---- qui contextualisent globalement le coportment de la page
// ----------------------------------------------------------------------
var contexte = new Object();
function setContexteValeur(parametre, valeur)
{
contexte[parametre] = valeur;
}
function getContexteValeur(parametre)
{
return contexte[parametre];
}

View File

@@ -0,0 +1,497 @@
window.addEventListener('load', function() {
window.scrollTo(0,0);
}, false);
/*
* Personnalisation
* Que se passe-t-il lorsque la bannière est invisible ?
*/
function setLogoVisiblity(visibilityFlag) {
let element = document.querySelector("nav>*>#settings");
let value = 'hidden';
if (visibilityFlag) value = "visible";
element.style.visibility = value;
}
function setNavbarStickOnTop(topFlag) {
let element = document.querySelector("#nav");
if (topFlag) element.style.setProperty('top', '0px');
else element.style.removeProperty('top');
}
function setDataGridFootSticky(stickyFlag) {
let element = null;
if (stickyFlag) {
//
// Mettre le tfoot sticky au bottom
//
element = document.querySelector("#datagrid>table>tfoot");
element.style.setProperty('position', 'sticky');
element.style.setProperty('bottom', '0px');
element.style.setProperty('z-index', '30');
} else {
element = document.querySelector("#datagrid>table>tfoot");
element.style.setProperty('position', 'relative');
element.style.setProperty('z-index', '10');
}
}
/*
* Personnalisation
* Que se passe-t-il lorsque la synthèse est invisible ?
*/
function setDatagridFirstColSticky(stickyFlag) {
let element = null;
if (stickyFlag) {
/*
* Mettre la première case sticky au top left
*/
element = document.querySelector("#datagrid>table>thead>tr>th:first-child");
element.style.setProperty('position', 'sticky');
element.style.setProperty('left', '0px');
element.style.setProperty('z-index', '30');
//
// Mettre la dernière case sticky au bottom left
//
element = document.querySelector("#datagrid>table>tfoot>tr>th:first-child");
element.style.setProperty('position', 'sticky');
element.style.setProperty('left', '0px');
element.style.setProperty('z-index', '30');
} else {
element = document.querySelector("#datagrid>table>thead>tr>th:first-child");
element.style.setProperty('position', 'sticky');
element.style.setProperty('left', '0px');
element.style.setProperty('z-index', '10');
element = document.querySelector("#datagrid>table>tfoot>tr>th:first-child");
element.style.setProperty('position', 'sticky');
element.style.setProperty('left', '0px');
element.style.setProperty('z-index', '10');
}
}
function setDatagridHeadSticky(stickyFlag) {
let element = document.querySelector("#datagrid>table>thead");
let navbar = document.querySelector("nav");
let offset = navbar.offsetHeight;
if (stickyFlag) {
/*
* Mettre le thead sticky au top
*/
//element = document.querySelector("#datagrid>table>thead");
element.style.setProperty('position', 'sticky');
element.style.setProperty('top', offset+'px');
element.style.setProperty('z-index', '30');
} else {
//element = document.querySelector("#datagrid>table>thead");
element.style.setProperty('position', 'relative');
element.style.setProperty('top', '0px');
element.style.setProperty('z-index', '10');
}
}
function smoothJump(hash) {
location.replace("#" + hash);
}
function documentGetElementById(id){
element = document.getElementById(id);
if (element === null ) return '';
return element.value;
}
function setElementHeight(elementSelector, elementHeight) {
let element = document.querySelector(elementSelector);
element.style.height = elementHeight;
}
function slideElement(elementSelector, elementHeight) {
let element = document.querySelector(elementSelector);
element.style.transition = "all 2s ease-in-out";
setElementHeight(elementSelector, elementHeight);
}
function scrollToElement(elementSelector) {
let element = document.querySelector(elementSelector);
element.scrollIntoView({ behavior: 'smooth' });
}
function gotoHelp() {
scrollToElement('#synthesis');
setTimeout(scrollToElement, 500, '#footer');
}
function gotoTop() {
let element = document.querySelector('header');
window.scrollTo(0, element.offsetHeight + 1);
}
function headerIsVisible(flagVisible) {
setLogoVisiblity(!flagVisible);
if (!flagVisible) gotoTop();
}
function synthesisTopIsNowVisible(entry) {
setDatagridHeadSticky(false);
setDataGridFootSticky(false);
/*
setDatagridFirstColSticky(true);
*/
myLog('Trigger synthesis is visible');
}
function synthesisTopIsNowInvisible(entry) {
setDatagridHeadSticky(true);
setDataGridFootSticky(true);
/*
setDatagridFirstColSticky(true);
*/
myLog('Trigger synthesis is invisible');
}
function initDatagrid()
{
let type = getContexteValeur('type');
switch(type){
case 'TODO':
initDatagridTodos();
break;
default:
initDatagridItems();
break;
}
}
function changeModeAffichage(valeur, texte)
{
let type='TODO';
switch(valeur){
case 'absences':
case 'releases':
case 'rdv':
case 'feries':
case 'taches':
type='TACHE';
break;
}
setContexteValeur('mode_affichage', valeur);
setContexteValeur('type_courant', type);
setFiltreValeur('type',type);
setFilAriane(['Home', 'List', texte]);
return afficherItems();
}
function changeModeAffichageEvent(e)
{
return changeModeAffichage(e.target.value, e.target.options[e.target.selectedIndex].text);
}
function changeAffichageItemsTermine(e)
{
setContexteValeur('termine', e.target.value);
setFiltreValeur('status',e.target.value);
afficherItems();
}
function changeAffichageItemsPrestations(e)
{
setContexteValeur('prestation', e.target.value);
afficherItems();
}
function changeFiltreClient(e)
{
let valeur = e.target.value;
if (valeur == 'ALL') valeur='';
setContexteValeur('client', valeur);
setFiltreValeur('client', valeur);
afficherItems();
}
function changeAffichageNiveauxEvent(e)
{
setContexteValeur('level', e.target.value);
setFiltreValeur('level', e.target.value);
afficherItems();
}
function changeCalendarEvent(e)
{
let valeur = todayStringDate;
switch(parseInt(e.target.value)) {
case 2 :
valeur = todayStringDate.substring(0,4)+'0101';
break;
}
setContexteValeur('debut',valeur);
setFiltreValeur('debut', valeur);
afficherItems();
}
function updateValue(e) {
if (e.target.value != '') editerItem(-1, e.target.value);
e.target.value = '';
}
function afficher_synthese(mode) {
let synthesis_body = document.querySelector('#synthesis_body');
if (synthesis_body) {
synthesis_body.innerHTML='';
let template = document.querySelector('#synthesis_body_' + mode);
if (template) {
let contenu = document.importNode(template.content, true);
if (contenu) synthesis_body.appendChild(contenu);
}
}
}
function afficher_footer(mode) {
let footer_body = document.querySelector('footer');
if (footer_body) {
footer_body.innerHTML='';
let template = document.querySelector('#footer_' + mode);
if (template) {
let contenu = document.importNode(template.content, true);
if (contenu) footer_body.appendChild(contenu);
}
}
}
function activeMenu(element) {
datagridEmptyLines(50);
activeMode(element.innerText);
gotoTop();
}
function modeToAffichage(mode)
{
let retour='taches';
switch (mode) {
case 'Releases':
retour='releases';
break;
case 'Hollidays':
retour='feries';
break;
case 'Rendez-Vous':
retour='rdv';
break;
case 'Rendez-Vous':
retour='rdv';
break;
case 'Items':
retour='items';
break;
case 'Project':
retour='prestations';
break;
default:
case 'Tasks':
retour='taches';
break;
}
return retour;
}
function activeMode(mode) {
setContexteValeur('type_courant', 'TODO');
setContexteValeur('items_type', 'items');
switch (mode) {
case 'Tree':
case 'TreeList' :
case 'List':
mode='Tasks';
case 'Tasks':
case 'Releases':
case 'Hollidays':
case 'Rendez-Vous':
case 'Items':
setContexteValeur('mode_feuille', false);
setContexteValeur('type_courant', 'TACHE');
setContexteValeur('mode_affichage', modeToAffichage(mode));
afficher_synthese('taches');
afficher_footer('taches');
setFilAriane(['Home', 'TreeList', mode]);
initDatagridItems();
break;
case 'Project':
setContexteValeur('mode_feuille', false);
setContexteValeur('termine', true);
setContexteValeur('prestation', true);
setContexteValeur('type_courant', 'PRESTATION');
setContexteValeur('mode_affichage', modeToAffichage(mode));
afficher_synthese('project');
afficher_footer('taches');
setFilAriane(['Home', 'Project']);
initDatagridItems();
break;
case 'Plan':
case 'Planning':
setFilAriane([mode]);
setContexteValeur('type_courant', 'TODO');
setContexteValeur('mode_feuille', true);
setContexteValeur('mode_affichage', 'planning');
setContexteValeur('termine', 'non');
afficher_synthese('planning');
afficher_footer('planning');
initDatagridItems();
break;
case 'Calendar':
setFilAriane(['Todo', mode]);
setContexteValeur('mode_feuille', true);
setContexteValeur('mode_affichage', 'calendar_intervenants');
setContexteValeur('debut', todayStringDate);
afficher_synthese('calendrier');
afficher_footer('calendrier');
initDatagridItems();
break;
case 'Administration':
setFilAriane(['Todo', mode]);
initAdministration();
break;
case 'Status':
setFilAriane(['Todo', 'Administration', mode]);
initDatagridStatus();
break;
case 'Clients':
setFilAriane(['Todo', 'Administration', mode]);
initDatagridClients();
break;
case 'Collaborateurs':
setFilAriane(['Todo', 'Administration', mode]);
initDatagridCollaborateurs();
break;
default:
case 'Home':
mode='Todo';
case 'Todo':
setFilAriane(['Home', mode]);
setDefaultContext();
setContexteValeur('type', 'TODO');
setContexteValeur('items_type', 'todos');
setContexteValeur('mode_affichage', 'todos');
setContexteValeur('mode_feuille', true);
setContexteValeur('parent', '1');
afficher_synthese('accueil');
afficher_footer('accueil');
initDatagridItems();
break;
}
}
function initAdministration() {
let element = document.querySelector('#synthesis_middle');
contenu = '<div style="padding:0px 10px;display: flex;flex-wrap: nowrap;justify-content: space-between;">';
contenu += '<a onclick="activeMenu(this)">Status</a>';
contenu += '<a onclick="activeMenu(this)">Clients</a>';
contenu += '<a onclick="activeMenu(this)">Collaborateurs</a>';
contenu += '</div>';
element.innerHTML = contenu;
}
function setDefaultContext()
{
// Contexte de départ
setContexteValeur('level', '9999');
setContexteValeur('parent', '1');
setContexteValeur('parent_level','0');
setContexteValeur('client', '');
setContexteValeur('termine', 'oui');
}
// UI
setLogoVisiblity(false);
// Contexte de départ
setContexteValeur('intervenant', 'Anonymous');
init_filtres(['type','client','debut','fin','level'])
// GO !
activeMode('Todo');
// Get the CSS root element
const rootCSS = document.querySelector(':root');
// Create a function for getting a variable value
function CSSgetSombre() {
let rs = getComputedStyle(rootCSS);
alert("The value of --couleur-sombre is: " + rs.getPropertyValue('--couleur-sombre'));
}
function CSSsetSombre(vr, vg, vb) {
// Couleur
rootCSS.style.setProperty('--r-sombre', vr);
rootCSS.style.setProperty('--g-sombre', vg);
rootCSS.style.setProperty('--b-sombre', vb);
// Logo
// let logo = document.querySelector('header>#logo>svg');
// if (logo) logo.style.fill = 'rgb(' + vr + ',' + vg + ',' + vb + ')';
}
function CSSsetClair(vr, vg, vb) {
// Couleur
rootCSS.style.setProperty('--r-clair', vr);
rootCSS.style.setProperty('--g-clair', vg);
rootCSS.style.setProperty('--b-clair', vb);
}
function CSSswitchCouleurTexte() {
let rs = getComputedStyle(rootCSS);
let actuel = rs.getPropertyValue('--couleur-texte');
if (actuel == 'black')
rootCSS.style.setProperty('--couleur-texte', 'var(--couleur-sombre)');
else
rootCSS.style.setProperty('--couleur-texte', 'black');
}

View File

@@ -0,0 +1,71 @@
var filtres = [];
function setFiltreValeur(filtre, valeur)
{
myError('setFiltreValeur est obsolète ! ['+filtre+' , '+ valeur+'] ')
filtres[filtre] = valeur;
}
function getFiltreValeur(filtre)
{
myError('getFiltreValeur est obsolète ! ['+filtre+'] ');
return filtres[filtre];
}
function init_filtres(liste){
liste.forEach((element=>{
filtres[element]='';
}));
}
function addDefaultFiltre(index, valeur){
let retour = '';
retour += '<tr><td>';
retour += '<label for="filtre_'+index+'">'+index+'</label>';
retour += '</td><td>';
retour += '<input type="" id="filtre_'+index+'" name="filtre_'+index+'" value="'+valeur+'"></inputl>';
retour += '</td></tr>';
return retour;
}
function openFiltrePopup(filtre)
{
let modal_header='Filtrer les items';
let modal_body='';
let modal_footer='<div align="right" width="100%" style="padding-top:2vh"><button onclick="applyFiltre()">Enregistrer</button></div>';
modal_body += '<table>';
Object.entries(filtres).forEach(element=>{
const [index,valeur] = element;
switch(index) {
default:
modal_body += addDefaultFiltre(index, valeur);
}
});
modal_body += '</table>';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
if (!modalDialog.open) modalDialog.showModal();
}
function applyFiltre(){
Object.entries(filtres).forEach(element=>{
const [index,valeur] = element;
let new_valeur=valeur;
switch(index) {
default:
let input_valeur = document.querySelector('#filtre_' + index);
if (input_valeur) new_valeur=input_valeur.value;
}
filtres[index] = new_valeur;
});
afficherItems();
}

View File

@@ -0,0 +1,13 @@
// ----------------------------------------------------------------------
// ---- Obsolète !
// ---- A remplacer par la notion de contexte
// ----------------------------------------------------------------------
function setParametreValeur(parametre, valeur)
{
return setContexteValeur(parametre, valeur)
}
function getParametreValeur(parametre)
{
return getContexteValeur(parametre);
}

View File

@@ -0,0 +1,128 @@
function stringDatePadDigits(num, digits) {
return num.toString().padStart(digits, '0');
}
function formatDatetoStringDateTime(uneDate){
let temp = '';
if (uneDate) {
temp += uneDate.getFullYear();
temp += ''+stringDatePadDigits(uneDate.getMonth()+1,2);
temp += ''+stringDatePadDigits(uneDate.getDate(),2);
temp += ''+stringDatePadDigits(uneDate.getHours(),2);
temp += ''+stringDatePadDigits(uneDate.getMinutes(),2);
}
temp += '000000000000';
return temp.substring(0,12);
}
function formatTimeFromStringDate(uneStringDate) {
let retour ='';
if ('0000' == uneStringDate.substring(8,12)) retour='-';
else retour = uneStringDate.substring(8,10)+':'+uneStringDate.substring(10,12);
return retour;
}
function formatDatetoStringDate(uneDate){
let temp = formatDatetoStringDateTime(uneDate);
return temp.substring(0,8);
return temp.substring(0,8)+'0000';
}
function formatLocaleDateFromStringDate(uneStringDate) {
if (uneStringDate.substring(0,8) == '00000000') return '-';
if (uneStringDate.substring(0,8) == '99999999') return '-';
return uneStringDate.substring(6,8) +'/'+uneStringDate.substring(4,6)+'/'+uneStringDate.substring(0,4);
}
function stringdateToDate(uneStringDate) {
let retour = new Date();
retour.setFullYear(parseInt(uneStringDate.substring(0,4)));
retour.setMonth(parseInt(uneStringDate.substring(4,6))-1);
retour.setDate(parseInt(uneStringDate.substring(6,8)));
retour = new Date(parseInt(uneStringDate.substring(0,4)), parseInt(uneStringDate.substring(4,6))-1, parseInt(uneStringDate.substring(6,8)))
return retour;
}
function stringdateGetDayOfYear(uneStringDate){
let currentYear = uneStringDate.substring(0,4);
let currentDate = stringdateToDate(uneStringDate);
let startDate = new Date(parseInt(currentYear), 0, 4);
return currentYear+stringDatePadDigits(Math.floor((currentDate - startDate) / (24 * 60 * 60 * 1000)),3);
}
function stringdateGetWeekOfYear(uneStringDate) {
let currentDayOfYear = dateGetPrevMonday(stringdateToDate(uneStringDate));
let startDayOfYear = dateGetPrevMonday(stringdateToDate(currentDayOfYear.getUTCFullYear()+'0104'));
let weekNo = Math.ceil(((currentDayOfYear-startDayOfYear) / 86400000 + 1) / 7);;
return startDayOfYear.getUTCFullYear() * 100 + weekNo;
}
function stringdateGetWeek(uneStringDate) {
myError('Fonction Obsolète : '+arguments.callee.name);
return stringdateGetWeekOfYear(uneStringDate);
}
function dateGetToday(){
let today = now.getDate();
today.setHours(0, 0, 0, 0);
return today;
}
function dateGetTomorrow(){
let now = new Date();
let today = now.getDate();
let tomorrow = new Date(now);
tomorrow.setDate(today + 1);
tomorrow.setHours(0, 0, 0, 0);
return tomorrow;
}
function dateGetLastDayOfWeek(uneDate, dayOfWeek){
let last = uneDate;
last.setHours(0, 0, 0, 0);
while(last.getDay() != dayOfWeek) {
last.setDate(last - 1)
}
return last;
}
function dateGetNextDayOfWeek(uneDate, dayOfWeek){
let next = uneDate;
next.setHours(0, 0, 0, 0);
while(next.getDay() != dayOfWeek) {
next.setDate(next - 1)
}
return next;
}
function dateGetPrevMonday(uneDate){
// return dateGetLastDayOfWeek(uneDate, 1);
let lastMonday = uneDate;
let daysDiff = uneDate.getDay() - 1;
lastMonday.setDate(uneDate.getDate() - (daysDiff > 0 ? daysDiff : (daysDiff * -6)));
lastMonday.setHours(0, 0, 0, 0);
return lastMonday;
}
function customParseFloat(valeur) {
let retour = valeur;
if (retour === null) retour = 0;
if (isNaN(retour)) retour = 0;
return parseFloat(retour);
}
function convertJourHeure(valeur) {
let retour = customParseFloat(valeur);
if (retour < 1.0) {
retour = (retour/0.125)+'H';
} else {
retour = retour+'J';
}
return retour;
}
const todayStringDate = formatDatetoStringDate(new Date());
const tomorrowStringDate = formatDatetoStringDate(dateGetTomorrow());

View File

@@ -0,0 +1,27 @@
/*
* Fonction pour introduire une attente
* usage : await delai(1000);
*/
function delai(milliseconds){
return new Promise(resolve => {
setTimeout(resolve, milliseconds);
});
}
var waitLoop = (ms) => {
const start = Date.now();
let now = start;
while (now - start < ms) {
now = Date.now();
}
}
async function attendre1(milliseconds)
{
await delai(milliseconds);
}
function attendre(milliseconds)
{
waitLoop(milliseconds);
}

View File

@@ -0,0 +1,10 @@
var useLog=false;
var useError=true;
function myLog(message) {
if (useLog)
console.log(message);
}
function myError(message) {
if (useError)
console.error(message);
}

View File

@@ -0,0 +1,19 @@
// Example POST method implementation:
async function postData(url = "", data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "cors", // no-cors, *cors, same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json",
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: "follow", // manual, *follow, error
referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}

View File

@@ -0,0 +1,10 @@
!function(o,l){var r,a,s="createElement",g="getElementsByTagName",b="length",E="style",d="title",y="undefined",k="setAttribute",w="getAttribute",x=null,A="__svgInject",C="--inject-",S=new RegExp(C+"\\d+","g"),I="LOAD_FAIL",t="SVG_NOT_SUPPORTED",L="SVG_INVALID",v=["src","alt","onload","onerror"],j=l[s]("a"),G=typeof SVGRect!=y,f={useCache:!0,copyAttributes:!0,makeIdsUnique:!0},N={clipPath:["clip-path"],"color-profile":x,cursor:x,filter:x,linearGradient:["fill","stroke"],marker:["marker",
"marker-end","marker-mid","marker-start"],mask:x,pattern:["fill","stroke"],radialGradient:["fill","stroke"]},u=1,c=2,O=1;function T(e){return(r=r||new XMLSerializer).serializeToString(e)}function P(e,r){var t,n,i,o,a=C+O++,f=/url\("?#([a-zA-Z][\w:.-]*)"?\)/g,u=e.querySelectorAll("[id]"),c=r?[]:x,l={},s=[],d=!1;if(u[b]){for(i=0;i<u[b];i++)(n=u[i].localName)in N&&(l[n]=1);for(n in l)(N[n]||[n]).forEach(function(e){s.indexOf(e)<0&&s.push(e)});s[b]&&s.push(E);var v,p,m,h=e[g]("*"),y=e;for(i=-1;y!=x;
){if(y.localName==E)(m=(p=y.textContent)&&p.replace(f,function(e,r){return c&&(c[r]=1),"url(#"+r+a+")"}))!==p&&(y.textContent=m);else if(y.hasAttributes()){for(o=0;o<s[b];o++)v=s[o],(m=(p=y[w](v))&&p.replace(f,function(e,r){return c&&(c[r]=1),"url(#"+r+a+")"}))!==p&&y[k](v,m);["xlink:href","href"].forEach(function(e){var r=y[w](e);/^\s*#/.test(r)&&(r=r.trim(),y[k](e,r+a),c&&(c[r.substring(1)]=1))})}y=h[++i]}for(i=0;i<u[b];i++)t=u[i],c&&!c[t.id]||(t.id+=a,d=!0)}return d}function V(e,r,t,n){if(r){
r[k]("data-inject-url",t);var i=e.parentNode;if(i){n.copyAttributes&&function c(e,r){for(var t,n,i,o=e.attributes,a=0;a<o[b];a++)if(n=(t=o[a]).name,-1==v.indexOf(n))if(i=t.value,n==d){var f,u=r.firstElementChild;u&&u.localName.toLowerCase()==d?f=u:(f=l[s+"NS"]("http://www.w3.org/2000/svg",d),r.insertBefore(f,u)),f.textContent=i}else r[k](n,i)}(e,r);var o=n.beforeInject,a=o&&o(e,r)||r;i.replaceChild(a,e),e[A]=u,m(e);var f=n.afterInject;f&&f(e,a)}}else D(e,n)}function p(){for(var e={},r=arguments,
t=0;t<r[b];t++){var n=r[t];for(var i in n)n.hasOwnProperty(i)&&(e[i]=n[i])}return e}function _(e,r){if(r){var t;try{t=function i(e){return(a=a||new DOMParser).parseFromString(e,"text/xml")}(e)}catch(o){return x}return t[g]("parsererror")[b]?x:t.documentElement}var n=l.createElement("div");return n.innerHTML=e,n.firstElementChild}function m(e){e.removeAttribute("onload")}function n(e){console.error("SVGInject: "+e)}function i(e,r,t){e[A]=c,t.onFail?t.onFail(e,r):n(r)}function D(e,r){m(e),i(e,L,r)
}function F(e,r){m(e),i(e,t,r)}function M(e,r){i(e,I,r)}function q(e){e.onload=x,e.onerror=x}function R(e){n("no img element")}var e=function z(e,r){var t=p(f,r),h={};function n(a,f){f=p(t,f);var e=function(r){var e=function(){var e=f.onAllFinish;e&&e(),r&&r()};if(a&&typeof a[b]!=y){var t=0,n=a[b];if(0==n)e();else for(var i=function(){++t==n&&e()},o=0;o<n;o++)u(a[o],f,i)}else u(a,f,e)};return typeof Promise==y?e():new Promise(e)}function u(u,c,e){if(u){var r=u[A];if(r)Array.isArray(r)?r.push(e
):e();else{if(q(u),!G)return F(u,c),void e();var t=c.beforeLoad,n=t&&t(u)||u[w]("src");if(!n)return""===n&&M(u,c),void e();var i=[];u[A]=i;var l=function(){e(),i.forEach(function(e){e()})},s=function f(e){return j.href=e,j.href}(n),d=c.useCache,v=c.makeIdsUnique,p=function(r){d&&(h[s].forEach(function(e){e(r)}),h[s]=r)};if(d){var o,a=function(e){if(e===I)M(u,c);else if(e===L)D(u,c);else{var r,t=e[0],n=e[1],i=e[2];v&&(t===x?(t=P(r=_(n,!1),!1),e[0]=t,e[2]=t&&T(r)):t&&(n=function o(e){
return e.replace(S,C+O++)}(i))),r=r||_(n,!1),V(u,r,s,c)}l()};if(typeof(o=h[s])!=y)return void(o.isCallbackQueue?o.push(a):a(o));(o=[]).isCallbackQueue=!0,h[s]=o}!function m(e,r,t){if(e){var n=new XMLHttpRequest;n.onreadystatechange=function(){if(4==n.readyState){var e=n.status;200==e?r(n.responseXML,n.responseText.trim()):400<=e?t():0==e&&t()}},n.open("GET",e,!0),n.send()}}(s,function(e,r){var t=e instanceof Document?e.documentElement:_(r,!0),n=c.afterLoad;if(n){var i=n(t,r)||t;if(i){
var o="string"==typeof i;r=o?i:T(t),t=o?_(i,!0):i}}if(t instanceof SVGElement){var a=x;if(v&&(a=P(t,!1)),d){var f=a&&T(t);p([a,r,f])}V(u,t,s,c)}else D(u,c),p(L);l()},function(){M(u,c),p(I),l()})}}else R()}return G&&function i(e){var r=l[g]("head")[0];if(r){var t=l[s](E);t.type="text/css",t.appendChild(l.createTextNode(e)),r.appendChild(t)}}('img[onload^="'+e+'("]{visibility:hidden;}'),n.setOptions=function(e){t=p(t,e)},n.create=z,n.err=function(e,r){e?e[A]!=c&&(q(e),G?(m(e),M(e,t)):F(e,t),r&&(m(
e),e.src=r)):R()},o[e]=n}("SVGInject");"object"==typeof module&&"object"==typeof module.exports&&(module.exports=e)}(window,document);