@miadi/stateloom-web 0.1.9 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/server/.next/BUILD_ID +1 -1
- package/server/.next/build-manifest.json +2 -2
- package/server/.next/server/app/_global-error.html +2 -2
- package/server/.next/server/app/_global-error.rsc +1 -1
- package/server/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/server/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/server/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/server/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/server/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/server/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/server/.next/server/app/_not-found.html +1 -1
- package/server/.next/server/app/_not-found.rsc +2 -2
- package/server/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/server/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/server/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/server/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/server/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/server/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/server/.next/server/app/api/docs/route.js.nft.json +1 -1
- package/server/.next/server/app/api/file/route.js.nft.json +1 -1
- package/server/.next/server/app/api/rispec/route.js.nft.json +1 -1
- package/server/.next/server/app/api/watch/route.js.nft.json +1 -1
- package/server/.next/server/app/index.html +1 -1
- package/server/.next/server/app/index.rsc +3 -3
- package/server/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/server/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/server/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/server/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/server/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/server/.next/server/app/page.js.nft.json +1 -1
- package/server/.next/server/app/page_client-reference-manifest.js +1 -1
- package/server/.next/server/chunks/[root-of-the-server]__13c3d2a8._.js +1 -1
- package/server/.next/server/chunks/[root-of-the-server]__2046b812._.js +2 -2
- package/server/.next/server/chunks/[root-of-the-server]__87bf4b91._.js +1 -1
- package/server/.next/server/chunks/[root-of-the-server]__95b05635._.js +3 -3
- package/server/.next/server/chunks/ssr/{[root-of-the-server]__d5879c0c._.js → [root-of-the-server]__b1b2bf74._.js} +2 -2
- package/server/.next/server/chunks/ssr/[root-of-the-server]__edbb995c._.js +4 -3
- package/server/.next/server/pages/404.html +1 -1
- package/server/.next/server/pages/500.html +2 -2
- package/server/.next/static/chunks/9390437c8b41a90e.js +11 -0
- package/server/.next/static/chunks/a8a37c487ef91a19.js +1 -0
- package/server/.next/static/chunks/c86e96e4d6eeb632.css +2 -0
- package/server/package-lock.json +2 -2
- package/server/package.json +1 -1
- package/server/src/app/api/file/route.ts +57 -12
- package/server/src/app/globals.css +15 -0
- package/server/src/app/page.tsx +52 -10
- package/server/src/components/BoardBoundary.tsx +46 -0
- package/server/src/components/PropertiesPanel.tsx +10 -0
- package/server/src/components/erd/ErdWorkspace.tsx +32 -3
- package/server/src/components/forms.tsx +129 -0
- package/server/src/components/sequence/SequenceWorkspace.tsx +1024 -0
- package/server/src/components/system/KindIcon.tsx +71 -0
- package/server/src/components/system/SystemStrip.tsx +285 -0
- package/server/src/components/system/SystemWorkspace.tsx +766 -0
- package/server/src/lib/docParam.ts +4 -1
- package/server/src/lib/machineFocus.ts +126 -0
- package/server/src/lib/projectFile.ts +180 -20
- package/server/src/lib/safely.ts +16 -0
- package/server/src/lib/systemLoad.ts +362 -0
- package/server/src/lib/systemParam.ts +110 -0
- package/server/src/types/definition.ts +2 -0
- package/server/stateloom-web.json +2 -2
- package/server/.next/static/chunks/636e7eb4aeda72e0.css +0 -2
- package/server/.next/static/chunks/92628504da59dcc8.js +0 -10
- package/server/.next/static/chunks/aea5b1716c68391c.js +0 -1
- /package/server/.next/static/{6dAVJYqnbe6oEAABQ1yMG → eIqAtQaBkU80e3XWuVwR8}/_buildManifest.js +0 -0
- /package/server/.next/static/{6dAVJYqnbe6oEAABQ1yMG → eIqAtQaBkU80e3XWuVwR8}/_clientMiddlewareManifest.json +0 -0
- /package/server/.next/static/{6dAVJYqnbe6oEAABQ1yMG → eIqAtQaBkU80e3XWuVwR8}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A small form for the panels of the sequence and system workspaces: text,
|
|
5
|
+
* select and checkbox fields, each with an initial value, and one submit.
|
|
6
|
+
*
|
|
7
|
+
* Used both to add (`reset` clears the text fields after a submit, keeping the
|
|
8
|
+
* selects, as the ERD panel's form does) and to edit (the host keys the form
|
|
9
|
+
* by the element it edits, so a changed element re-seeds it).
|
|
10
|
+
*/
|
|
11
|
+
import { useState } from "react";
|
|
12
|
+
|
|
13
|
+
export const panelInput =
|
|
14
|
+
"w-full rounded border border-gray-700 bg-gray-950 px-2 py-1 text-xs text-gray-200 placeholder:text-gray-600";
|
|
15
|
+
export const panelButton = "rounded border border-gray-700 bg-gray-800 px-2 py-1 text-xs text-gray-200 hover:bg-gray-700";
|
|
16
|
+
export const panelHeading = "mb-1 mt-3 text-[11px] font-semibold uppercase tracking-wide text-gray-500";
|
|
17
|
+
|
|
18
|
+
export interface FormField {
|
|
19
|
+
name: string;
|
|
20
|
+
label?: string;
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
/** A select. `""` is shown as `(label)`. */
|
|
23
|
+
options?: readonly string[];
|
|
24
|
+
/** A text field that suggests these (a datalist); any text is still accepted. */
|
|
25
|
+
suggest?: readonly string[];
|
|
26
|
+
checkbox?: boolean;
|
|
27
|
+
initial?: string | boolean;
|
|
28
|
+
/** Takes the whole row. */
|
|
29
|
+
wide?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type FormValues = Record<string, string | boolean>;
|
|
33
|
+
|
|
34
|
+
export function FieldForm({
|
|
35
|
+
id,
|
|
36
|
+
fields,
|
|
37
|
+
submit,
|
|
38
|
+
onSubmit,
|
|
39
|
+
reset = false,
|
|
40
|
+
required,
|
|
41
|
+
}: {
|
|
42
|
+
/** Prefix for datalist ids — unique per form on the page. */
|
|
43
|
+
id: string;
|
|
44
|
+
fields: FormField[];
|
|
45
|
+
submit: string;
|
|
46
|
+
onSubmit: (values: FormValues) => void;
|
|
47
|
+
reset?: boolean;
|
|
48
|
+
/** Fields that must not be empty for the submit to go through. */
|
|
49
|
+
required?: string[];
|
|
50
|
+
}) {
|
|
51
|
+
const initial = (): FormValues =>
|
|
52
|
+
Object.fromEntries(
|
|
53
|
+
fields.map((f) => [f.name, f.initial ?? (f.checkbox ? false : f.options ? (f.options[0] ?? "") : "")]),
|
|
54
|
+
);
|
|
55
|
+
const [values, setValues] = useState<FormValues>(initial);
|
|
56
|
+
const set = (name: string, value: string | boolean) => setValues((v) => ({ ...v, [name]: value }));
|
|
57
|
+
return (
|
|
58
|
+
<form
|
|
59
|
+
className="mt-1 grid grid-cols-2 gap-1"
|
|
60
|
+
onSubmit={(e) => {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
const merged = { ...initial(), ...values };
|
|
63
|
+
if ((required ?? []).some((n) => !String(merged[n] ?? "").trim())) return;
|
|
64
|
+
onSubmit(merged);
|
|
65
|
+
if (reset) {
|
|
66
|
+
setValues((prev) =>
|
|
67
|
+
Object.fromEntries(
|
|
68
|
+
fields.map((f) => [f.name, f.options || f.checkbox ? (prev[f.name] ?? "") : (f.initial ?? "")]),
|
|
69
|
+
),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}}
|
|
73
|
+
>
|
|
74
|
+
{fields.map((f) => {
|
|
75
|
+
const title = f.label ?? f.name;
|
|
76
|
+
if (f.checkbox) {
|
|
77
|
+
return (
|
|
78
|
+
<label key={f.name} className="flex items-center gap-2 text-[11px] text-gray-400">
|
|
79
|
+
<input type="checkbox" checked={!!values[f.name]} onChange={(e) => set(f.name, e.target.checked)} />
|
|
80
|
+
{title}
|
|
81
|
+
</label>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (f.options) {
|
|
85
|
+
return (
|
|
86
|
+
<select
|
|
87
|
+
key={f.name}
|
|
88
|
+
className={`${panelInput} ${f.wide ? "col-span-2" : ""}`}
|
|
89
|
+
aria-label={title}
|
|
90
|
+
title={title}
|
|
91
|
+
value={String(values[f.name] ?? "")}
|
|
92
|
+
onChange={(e) => set(f.name, e.target.value)}
|
|
93
|
+
>
|
|
94
|
+
{f.options.map((o) => (
|
|
95
|
+
<option key={o} value={o}>
|
|
96
|
+
{o || `(${title})`}
|
|
97
|
+
</option>
|
|
98
|
+
))}
|
|
99
|
+
</select>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
const listId = f.suggest?.length ? `${id}-${f.name}` : undefined;
|
|
103
|
+
return (
|
|
104
|
+
<span key={f.name} className={f.wide ? "col-span-2" : ""}>
|
|
105
|
+
<input
|
|
106
|
+
className={panelInput}
|
|
107
|
+
aria-label={title}
|
|
108
|
+
title={title}
|
|
109
|
+
placeholder={f.placeholder ?? title}
|
|
110
|
+
list={listId}
|
|
111
|
+
value={String(values[f.name] ?? "")}
|
|
112
|
+
onChange={(e) => set(f.name, e.target.value)}
|
|
113
|
+
/>
|
|
114
|
+
{listId && (
|
|
115
|
+
<datalist id={listId}>
|
|
116
|
+
{f.suggest!.map((s) => (
|
|
117
|
+
<option key={s} value={s} />
|
|
118
|
+
))}
|
|
119
|
+
</datalist>
|
|
120
|
+
)}
|
|
121
|
+
</span>
|
|
122
|
+
);
|
|
123
|
+
})}
|
|
124
|
+
<button type="submit" className={`${panelButton} col-span-2`}>
|
|
125
|
+
{submit}
|
|
126
|
+
</button>
|
|
127
|
+
</form>
|
|
128
|
+
);
|
|
129
|
+
}
|