upend/webui/src/components/widgets/Gallery.svelte

135 lines
3.2 KiB
Svelte
Raw Normal View History

2022-02-02 19:17:30 +01:00
<script lang="ts">
import { readable, type Readable } from "svelte/store";
import type { UpEntry, UpListing } from "upend";
2022-02-15 22:05:51 +01:00
import { query } from "../../lib/entity";
import { defaultEntitySort, entityValueSort } from "../../util/sort";
import BlobPreview from "../display/BlobPreview.svelte";
import UpLink from "../display/UpLink.svelte";
import UpObject from "../display/UpObject.svelte";
2022-02-02 19:17:30 +01:00
export let entries: UpEntry[];
2022-02-20 12:56:46 +01:00
export const editable = false;
export let showEntities = false;
2022-02-02 19:17:30 +01:00
// Sorting
let sortedAttributes = entries;
let sortKeys: { [key: string]: string[] } = {};
function addSortKeys(key: string, vals: string[], resort = true) {
if (!sortKeys[key]) {
sortKeys[key] = [];
}
let changed = false;
vals.forEach((val) => {
if (!sortKeys[key].includes(val)) {
changed = true;
sortKeys[key].push(val);
}
});
if (resort && changed) sortAttributes();
}
// Labelling
let labelListing: Readable<UpListing> = readable(undefined);
$: {
const addresses = [];
entries
.flatMap((e) =>
e.value.t === "Address" ? [e.entity, e.value.c] : [e.entity]
)
.forEach((addr) => {
if (!addresses.includes(addr)) {
addresses.push(addr);
}
});
const addressesString = addresses.map((addr) => `@${addr}`).join(" ");
labelListing = query(`(matches (in ${addressesString}) "LBL" ? )`).result;
}
2022-02-02 19:17:30 +01:00
function sortAttributes() {
sortedAttributes = showEntities
? entityValueSort(entries, sortKeys)
: defaultEntitySort(entries, sortKeys);
2022-02-02 19:17:30 +01:00
}
$: {
if ($labelListing) {
entries.forEach((entry) => {
addSortKeys(
entry.entity,
$labelListing.getObject(entry.entity).identify()
);
if (entry.value.t === "Address") {
addSortKeys(
entry.value.c,
$labelListing.getObject(String(entry.value.c)).identify(),
false
);
}
});
sortAttributes();
}
}
2022-02-02 19:17:30 +01:00
entries.forEach((entry) => {
addSortKeys(entry.entity, entry.listing.getObject(entry.entity).identify());
if (entry.value.t === "Address") {
addSortKeys(
entry.value.c,
entry.listing.getObject(String(entry.value.c)).identify(),
false
);
}
});
sortAttributes();
</script>
<div class="gallery">
{#each sortedAttributes as entry (entry.address)}
<div class="thumbnail">
<UpLink
to={{ entity: String(showEntities ? entry.entity : entry.value.c) }}
>
<BlobPreview
address={String(showEntities ? entry.entity : entry.value.c)}
/>
<div class="label">
<UpObject
address={String(showEntities ? entry.entity : entry.value.c)}
on:resolved={(event) => {
addSortKeys(String(entry.value.c), event.detail);
}}
/>
</div>
</UpLink>
2022-02-02 19:17:30 +01:00
</div>
{/each}
</div>
<style lang="scss">
.thumbnail {
border: 1px solid var(--foreground);
border-radius: 4px;
padding: 0.25em;
}
2022-02-02 19:17:30 +01:00
.gallery {
display: flex;
gap: 1rem;
flex-wrap: wrap;
align-items: flex-end;
2022-02-02 19:17:30 +01:00
}
.thumbnail {
flex-grow: 1;
min-width: 0;
flex-basis: 20%;
2022-02-02 19:17:30 +01:00
}
</style>