upend/webui/src/views/Home.svelte

146 lines
3.5 KiB
Svelte

<script lang="ts">
import { formatRelative, parseISO } from "date-fns";
import { Link } from "svelte-navigator";
import { UpListing } from "upend";
import type { IFile, ListingResult } from "upend/types";
import UpObject from "../components/display/UpObject.svelte";
import UpObjectCard from "../components/display/UpObjectCard.svelte";
import Spinner from "../components/utils/Spinner.svelte";
import { query } from "../lib/entity";
import { vaultInfo } from "../util/info";
import { updateTitle } from "../util/title";
const roots = (async () => {
const response = await fetch("api/hier_roots");
const data = (await response.json()) as ListingResult;
const listing = new UpListing(data);
return Object.values(listing.objects).filter((obj) =>
Boolean(obj.attr["LBL"])
);
})();
const { result: lastVisitedQuery } = query(`(matches ? "LAST_VISITED" ? )`);
$: lastVisited = ($lastVisitedQuery?.entries || [])
.filter((e) => e.value.t == "Number")
.sort((a, b) => (b.value.c as number) - (a.value.c as number))
.map((e) => [e.entity, e.value.c as number])
.slice(0, 25) as [string, number][];
const { result: latestQuery } = query(`(matches ? "ADDED" ?)`);
$: latest = ($latestQuery?.entries || [])
.filter((e) => e.value.t == "Number")
.sort((a, b) => (b.value.c as number) - (a.value.c as number))
.map((e) => [e.entity, e.value.c as number])
.slice(0, 25) as [string, number][];
updateTitle("Home");
</script>
<div class="home">
<h1>
{$vaultInfo?.name || "UpEnd"}
</h1>
<section class="roots">
<h2>Roots</h2>
{#await roots}
<Spinner centered />
{:then data}
<ul>
{#each data as root}
<li class="root">
<UpObjectCard address={root.address} />
</li>
{:else}
<li>No roots :(</li>
{/each}
</ul>
{/await}
</section>
{#if lastVisited.length > 0}
<section class="lastVisited">
<h2>Last visited</h2>
<table>
{#each lastVisited as [address, visited]}
<tr>
<td class="timestamp"
>{formatRelative(visited * 1000, new Date())}</td
>
<td class="object"><UpObject link {address} /></td>
</tr>
{/each}
</table>
</section>
{/if}
<section class="latest">
<h2>Most recently added</h2>
<table>
{#each latest as [address, added]}
<tr>
<td class="timestamp">{formatRelative(added * 1000, new Date())}</td>
<td class="object"><UpObject link {address} /></td>
</tr>
{/each}
</table>
</section>
<footer>
<div>
<strong>UpEnd</strong> - a database for the complex, the changing, and the
indeterminate
</div>
<div>
<a target="_blank" href="https://upendproject.net">
v{$vaultInfo?.version || "???"}
</a>
</div>
</footer>
</div>
<style lang="scss">
h1,
h2 {
text-align: center;
}
.latest,
.lastVisited {
table {
border-spacing: 1em 0.25em;
}
.timestamp {
opacity: 0.77;
white-space: nowrap;
text-align: center;
}
}
.roots {
ul {
list-style: none;
padding: 0;
margin: 0 2rem;
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 2rem;
}
.root {
font-size: 24px;
}
}
footer {
border-top: 1px solid var(--foreground);
text-align: center;
margin: 3em 3em 1em 3em;
& > * {
margin: 0.5em;
}
}
</style>