ruview @ v1407
integrity
- size
- 60.4 MiB
- downloaded
- last checked
release notes
Automated release from CI pipeline
Changes: feat(homecore-ui iter 4): live per-field validation + inline server errors
CRUD increment 4/6. The form now shows validity feedback on every keystroke instead of only on Create click, makes the warning vs error distinction visible (amber vs red), and propagates backend 4xx responses into the form's own error surface.
frontend/src/components/EntityForm.ts (~80 LOC delta):
- Three new @state fields tracking per-field validity: _idValid,
_stateValid, _attrsValid (each is
{ok:true} | {ok:false, level: 'err'|'warn', msg}or null when untouched). - Pure validators outside the class so they can be unit-tested: validateEntityId, validateState, validateAttrs.
- validateEntityId now warns (amber, not red) if the domain prefix
is outside the standard HA set. KNOWN_DOMAINS lists ~40 standard
domains (sensor, light, switch, binary_sensor, climate, cover,
fan, media_player, lock, camera, vacuum, climate, scene, script,
automation, input_*, person, device_tracker, zone, weather, etc.)
- homecore-native domain. Unknown domains create entities anyway (backend regex still passes them) but the operator sees the soft signal.
- Sigils render below each field: ✓ green when ok, ✗ red on err, ! amber on warn. Field borders adopt the level color via .invalid / .warn classes.
- New public method
isValid()so the host can bind a disabled state on its Save button (unused for now; ready for a follow-up). - New public method
setSubmitError(msg)so the host can surface server-side rejection text inline in the form's red error block, not just at the page top.
frontend/src/pages/Dashboard.ts (small delta):
_onSubmit()now callsthis._form?.setSubmitError(null)before each attempt to clear stale text, and on non-2xx responses it surfaces the server's body text inline viasetSubmitError. Page-top error block is no longer hijacked for form errors.
Browser-verified end-to-end (real homecore-server :8123):
entity_id field: BadID → red border + "must match domain.snake_case…" light.kitchen_test → green ✓ "entity_id OK" madeup_domain.foo → amber border + "unknown domain 'madeup_domain' — HA-standard…"
state field: empty → red ✗ required "on" → green ✓
attributes field: empty → green ✓ (defaults to {}) [1,2,3] → red ✗ "must be a JSON object…" {"key": → red ✗ "JSON parse: Unexpected end of JSON input" {"friendly_name":"Test"} → green ✓
Server-error inline: Force 401 via wrong token → form red block shows "server rejected (401): unauthorized"
Successful create: still works, toast still shown, 0 console errors.
Co-Authored-By: claude-flow ruv@ruv.net
Docker Image:
ghcr.io/ruvnet/RuView:3f5a7411db2d449f603532435c5cc68079ffb222
download
curl -fL -o v1407.zip https://ratatoskr.space/pkg/ruview/v1407.zip
printf '%s %s\n' 'c84c0af625bec1d97e7ea01968f3930209b8b9da1ce593d926f9b142ff6f05b7' 'v1407.zip' | sha256sum -c -
$url = "https://ratatoskr.space/pkg/ruview/v1407.zip"
$out = "v1407.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "c84c0af625bec1d97e7ea01968f3930209b8b9da1ce593d926f9b142ff6f05b7") { throw "sha256 mismatch" }
curl -fL -o v1407.tar.gz https://ratatoskr.space/pkg/ruview/v1407.tar.gz
printf '%s %s\n' 'a0ad8d6092dd23652540d190e8ef84e2d24996466350e82e9656f68f4d61488f' 'v1407.tar.gz' | sha256sum -c -
$url = "https://ratatoskr.space/pkg/ruview/v1407.tar.gz"
$out = "v1407.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "a0ad8d6092dd23652540d190e8ef84e2d24996466350e82e9656f68f4d61488f") { throw "sha256 mismatch" }
download via yggdrasil mesh
curl -fL -o v1407.zip http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1407.zip
printf '%s %s\n' 'c84c0af625bec1d97e7ea01968f3930209b8b9da1ce593d926f9b142ff6f05b7' 'v1407.zip' | sha256sum -c -
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1407.zip"
$out = "v1407.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "c84c0af625bec1d97e7ea01968f3930209b8b9da1ce593d926f9b142ff6f05b7") { throw "sha256 mismatch" }
curl -fL -o v1407.tar.gz http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1407.tar.gz
printf '%s %s\n' 'a0ad8d6092dd23652540d190e8ef84e2d24996466350e82e9656f68f4d61488f' 'v1407.tar.gz' | sha256sum -c -
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1407.tar.gz"
$out = "v1407.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "a0ad8d6092dd23652540d190e8ef84e2d24996466350e82e9656f68f4d61488f") { throw "sha256 mismatch" }
| artifact | format | size | hashes |
|---|---|---|---|
| v1407.zip | zip | 60.4 MiB |
blake3-24 36df08374557d681c275e68f6aac598dcfcaece6e18d95f4
sha256 c84c0af625bec1d97e7ea01968f3930209b8b9da1ce593d926f9b142ff6f05b7
sha1 9f5f986b0016d4488660b3d3e6a8897e0f9b1069
|
| v1407.tar.gz | tar.gz | 58.7 MiB |
blake3-24 f87ee19f77db782ab9abfa697379c46ef43aff3f8ecd04f5
sha256 a0ad8d6092dd23652540d190e8ef84e2d24996466350e82e9656f68f4d61488f
sha1 e153cffe45791a518cf45124043c04e0a3172a2d
|
install
http_archive(
name = "ruview",
urls = ["https://ratatoskr.space/pkg/ruview/v1407.tar.gz"],
integrity = "sha256-oK2NYJLdI2UlQNGQ6O+E4tJJlkZjUOgullb2j01hSI8=",
strip_prefix = "ruview-v1407",
)
.url = "https://ratatoskr.space/pkg/ruview/v1407.tar.gz",
install via yggdrasil mesh
http_archive(
name = "ruview",
urls = ["http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1407.tar.gz"],
integrity = "sha256-oK2NYJLdI2UlQNGQ6O+E4tJJlkZjUOgullb2j01hSI8=",
strip_prefix = "ruview-v1407",
)
.url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1407.tar.gz",