You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.0 KiB
72 lines
2.0 KiB
<script lang="ts" context="module">
|
|
const contextKey = {ctx: "itemMultiListContext"};
|
|
|
|
interface ItemMultiListContextData {
|
|
lists: Readable<Record<string, Item[]>>,
|
|
reloadItemLists(): void,
|
|
};
|
|
|
|
const fallback: ItemMultiListContextData = {
|
|
lists: readable({}),
|
|
reloadItemLists() {},
|
|
}
|
|
|
|
export function getItemMultiListContext() {
|
|
return getContext(contextKey) as ItemMultiListContextData || fallback
|
|
}
|
|
</script>
|
|
|
|
<script lang="ts">
|
|
import { readable, writable, type Readable } from "svelte/store";
|
|
import { getContext, setContext } from "svelte";
|
|
import type Item from "$lib/models/item";
|
|
import type { ItemFilter } from "$lib/models/item";
|
|
import { getScopeContext } from "./ScopeContext.svelte";
|
|
import deepEqual from "$lib/utils/object";
|
|
import { sl3 } from "$lib/clients/sl3";
|
|
|
|
const {scope} = getScopeContext();
|
|
|
|
export let lists: Record<string, Item[]>
|
|
export let filters: Record<string, ItemFilter>
|
|
export let global: boolean = false;
|
|
|
|
let loaded: Record<string, ItemFilter> = {...filters};
|
|
let loading: Record<string, boolean> = {};
|
|
const listsWritable = writable<Record<string, Item[]>>({...lists});
|
|
|
|
function reloadItemLists() {
|
|
loaded = {};
|
|
}
|
|
|
|
async function runLoad(key: string, filter: ItemFilter) {
|
|
loading = {...loading, [key]: true};
|
|
|
|
try {
|
|
const items = await sl3(fetch).listItems(global ? "ALL" : $scope.id, filter)
|
|
listsWritable.update(l => ({...l, [key.replace("Filter", "Items")]: items}));
|
|
} catch(_err) {
|
|
// TODO: Use err
|
|
}
|
|
|
|
loading = {...loading, [key]: false};
|
|
loaded = {...loaded, [key]: filter};
|
|
}
|
|
|
|
setContext<ItemMultiListContextData>(contextKey, {
|
|
lists: {subscribe: listsWritable.subscribe},
|
|
reloadItemLists,
|
|
});
|
|
|
|
$: for (const key in filters) {
|
|
if (loading[key]) {
|
|
continue;
|
|
}
|
|
|
|
if (loaded[key] == null || !deepEqual(filters[key], loaded[key])) {
|
|
runLoad(key, {...filters[key]})
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<slot></slot>
|