scrowl/src/ui/Digith/Signal/NewSignalDraftDigith.tsx
2026-02-16 19:11:57 +01:00

107 lines
3.1 KiB
TypeScript

import { createSignal } from "solid-js";
import { Digith } from "src/ui/Digith";
import { useProgram } from "src/ui/ProgramProvider";
import { CodeEditor } from "src/ui/Component/CodeEditor";
import { sourceText } from "src/lang/parser/source_text";
import { Program } from "src/lang/program";
import { V, Validation, letValidate } from "src/ui/validation";
import { validateNameRaw, validateSignalExprRaw } from "src/ui/validation/helpers";
import { DigithError } from "src/ui/Digith/DigithError";
import { spawnSignalDigith } from "src/ui/Scrowl/scrowlStore";
type Input = {
raw_name: string,
raw_body: string,
}
const validator: Validation<Input, Program.CreateSignal, DigithError> = letValidate(
(input) =>({
name: V.elseErr(validateNameRaw(input.raw_name), err =>({
payload: { tag: "Parse", err, src: sourceText(input.raw_name) },
ids: ["name"],
tags: ["footer"],
config: { title: "Signal Name", display: "flat" },
})),
body: V.elseErr(validateSignalExprRaw(input.raw_body), err => ({
payload: { tag: "Parse", err, src: sourceText(input.raw_body) },
ids: ["body"],
tags: ["footer"],
config: { title: "Signal Body", display: "flat" },
})),
}),
(fields, input) => {
const createSignal: Program.CreateSignal = {
name: fields.name,
body: fields.body,
raw_body: input.raw_body,
};
return V.ok(createSignal);
})
export function NewSignalDraftDigith(props: { draft: Digith.NewSignalDraft }) {
const program = useProgram();
const [name, setName] = createSignal(props.draft.raw_name);
const [body, setBody] = createSignal(props.draft.raw_body);
const [errors, setErrors] = createSignal<DigithError[]>([]);
function handleCommit() {
setErrors([]);
const validRes = validator({ raw_name: name(), raw_body: body() });
if (validRes.tag === "errors") {
setErrors(validRes.errors);
return;
}
const createSignal = validRes.value;
const programRes = Program.registerSignal(program, createSignal);
if (programRes.tag === "error") {
setErrors([{
payload: { tag: "Program", err: programRes.error },
ids: ["program"],
tags: ["footer"],
config: { title: "Registration Failed" },
}]);
return;
}
const signalName = programRes.value;
spawnSignalDigith(program, signalName, props.draft.id);
};
return (
<article>
<header><strong>Signal (Draft)</strong></header>
<div class="grid">
<label>
Name
<input
type="text"
placeholder="my_sig"
value={name()}
onInput={(e) => setName(e.currentTarget.value)}
/>
</label>
</div>
<label>Body</label>
<CodeEditor
value={body()}
onUpdate={setBody}
onRun={handleCommit}
/>
<footer>
<button class="primary" onClick={handleCommit}>Commit</button>
</footer>
<div style={{ "margin-top": "1rem" }}>
<DigithError.ByTag errors={errors()} tag="footer" />
</div>
</article>
);
}