<!--
What this repository commits about itself: `.wsb/repo.json` — its name, the
alias other repositories' templates know it by, where its templates look,
and how its version is made. Saved whole, as the file is; the change is in
the next commit like any other.
-->
<script lang="ts">
import type { RepoSettings } from "../../api/client.js";
import { settings } from "../../stores/settings.svelte.js";
import SettingsSection from "./SettingsSection.svelte";
/** One per line, blank lines dropped. */
function lines(text: string): string[] {
return text
.split("\n")
.map((line) => line.trim())
.filter((line) => line.length > 0);
}
function draftOf(held: RepoSettings | undefined) {
return {
name: held?.name ?? "",
alias: held?.alias ?? "",
templatesRoot: held?.templates_root ?? ".",
major: held?.version.major ?? 0,
file: held?.version.file ?? "version.txt",
suffix: held?.version.suffix ?? "",
detect: held?.version.detect_manifests ?? true,
manifests: (held?.version.manifests ?? []).join("\n"),
};
}
const held = $derived(settings.repo?.settings);
let draft = $state(draftOf(undefined));
$effect(() => {
draft = draftOf(held);
});
const written = $derived<RepoSettings>({
name: draft.name.trim(),
alias: draft.alias.trim(),
templates_root: draft.templatesRoot.trim(),
version: {
major: draft.major,
file: draft.file.trim(),
suffix: draft.suffix.trim() || null,
detect_manifests: draft.detect,
manifests: lines(draft.manifests),
},
});
const dirty = $derived(JSON.stringify(draftOf(held)) !== JSON.stringify(draft));
async function save() {
await settings.save({ repo: written });
}
</script>
<SettingsSection
title="Repository"
description="What this repository commits about itself, in {settings.repo?.path ?? '.wsb/repo.json'}."
>
<div class="settings-form">
<label class="field">
<span class="field-label">Name</span>
<input class="field-input" bind:value={draft.name} />
</label>
<label class="field">
<span class="field-label">Alias — what other repositories' templates call it</span>
<input class="field-input" bind:value={draft.alias} />
</label>
<label class="field">
<span class="field-label">Templates root — where its templates look for the repositories they name</span>
<input class="field-input" bind:value={draft.templatesRoot} />
</label>
<div class="settings-row">
<label class="field">
<span class="field-label">Major version</span>
<input class="field-input" type="number" min="0" bind:value={draft.major} />
</label>
<label class="field">
<span class="field-label">Version file</span>
<input class="field-input" bind:value={draft.file} />
</label>
<label class="field">
<span class="field-label">Suffix</span>
<input class="field-input" placeholder="none" bind:value={draft.suffix} />
</label>
</div>
<label class="check">
<input type="checkbox" bind:checked={draft.detect} />
The manifests at the repository's root (Cargo.toml, package.json, …) carry the version
</label>
<label class="field">
<span class="field-label">Further manifests that carry it, one per line</span>
<textarea class="field-input" rows="3" bind:value={draft.manifests}></textarea>
</label>
{#if dirty}
<div class="button-row">
<button class="primary" disabled={settings.saving} onclick={() => void save()}>
{settings.saving ? "Saving…" : "Save"}
</button>
<button class="secondary" onclick={() => (draft = draftOf(held))}>Discard</button>
</div>
{/if}
</div>
</SettingsSection>
<style>
.settings-form {
display: flex;
flex-direction: column;
gap: var(--wb-spacing-10);
}
.settings-row {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: var(--wb-spacing-10);
}
</style>