107 lines
3.1 KiB
TypeScript
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>
|
|
);
|
|
}
|