Something went wrong. Try again.
Monorepo for Tangled
Something went wrong. Try again.
Svelte
at sl/gitmirror
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111<script lang="ts"> import type { ResolvedPathname } from "$app/types"; import type { ResourceUri } from "@atcute/lexicons/syntax"; import { createBobbinClient } from "$lib/api/client"; import { BASIC_LABEL_VALUE, createLabelOp, createRepoLabel, isBasicLabel, type AppliedLabels, type LabelView, type SubjectLabels } from "$lib/api/labels"; import { getRepo } from "$lib/api/records"; import { didFromUri } from "$lib/api/uri"; import { getAuth } from "$lib/auth.svelte"; import LabelPanel, { type Label } from "$lib/components/repo/LabelPanel.svelte";
interface Props { subject: string; repoUri: string; labels: SubjectLabels; listHref: string; settingsHref: string; canEdit?: boolean; direction?: "horizontal" | "vertical"; }
let { subject, repoUri, labels, listHref, settingsHref, canEdit = false, direction }: Props = $props();
const auth = getAuth();
let applied = $derived<AppliedLabels>(labels.applied);
let created = $state<LabelView[]>([]);
const isOwner = $derived(auth.currentDid === didFromUri(repoUri));
const allLabels = $derived<Label[]>( [...labels.definitions, ...created] .filter((definition) => isBasicLabel(definition.value)) .map((definition) => ({ key: definition.uri, name: definition.value.name, color: definition.value.color ?? "", href: `${listHref}?label=${encodeURIComponent(definition.value.name)}` as ResolvedPathname })) );
const picked = $derived(allLabels.filter((label) => applied[label.key]?.length));
const operands = (keys: string[]) => keys.map((key) => ({ key: key as ResourceUri, value: BASIC_LABEL_VALUE }));
const change = async (keys: string[]) => { const agent = auth.agent; if (!agent) return; const before = applied; const current = picked.map((label) => label.key); const add = keys.filter((key) => !current.includes(key)); const remove = current.filter((key) => !keys.includes(key)); if (add.length === 0 && remove.length === 0) return; const next = { ...before }; for (const key of add) next[key] = [BASIC_LABEL_VALUE]; for (const key of remove) delete next[key]; applied = next; try { await createLabelOp(agent, subject, { add: operands(add), delete: operands(remove) }); } catch { applied = before; } };
const createLabel = async (name: string, color: string) => { const agent = auth.agent; if (!agent) return; const label = await getRepo(createBobbinClient({ serviceUrl: auth.bobbinUrl }), repoUri) .then((repo) => createRepoLabel(agent, auth.bobbinUrl, repo, { name, color, issues: true, pulls: true, keyValue: false }) ) .catch(() => null); if (!label) return; created = [...created, label]; await change([...picked.map((current) => current.key), label.uri]); };</script>
<LabelPanel {direction} labels={picked} {allLabels} canEdit={canEdit && !!auth.agent} onLabelsChange={change} onCreateLabel={canEdit && isOwner ? createLabel : undefined} settingsHref={canEdit && isOwner ? settingsHref : undefined}/>