UI: Create/Submit buttons remain enabled with empty required fields — silent no-op across multiple islands #68
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_os#68
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Across several islands, the primary Create/Submit button is not disabled when required fields are empty. Clicking it with empty required fields does nothing: no validation message, no focus-to-field, no error banner. The user sees zero response and is left guessing. This pattern was fixed for Contacts in closed #50 but has re-emerged in multiple islands on the current dev build.
Reproductions (local build via hero_router at
http://127.0.0.1:9988/hero_os/ui/...)(Filled submissions succeed or produce their real RPC error — this issue is specifically about the empty-fields path.)
Related existing issues
Expected
Either:
Preferably the first — consistent with the Contacts fix from #50.
Repo rationale
Validation lives in the Dioxus form components in hero_os, not the backend.
Implementation Spec for Issue #68
Note on repo scope
The issue is filed here on
hero_os, but the failing forms are Dioxus islands that live in the sibling repolhumina_code/hero_archipelagos. The fix will land inhero_archipelagos; this issue will be closed by a PR there, and this comment will link to it.Objective
Disable the primary submit button across three islands (Contexts, Conference/Room, Tasks) whenever required fields are empty or whitespace-only, mirroring the Contacts form pattern from #50.
Reference pattern (from #50 Contacts fix)
File:
archipelagos/contacts/src/islands/contact_form.rscan_submitderivation (L48):Submit button RSX (L222-239):
Shape: one
can_submit: boolderived from!signal.read().is_empty()clauses ANDed together, passed asdisabled: !can_submitto the sharedhero_archipelagos_core::Button. Theonclickhandler also early-returns when!can_submitas defense-in-depth. The sharedButtonnever emits the HTMLdisabledattribute — it applies thehero-btn-disabledCSS class and gatesonclickinternally, so passingdisabled: !can_submitis the correct visual and behavioral switch (core/src/components/button.rsL119-138).Requirements
trim().is_empty()rather thanis_empty().disabled: !can_submiton the sharedButtoncomponent, not an ad-hocpointer-events: nonediv wrapper.cargo checkmust still pass.Files to modify
archipelagos/system/contexts/src/views/create_form.rs(L47-48 and L207-242) — replace div-wrapper visual gating with realdisabledprop; tightencan_submitwithtrim().archipelagos/communication/room/src/views/room_card.rs(L111) — tightencan_savewithtrim()(button already usesdisabled: !can_saveat L374-399).archipelagos/productivity/tasks/src/views/new_task_view.rs(L31) — tightencan_submitwithtrim()(button already usesdisabled: !can_submitat L177-185).Implementation plan
Step 1 — Contexts "Create Context" button
File:
archipelagos/system/contexts/src/views/create_form.rs1a. Derivation (L47-48)
Current:
Replace with:
1b. Submit button (L207-242)
Current — a div wrapper fakes disablement with
pointer-events: none, which is the root cause of the "silent no-op" (clicks are swallowed with zero feedback):Replace with (mirror Contacts pattern):
Dependencies: none.
Step 2 — Conference "Create Room" button
File:
archipelagos/communication/room/src/views/room_card.rsThe button at L374-399 already uses
disabled: !can_save. Only the derivation needs tightening.Current (L111):
Replace with:
Dependencies: none (independent of Step 1 and Step 3).
Step 3 — Tasks "Create Task" button
File:
archipelagos/productivity/tasks/src/views/new_task_view.rsThe button at L177-185 already uses
disabled: !can_submit. Only the derivation needs tightening.Current (L31):
Replace with:
Dependencies: none (independent of Steps 1 and 2).
Acceptance criteria
pointer-events: nonediv wrapper remains —disabledprop is on theButtondirectly.disabled: !<bool>to the sharedButton, matching the Contacts reference pattern.cargo checkpasses for the workspace.Notes
can_submitwas already computed, but the author tried to fake disablement withpointer-events: noneon a wrapping div. The click is swallowed by the CSS gate with no visible response. Moving to the realdisabledprop fixes this and aligns with the rest of the codebase.disabled: !can_*correctly on theButton, but use bareis_empty()— so a single space character enables the button and lets whitespace-only values through. One-line fix per file.contact_form.rsL48 also uses bareis_empty(); this spec tightens beyond the original to match this issue's acceptance criteria ("whitespace-only counts as empty").TaskFormcomponent (productivity/tasks/src/views/task_form.rsL35) with the same pattern. It is not the flow reached by "Tasks → Add Task" in the current build, so it is out of scope here but flagged for a follow-up.Build & Test Results
Branch:
development_ui_required_field_validation(inlhumina_code/hero_archipelagos)Files changed:
archipelagos/system/contexts/src/views/create_form.rsarchipelagos/communication/room/src/views/room_card.rsarchipelagos/productivity/tasks/src/views/new_task_view.rscargo check --workspace: fail (pre-existing, unrelated to this refactor)The workspace-level check fails in two crates that are not touched by this branch:
hero_archipelagos_knowledge: 9 errors (unresolvedhero_osis_sdkmodule, type inference failures onEmbedderClient/BucketListResult/CreateBucketResult)hero_archipelagos_messaging: 2 errors (missing methodconversationservice_list_messagesonCommunicationClient, suggestedconversation_list; downstream type-inference error)Error tail:
All three crates touched by this branch pass
cargo checkindividually:cargo check -p hero_archipelagos_contexts: passcargo check -p hero_archipelagos_room: passcargo check -p hero_archipelagos_tasks: passPer-crate
cargo test:hero_archipelagos_contexts: no-tests (0 passed, 0 failed; 0 doc-tests)hero_archipelagos_room: no-tests (0 passed, 0 failed; 0 doc-tests)hero_archipelagos_tasks: no-tests (0 passed, 0 failed; 0 doc-tests)The refactor to the three view modules compiles cleanly and does not introduce any regressions in the touched crates. The workspace-level failures are upstream SDK drift (
hero_osis_sdk/CommunicationClientAPI changes) and should be addressed separately.Implementation Summary
Fix landed on branch
development_ui_required_field_validationin sibling repolhumina_code/hero_archipelagos.Changes
Three files, each gating the primary submit button via the shared
hero_archipelagos_core::Buttondisabledprop and usingtrim().is_empty()so whitespace-only counts as empty:archipelagos/system/contexts/src/views/create_form.rs— removed thepointer-events: nonediv wrapper that was silently swallowing clicks; addeddisabled: !can_submitdirectly on theButton; switched variant toSecondarywhen disabled; inverted the inneronclickguard to an early return.archipelagos/communication/room/src/views/room_card.rs— tightenedcan_savewithtrim()(button already passeddisabled: !can_save).archipelagos/productivity/tasks/src/views/new_task_view.rs— tightenedcan_submitwithtrim()(button already passeddisabled: !can_submit).Build & tests
cargo checkpasses for all three touched crates (hero_archipelagos_contexts,hero_archipelagos_room,hero_archipelagos_tasks).cargo testfor the three crates: no unit tests defined; all pass vacuously.cargo checkhas pre-existing, unrelated compile errors inhero_archipelagos_knowledge(unresolvedhero_osis_sdkmodule) andhero_archipelagos_messaging(upstream SDK drift —conversationservice_list_messagesrenamed). Neither is touched by this branch.Live browser verification (headless Chromium via hero_browser MCP, then local Chrome)
For each form: empty required fields, whitespace-only required fields, valid content, and cleared-again states were checked.
hero-btn-disabledclass (opacity 0.5,cursor: not-allowed,pointer-events: none); click does not register; nopointer-events: nonewrapper div remains. Valid fields → button switches toSuccessvariant and is fully clickable. Reactive in both directions.NewTaskView): verified. Same four-state behaviour.hero_os_appwebfeature does not compileisland-room; the Conferences island embeds ahero_livekitiframe instead. The fix is in place inroom_card.rsand will activate in any build that includesisland-roomor renders the room card standalone.Notes
hero_archipelagos_core::Buttondisabled behaviour relies on the.hero-btn-disabledCSS rule added in the recent pull (core/src/island.cssL128).hero_os_appembeds this viahero_archipelagos_core::ISLAND_CSS. A stale WASM build cached from before that CSS arrived must be cleanly rebuilt once to pick it up.#50Contacts fix atarchipelagos/contacts/src/islands/contact_form.rs.PR link will follow in the next comment.
Pull request opened: lhumina_code/hero_archipelagos#93
This PR implements the Create/Submit button disable behaviour discussed in this issue across the three affected islands (Contexts, Conference/Room, Tasks).