73 lines
1.7 KiB
Svelte
73 lines
1.7 KiB
Svelte
<script lang="ts">
|
|
import { toast } from "svelte-sonner";
|
|
import type { ApiClient } from "$lib/api/client";
|
|
import type { ConversationSummary } from "$lib/api/types";
|
|
import { Button } from "$lib/components/ui/button";
|
|
import * as Dialog from "$lib/components/ui/dialog";
|
|
import { Input } from "$lib/components/ui/input";
|
|
|
|
let {
|
|
client,
|
|
info,
|
|
open = $bindable(false),
|
|
onChanged,
|
|
}: {
|
|
client: ApiClient;
|
|
info: Pick<ConversationSummary, "id" | "title">;
|
|
open?: boolean;
|
|
onChanged: () => void;
|
|
} = $props();
|
|
|
|
let title = $state("");
|
|
let busy = $state(false);
|
|
|
|
$effect(() => {
|
|
if (open) {
|
|
title = info.title ?? "";
|
|
}
|
|
});
|
|
|
|
async function save() {
|
|
busy = true;
|
|
try {
|
|
await client.update(info.id, { title });
|
|
open = false;
|
|
toast.success("Renamed");
|
|
onChanged();
|
|
} catch (error) {
|
|
toast.error(error instanceof Error ? error.message : String(error));
|
|
} finally {
|
|
busy = false;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<Dialog.Root bind:open>
|
|
<Dialog.Content>
|
|
<Dialog.Header>
|
|
<Dialog.Title>Rename</Dialog.Title>
|
|
</Dialog.Header>
|
|
<form
|
|
class="flex flex-col gap-4"
|
|
onsubmit={(event) => {
|
|
event.preventDefault();
|
|
save();
|
|
}}
|
|
>
|
|
<Input aria-label="Title" placeholder="Title" bind:value={title} />
|
|
<Dialog.Footer>
|
|
<Button
|
|
onclick={() => {
|
|
// biome-ignore lint/suspicious/noGlobalAssign: bindable prop, not window.open
|
|
open = false;
|
|
}}
|
|
variant="ghost"
|
|
>
|
|
Cancel
|
|
</Button>
|
|
<Button disabled={busy} type="submit">Save</Button>
|
|
</Dialog.Footer>
|
|
</form>
|
|
</Dialog.Content>
|
|
</Dialog.Root>
|