Files
firefly-ui/src/routes/currencies/CurrencyForm.svelte
T

133 lines
3.9 KiB
Svelte

<script lang="ts">
import { untrack } from "svelte";
import { api } from "#lib/api/client.js";
import { invalidate } from "#lib/api/lists.js";
import type { Currency, Item } from "#lib/api/types.js";
import Box from "#lib/components/Box.svelte";
import ConfirmButton from "#lib/components/ConfirmButton.svelte";
import { Action } from "#lib/components/misc/action.svelte.js";
import Field from "#lib/components/misc/Field.svelte";
import Status from "#lib/components/misc/Status.svelte";
import Button from "#lib/components/ui/button/button.svelte";
import Input from "#lib/components/ui/input/input.svelte";
import { useKeys } from "#lib/keys.svelte.js";
import { session } from "#lib/session.svelte.js";
import { goto } from "$app/navigation";
let { item }: { item?: Item<Currency> } = $props();
const form = $state(
untrack(() => ({
code: item?.attributes.code ?? "",
decimal_places: item?.attributes.decimal_places ?? 2,
enabled: item?.attributes.enabled ?? true,
name: item?.attributes.name ?? "",
symbol: item?.attributes.symbol ?? "",
}))
);
const save = new Action();
const removal = new Action();
let element: HTMLFormElement | undefined = $state();
async function done() {
await Promise.all([invalidate(), session.loadCurrencies()]);
await goto("/currencies");
}
async function submit(event?: SubmitEvent) {
event?.preventDefault();
const body = { ...form, decimal_places: Number(form.decimal_places) };
const ok = await save.run(() =>
item
? api(`/v1/currencies/${item.attributes.code}`, { body, method: "PUT" })
: api("/v1/currencies", { body, method: "POST" })
);
if (ok) {
await done();
}
}
async function remove() {
if (
item &&
(await removal.run(
() =>
api(`/v1/currencies/${item.attributes.code}`, { method: "DELETE" }),
"Deleted"
))
) {
await done();
}
}
useKeys(() => [
{
group: "Form",
input: true,
keys: "mod+Enter",
label: item ? "Update currency" : "Store new currency",
run: () => element?.requestSubmit(),
},
]);
</script>
<form class="max-w-3xl" onsubmit={submit} bind:this={element}>
<Box title="Mandatory fields">
<div class="flex flex-col gap-3">
<Field for="name" label="Name" problem={save.field("name")}>
<Input id="name" maxlength={48} required bind:value={form.name} />
</Field>
<Field for="symbol" label="Symbol" problem={save.field("symbol")}>
<Input id="symbol" maxlength={51} required bind:value={form.symbol} />
</Field>
<Field for="code" label="Code" problem={save.field("code")}>
<Input
class="num uppercase"
id="code"
maxlength={51}
required
bind:value={form.code}
/>
</Field>
<Field
for="decimal_places"
label="Number of decimals"
problem={save.field("decimal_places")}
>
<Input
class="num w-24"
id="decimal_places"
max={12}
min={0}
required
type="number"
bind:value={form.decimal_places}
/>
</Field>
{#if item}
<Field for="enabled" label="Enabled">
<input
class="mt-2 size-3.5 accent-brand"
id="enabled"
type="checkbox"
bind:checked={form.enabled}
>
</Field>
{/if}
</div>
{#snippet footer()}
<Button disabled={save.busy} size="sm" type="submit">
{item ? "Update currency" : "Store new currency"}
</Button>
<Status action={save} />
{#if item}
<span class="ml-auto flex items-center gap-2">
<Status action={removal} busy="Deleting" />
<ConfirmButton onconfirm={remove}>Delete currency</ConfirmButton>
</span>
{/if}
{/snippet}
</Box>
</form>