lowlander 0.5.0 → 0.6.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/README.md +43 -67
- package/build/client/client.d.ts +8 -1
- package/build/client/client.js +39 -22
- package/build/client/client.js.map +1 -1
- package/build/dashboard/client/crud.d.ts +16 -0
- package/build/dashboard/client/crud.js +525 -0
- package/build/dashboard/client/crud.js.map +1 -0
- package/build/dashboard/client/main.js +238 -246
- package/build/dashboard/client/main.js.map +1 -1
- package/build/dashboard/dashboard.html +8 -8
- package/build/dashboard/server.d.ts +20 -9
- package/build/dashboard/server.d.ts.map +1 -1
- package/build/dashboard/server.js +139 -3
- package/build/dashboard/server.js.map +1 -1
- package/build/examples/helloworld/.edinburgh/commit_worker.log +1809 -0
- package/build/examples/helloworld/.edinburgh/data.mdb +0 -0
- package/build/examples/helloworld/.edinburgh/lock.mdb +0 -0
- package/build/examples/helloworld/client/assets/style.css +0 -45
- package/build/examples/helloworld/client/index.html +2 -13
- package/build/examples/helloworld/client/js/base.d.ts +1 -4
- package/build/examples/helloworld/client/js/base.js +8 -217
- package/build/examples/helloworld/client/js/base.js.map +1 -1
- package/build/examples/helloworld/server/api.d.ts +4 -0
- package/build/examples/helloworld/server/api.d.ts.map +1 -1
- package/build/examples/helloworld/server/api.js +10 -0
- package/build/examples/helloworld/server/api.js.map +1 -1
- package/build/server/server.d.ts +3 -3
- package/build/server/server.d.ts.map +1 -1
- package/build/server/server.js +44 -5
- package/build/server/server.js.map +1 -1
- package/build/tsconfig.client.tsbuildinfo +1 -1
- package/build/tsconfig.server.tsbuildinfo +1 -1
- package/client/client.ts +41 -23
- package/dashboard/build-bundle.ts +8 -2
- package/dashboard/client/crud.ts +634 -0
- package/dashboard/client/main.ts +234 -246
- package/dashboard/server.ts +149 -5
- package/package.json +9 -5
- package/server/server.ts +43 -8
- package/skill/SKILL.md +30 -47
- package/skill/Connection_pruneCommitIds.md +0 -8
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CRUD row editor for the Lowlander dashboard.
|
|
3
|
+
*
|
|
4
|
+
* Provides openEditModal, openCreateModal, and openDeleteConfirm, each of
|
|
5
|
+
* which opens a Staffa modal to let the user create, edit or delete a record.
|
|
6
|
+
* Field editors are chosen recursively based on Edinburgh TypeInfo descriptors.
|
|
7
|
+
*/
|
|
8
|
+
import A from 'aberdeen';
|
|
9
|
+
import * as S from 'staffa';
|
|
10
|
+
// ─── Value conversion helpers ─────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Convert a display-serialised value (from serializeValue on the server) into
|
|
13
|
+
* an editor-friendly form. The editor sends these back to the server, which
|
|
14
|
+
* runs parseValueFromJson to reconstruct the Edinburgh value.
|
|
15
|
+
*/
|
|
16
|
+
function toEditValue(type, value) {
|
|
17
|
+
if (value === null || value === undefined)
|
|
18
|
+
return null;
|
|
19
|
+
switch (type.kind) {
|
|
20
|
+
case 'dateTime':
|
|
21
|
+
// ISO → datetime-local (slice to "YYYY-MM-DDTHH:MM")
|
|
22
|
+
if (typeof value === 'string')
|
|
23
|
+
return value.slice(0, 16);
|
|
24
|
+
return value;
|
|
25
|
+
case 'link':
|
|
26
|
+
// { __ref, pk } → just pk (server knows the type)
|
|
27
|
+
return value?.__ref != null ? value.pk : value;
|
|
28
|
+
case 'array':
|
|
29
|
+
case 'set':
|
|
30
|
+
if (!Array.isArray(value))
|
|
31
|
+
return [];
|
|
32
|
+
return value.map((v) => toEditValue(type.inner, v));
|
|
33
|
+
case 'record':
|
|
34
|
+
if (!value || typeof value !== 'object')
|
|
35
|
+
return {};
|
|
36
|
+
const out = {};
|
|
37
|
+
for (const [k, v] of Object.entries(value))
|
|
38
|
+
out[k] = toEditValue(type.innerValue, v);
|
|
39
|
+
return out;
|
|
40
|
+
case 'or':
|
|
41
|
+
if (type.isOptional && type.inner) {
|
|
42
|
+
return value === null ? null : toEditValue(type.inner, value);
|
|
43
|
+
}
|
|
44
|
+
return value;
|
|
45
|
+
default:
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Default edit value for a type when creating a new record. */
|
|
50
|
+
function defaultEditValue(type) {
|
|
51
|
+
if (type.isOptional)
|
|
52
|
+
return null;
|
|
53
|
+
switch (type.kind) {
|
|
54
|
+
case 'string': return '';
|
|
55
|
+
case 'number': return 0;
|
|
56
|
+
case 'boolean': return false;
|
|
57
|
+
case 'dateTime': return new Date().toISOString().slice(0, 16);
|
|
58
|
+
case 'array':
|
|
59
|
+
case 'set': return [];
|
|
60
|
+
case 'record': return {};
|
|
61
|
+
case 'link': return null;
|
|
62
|
+
case 'or':
|
|
63
|
+
case 'literal': return null;
|
|
64
|
+
default: return '';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// ─── Inline field editors ─────────────────────────────────────────────────
|
|
68
|
+
/**
|
|
69
|
+
* Draw the standard Staffa field chrome (a `.s-field` wrapper with a label)
|
|
70
|
+
* around a caller-supplied control. Composite editors (link/collection/record/
|
|
71
|
+
* optional/enum) use this so their labels match Staffa's own form fields.
|
|
72
|
+
*
|
|
73
|
+
* Staffa doesn't export its internal `drawField`, but the `.s-field` CSS class
|
|
74
|
+
* (and its `> label` rule) is registered globally, so reusing the class gives us
|
|
75
|
+
* the exact same styling.
|
|
76
|
+
*/
|
|
77
|
+
function drawFieldChrome(label, drawControl) {
|
|
78
|
+
A('div.s-field', () => {
|
|
79
|
+
if (label != null)
|
|
80
|
+
A('label', () => A('#', label));
|
|
81
|
+
drawControl();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Render an appropriate input widget for the given TypeInfo.
|
|
86
|
+
* $bind.value holds/receives the edit-format value.
|
|
87
|
+
*/
|
|
88
|
+
function renderFieldEditor(type, $bind, proxy, label, readOnly = false) {
|
|
89
|
+
// Unwrap opt(T) → checkbox + inner editor
|
|
90
|
+
if (type.isOptional && type.inner) {
|
|
91
|
+
renderOptionalEditor(type.inner, $bind, proxy, label, readOnly);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
switch (type.kind) {
|
|
95
|
+
case 'string':
|
|
96
|
+
S.textline({ label, disabled: readOnly, bind: $bind });
|
|
97
|
+
return;
|
|
98
|
+
case 'id':
|
|
99
|
+
S.textline({ label, disabled: true, bind: $bind,
|
|
100
|
+
help: readOnly ? 'auto-generated' : undefined });
|
|
101
|
+
return;
|
|
102
|
+
case 'number':
|
|
103
|
+
S.textline({ label, type: 'number', disabled: readOnly, bind: $bind });
|
|
104
|
+
return;
|
|
105
|
+
case 'boolean':
|
|
106
|
+
S.checkbox({ label: label ?? 'Yes', disabled: readOnly, bind: $bind });
|
|
107
|
+
return;
|
|
108
|
+
case 'dateTime':
|
|
109
|
+
S.textline({ label, type: 'datetime-local', disabled: readOnly, bind: $bind });
|
|
110
|
+
return;
|
|
111
|
+
case 'link':
|
|
112
|
+
renderLinkEditor(type, $bind, proxy, label, readOnly);
|
|
113
|
+
return;
|
|
114
|
+
case 'array':
|
|
115
|
+
case 'set':
|
|
116
|
+
renderCollectionEditor(type, $bind, proxy, label, readOnly);
|
|
117
|
+
return;
|
|
118
|
+
case 'record':
|
|
119
|
+
renderRecordEditor(type, $bind, proxy, label, readOnly);
|
|
120
|
+
return;
|
|
121
|
+
case 'or': {
|
|
122
|
+
// A union of literals is an enum → render as a segmented chooser.
|
|
123
|
+
const choices = type.choices ?? [];
|
|
124
|
+
if (choices.length && choices.every(c => c.kind === 'literal')) {
|
|
125
|
+
renderEnumEditor(choices, $bind, label, readOnly);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// General union: fall back to raw JSON textarea
|
|
129
|
+
renderJsonEditor($bind, label, readOnly);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
case 'literal':
|
|
133
|
+
// Read-only — show value as disabled text
|
|
134
|
+
S.textline({ label, disabled: true, value: type.literalValue ?? '' });
|
|
135
|
+
return;
|
|
136
|
+
default:
|
|
137
|
+
renderJsonEditor($bind, label, readOnly);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function renderOptionalEditor(innerType, $bind, proxy, label, readOnly = false) {
|
|
141
|
+
// $mode ('set' | 'undefined') tracks enabled state independently from $bind so
|
|
142
|
+
// the inner editor scope doesn't re-run (and lose focus) on every value change.
|
|
143
|
+
// Peek the initial value so the enclosing scope doesn't subscribe to it.
|
|
144
|
+
const initiallySet = A.peek(() => $bind.value !== null && $bind.value !== undefined);
|
|
145
|
+
const $mode = A.proxy({ v: initiallySet ? 'set' : 'undefined' });
|
|
146
|
+
// One-way sync: $mode.v → $bind.value.
|
|
147
|
+
// Uses A.peek to read $bind.value without subscribing (avoids circular loop).
|
|
148
|
+
A(() => {
|
|
149
|
+
if ($mode.v === 'set') {
|
|
150
|
+
if (A.peek(() => $bind.value) === null || A.peek(() => $bind.value) === undefined) {
|
|
151
|
+
$bind.value = defaultEditValue(innerType);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
$bind.value = null;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
drawFieldChrome(label, () => {
|
|
159
|
+
S.buttonChooser({
|
|
160
|
+
attrs: readOnly ? 'pointer-events:none opacity:0.6' : undefined,
|
|
161
|
+
options: { set: 'set', undefined: 'undefined' },
|
|
162
|
+
bind: A.ref($mode, 'v'),
|
|
163
|
+
});
|
|
164
|
+
// Inner editor: depends on $mode.v, NOT on $bind.value — so typing
|
|
165
|
+
// in a text field inside the optional editor won't recreate the DOM.
|
|
166
|
+
A(() => {
|
|
167
|
+
if ($mode.v !== 'set')
|
|
168
|
+
return;
|
|
169
|
+
renderFieldEditor(innerType, $bind, proxy, undefined, readOnly);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Render a union of literal values (an enum) as a segmented buttonChooser.
|
|
175
|
+
* Each literal's JSON-serialised form (TypeInfo.literalValue) is used as the
|
|
176
|
+
* button id; the `undefined` literal becomes a "(none)" choice.
|
|
177
|
+
*/
|
|
178
|
+
function renderEnumEditor(choices, $bind, label, readOnly = false) {
|
|
179
|
+
const idForValue = (v) => v === null || v === undefined ? 'undefined' : JSON.stringify(v);
|
|
180
|
+
const valueForId = (id) => id == null || id === 'undefined' ? null : JSON.parse(id);
|
|
181
|
+
const options = {};
|
|
182
|
+
let hasNone = false;
|
|
183
|
+
for (const c of choices) {
|
|
184
|
+
const id = c.literalValue ?? 'undefined';
|
|
185
|
+
if (id === 'undefined') {
|
|
186
|
+
hasNone = true;
|
|
187
|
+
options[id] = '(none)';
|
|
188
|
+
}
|
|
189
|
+
else
|
|
190
|
+
options[id] = String(valueForId(id));
|
|
191
|
+
}
|
|
192
|
+
const $sel = A.proxy({ v: idForValue(A.peek(() => $bind.value)) });
|
|
193
|
+
// One-way: $sel.v → $bind.value (reads $sel only, so no circular loop).
|
|
194
|
+
A(() => { $bind.value = valueForId($sel.v); });
|
|
195
|
+
drawFieldChrome(label, () => {
|
|
196
|
+
S.buttonChooser({
|
|
197
|
+
attrs: readOnly ? 'pointer-events:none opacity:0.6' : undefined,
|
|
198
|
+
options,
|
|
199
|
+
bind: A.ref($sel, 'v'),
|
|
200
|
+
// Without an explicit "(none)" choice, allow clearing back to null.
|
|
201
|
+
allowDeselect: !hasNone,
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function renderLinkEditor(type, $bind, proxy, label, readOnly = false) {
|
|
206
|
+
const linkedModel = type.linkedModel;
|
|
207
|
+
if (!linkedModel) {
|
|
208
|
+
renderJsonEditor($bind, label, readOnly);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
// The autocomplete needs a real proxy Bindable holding a string. We keep a
|
|
212
|
+
// display proxy ($acStr) and one-way sync it back to $bind (string → pk).
|
|
213
|
+
const initial = A.peek(() => $bind.value);
|
|
214
|
+
const $acStr = A.proxy({ v: initial === null || initial === undefined ? '' : String(initial) });
|
|
215
|
+
// One-way: $acStr.v → $bind.value. Reads $acStr only (writes $bind), no loop.
|
|
216
|
+
A(() => {
|
|
217
|
+
const s = $acStr.v;
|
|
218
|
+
if (s === '') {
|
|
219
|
+
$bind.value = null;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
const asNum = Number(s);
|
|
223
|
+
$bind.value = !isNaN(asNum) && !/[^0-9.\-]/.test(s) ? asNum : s;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
// Load candidate records ONCE into a stable proxy. The outer scope has no
|
|
227
|
+
// reactive dependencies, so findRecords runs a single time; the inner scope
|
|
228
|
+
// copies the rows over once the RPC resolves. (Calling findRecords directly
|
|
229
|
+
// inside the autocomplete's reactive options() refetched on every settle and
|
|
230
|
+
// never produced a stable result — hence the perpetual "No matches".)
|
|
231
|
+
const $opts = A.proxy({ rows: [] });
|
|
232
|
+
A(() => {
|
|
233
|
+
const result = proxy.serverProxy.findRecords(linkedModel, '(primary)', { limit: 100 });
|
|
234
|
+
A(() => { if (result.value)
|
|
235
|
+
$opts.rows = result.value.rows; });
|
|
236
|
+
});
|
|
237
|
+
S.autocomplete({
|
|
238
|
+
label,
|
|
239
|
+
disabled: readOnly,
|
|
240
|
+
allowCustom: false,
|
|
241
|
+
placeholder: `Search ${linkedModel}…`,
|
|
242
|
+
bind: A.ref($acStr, 'v'),
|
|
243
|
+
// The autocomplete filters these client-side by label as the user types.
|
|
244
|
+
options: () => $opts.rows.map((row) => ({
|
|
245
|
+
value: jsonStringify(row.pk),
|
|
246
|
+
label: jsonStringify(row.pk),
|
|
247
|
+
})),
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
function renderCollectionEditor(type, $bind, proxy, label, readOnly = false) {
|
|
251
|
+
const innerType = type.inner;
|
|
252
|
+
// Build the local state WITHOUT subscribing the enclosing scope. Every read
|
|
253
|
+
// here (the initial value, its elements, the new proxy's length) must happen
|
|
254
|
+
// inside A.peek — otherwise, when this editor renders inside a reactive scope
|
|
255
|
+
// such as S.form's content, reading $items.length would subscribe that scope
|
|
256
|
+
// and pushing/removing items would re-run it, wiping this local state.
|
|
257
|
+
const [$items, $len] = A.peek(() => {
|
|
258
|
+
const initVal = $bind.value;
|
|
259
|
+
const initArr = Array.isArray(initVal) ? initVal : [];
|
|
260
|
+
// Stable per-item proxies: the item editors write to $items[i].v, which
|
|
261
|
+
// syncs back to $bind.value via a one-way reactive block.
|
|
262
|
+
const items = A.proxy(initArr.map((v) => ({ v })));
|
|
263
|
+
// Count proxy: drives add/remove re-renders without coupling to item values.
|
|
264
|
+
const len = A.proxy({ v: items.length });
|
|
265
|
+
return [items, len];
|
|
266
|
+
});
|
|
267
|
+
// One-way sync: item proxies → $bind.value (never reads $bind.value so no loop)
|
|
268
|
+
A(() => { $bind.value = $items.map((item) => item.v); });
|
|
269
|
+
drawFieldChrome(label, () => {
|
|
270
|
+
A('div.s-s.raised', 'display:flex flex-direction:column gap:$2 p:$2 border: 1px solid $s-border;', () => {
|
|
271
|
+
A(() => {
|
|
272
|
+
const len = $len.v;
|
|
273
|
+
if (len === 0) {
|
|
274
|
+
A('span', 'fg:$s-fg-faint font-size:0.9em', '#(empty)');
|
|
275
|
+
}
|
|
276
|
+
for (let i = 0; i < len; i++) {
|
|
277
|
+
const idx = i;
|
|
278
|
+
A('div', 'display:flex gap:$2 align-items:flex-start', () => {
|
|
279
|
+
A('div', 'flex:1', () => {
|
|
280
|
+
// A.ref gives Aberdeen's bind= an actual proxy Bindable
|
|
281
|
+
const $item = A.ref($items[idx], 'v');
|
|
282
|
+
renderFieldEditor(innerType, $item, proxy, undefined, readOnly);
|
|
283
|
+
});
|
|
284
|
+
if (!readOnly) {
|
|
285
|
+
S.button({
|
|
286
|
+
content: '×',
|
|
287
|
+
attrs: '.outlined.danger .small flex-shrink:0 mt:$3',
|
|
288
|
+
click: () => {
|
|
289
|
+
$items.splice(idx, 1);
|
|
290
|
+
$len.v = $items.length;
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
if (!readOnly) {
|
|
298
|
+
S.button({
|
|
299
|
+
content: `+ Add ${innerType.display}`,
|
|
300
|
+
attrs: '.tonal .small',
|
|
301
|
+
click: () => {
|
|
302
|
+
$items.push({ v: defaultEditValue(innerType) });
|
|
303
|
+
$len.v = $items.length;
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
function renderRecordEditor(type, $bind, proxy, label, readOnly = false) {
|
|
311
|
+
const valueType = type.innerValue;
|
|
312
|
+
// Build local state without subscribing the enclosing scope (see
|
|
313
|
+
// renderCollectionEditor for why every read must be inside A.peek).
|
|
314
|
+
const [$entries, $eLen] = A.peek(() => {
|
|
315
|
+
const initVal = $bind.value;
|
|
316
|
+
const initObj = initVal && typeof initVal === 'object' && !Array.isArray(initVal) ? initVal : {};
|
|
317
|
+
// Stable per-entry proxies (same pattern as renderCollectionEditor).
|
|
318
|
+
const entries = A.proxy(Object.entries(initObj).map(([k, v]) => ({ k, v })));
|
|
319
|
+
const len = A.proxy({ v: entries.length });
|
|
320
|
+
return [entries, len];
|
|
321
|
+
});
|
|
322
|
+
// Entries with a blank key are skipped; on duplicate keys the last one wins.
|
|
323
|
+
A(() => {
|
|
324
|
+
const obj = {};
|
|
325
|
+
for (const e of $entries) {
|
|
326
|
+
if (e.k === '')
|
|
327
|
+
continue;
|
|
328
|
+
obj[e.k] = e.v;
|
|
329
|
+
}
|
|
330
|
+
$bind.value = obj;
|
|
331
|
+
});
|
|
332
|
+
drawFieldChrome(label, () => {
|
|
333
|
+
A('div.s-s.raised', 'display:flex flex-direction:column gap:$4 p:$2 border: 1px solid $s-border;', () => {
|
|
334
|
+
A(() => {
|
|
335
|
+
const len = $eLen.v;
|
|
336
|
+
if (len === 0)
|
|
337
|
+
A('span', 'fg:$s-fg-faint font-size:0.9em', '#(empty)');
|
|
338
|
+
for (let i = 0; i < len; i++) {
|
|
339
|
+
const idx = i;
|
|
340
|
+
A('div', 'display:flex flex-direction:column gap:$1', () => {
|
|
341
|
+
// Key row: key field + delete button
|
|
342
|
+
A('div', 'display:flex gap:$2 align-items:center', () => {
|
|
343
|
+
if (readOnly) {
|
|
344
|
+
A('code', 'flex:1 font-size:0.85em fg:$s-fg-muted', '#', A.peek(() => $entries[idx].k));
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
A('div', 'flex:1', () => {
|
|
348
|
+
S.textline({ placeholder: 'key', bind: A.ref($entries[idx], 'k') });
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
if (!readOnly) {
|
|
352
|
+
S.button({
|
|
353
|
+
content: '×', attrs: '.outlined.danger .small flex-shrink:0', click: () => {
|
|
354
|
+
$entries.splice(idx, 1);
|
|
355
|
+
$eLen.v = $entries.length;
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
// Value row
|
|
361
|
+
A('div', () => {
|
|
362
|
+
const $item = A.ref($entries[idx], 'v');
|
|
363
|
+
renderFieldEditor(valueType, $item, proxy, undefined, readOnly);
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
if (!readOnly) {
|
|
369
|
+
S.button({
|
|
370
|
+
content: '+ Add entry',
|
|
371
|
+
attrs: '.tonal .small',
|
|
372
|
+
click: () => {
|
|
373
|
+
$entries.push({ k: '', v: defaultEditValue(valueType) });
|
|
374
|
+
$eLen.v = $entries.length;
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
function renderJsonEditor($bind, label, readOnly = false) {
|
|
382
|
+
const initial = A.peek(() => $bind.value);
|
|
383
|
+
const $str = A.proxy({ v: initial === undefined ? '' : jsonStringify(initial) });
|
|
384
|
+
const $error = A.proxy({ v: '' });
|
|
385
|
+
// One-way: $str.v → $bind.value. Writes $bind only, so no circular loop.
|
|
386
|
+
A(() => {
|
|
387
|
+
const s = $str.v;
|
|
388
|
+
if (s.trim() === '') {
|
|
389
|
+
$bind.value = undefined;
|
|
390
|
+
$error.v = '';
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
try {
|
|
394
|
+
$bind.value = JSON.parse(s);
|
|
395
|
+
$error.v = '';
|
|
396
|
+
}
|
|
397
|
+
catch {
|
|
398
|
+
$error.v = 'Invalid JSON';
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
// Textarea binds to a real proxy ref; error shown in its own scope so the
|
|
402
|
+
// textarea is never recreated (which would lose focus on each keystroke).
|
|
403
|
+
S.textarea({ label, disabled: readOnly, rows: 3, bind: A.ref($str, 'v') });
|
|
404
|
+
A(() => {
|
|
405
|
+
if ($error.v)
|
|
406
|
+
A('div', 'fg:$s-danger font-size:0.82em mt:$1', '#', $error.v);
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
410
|
+
function openFormDialog(proxy, header, fields, initValue, isReadOnly, submitText, onSubmit) {
|
|
411
|
+
const boxes = {};
|
|
412
|
+
for (const f of fields) {
|
|
413
|
+
boxes[f.name] = A.proxy({ v: initValue(f) });
|
|
414
|
+
}
|
|
415
|
+
const $status = A.proxy({ saving: false });
|
|
416
|
+
S.dialog({
|
|
417
|
+
header,
|
|
418
|
+
attrs: "width:800px",
|
|
419
|
+
content: (close) => {
|
|
420
|
+
S.form({
|
|
421
|
+
content: () => {
|
|
422
|
+
for (const f of fields) {
|
|
423
|
+
renderFieldEditor(f.type, A.ref(boxes[f.name], 'v'), proxy, f.name, isReadOnly(f));
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
layout: "grid",
|
|
427
|
+
actions: () => {
|
|
428
|
+
S.button({ content: 'Cancel', attrs: '.outlined.neutral', click: close });
|
|
429
|
+
A(() => {
|
|
430
|
+
S.button({
|
|
431
|
+
content: submitText,
|
|
432
|
+
type: 'button',
|
|
433
|
+
disabled: $status.saving,
|
|
434
|
+
click: async () => {
|
|
435
|
+
$status.saving = true;
|
|
436
|
+
try {
|
|
437
|
+
await onSubmit(boxes, close);
|
|
438
|
+
}
|
|
439
|
+
catch (err) {
|
|
440
|
+
S.toast({ message: err?.message ?? String(err), type: 'danger' });
|
|
441
|
+
}
|
|
442
|
+
finally {
|
|
443
|
+
$status.saving = false;
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
},
|
|
449
|
+
});
|
|
450
|
+
},
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
export function openCreateModal(proxy, modelName, fields, onCreated) {
|
|
454
|
+
const editableFields = fields.filter(f => f.type.kind !== 'id');
|
|
455
|
+
openFormDialog(proxy, `New ${modelName}`, editableFields, (f) => defaultEditValue(f.type), () => false, 'Create', async (boxes, close) => {
|
|
456
|
+
const payload = {};
|
|
457
|
+
for (const f of editableFields)
|
|
458
|
+
payload[f.name] = boxes[f.name].v;
|
|
459
|
+
const pk = await proxy.serverProxy.createRecord(modelName, payload).promise;
|
|
460
|
+
close();
|
|
461
|
+
onCreated?.(pk);
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
export function openEditModal(proxy, modelName, fields, pk, currentValues, onSaved) {
|
|
465
|
+
openFormDialog(proxy, `Edit ${modelName}`, fields, (f) => toEditValue(f.type, currentValues[f.name]), (f) => f.isPk, 'Save', async (boxes, close) => {
|
|
466
|
+
const payload = {};
|
|
467
|
+
for (const f of fields) {
|
|
468
|
+
if (!f.isPk)
|
|
469
|
+
payload[f.name] = boxes[f.name].v;
|
|
470
|
+
}
|
|
471
|
+
await proxy.serverProxy.updateRecord(modelName, pk, payload).promise;
|
|
472
|
+
close();
|
|
473
|
+
onSaved?.();
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
export function openDeleteConfirm(proxy, modelName, pk, displayLabel, onDeleted) {
|
|
477
|
+
const $status = A.proxy({ deleting: false, error: '' });
|
|
478
|
+
S.dialog({
|
|
479
|
+
header: `Delete ${modelName}`,
|
|
480
|
+
content: (close) => {
|
|
481
|
+
A('p', 'fg:$s-fg m:0', () => {
|
|
482
|
+
A('#Delete ');
|
|
483
|
+
A('strong', '#', displayLabel);
|
|
484
|
+
A('#? This cannot be undone.');
|
|
485
|
+
});
|
|
486
|
+
A(() => {
|
|
487
|
+
if ($status.error)
|
|
488
|
+
A('p', 'fg:$s-danger m:0', '#', $status.error);
|
|
489
|
+
});
|
|
490
|
+
A('div', 'display:flex gap:$2 mt:$3', () => {
|
|
491
|
+
S.button({
|
|
492
|
+
content: 'Delete',
|
|
493
|
+
attrs: '.danger',
|
|
494
|
+
disabled: A.peek(() => $status.deleting),
|
|
495
|
+
click: async () => {
|
|
496
|
+
$status.deleting = true;
|
|
497
|
+
$status.error = '';
|
|
498
|
+
try {
|
|
499
|
+
await proxy.serverProxy.deleteRecord(modelName, pk).promise;
|
|
500
|
+
close();
|
|
501
|
+
onDeleted?.();
|
|
502
|
+
}
|
|
503
|
+
catch (err) {
|
|
504
|
+
$status.error = err?.message ?? String(err);
|
|
505
|
+
$status.deleting = false;
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
});
|
|
509
|
+
S.button({ content: 'Cancel', attrs: '.outlined.neutral', click: close });
|
|
510
|
+
});
|
|
511
|
+
},
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
515
|
+
function jsonStringify(v) {
|
|
516
|
+
if (typeof v === 'string')
|
|
517
|
+
return v;
|
|
518
|
+
try {
|
|
519
|
+
return JSON.stringify(v);
|
|
520
|
+
}
|
|
521
|
+
catch {
|
|
522
|
+
return String(v);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
//# sourceMappingURL=crud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crud.js","sourceRoot":"","sources":["../../../dashboard/client/crud.ts"],"names":[],"mappings":"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"}
|