Files
beavergram/frontend/src/lib/components/watches/WatchesPanel.svelte
T

81 lines
1.8 KiB
Svelte

<script lang="ts">
import {
createWatch,
deleteWatch,
listWatches,
updateWatch,
} from "$lib/api/endpoints";
import type { Watch } from "$lib/api/types";
import { accounts } from "$lib/stores/accounts.svelte";
import Spinner from "../ui/Spinner.svelte";
import WatchEditor from "./WatchEditor.svelte";
import WatchList from "./WatchList.svelte";
let watches = $state<Watch[]>([]);
let loading = $state(true);
let saving = $state(false);
async function load(_account: number | null) {
loading = true;
try {
watches = await listWatches();
} finally {
loading = false;
}
}
$effect(() => {
load(accounts.selectedId);
});
async function add(data: {
kind: string;
params: Record<string, unknown>;
enabled: boolean;
}) {
saving = true;
try {
const created = await createWatch(data.kind, data.params, data.enabled);
watches = [created, ...watches];
} finally {
saving = false;
}
}
async function toggle(watch: Watch) {
const updated = await updateWatch(watch.id, watch.params, !watch.enabled);
watches = watches.map((w) => (w.id === updated.id ? updated : w));
}
async function remove(watch: Watch) {
await deleteWatch(watch.id);
watches = watches.filter((w) => w.id !== watch.id);
}
</script>
<div class="panel-content">
<WatchEditor {saving} onsave={add} />
{#if loading}
<Spinner />
{:else if watches.length === 0}
<p class="empty">Пока нет отслеживаний.</p>
{:else}
<WatchList {watches} ontoggle={toggle} ondelete={remove} />
{/if}
</div>
<style lang="scss">
.panel-content {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
}
.empty {
color: var(--color-text-secondary);
text-align: center;
}
</style>