added monthly summary on dashboard
This commit is contained in:
@ -79,4 +79,8 @@ button:hover, select:hover {
|
||||
|
||||
button, select {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.template {
|
||||
display: none !important;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
.monthly {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1.2em;
|
||||
border: solid var(--light4) 1px;
|
||||
gap: 1.2em;
|
||||
}
|
||||
|
||||
.monthly .controls {
|
||||
display: flex;
|
||||
gap: 1.2em;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.monthly .controls button {
|
||||
background-color: var(--dark3);
|
||||
color: var(--light1);
|
||||
padding: 0.4em 0.8em;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monthly .controls button:hover {
|
||||
background-color: var(--dark4);
|
||||
}
|
||||
|
||||
.monthly #list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.8em;
|
||||
}
|
||||
|
||||
.monthly #list .row {
|
||||
display: flex;
|
||||
gap: 1.2em;
|
||||
padding: 0.4em 0.8em;
|
||||
background-color: var(--dark3);
|
||||
}
|
||||
|
||||
.monthly #list .no-data {
|
||||
font-style: italic;
|
||||
padding: 0.4em 0.8em;
|
||||
background-color: var(--dark2);
|
||||
}
|
94
dispatcher/static/dashboard.js
Normal file
94
dispatcher/static/dashboard.js
Normal file
@ -0,0 +1,94 @@
|
||||
let prevBtn, nextBtn, month
|
||||
let curYear = new Date().getFullYear()
|
||||
let curMonth = new Date().getMonth()
|
||||
|
||||
const MONTHS = [
|
||||
"Janvier",
|
||||
"Février",
|
||||
"Mars",
|
||||
"Avril",
|
||||
"Mai",
|
||||
"Juin",
|
||||
"Juillet",
|
||||
"Août",
|
||||
"Septembre",
|
||||
"Octobre",
|
||||
"Novembre",
|
||||
"Décembre"
|
||||
]
|
||||
|
||||
function formatDuration(duration) {
|
||||
let hours = Math.floor(duration / 60)
|
||||
duration -= hours * 60
|
||||
let res = ""
|
||||
if (hours > 0) {
|
||||
res += hours.toString() + "h"
|
||||
res += duration.toString().padStart(2, "0")
|
||||
} else {
|
||||
res += duration.toString() + "min"
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function prevMonth() {
|
||||
curMonth = curMonth - 1
|
||||
if (curMonth < 0) {
|
||||
curMonth += 12
|
||||
curYear -= 1
|
||||
}
|
||||
updateList()
|
||||
}
|
||||
function nextMonth() {
|
||||
curMonth = curMonth + 1
|
||||
if (curMonth >= 12) {
|
||||
curMonth -= 12
|
||||
curYear += 1
|
||||
}
|
||||
updateList()
|
||||
}
|
||||
|
||||
function updateList() {
|
||||
let year = curYear.toString().padStart(4, "0")
|
||||
let month = (curMonth + 1).toString().padStart(2, "0")
|
||||
let today = new Date()
|
||||
let txt = MONTHS[curMonth]
|
||||
if (today.getFullYear() !== curYear) {
|
||||
txt += " " + year.toString().padStart(4, "0")
|
||||
}
|
||||
document.getElementById("month").innerText = txt
|
||||
|
||||
fetch(`stats/by-month/${year}/${month}/`).then(res => {
|
||||
return res.json()
|
||||
}).then(res => {
|
||||
if (res.status !== "success") {
|
||||
return
|
||||
}
|
||||
let data = res.data.filter(parent => parent.duration !== null)
|
||||
let list = document.getElementById("list")
|
||||
let template = document.querySelector(".monthly .template.row").cloneNode(true)
|
||||
template.classList.remove("template")
|
||||
list.innerHTML = ""
|
||||
if (data.length === 0) {
|
||||
let noData = document.querySelector(".monthly .template.no-data").cloneNode(true)
|
||||
noData.classList.remove("template")
|
||||
list.appendChild(noData)
|
||||
return
|
||||
}
|
||||
data.forEach(parent => {
|
||||
let row = template.cloneNode(true)
|
||||
row.querySelector(".name").innerText = `${parent.name} (${parent.project_num})`
|
||||
row.querySelector(".duration").innerText = formatDuration(parent.duration)
|
||||
list.appendChild(row)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
prevBtn = document.getElementById("prev")
|
||||
nextBtn = document.getElementById("next")
|
||||
month = document.getElementById("month")
|
||||
|
||||
prevBtn.addEventListener("click", () => prevMonth())
|
||||
nextBtn.addEventListener("click", () => nextMonth())
|
||||
updateList()
|
||||
})
|
@ -1,6 +1,20 @@
|
||||
window.addEventListener("load", () => {
|
||||
document.querySelectorAll(".projects tbody tr").forEach(row => {
|
||||
let id = row.dataset.id
|
||||
let selector = row.querySelector(".parent-sel")
|
||||
selector.addEventListener("change", () => {
|
||||
let fd = new FormData()
|
||||
fd.set("parent_id", selector.value)
|
||||
let csrftoken = document.querySelector("input[name='csrfmiddlewaretoken']").value
|
||||
fetch(`${id}/set_parent`, {
|
||||
method: "POST",
|
||||
body: fd,
|
||||
headers: {
|
||||
"X-CSRFToken": csrftoken
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
row.querySelector("button.see").addEventListener("click", () => {
|
||||
window.location.href = `${id}/`
|
||||
})
|
||||
|
Reference in New Issue
Block a user