Resource-backed multi/single-select requirement
Deploy / deploy (push) Successful in 34s

Requirement gains an optional `resource` (reuses ResourceSpec/
ResourceSource/jq wholesale - a resource is a resource whether it's
displayed read-only or offered as choices to pick from) and `id_field`
(which field in each item is its stable id, defaults to _id then id).
`type: select` + `multiple` (already-existing field, previously file
-only) picks single vs multi. New get_requirement_options server fn
shares its auth/fetch/jq logic with get_resource via two extracted
helpers rather than duplicating it.

Submitted value is the selected id (single) or a JSON array of ids
(multi) - a new select_field_map (RwSignal<Vec<String>>, alongside the
existing field_map/file_refs maps, since a multi-select's value is a
set, not a string) threaded through the same nested <For> structure
the other requirement kinds already use.

Content validation extended: a `type: select` requirement declaring no
resource now fails at load time instead of rendering a dead field.
Caught a real bug in my own first version of that check while testing
it - it was nested inside a feature-level resource guard, so it never
ran unless the *feature* also happened to have its own resource.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Bendik Aagaard Lynghaug
2026-08-06 11:57:15 +02:00
co-authored by Claude Sonnet 5
parent 43fa496778
commit 755b796ad1
4 changed files with 324 additions and 43 deletions
+24
View File
@@ -411,6 +411,30 @@ input:focus, textarea:focus {
margin-right: 0.3rem;
}
.select-field { margin-top: 0.3rem; }
.select-options { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.select-option {
font-family: var(--sans);
font-size: 0.85rem;
color: var(--ink);
background: var(--paper);
border: 1px solid var(--line);
border-radius: 999px;
padding: 0.4rem 0.9rem;
cursor: pointer;
transition: border-color 120ms, color 120ms, background 120ms;
}
.select-option:hover { border-color: var(--accent); color: var(--accent); }
.select-option.selected {
border-color: var(--accent);
color: var(--paper);
background: var(--accent);
}
@media (max-width: 640px) {
.hero { padding: 3rem 1.25rem 2rem; }
.alt-card { padding: 1.4rem 1.3rem; }