Show selected signals as a table with relative time data.
This commit is contained in:
parent
49a109ae85
commit
662188485e
2 changed files with 126 additions and 20 deletions
92
html/static/js/time-relative.js
Normal file
92
html/static/js/time-relative.js
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* Custom HTML element <time-relative> that displays relative time
|
||||
* Usage: <time-relative time="2024-01-01T12:00:00Z"></time-relative>
|
||||
*/
|
||||
|
||||
class TimeRelative extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.span = null;
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["time"];
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
// Create the span element if it doesn't exist
|
||||
if (!this.span) {
|
||||
this.span = document.createElement("span");
|
||||
this.span.className = "time-relative";
|
||||
this.appendChild(this.span);
|
||||
}
|
||||
this.updateTime();
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (name === "time" && oldValue !== newValue) {
|
||||
this.updateTime();
|
||||
}
|
||||
}
|
||||
|
||||
updateTime() {
|
||||
if (this.span) {
|
||||
const timeValue = this.getAttribute("time");
|
||||
if (timeValue) {
|
||||
this.span.textContent = this.formatRelativeTime(timeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formatRelativeTime(timestamp) {
|
||||
const now = new Date();
|
||||
const date = new Date(timestamp);
|
||||
const diffInSeconds = Math.floor((now - date) / 1000);
|
||||
|
||||
// Time units in seconds
|
||||
const minute = 60;
|
||||
const hour = minute * 60;
|
||||
const day = hour * 24;
|
||||
const week = day * 7;
|
||||
const month = day * 30;
|
||||
const year = day * 365;
|
||||
|
||||
if (diffInSeconds < minute) {
|
||||
return "just now";
|
||||
} else if (diffInSeconds < hour) {
|
||||
const minutes = Math.floor(diffInSeconds / minute);
|
||||
return `${minutes} ${minutes === 1 ? "minute" : "minutes"} ago`;
|
||||
} else if (diffInSeconds < day) {
|
||||
const hours = Math.floor(diffInSeconds / hour);
|
||||
return `${hours} ${hours === 1 ? "hour" : "hours"} ago`;
|
||||
} else if (diffInSeconds < week) {
|
||||
const days = Math.floor(diffInSeconds / day);
|
||||
return `${days} ${days === 1 ? "day" : "days"} ago`;
|
||||
} else if (diffInSeconds < month) {
|
||||
const weeks = Math.floor(diffInSeconds / week);
|
||||
return `${weeks} ${weeks === 1 ? "week" : "weeks"} ago`;
|
||||
} else if (diffInSeconds < year) {
|
||||
const months = Math.floor(diffInSeconds / month);
|
||||
return `${months} ${months === 1 ? "month" : "months"} ago`;
|
||||
} else {
|
||||
const years = Math.floor(diffInSeconds / year);
|
||||
return `${years} ${years === 1 ? "year" : "years"} ago`;
|
||||
}
|
||||
}
|
||||
|
||||
// Property getter and setter for JavaScript access
|
||||
get time() {
|
||||
return this.getAttribute("time");
|
||||
}
|
||||
|
||||
set time(value) {
|
||||
if (value) {
|
||||
this.setAttribute("time", value);
|
||||
} else {
|
||||
this.removeAttribute("time");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register the custom element
|
||||
customElements.define("time-relative", TimeRelative);
|
||||
|
|
@ -6,13 +6,14 @@
|
|||
type="text/javascript"
|
||||
src="//unpkg.com/maplibre-gl@5.0.1/dist/maplibre-gl.js"
|
||||
></script>
|
||||
<script src="/static/js/map-arcgis-tile.js"></script>
|
||||
<script src="/static/js/map-multipoint.js"></script>
|
||||
<script
|
||||
defer
|
||||
src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"
|
||||
></script>
|
||||
<script src="https://unpkg.com/@esri/maplibre-arcgis@1.1.0/dist/umd/maplibre-arcgis.min.js"></script>
|
||||
<script src="/static/js/map-arcgis-tile.js"></script>
|
||||
<script src="/static/js/map-multipoint.js"></script>
|
||||
<script src="/static/js/time-relative.js"></script>
|
||||
|
||||
<script>
|
||||
// Return two points defining a bounding box for the given points
|
||||
|
|
@ -43,7 +44,7 @@
|
|||
);
|
||||
}
|
||||
function shortAddress(a) {
|
||||
return a.number + " " + a.street + ", " + a.locality + ", " + a.region;
|
||||
return a.number + " " + a.street + ", " + a.locality;
|
||||
}
|
||||
function updateMap(signals) {
|
||||
const map = document.querySelector("map-multipoint");
|
||||
|
|
@ -512,23 +513,36 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<ul class="small mt-2" x-show="selectedSignals.length > 0">
|
||||
<table
|
||||
class="small mt-2 table"
|
||||
x-show="selectedSignals.length > 0"
|
||||
>
|
||||
<tbody>
|
||||
<template
|
||||
x-for="signal in selectedSignals"
|
||||
:key="signal.id"
|
||||
>
|
||||
<li>
|
||||
<span x-text="signal.title"></span>
|
||||
<tr x-if="signal.type == 'flyover pool'">
|
||||
<td>
|
||||
<button
|
||||
@click="toggleSignal(signal)"
|
||||
class="btn btn-sm btn-link text-danger p-0 ms-1"
|
||||
style="font-size: 0.7rem;"
|
||||
>
|
||||
✕
|
||||
<i class="bi bi-x"></i>
|
||||
</button>
|
||||
</li>
|
||||
</td>
|
||||
<td>Green pool</td>
|
||||
<td>
|
||||
<time-relative
|
||||
:time="signal.created"
|
||||
></time-relative>
|
||||
</td>
|
||||
<td x-text="shortAddress(signal.address)"></td>
|
||||
</tr>
|
||||
</template>
|
||||
</ul>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<button
|
||||
x-show="selectedSignals.length > 0"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue