diff --git a/Cargo.lock b/Cargo.lock index 0c2fff0..785bb2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2217,7 +2217,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "reminder-rs" -version = "1.6.16" +version = "1.6.17" dependencies = [ "base64 0.21.2", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 3f0cff9..c755df8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "reminder-rs" -version = "1.6.16" +version = "1.6.17" authors = ["Jude Southworth "] edition = "2021" license = "AGPL-3.0 only" diff --git a/web/src/routes/admin.rs b/web/src/routes/admin.rs index 14a9b33..cce5c57 100644 --- a/web/src/routes/admin.rs +++ b/web/src/routes/admin.rs @@ -51,16 +51,19 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State>) -> Jso .await .unwrap(); - let schedule = sqlx::query_as_unchecked!( + let schedule_once = sqlx::query_as_unchecked!( TimeFrame, "SELECT - FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 60) * 60) AS `time_key`, + FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 600) * 600) AS `time_key`, COUNT(1) AS `count` FROM reminders WHERE `utc_time` < DATE_ADD(NOW(), INTERVAL 1 DAY) AND `utc_time` >= NOW() AND - `enabled` = 1 + `enabled` = 1 AND + `interval_seconds` IS NULL AND + `interval_months` IS NULL AND + `interval_days` IS NULL GROUP BY `time_key` ORDER BY `time_key`" ) @@ -68,16 +71,40 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State>) -> Jso .await .unwrap(); - let schedule_long = sqlx::query_as_unchecked!( + let schedule_interval = sqlx::query_as_unchecked!( + TimeFrame, + "SELECT + FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 600) * 600) AS `time_key`, + COUNT(1) AS `count` + FROM reminders + WHERE + `utc_time` < DATE_ADD(NOW(), INTERVAL 1 DAY) AND + `utc_time` >= NOW() AND + `enabled` = 1 AND ( + `interval_seconds` IS NOT NULL OR + `interval_months` IS NOT NULL OR + `interval_days` IS NOT NULL + ) + GROUP BY `time_key` + ORDER BY `time_key`" + ) + .fetch_all(pool.inner()) + .await + .unwrap(); + + let schedule_once_long = sqlx::query_as_unchecked!( TimeFrame, "SELECT FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 86400) * 86400) AS `time_key`, COUNT(1) AS `count` FROM reminders WHERE - `utc_time` < DATE_ADD(NOW(), INTERVAL 31 DAY) AND + `utc_time` < DATE_ADD(NOW(), INTERVAL 14 DAY) AND `utc_time` >= NOW() AND - `enabled` = 1 + `enabled` = 1 AND + `interval_seconds` IS NULL AND + `interval_months` IS NULL AND + `interval_days` IS NULL GROUP BY `time_key` ORDER BY `time_key`" ) @@ -85,5 +112,36 @@ pub async fn bot_data(cookies: &CookieJar<'_>, pool: &State>) -> Jso .await .unwrap(); - Ok(json!({ "backlog": backlog.backlog, "schedule": schedule, "scheduleLong": schedule_long })) + let schedule_interval_long = sqlx::query_as_unchecked!( + TimeFrame, + "SELECT + FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`utc_time`) / 86400) * 86400) AS `time_key`, + COUNT(1) AS `count` + FROM reminders + WHERE + `utc_time` < DATE_ADD(NOW(), INTERVAL 14 DAY) AND + `utc_time` >= NOW() AND + `enabled` = 1 AND ( + `interval_seconds` IS NOT NULL OR + `interval_months` IS NOT NULL OR + `interval_days` IS NOT NULL + ) + GROUP BY `time_key` + ORDER BY `time_key`" + ) + .fetch_all(pool.inner()) + .await + .unwrap(); + + Ok(json!({ + "backlog": backlog.backlog, + "scheduleShort": { + "once": schedule_once, + "interval": schedule_interval + }, + "scheduleLong": { + "once": schedule_once_long, + "interval": schedule_interval_long, + } + })) } diff --git a/web/static/js/admin.js b/web/static/js/admin.js index 49dbd5f..18e5bc9 100644 --- a/web/static/js/admin.js +++ b/web/static/js/admin.js @@ -7,13 +7,18 @@ document.addEventListener("DOMContentLoaded", () => { new Chart(document.getElementById("schedule"), { type: "bar", data: { - labels: data.schedule.map((row) => - luxon.DateTime.fromISO(row.time_key) - ), + labels: [ + ...data.scheduleShort.once, + ...data.scheduleShort.interval, + ].map((row) => luxon.DateTime.fromISO(row.time_key)), datasets: [ { label: "Reminders", - data: data.schedule.map((row) => row.count), + data: data.scheduleShort.once.map((row) => row.count), + }, + { + label: "Intervals", + data: data.scheduleShort.interval.map((row) => row.count), }, ], }, @@ -22,11 +27,15 @@ document.addEventListener("DOMContentLoaded", () => { maintainAspectRatio: false, scales: { x: { + stacked: true, type: "time", time: { unit: "minute", }, }, + y: { + stacked: true, + }, }, }, }); @@ -34,13 +43,18 @@ document.addEventListener("DOMContentLoaded", () => { new Chart(document.getElementById("scheduleLong"), { type: "bar", data: { - labels: data.scheduleLong.map((row) => - luxon.DateTime.fromISO(row.time_key) - ), + labels: [ + ...data.scheduleLong.once, + ...data.scheduleLong.interval, + ].map((row) => luxon.DateTime.fromISO(row.time_key)), datasets: [ { label: "Reminders", - data: data.scheduleLong.map((row) => row.count), + data: data.scheduleLong.once.map((row) => row.count), + }, + { + label: "Intervals", + data: data.scheduleLong.interval.map((row) => row.count), }, ], }, @@ -49,11 +63,15 @@ document.addEventListener("DOMContentLoaded", () => { maintainAspectRatio: false, scales: { x: { + stacked: true, type: "time", time: { unit: "day", }, }, + y: { + stacked: true, + }, }, }, });