Assiduites : Gestions couleurs + bugfix calendrier Close #800
@ -1,3 +1,33 @@
|
||||
:root {
|
||||
--color-present: #6bdb83;
|
||||
--color-absent: #e62a11;
|
||||
--color-retard: #f0c865;
|
||||
--color-justi: #7059FF;
|
||||
--color-justi-invalide: #a84476;
|
||||
--color-nonwork: #badfff;
|
||||
|
||||
--color-absent-justi: #e65ab7;
|
||||
--color-retard-justi: #ffef7a;
|
||||
|
||||
--color-error: #FF0000;
|
||||
--color-warning: #eec660;
|
||||
--color-information: #658ef0;
|
||||
|
||||
--color-def: #d61616;
|
||||
--color-conflit: #ff00009c;
|
||||
--color-bg-def: #c8c8c8;
|
||||
--color-primary: #7059FF;
|
||||
--color-secondary: #6f9fff;
|
||||
|
||||
--color-defaut: #FFF;
|
||||
--color-defaut-dark: #444;
|
||||
|
||||
|
||||
|
||||
--motif-justi: repeating-linear-gradient(135deg, transparent, transparent 4px, var(--color-justi) 4px, var(--color-justi) 8px);
|
||||
--motif-justi-invalide: repeating-linear-gradient(-135deg, transparent, transparent 4px, var(--color-justi-invalide) 4px, var(--color-justi-invalide) 8px);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@ -87,7 +117,7 @@
|
||||
}
|
||||
|
||||
.ui-slider-range.ui-widget-header.ui-corner-all {
|
||||
background-color: #F9C768;
|
||||
background-color: var(--color-warning);
|
||||
background-image: none;
|
||||
opacity: 0.50;
|
||||
visibility: visible;
|
||||
@ -122,7 +152,7 @@
|
||||
|
||||
.etud_row.def,
|
||||
.etud_row.dem {
|
||||
background-color: #c8c8c8;
|
||||
background-color: var(--color-bg-def);
|
||||
}
|
||||
|
||||
/* --- Index --- */
|
||||
@ -149,7 +179,7 @@
|
||||
.tr.def .td.sticky span::after {
|
||||
display: block;
|
||||
content: " (Déf.)";
|
||||
color: #d61616;
|
||||
color: var(--color-def);
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
@ -157,7 +187,7 @@
|
||||
.tr.dem .td.sticky span::after {
|
||||
display: block;
|
||||
content: " (Dém.)";
|
||||
color: #d61616;
|
||||
color: var(--color-def);
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
@ -213,32 +243,36 @@
|
||||
}
|
||||
|
||||
.etud_row.conflit {
|
||||
background-color: #ff0000c2;
|
||||
background-color: var(--color-conflit);
|
||||
}
|
||||
|
||||
.etud_row .assiduites_bar .absent,
|
||||
.demo.absent {
|
||||
background-color: #F1A69C !important;
|
||||
background-color: var(--color-absent) !important;
|
||||
}
|
||||
|
||||
.etud_row .assiduites_bar .present,
|
||||
.demo.present {
|
||||
background-color: #9CF1AF !important;
|
||||
background-color: var(--color-present) !important;
|
||||
}
|
||||
|
||||
.etud_row .assiduites_bar .retard,
|
||||
.demo.retard {
|
||||
background-color: #F1D99C !important;
|
||||
background-color: var(--color-retard) !important;
|
||||
}
|
||||
|
||||
.demo.nonwork {
|
||||
background-color: var(--color-nonwork) !important;
|
||||
}
|
||||
|
||||
.etud_row .assiduites_bar .justified,
|
||||
.demo.justified {
|
||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 4px, #7059FF 4px, #7059FF 8px);
|
||||
background-image: var(--motif-justi);
|
||||
}
|
||||
|
||||
.etud_row .assiduites_bar .invalid_justified,
|
||||
.demo.invalid_justified {
|
||||
background-image: repeating-linear-gradient(225deg, transparent, transparent 4px, #d61616 4px, #d61616 8px);
|
||||
background-image: var(--motif-justi-invalide);
|
||||
}
|
||||
|
||||
|
||||
@ -273,27 +307,35 @@
|
||||
height: 35px;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
border-radius: 5px;
|
||||
border: 1px solid var(--color-defaut-dark);
|
||||
}
|
||||
|
||||
|
||||
.rbtn.present::before {
|
||||
background-image: url(../icons/present.svg);
|
||||
background-color: var(--color-present);
|
||||
|
||||
}
|
||||
|
||||
.rbtn.absent::before {
|
||||
background-color: var(--color-absent);
|
||||
background-image: url(../icons/absent.svg);
|
||||
}
|
||||
|
||||
.rbtn.aucun::before {
|
||||
background-image: url(../icons/aucun.svg);
|
||||
background-color: var(--color-defaut-dark);
|
||||
|
||||
}
|
||||
|
||||
.rbtn.retard::before {
|
||||
background-color: var(--color-retard);
|
||||
background-image: url(../icons/retard.svg);
|
||||
}
|
||||
|
||||
.rbtn:checked:before {
|
||||
outline: 5px solid #7059FF;
|
||||
outline: 5px solid var(--color-primary);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@ -486,7 +528,7 @@
|
||||
.loader {
|
||||
border: 6px solid #f3f3f3;
|
||||
border-radius: 50%;
|
||||
border-top: 6px solid #3498db;
|
||||
border-top: 6px solid var(--color-primary);
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
position: absolute;
|
||||
@ -532,7 +574,7 @@
|
||||
}
|
||||
|
||||
.rouge {
|
||||
color: crimson;
|
||||
color: var(--color-error);
|
||||
}
|
||||
|
||||
.legende {
|
||||
@ -588,7 +630,7 @@
|
||||
|
||||
#forcemodule {
|
||||
border-radius: 8px;
|
||||
background: crimson;
|
||||
background: var(--color-error);
|
||||
max-width: fit-content;
|
||||
padding: 5px;
|
||||
color: white;
|
||||
|
16
app/static/icons/absent.svg
Executable file → Normal file
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 14 KiB |
11
app/static/icons/absent_ancien.svg
Executable file
@ -0,0 +1,11 @@
|
||||
<svg width="85" height="85" viewBox="0 0 85 85" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="85" height="85" rx="15" fill=""/>
|
||||
<g opacity="0.7" clip-path="url(#clip0_120_4425)">
|
||||
<path d="M67.2116 70L43 45.707L18.7885 70L15.0809 66.3043L39.305 41.9995L15.0809 17.6939L18.7885 14L43 38.2922L67.2116 14L70.9191 17.6939L46.695 41.9995L70.9191 66.3043L67.2116 70Z" fill="black"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_120_4425">
|
||||
<rect width="56" height="56" fill="white" transform="matrix(1 0 0 -1 15 70)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 540 B |
@ -1,5 +1,5 @@
|
||||
<svg width="85" height="85" viewBox="0 0 85 85" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="85" height="85" rx="15" fill="#BBB"/>
|
||||
<rect width="85" height="85" rx="15" fill=""/>
|
||||
<defs>
|
||||
<clipPath id="clip0_120_4425">
|
||||
<rect width="56" height="56" fill="white" transform="matrix(1 0 0 -1 15 70)"/>
|
||||
|
Before Width: | Height: | Size: 291 B After Width: | Height: | Size: 287 B |
@ -1,7 +1,7 @@
|
||||
<svg width="85" height="85" viewBox="0 0 85 85" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="85" height="85" rx="15" fill="#9CF1AF"/>
|
||||
<rect width="85" height="85" rx="15" fill=""/>
|
||||
<g clip-path="url(#clip0_120_4405)">
|
||||
<g opacity="0.5">
|
||||
<g opacity="0.7">
|
||||
<path d="M70.7713 27.5875L36.0497 62.3091C35.7438 62.6149 35.2487 62.6149 34.9435 62.3091L15.2286 42.5935C14.9235 42.2891 14.9235 41.7939 15.2286 41.488L20.0191 36.6976C20.3249 36.3924 20.8201 36.3924 21.1252 36.6976L35.4973 51.069L64.8754 21.6909C65.1819 21.3858 65.6757 21.3858 65.9815 21.6909L70.7713 26.4814C71.0771 26.7865 71.0771 27.281 70.7713 27.5875Z" fill="black"/>
|
||||
</g>
|
||||
</g>
|
||||
|
Before Width: | Height: | Size: 729 B After Width: | Height: | Size: 722 B |
@ -1,6 +1,6 @@
|
||||
<svg width="85" height="85" viewBox="0 0 85 85" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="85" height="85" rx="15" fill="#F1D99C"/>
|
||||
<g opacity="0.5" clip-path="url(#clip0_120_4407)">
|
||||
<rect width="85" height="85" rx="15" fill=""/>
|
||||
<g opacity="0.7" clip-path="url(#clip0_120_4407)">
|
||||
<path d="M55.2901 49.1836L44.1475 41.3918V28C44.1475 27.3688 43.6311 26.8524 43 26.8524C42.3688 26.8524 41.8524 27.3688 41.8524 28V42C41.8524 42.3787 42.036 42.7229 42.3459 42.941L53.9819 51.077C54.177 51.2147 54.4065 51.2836 54.636 51.2836C54.9918 51.2836 55.3475 51.1115 55.577 50.7787C55.9327 50.2623 55.8065 49.5508 55.2901 49.1836Z" fill="black"/>
|
||||
<path d="M62.7836 22.2164C57.482 16.9148 50.459 14 43 14C35.541 14 28.518 16.9148 23.2164 22.2164C17.9148 27.518 15 34.541 15 42C15 49.459 17.9148 56.482 23.2164 61.7836C28.518 67.0852 35.541 70 43 70C50.459 70 57.482 67.0852 62.7836 61.7836C68.0852 56.482 71 49.459 71 42C71 34.541 68.0852 27.518 62.7836 22.2164ZM44.1475 67.682V63C44.1475 62.3689 43.6311 61.8525 43 61.8525C42.3689 61.8525 41.8525 62.3689 41.8525 63V67.682C28.5869 67.0967 17.9033 56.4131 17.318 43.1475H22C22.6311 43.1475 23.1475 42.6311 23.1475 42C23.1475 41.3689 22.6311 40.8525 22 40.8525H17.318C17.9033 27.5869 28.5869 16.9033 41.8525 16.318V21C41.8525 21.6311 42.3689 22.1475 43 22.1475C43.6311 22.1475 44.1475 21.6311 44.1475 21V16.318C57.4131 16.9033 68.0967 27.5869 68.682 40.8525H64C63.3689 40.8525 62.8525 41.3689 62.8525 42C62.8525 42.6311 63.3689 43.1475 64 43.1475H68.682C68.0967 56.4131 57.4131 67.0967 44.1475 67.682Z" fill="black"/>
|
||||
</g>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@ -1696,7 +1696,7 @@ function fastJustify(assiduite) {
|
||||
content,
|
||||
success,
|
||||
() => {},
|
||||
"#7059FF"
|
||||
"var(--color-primary)"
|
||||
);
|
||||
};
|
||||
if (assiduite.etudid) {
|
||||
|
@ -48,6 +48,17 @@ Date.toFRA = function (dateIso) {
|
||||
7
|
||||
)}/${dateIso.substring(0, 4)}`;
|
||||
};
|
||||
/**
|
||||
* Vérifie si le début de l'une des périodes est avant la fin de l'autre
|
||||
* et si la fin de cette période est après le début de l'autre.
|
||||
* @param {Object} period {deb:Object, fin:Object}
|
||||
* @param {Object} interval {deb:Object, fin:Object}
|
||||
* @returns vrai si la periode et l'interval ont une intersection commune
|
||||
*/
|
||||
Date.intersect = function (period, interval) {
|
||||
return period.deb <= interval.fin && period.fin >= interval.deb;
|
||||
};
|
||||
|
||||
Object.defineProperty(Date.prototype, "isValid", {
|
||||
value: function () {
|
||||
return !Number.isNaN(this.getTime());
|
||||
|
@ -152,7 +152,7 @@
|
||||
|
||||
const requests = []
|
||||
Array.from(in_files.files).forEach((f) => {
|
||||
pushToast(generateToast(document.createTextNode(`Importation du fichier : ${f.name} commencée`), color = "#f0c865"));
|
||||
pushToast(generateToast(document.createTextNode(`Importation du fichier : ${f.name} commencée`), color = "var(--color-information)"));
|
||||
const fd = new FormData();
|
||||
fd.append('file', f);
|
||||
requests.push(
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div class="options">
|
||||
<input type="checkbox" id="show_pres" name="show_pres"><label for="show_pres">afficher les présences</label>
|
||||
<input type="checkbox" name="show_reta" id="show_reta"><label for="show_reta">afficher les retards</label>
|
||||
<input type="checkbox" name="mode_demi" id="mode_demi"><label for="mode_demi">mode demi journée</label>
|
||||
<input type="checkbox" name="mode_demi" id="mode_demi" checked><label for="mode_demi">mode demi journée</label>
|
||||
</div>
|
||||
|
||||
<div class="calendrier">
|
||||
@ -25,54 +25,98 @@
|
||||
|
||||
<div class="help">
|
||||
<h3>Calendrier</h3>
|
||||
<p>Les jours non travaillés sont affiché en violet</p>
|
||||
<p>Les jours possèdant une bordure "bleu" sont des jours où des absences/retards ont été justifiées par un
|
||||
justificatif valide</p>
|
||||
<p>Les jours possèdant une bordure "rouge" sont des jours où des absences/retards ont été justifiées par un
|
||||
justificatif non valide</p>
|
||||
<p>Le jour sera affiché en : </p>
|
||||
<ul>
|
||||
<li>Rouge : s'il y a une absence enregistrée</li>
|
||||
<li>Orange : s'il y a un retard et pas d'absence</li>
|
||||
<li>Vert : s'il y a une présence enregistrée mais pas d'absence ni de retard</li>
|
||||
<li>Blanc : s'il n'y a rien d'enregistré</li>
|
||||
<p>Code couleur</p>
|
||||
<ul class="couleurs">
|
||||
<li><span title="Vert" class="present demo"></span> → présence de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Bleu clair" class="nonwork demo"></span> → la période n'est pas travaillée
|
||||
</li>
|
||||
<li><span title="Rouge" class="absent demo"></span> → absence de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Rose" class="demo color absent est_just"></span> → absence justifiée
|
||||
</li>
|
||||
<li><span title="Orange" class="retard demo"></span> → retard de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Jaune clair" class="demo color retard est_just"></span> → retard justifié
|
||||
</li>
|
||||
|
||||
<li><span title="Quart Bleu" class="est_just demo"></span> → la période est justifiée par un
|
||||
justificatif valide</li>
|
||||
<li><span title="Quart Violet" class="invalide demo"></span> → la période est
|
||||
justifiée par un justificatif non valide / en attente de validation
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>Vous pouvez passer le curseur sur les jours colorés afin de voir les informations de cette journée.</p>
|
||||
|
||||
<p>Vous pouvez passer le curseur sur les jours colorés afin de voir les informations supplémentaires</p>
|
||||
</div>
|
||||
<ul class="couleurs print">
|
||||
<li><span title="Vert" class="present demo"></span> présence
|
||||
</li>
|
||||
<li><span title="Bleu clair" class="nonwork demo"></span> non travaillé
|
||||
</li>
|
||||
<li><span title="Rouge" class="absent demo"></span> absence
|
||||
</li>
|
||||
<li><span title="Rose" class="demo color absent est_just"></span> absence justifiée
|
||||
</li>
|
||||
<li><span title="Orange" class="retard demo"></span> retard
|
||||
</li>
|
||||
<li><span title="Jaune clair" class="demo color retard est_just"></span>retard justifié
|
||||
</li>
|
||||
<li><span title="Quart Bleu" class="est_just demo"></span>
|
||||
justificatif valide</li>
|
||||
<li><span title="Quart Violet" class="invalide demo"></span> justificatif non valide
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--color-present: #6bdb83;
|
||||
--color-absent: #F1A69C;
|
||||
--color-retard: #f0c865;
|
||||
--color-nonwork: #badfff;
|
||||
--color-defaut: #FFF;
|
||||
.help .couleurs {
|
||||
grid-template-columns: 2;
|
||||
grid-template-rows: auto;
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.couleurs.print {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.help .couleurs li:nth-child(odd) {
|
||||
grid-column: 1;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.help .couleurs li:nth-child(even) {
|
||||
grid-column: 2;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.color.present {
|
||||
background-color: var(--color-present);
|
||||
background-color: var(--color-present) !important;
|
||||
}
|
||||
|
||||
.color.absent {
|
||||
background-color: var(--color-absent);
|
||||
background-color: var(--color-absent) !important;
|
||||
}
|
||||
|
||||
.color.absent.est_just {
|
||||
background-color: var(--color-absent-justi) !important;
|
||||
}
|
||||
|
||||
.color.retard {
|
||||
background-color: var(--color-retard);
|
||||
background-color: var(--color-retard) !important;
|
||||
}
|
||||
|
||||
.color.retard.est_just {
|
||||
background-color: var(--color-retard-justi) !important;
|
||||
}
|
||||
|
||||
.color.nonwork {
|
||||
background-color: var(--color-nonwork);
|
||||
background-color: var(--color-nonwork) !important;
|
||||
}
|
||||
|
||||
.color {
|
||||
background-color: var(--color-defaut);
|
||||
background-color: var(--color-defaut) !important;
|
||||
}
|
||||
|
||||
.pageContent {
|
||||
@ -94,40 +138,62 @@
|
||||
}
|
||||
|
||||
.day,
|
||||
.demi .day.color.color.nonwork {
|
||||
/* border: 1px solid #444; */
|
||||
/* border-radius: 8px; */
|
||||
text-align: center;
|
||||
.demi .day.color.nonwork {
|
||||
text-align: left;
|
||||
margin: 2px;
|
||||
cursor: default;
|
||||
font-size: 13px;
|
||||
position: relative;
|
||||
font-weight: normal;
|
||||
min-width: 6em;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.color.est_just.sans_etat::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 25%;
|
||||
height: 100%;
|
||||
background-color: var(--color-justi) !important;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.color.invalide::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 25%;
|
||||
height: 100%;
|
||||
right: 0;
|
||||
background-color: var(--color-justi-invalide) !important;
|
||||
}
|
||||
|
||||
.demo.invalide {
|
||||
background-color: var(--color-justi-invalide) !important;
|
||||
}
|
||||
|
||||
.demo.est_just {
|
||||
background-color: var(--color-justi) !important;
|
||||
}
|
||||
|
||||
|
||||
.demi .day.nonwork>span {
|
||||
flex: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.demi .day {
|
||||
border-radius: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.day.est_just,
|
||||
.demi .day span.est_just {
|
||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 4px, #7059FFA0 4px, #7059FFA0 8px);
|
||||
|
||||
}
|
||||
|
||||
.day.est_just.invalide,
|
||||
.demi .day span.invalide {
|
||||
background-image: repeating-linear-gradient(-135deg, transparent, transparent 4px, #d61616A0 4px, #d61616A0 8px);
|
||||
}
|
||||
|
||||
.day .dayline {
|
||||
position: absolute;
|
||||
display: none;
|
||||
left: -237%;
|
||||
bottom: -420%;
|
||||
bottom: -390%;
|
||||
z-index: 50;
|
||||
width: 250px;
|
||||
width: max-content;
|
||||
height: 75px;
|
||||
background-color: #dedede;
|
||||
border-radius: 15px;
|
||||
@ -139,7 +205,11 @@
|
||||
}
|
||||
|
||||
.dayline .mini-timeline {
|
||||
margin-top: 14%;
|
||||
margin-top: 10%;
|
||||
}
|
||||
|
||||
.dayline-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.dayline .mini_tick {
|
||||
@ -159,7 +229,8 @@
|
||||
transform: translateX(200%);
|
||||
}
|
||||
|
||||
#label-nom {
|
||||
#label-nom,
|
||||
#label-justi {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -175,7 +246,7 @@
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
border: 1px solid #d5d5d5;
|
||||
/*border-radius: 3px;*/
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.demi .day>span:first-of-type {
|
||||
@ -186,47 +257,64 @@
|
||||
.options>* {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.options input {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.options label {
|
||||
font-weight: normal;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.color.present {
|
||||
background-color: var(--color-present) !important;
|
||||
|
||||
.couleurs.print {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.couleurs.print li {
|
||||
list-style-type: none !important;
|
||||
-webkit-print-color-adjust: exact !important;
|
||||
print-color-adjust: exact !important;
|
||||
}
|
||||
|
||||
.color.absent {
|
||||
background-color: var(--color-absent) !important;
|
||||
print-color-adjust: exact !important;
|
||||
.day,
|
||||
.demi .day.color.color.nonwork {
|
||||
min-width: 5em;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.color.retard {
|
||||
background-color: var(--color-retard) !important;
|
||||
print-color-adjust: exact !important;
|
||||
.demi .day>span:first-of-type {
|
||||
width: 2.5em;
|
||||
min-width: 2.5em;
|
||||
}
|
||||
|
||||
.color.nonwork {
|
||||
background-color: var(--color-nonwork) !important;
|
||||
.color {
|
||||
-webkit-print-color-adjust: exact !important;
|
||||
print-color-adjust: exact !important;
|
||||
}
|
||||
|
||||
.day.est_just,
|
||||
.demi .day span.est_just {
|
||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 4px, #7059FFA0 4px, #7059FFA0 8px) !important;
|
||||
print-color-adjust: exact !important;
|
||||
background-image: none;
|
||||
|
||||
}
|
||||
|
||||
.day.est_just.invalide,
|
||||
.day.invalide,
|
||||
.demi .day span.invalide {
|
||||
print-color-adjust: exact !important;
|
||||
background-image: repeating-linear-gradient(-135deg, transparent, transparent 4px, #d61616A0 4px, #d61616A0 8px) !important;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.demi .day span.est_just::before {
|
||||
content: "J";
|
||||
}
|
||||
|
||||
.demi .day span.invalide::before {
|
||||
content: "JI";
|
||||
}
|
||||
|
||||
#sidebar,
|
||||
.help,
|
||||
@ -237,13 +325,20 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
#label-nom {
|
||||
#label-nom,
|
||||
#label-justi {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#gtrcontent {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.annee {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -310,28 +405,6 @@
|
||||
return assiduitiesByDay;
|
||||
}
|
||||
|
||||
function getDayColor(etat) {
|
||||
let color;
|
||||
switch (etat.toUpperCase()) {
|
||||
case "PRESENT":
|
||||
color = "";
|
||||
break;
|
||||
case "ABSENT":
|
||||
color = "#F1A69C";
|
||||
break;
|
||||
case "RETARD":
|
||||
color = "#f0c865";
|
||||
break;
|
||||
case "NONWORK":
|
||||
color = "#bd81ca"
|
||||
break;
|
||||
default:
|
||||
color = "#FFF";
|
||||
break;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
function generateCalendar(assiduitiesByDay, nonWorkdays = []) {
|
||||
const calendar = document.querySelector('.calendrier')
|
||||
const options = getOptions();
|
||||
@ -360,7 +433,7 @@
|
||||
Object.keys(assiduitiesByDay[month]).forEach((date) => {
|
||||
let dayAssiduities = assiduitiesByDay[month][date].assiduites;
|
||||
let dayJustificatifs = assiduitiesByDay[month][date].justificatifs;
|
||||
let color = "";
|
||||
let color = "sans_etat";
|
||||
|
||||
if (dayAssiduities.some((a) => a.etat.toLowerCase() === "absent")) color = "absent";
|
||||
else if (dayAssiduities.some((a) => a.etat.toLowerCase() === "retard") && options.show_reta)
|
||||
@ -373,45 +446,49 @@
|
||||
if (dayJustificatifs.some((j) => j.etat.toLowerCase() === "valide")) {
|
||||
est_just = "est_just";
|
||||
} else if (dayJustificatifs.some((j) => j.etat.toLowerCase() !== "valide")) {
|
||||
est_just = "est_just invalide";
|
||||
est_just = "invalide";
|
||||
}
|
||||
const momentDate = new Date(date);
|
||||
let dayOfMonth = momentDate.getDate();
|
||||
let dayOfWeek = momentDate.getDay();
|
||||
dayOfWeek = days[dayOfWeek];
|
||||
|
||||
let isWorkDay = nonWorkdays.includes(dayOfWeek.toLowerCase());
|
||||
let isNonWorkDay = nonWorkdays.includes(dayOfWeek.toLowerCase());
|
||||
const day = document.createElement('div');
|
||||
day.className = `day`;
|
||||
if (isWorkDay) {
|
||||
if (isNonWorkDay) {
|
||||
color = "nonwork";
|
||||
} else if (!options.mode_demi) {
|
||||
day.className = `day ${est_just}`;
|
||||
}
|
||||
|
||||
if (options.mode_demi && !isWorkDay) {
|
||||
|
||||
if (options.mode_demi && !isNonWorkDay) {
|
||||
|
||||
est_just = []
|
||||
// affichage n° jour + matin + aprem
|
||||
|
||||
const span_jour = document.createElement("span")
|
||||
span_jour.textContent = dayOfMonth + dayOfWeek[0];
|
||||
span_jour.textContent = dayOfWeek[0] + dayOfMonth;
|
||||
|
||||
const span_matin = document.createElement("span");
|
||||
span_matin.classList.add("color");
|
||||
const matin = [new Date(date), new Date(date)]
|
||||
color = ""
|
||||
color = "sans_etat"
|
||||
matin[0].setHours(0, 0, 0, 0)
|
||||
matin[1].setHours(12, 59, 59)
|
||||
|
||||
|
||||
|
||||
const assiduitesMatin = dayAssiduities.filter((el) => {
|
||||
const deb = new Date(el.date_debut);
|
||||
const fin = new Date(el.date_fin);
|
||||
return deb.isBetween(matin[0], matin[1]) || fin.isBetween(matin[0], matin[1])
|
||||
return Date.intersect({ deb: deb, fin: fin }, { deb: matin[0], fin: matin[1] })
|
||||
})
|
||||
const justificatifsMatin = dayJustificatifs.filter((el) => {
|
||||
const deb = new Date(el.date_debut);
|
||||
const fin = new Date(el.date_fin);
|
||||
return deb.isBetween(matin[0], matin[1]) || fin.isBetween(matin[0], matin[1])
|
||||
return Date.intersect({ deb: deb, fin: fin }, { deb: matin[0], fin: matin[1] })
|
||||
})
|
||||
|
||||
if (assiduitesMatin.some((a) => a.etat.toLowerCase() === "absent")) color = "absent";
|
||||
@ -427,7 +504,7 @@
|
||||
if (justificatifsMatin.some((j) => j.etat.toLowerCase() === "valide")) {
|
||||
est_just = ["est_just"];
|
||||
} else if (justificatifsMatin.some((j) => j.etat.toLowerCase() !== "valide")) {
|
||||
est_just = ["est_just", "invalide"];
|
||||
est_just = ["invalide"];
|
||||
}
|
||||
|
||||
span_matin.classList.add(...est_just)
|
||||
@ -437,20 +514,21 @@
|
||||
const span_aprem = document.createElement("span");
|
||||
span_aprem.classList.add("color");
|
||||
const aprem = [new Date(date), new Date(date)]
|
||||
color = ""
|
||||
color = "sans_etat"
|
||||
aprem[0].setHours(13, 0, 0, 0)
|
||||
aprem[1].setHours(23, 59, 59)
|
||||
|
||||
|
||||
const assiduitesAprem = dayAssiduities.filter((el) => {
|
||||
const deb = new Date(el.date_debut);
|
||||
const fin = new Date(el.date_fin);
|
||||
return deb.isBetween(aprem[0], aprem[1]) || fin.isBetween(aprem[0], aprem[1])
|
||||
return Date.intersect({ deb: deb, fin: fin }, { deb: aprem[0], fin: aprem[1] })
|
||||
})
|
||||
|
||||
const justificatifsAprem = dayJustificatifs.filter((el) => {
|
||||
const deb = new Date(el.date_debut);
|
||||
const fin = new Date(el.date_fin);
|
||||
return deb.isBetween(aprem[0], aprem[1]) || fin.isBetween(aprem[0], aprem[1])
|
||||
return Date.intersect({ deb: deb, fin: fin }, { deb: aprem[0], fin: aprem[1] })
|
||||
})
|
||||
|
||||
if (assiduitesAprem.some((a) => a.etat.toLowerCase() === "absent")) color = "absent";
|
||||
@ -464,34 +542,53 @@
|
||||
}
|
||||
|
||||
if (justificatifsAprem.some((j) => j.etat.toLowerCase() === "valide")) {
|
||||
est_just = ["est_just"];;
|
||||
est_just = ["est_just"];
|
||||
} else if (justificatifsAprem.some((j) => j.etat.toLowerCase() !== "valide")) {
|
||||
est_just = ["est_just", "invalide"];;
|
||||
est_just = ["invalide"];
|
||||
}
|
||||
|
||||
span_matin.classList.add(...est_just)
|
||||
span_aprem.classList.add(...est_just)
|
||||
|
||||
day.appendChild(span_jour)
|
||||
day.appendChild(span_matin)
|
||||
day.appendChild(span_aprem)
|
||||
|
||||
|
||||
} else {
|
||||
day.classList.add("color")
|
||||
if (color != "") {
|
||||
day.classList.add(color);
|
||||
}
|
||||
day.textContent = `${dayOfWeek} ${dayOfMonth}`;
|
||||
|
||||
if (isNonWorkDay) {
|
||||
const span_jour = document.createElement("span")
|
||||
span_jour.textContent = dayOfWeek[0] + dayOfMonth;
|
||||
day.appendChild(span_jour);
|
||||
} else {
|
||||
day.textContent = `${dayOfWeek} ${dayOfMonth}`;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
console.warn(day.classList, day.classList.length)
|
||||
|
||||
|
||||
if (!nonWorkdays.includes(dayOfWeek.toLowerCase()) && dayAssiduities.length > 0) {
|
||||
const cache = document.createElement('div')
|
||||
cache.classList.add('dayline');
|
||||
const title = document.createElement('div')
|
||||
title.className = "dayline-title";
|
||||
|
||||
title.innerHTML = "<span>Assiduité du </span><br>" + `<span>${formatDate(momentDate)}</span>`;
|
||||
cache.appendChild(title)
|
||||
cache.appendChild(
|
||||
createMiniTimeline(dayAssiduities, date)
|
||||
)
|
||||
day.appendChild(cache)
|
||||
}
|
||||
|
||||
|
||||
|
||||
daysEl.appendChild(day);
|
||||
});
|
||||
monthEl.appendChild(daysEl)
|
||||
|
@ -59,18 +59,9 @@
|
||||
Correspondance des couleurs :
|
||||
</p>
|
||||
<ul>
|
||||
<li><span title="Vert" class="present demo"></span> → présence de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Orange" class="retard demo"></span> → retard de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Rouge" class="absent demo"></span> → absence de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Hachure Bleue" class="justified demo"></span> → l'assiduité est justifiée par un
|
||||
justificatif valide</li>
|
||||
<li><span title="Hachure Rouge" class="invalid_justified demo"></span> → l'assiduité est
|
||||
justifiée par un justificatif non valide / en attente de validation
|
||||
</li>
|
||||
{% include "assiduites/widgets/legende_couleur.j2" %}
|
||||
</ul>
|
||||
|
||||
<p>Vous pouvez justifier rapidement une assiduité en saisisant l'assiduité puis en appuyant sur "Justifier"</p>
|
||||
|
||||
<h3>Explication de la saisie différée</h3>
|
||||
|
@ -70,17 +70,7 @@
|
||||
Correspondance des couleurs :
|
||||
</p>
|
||||
<ul>
|
||||
<li><span title="Vert" class="present demo"></span> → présence de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Orange" class="retard demo"></span> → retard de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Rouge" class="absent demo"></span> → absence de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Hachure Bleue" class="justified demo"></span> → l'assiduité est justifiée par un
|
||||
justificatif valide</li>
|
||||
<li><span title="Hachure Rouge" class="invalid_justified demo"></span> → l'assiduité est
|
||||
justifiée par un justificatif non valide / en attente de validation
|
||||
</li>
|
||||
{% include "assiduites/widgets/legende_couleur.j2" %}
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Ajout d'un conteneur pour le loader -->
|
||||
|
@ -127,7 +127,7 @@
|
||||
|
||||
<script>
|
||||
const alertmodal = document.getElementById("alertModal");
|
||||
function openAlertModal(titre, contenu, footer, color = "crimson") {
|
||||
function openAlertModal(titre, contenu, footer, color = "var(--color-error)") {
|
||||
alertmodal.classList.add('is-active');
|
||||
|
||||
alertmodal.querySelector('.alertmodal-title').textContent = titre;
|
||||
|
@ -54,13 +54,13 @@
|
||||
function getColor(state) {
|
||||
switch (state) {
|
||||
case "PRESENT":
|
||||
return "#9CF1AF";
|
||||
return "var(--color-present)";
|
||||
case "ABSENT":
|
||||
return "#F1A69C";
|
||||
return "var(--color-absent)";
|
||||
case "RETARD":
|
||||
return "#F1D99C";
|
||||
return "var(--color-retard)";
|
||||
default:
|
||||
return "gray";
|
||||
return "var(--color-defaut-dark)";
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,11 +309,11 @@
|
||||
"L'heure de séparation doit être compris dans la période de l'assiduité sélectionnée."
|
||||
);
|
||||
|
||||
openAlertModal("Attention", att, "", "#ecb52a");
|
||||
openAlertModal("Attention", att, "", "var(--color-warning))");
|
||||
}
|
||||
};
|
||||
|
||||
openPromptModal("Séparation de l'assiduité sélectionnée", fieldSet, success, () => { }, "#23aa40");
|
||||
openPromptModal("Séparation de l'assiduité sélectionnée", fieldSet, success, () => { }, "var(--color-present)");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -342,7 +342,7 @@
|
||||
const att = document.createTextNode(
|
||||
"L'état doit être 'present', 'absent' ou 'retard'."
|
||||
);
|
||||
openAlertModal("Attention", att, "", "#ecb52a");
|
||||
openAlertModal("Attention", att, "", "var(--color-warning)");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -357,7 +357,7 @@
|
||||
};
|
||||
|
||||
//Affichage du prompt
|
||||
openPromptModal("Modification de l'état de l'assiduité sélectionnée", fieldSet, success, () => { }, "#23aa40");
|
||||
openPromptModal("Modification de l'état de l'assiduité sélectionnée", fieldSet, success, () => { }, "var(--color-present)");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,7 +147,7 @@
|
||||
}
|
||||
|
||||
#addColumn:hover {
|
||||
background-color: #0056b3;
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.th {
|
||||
@ -157,7 +157,7 @@
|
||||
}
|
||||
|
||||
.th.error {
|
||||
background-color: #d71111;
|
||||
background-color: var(--color-error);
|
||||
}
|
||||
|
||||
.tbody .tr:nth-child(even) {
|
||||
@ -226,7 +226,7 @@
|
||||
}
|
||||
|
||||
.td[assiduite_id='conflit'] {
|
||||
background-color: #ff0000c2;
|
||||
background-color: var(--color-error);
|
||||
}
|
||||
|
||||
input[type='radio']:disabled {
|
||||
@ -237,7 +237,7 @@
|
||||
.th.error:hover .col-error {
|
||||
display: block;
|
||||
z-index: 2000;
|
||||
background-color: #d71111;
|
||||
background-color: var(--color-error);
|
||||
width: 100%;
|
||||
min-height: 25%;
|
||||
bottom: -25%;
|
||||
@ -481,16 +481,16 @@
|
||||
let color;
|
||||
switch (etatId) {
|
||||
case 0:
|
||||
color = "#9CF1AF";
|
||||
color = "var(--color-present)";
|
||||
break
|
||||
case 1:
|
||||
color = "#F1D99C";
|
||||
color = "var(--color-retard)";
|
||||
break
|
||||
case 2:
|
||||
color = "#F1A69C";
|
||||
color = "var(--color-absent)";
|
||||
break
|
||||
default:
|
||||
color = "white";
|
||||
color = "var(--color-defaut)";
|
||||
break;
|
||||
}
|
||||
|
||||
@ -679,13 +679,13 @@
|
||||
|
||||
switch (etat.toUpperCase()) {
|
||||
case "PRESENT":
|
||||
color = "#6bdb83";
|
||||
color = "var(--color-present)";
|
||||
break;
|
||||
case "ABSENT":
|
||||
color = "#F1A69C";
|
||||
color = "var(--color-absent)";
|
||||
break;
|
||||
case "RETARD":
|
||||
color = "#f0c865";
|
||||
color = "var(--color-retard)";
|
||||
break;
|
||||
default:
|
||||
color = "#AAA";
|
||||
|
12
app/templates/assiduites/widgets/legende_couleur.j2
Normal file
@ -0,0 +1,12 @@
|
||||
<li><span title="Vert" class="present demo"></span> → présence de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Orange" class="retard demo"></span> → retard de l'étudiant lors de la période
|
||||
</li>
|
||||
<li><span title="Rouge" class="absent demo"></span> → absence de l'étudiant lors de la période
|
||||
</li>
|
||||
|
||||
<li><span title="Hachure Bleue" class="justified demo"></span> → l'assiduité est justifiée par un
|
||||
justificatif valide</li>
|
||||
<li><span title="Hachure Rouge" class="invalid_justified demo"></span> → l'assiduité est
|
||||
justifiée par un justificatif non valide / en attente de validation
|
||||
</li>
|
@ -247,15 +247,15 @@
|
||||
}
|
||||
|
||||
.assiduite-bubble.absent {
|
||||
border-color: #F1A69C !important;
|
||||
border-color: var(--color-absent) !important;
|
||||
}
|
||||
|
||||
.assiduite-bubble.present {
|
||||
border-color: #9CF1AF !important;
|
||||
border-color: var(--color-present) !important;
|
||||
}
|
||||
|
||||
.assiduite-bubble.retard {
|
||||
border-color: #F1D99C !important;
|
||||
border-color: var(--color-retard) !important;
|
||||
}
|
||||
|
||||
.mini-timeline {
|
||||
@ -297,27 +297,27 @@
|
||||
}
|
||||
|
||||
.mini-timeline-block.creneau {
|
||||
outline: 3px solid #7059FF;
|
||||
outline: 3px solid var(--color-primary);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mini-timeline-block.absent {
|
||||
background-color: #F1A69C !important;
|
||||
background-color: var(--color-absent) !important;
|
||||
}
|
||||
|
||||
.mini-timeline-block.present {
|
||||
background-color: #9CF1AF !important;
|
||||
background-color: var(--color-present) !important;
|
||||
}
|
||||
|
||||
.mini-timeline-block.retard {
|
||||
background-color: #F1D99C !important;
|
||||
background-color: var(--color-retard) !important;
|
||||
}
|
||||
|
||||
.mini-timeline-block.justified {
|
||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 4px, #7059FF 4px, #7059FF 8px);
|
||||
background-image: var(--motif-justi);
|
||||
}
|
||||
|
||||
.mini-timeline-block.invalid_justified {
|
||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 4px, #d61616 4px, #d61616 8px);
|
||||
background-image: var(--motif-justi-invalide);
|
||||
}
|
||||
</style>
|
@ -158,7 +158,7 @@
|
||||
|
||||
<script>
|
||||
const promptModal = document.getElementById("promptModal");
|
||||
function openPromptModal(titre, contenu, success, cancel = () => { }, color = "crimson") {
|
||||
function openPromptModal(titre, contenu, success, cancel = () => { }, color = "var(--color-error)") {
|
||||
promptModal.classList.add('is-active');
|
||||
|
||||
promptModal.querySelector('.promptModal-title').textContent = titre;
|
||||
|
@ -174,7 +174,7 @@
|
||||
const el = document.createElement('div');
|
||||
el.innerHTML = html;
|
||||
|
||||
openAlertModal("Détails", el.firstElementChild, null, "green")
|
||||
openAlertModal("Détails", el.firstElementChild, null, "var(--color-information)")
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -245,7 +245,7 @@
|
||||
})
|
||||
|
||||
|
||||
}, () => { }, "green");
|
||||
}, () => { }, "var(--color-information)");
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -449,7 +449,7 @@
|
||||
|
||||
getAssi(assiduiteCallBack)
|
||||
|
||||
}, () => { }, "#7059FF");
|
||||
}, () => { }, "var(--color-primary)");
|
||||
|
||||
}
|
||||
|
||||
|
@ -385,7 +385,7 @@
|
||||
|
||||
downloadStr(data, input.value ? input.value : "download.csv")
|
||||
|
||||
}, () => { }, "green");
|
||||
}, () => { }, "var(--color-present)");
|
||||
}
|
||||
|
||||
function toCSV(array, filters) {
|
||||
@ -489,24 +489,24 @@
|
||||
}
|
||||
|
||||
#deleteOption {
|
||||
background-color: #F1A69C;
|
||||
background-color: var(--color-absent);
|
||||
}
|
||||
|
||||
.l-present {
|
||||
background-color: #9CF1AF;
|
||||
background-color: var(--color-present)
|
||||
}
|
||||
|
||||
.l-absent,
|
||||
.l-invalid {
|
||||
background-color: #F1A69C;
|
||||
background-color: var(--color-absent);
|
||||
}
|
||||
|
||||
.l-valid {
|
||||
background-color: #8f7eff;
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.l-retard {
|
||||
background-color: #F1D99C;
|
||||
background-color: var(--color-retard);
|
||||
}
|
||||
|
||||
/* Ajoutez des styles pour le conteneur de pagination et les boutons */
|
||||
@ -531,9 +531,9 @@
|
||||
}
|
||||
|
||||
.pagination-button.active {
|
||||
background-color: #007bff;
|
||||
background-color: var(--color-primary);
|
||||
color: #fff;
|
||||
border-color: #007bff;
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
th>div {
|
||||
|
@ -201,7 +201,7 @@
|
||||
fichContent.appendChild(a);
|
||||
})
|
||||
|
||||
openAlertModal("Détails", el.firstElementChild, null, "green")
|
||||
openAlertModal("Détails", el.firstElementChild, null, "var(--color-information)")
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -388,7 +388,7 @@
|
||||
})
|
||||
|
||||
|
||||
}, () => { }, "green");
|
||||
}, () => { }, "var(--color-information)");
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -642,7 +642,7 @@
|
||||
loadAll();
|
||||
|
||||
|
||||
}, () => { }, "#7059FF");
|
||||
}, () => { }, "var(--color-primary)");
|
||||
}
|
||||
|
||||
function downloadJusti() {
|
||||
|
@ -319,7 +319,7 @@
|
||||
.period {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 183, 255, 0.5);
|
||||
background-color: var(--color-secondary);
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
@ -351,7 +351,7 @@
|
||||
.period:hover .period-time {
|
||||
display: flex;
|
||||
|
||||
background-color: rgba(0, 183, 255, 1);
|
||||
background-color: var(--color-secondary);
|
||||
border-radius: 15px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@
|
||||
|
||||
<script>
|
||||
|
||||
function generateToast(content, color = "#12d3a5", ttl = 5) {
|
||||
function generateToast(content, color = "var(--color-present)", ttl = 5) {
|
||||
const toast = document.createElement('div')
|
||||
toast.classList.add('toast', 'fadeIn')
|
||||
|
||||
@ -97,13 +97,13 @@
|
||||
let color;
|
||||
switch (etat.toUpperCase()) {
|
||||
case "PRESENT":
|
||||
color = "#6bdb83";
|
||||
color = "var(--color-present)";
|
||||
break;
|
||||
case "ABSENT":
|
||||
color = "#F1A69C";
|
||||
color = "var(--color-absent)";
|
||||
break;
|
||||
case "RETARD":
|
||||
color = "#f0c865";
|
||||
color = "var(--color-retard)";
|
||||
break;
|
||||
default:
|
||||
color = "#AAA";
|
||||
|