summaryrefslogtreecommitdiffstats
path: root/web/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/index.js')
-rw-r--r--web/index.js97
1 files changed, 84 insertions, 13 deletions
diff --git a/web/index.js b/web/index.js
index e8accf0..63292aa 100644
--- a/web/index.js
+++ b/web/index.js
@@ -7,6 +7,50 @@ closeButton.addEventListener("click", () => {
7 dialog.close(); 7 dialog.close();
8}); 8});
9 9
10function handlePeriodLimitPresetSelInput(selEl, inputEl) {
11 selEl.addEventListener("input", (event) => {
12 if (selEl.value === "custom") {
13 inputEl.classList.remove("hidden");
14 } else {
15 inputEl.classList.add("hidden");
16 }
17 });
18}
19
20function getPeriodLimitPresetSelInput(selEl, inputEl) {
21 const relativeDateTime = (durationArgs) => Temporal.Now.plainDateTimeISO().add(durationArgs);
22
23 let durationArgs = {};
24 switch (selEl.value) {
25 case "-1m": return relativeDateTime({ months: -1 });
26 case "-2w": return relativeDateTime({ weeks: -2 });
27 case "-1w": return relativeDateTime({ weeks: -1 });
28 case "0": return relativeDateTime({ seconds: 0 });
29 case "+1w": return relativeDateTime({ weeks: 1 });
30 case "+2w": return relativeDateTime({ weeks: 2 });
31 case "+1m": return relativeDateTime({ months: 1 });
32 case "custom": return Temporal.PlainDateTime.from(inputEl.value);
33 }
34}
35
36handlePeriodLimitPresetSelInput(
37 document.getElementById("check-period-begin-preset-select"),
38 document.getElementById("check-period-begin-input"));
39handlePeriodLimitPresetSelInput(
40 document.getElementById("check-period-end-preset-select"),
41 document.getElementById("check-period-end-input"));
42
43window.addEventListener("load", (event) => {
44 const oneWeek = Temporal.Duration.from({ weeks: 1 });
45 const now = Temporal.Now.plainDateTimeISO();
46 document.getElementById("check-period-begin-input").value = now.subtract(oneWeek).toString({
47 smallestUnit: "minute",
48 });
49 document.getElementById("check-period-end-input").value = now.add(oneWeek).toString({
50 smallestUnit: "minute",
51 });
52});
53
10let map = L.map("map"); 54let map = L.map("map");
11 55
12L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { 56L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
@@ -19,10 +63,27 @@ document.forms["gpx-upload-form"].addEventListener("submit", (event) => {
19 event.preventDefault(); 63 event.preventDefault();
20 const gpxFileInput = document.getElementById("gpx-file-input"); 64 const gpxFileInput = document.getElementById("gpx-file-input");
21 if (gpxFileInput.files.length !== 1) { 65 if (gpxFileInput.files.length !== 1) {
22 alert("Voor de upload moet er exact één GPX-bestand zijn geselecteerd"); 66 showDialog({
67 title: "Geen bestand geselecteerd",
68 detail: "Voor de upload moet er exact één GPX-bestand zijn geselecteerd",
69 moreInfoEl: null,
70 });
23 return; 71 return;
24 } 72 }
25 load(gpxFileInput.files[0]); 73
74 const tzidHere = Temporal.Now.timeZoneId();
75 const cpBegin = getPeriodLimitPresetSelInput(document.getElementById("check-period-begin-preset-select"),
76 document.getElementById("check-period-begin-input")).toZonedDateTime(tzidHere).toInstant();
77 const cpEnd = getPeriodLimitPresetSelInput(document.getElementById("check-period-end-preset-select"),
78 document.getElementById("check-period-end-input")).toZonedDateTime(tzidHere).toInstant();
79
80 load({
81 gpxFile: gpxFileInput.files[0],
82 checkPeriod: {
83 begin: cpBegin,
84 end: cpEnd,
85 },
86 });
26}); 87});
27 88
28function el(name, attrs, ...children) { 89function el(name, attrs, ...children) {
@@ -47,15 +108,22 @@ function tbl(rowcols) {
47 )))); 108 ))));
48} 109}
49 110
50async function showProblem(rsp) { 111function showDialog({ title, detail, moreInfoEl }) {
51 const problem = await rsp.json(); 112 document.getElementById("dialog-title").innerText = title;
113 document.getElementById("dialog-message").innerText = detail !== null ? detail : "";
114 if (moreInfoEl !== null) {
115 document.getElementById("dialog-more-info").replaceChildren(moreInfoEl);
116 document.getElementById("dialog-more-info-container").classList.remove("hidden");
117 } else {
118 document.getElementById("dialog-more-info").replaceChildren();
119 document.getElementById("dialog-more-info-container").classList.add("hidden");
120 }
52 121
53 document.getElementById("dialog-title").innerText = problem.title;
54 if (problem.detail)
55 document.getElementById("dialog-message").innerText = problem.detail;
56 else
57 document.getElementById("dialog-message").innerText = "";
58 dialog.showModal(); 122 dialog.showModal();
123}
124
125async function showProblem(rsp) {
126 const problem = await rsp.json();
59 127
60 let rows = [ 128 let rows = [
61 [txt("HTTP-statuscode"), 129 [txt("HTTP-statuscode"),
@@ -70,9 +138,12 @@ async function showProblem(rsp) {
70 rows.push([txt("Instantie"), 138 rows.push([txt("Instantie"),
71 el("code", {}, txt(problem.instance))]); 139 el("code", {}, txt(problem.instance))]);
72 } 140 }
73 document.getElementById("dialog-more-info").replaceChildren(tbl(rows));
74 141
75 return; 142 showDialog({
143 title: problem.title,
144 detail: problem.detail ? problem.detail : null,
145 moreInfoEl: tbl(rows),
146 });
76} 147}
77 148
78async function getSysinfo() { 149async function getSysinfo() {
@@ -101,7 +172,7 @@ async function getSysinfo() {
101 document.getElementById("sysinfo-details").replaceChildren(tbl(rows)); 172 document.getElementById("sysinfo-details").replaceChildren(tbl(rows));
102} 173}
103 174
104async function load(gpxFile) { 175async function load({ gpxFile, checkPeriod }) {
105 let compressedParts = []; 176 let compressedParts = [];
106 const compressedReader = gpxFile.stream().pipeThrough(new CompressionStream("deflate-raw")).getReader(); 177 const compressedReader = gpxFile.stream().pipeThrough(new CompressionStream("deflate-raw")).getReader();
107 while (true) { 178 while (true) {
@@ -113,7 +184,7 @@ async function load(gpxFile) {
113 } 184 }
114 } 185 }
115 186
116 const rsp = await fetch(apiBaseUrl + "/gpx", { 187 const rsp = await fetch(apiBaseUrl + `/gpx?cpbegin=${encodeURI(checkPeriod.begin.toString({ smallestUnit: "minute" }))}&cpend=${encodeURI(checkPeriod.end.toString({ smallestUnit: "minute" }))}`, {
117 method: "POST", 188 method: "POST",
118 headers: { 189 headers: {
119 "Accept-Language": "nl-NL", 190 "Accept-Language": "nl-NL",