Skip to content

fix(frontend): tell the user what is wrong instead of showing nothing - #11

Merged
TheMeinerLP merged 1 commit into
feat/tailwind-dashboard-uifrom
fix/frontend-broken-states
Aug 8, 2026
Merged

fix(frontend): tell the user what is wrong instead of showing nothing#11
TheMeinerLP merged 1 commit into
feat/tailwind-dashboard-uifrom
fix/frontend-broken-states

Conversation

@TheMeinerLP

@TheMeinerLP TheMeinerLP commented Aug 8, 2026

Copy link
Copy Markdown

Description

Stacked on #10. This targets feat/tailwind-dashboard-ui, not main, so the diff stays readable. Merge #10 first and GitHub retargets this one.

Four places in the dashboard reported failure by not reporting it. Two of them lost the message entirely.

The console showed nothing at all

When the log stream did not come up, the panel was an empty white rectangle. The only signal was a toast, which faded after a few seconds and left no trace, so a broken connection looked exactly like a server with nothing to say.

It carries its own state now: connecting, connected but quiet, or disconnected with the reason and a Reconnect button. The command input is disabled while the stream is down instead of silently swallowing whatever gets typed into it. The three toasts are gone, because the information belongs where the reader is already looking.

The console with no connection, before and after

No automatic retry, on purpose. A stream that failed because the server is struggling is the worst moment to start reconnecting in a loop, so the retry happens when somebody decides it should.

Toasts covered the logout button

They appeared top right, which is where the header keeps the account name and the logout button. While a toast was up, logging out was not clickable.

Bottom right now, decided once in helpers/toast.js. Four files reached for createToast directly and picked a corner each, so a single login attempt could put its success message in one corner and its failure in another.

The sign-in button looked disabled

Filled light grey on white, the same treatment this interface gives a disabled control, and it is the primary action of the whole authentication flow. The fields carried no label beyond a placeholder that disappears the moment anything is typed.

It is a primary button now in the blue the token page already uses, with real labels, and the failure appears inside the dialog rather than behind it.

The login dialog with rejected credentials, before and after

Upload looked like a directory

It sat inside the file list as a rounded row the same size and shape as a directory entry, told apart from real content by the colour of a dot. It is a labelled drop area below the listing now.

The upload target inside a repository, before and after

The screenshots come from fake-api/fake-ingot-backend.js and live on the orphan branch assets/pr-11-screenshots, which shares no history with main and is never merged. Deleting that branch breaks the images above.

Two defects found while reading that code

  • Nothing ever closed the log stream. close() on unmount was commented out, so every visit to the Console tab left another EventSource running against the server. Measured after the fix: one connection per mount, one per reconnect, none left behind.
  • Every error formatter threw on the errors that matter most. .catch handlers read error.response.status and error.response.data.message directly. That works for a server that answered and throws for one that did not, and the throw happened inside the catch, taking the handler with it. A refused connection or an unreachable host produced no message at all. There is one errorMessage helper now, lifted out of store/tokens.js where a correct version was already hiding, and the five call sites use it.

Type of change

  • fix - bug fix

How was this tested?

Same method as #10: both states rendered and compared per pixel, five views times two themes times two viewports.

overview-light-desktop      0     overview-dark-desktop      0
overview-light-mobile       0     overview-dark-mobile       0
tokens-light-desktop        0     tokens-dark-desktop        0.004
tokens-light-mobile         0     tokens-dark-mobile         0

The views that do differ were checked band by band rather than accepted:

  • settings differs in exactly two horizontal bands, y 12-75 and y 824-887, which is the toast leaving one corner and arriving in the other. Nothing else on that page moved.
  • dashboard differs only in its live values: the uptime figure and the two chart areas.
  • console is the intended redesign.

Behaviour was checked directly rather than inferred:

Step /api/console/log requests
First mount 1
Leaving the tab 1, unchanged
Returning 2
Pressing Reconnect 3

The rejected-login path was exercised against the stub and renders the server's own message inline. No page errors during any of it.

npm run eslint: errors drop from 7 to 2. Five were stray semicolons in the console store, which this change rewrites anyway. Both survivors sit in files this branch does not open.

./gradlew build passes.

Checklist

  • Commit messages follow the Conventional Commits convention documented in CLAUDE.md
  • Tests cover the change, or the change is not testable and I explained why above
  • ./gradlew build passes locally
  • Documentation and configuration samples are updated if the change is user-facing
  • Existing copyright headers are preserved; new files carry the appropriate header
  • No credentials, tokens or personal data are included in the diff

Same note as #10 on the tests box: the frontend has no test infrastructure and this branch does not add one. The verification above is a screenshot comparison plus a request count, reproducible but not committed. The connection lifecycle in particular is the kind of thing that deserves a real test, and that is worth its own PR.

Four places reported failure by not reporting it, and two of them lost
the message entirely.

The console rendered an empty white rectangle whenever the log stream
did not come up. The only signal was a toast, which faded after a few
seconds and left no trace, so the panel was indistinguishable from a
server that simply had nothing to say. It now carries its own state:
connecting, connected but quiet, or disconnected with the reason and a
Reconnect button. The command input is disabled while the stream is
down instead of silently swallowing what gets typed into it. The three
toasts are gone, because the information belongs where the reader is
already looking.

Toasts appeared in the top right corner, which is where the header
keeps the account name and the logout button. While one was up, logging
out was not clickable. They come up bottom right now, decided once in
helpers/toast.js rather than per call site. Four files reached for
`createToast` directly and picked a corner each; one login attempt
could put its success message in one corner and its failure in another.

The sign-in button was filled light grey on white, the same treatment
this interface gives a disabled control, and the fields carried no
label beyond a placeholder that disappears as soon as anything is
typed. It is a primary button now, in the same blue the token page
already uses, with real labels and the failure shown inside the dialog
rather than behind it.

Upload sat inside the file list as a rounded row the same size and
shape as a directory entry, told apart from real content by the colour
of a dot. It is a labelled drop area below the listing now, so an
action no longer looks like content.

Two defects surfaced while reading that code and are fixed here:

- Nothing ever closed the log stream. `close()` on unmount was
  commented out, so every visit to the tab left another EventSource
  running against the server. Verified: one connection per mount, none
  left behind after leaving.
- Every `.catch` that formatted an error read `error.response.status`
  and `error.response.data.message` directly. That works for a server
  that answered and throws for one that did not, and the throw happened
  inside the catch, taking the handler with it. A refused connection or
  an unreachable host, the most common failure of all, produced no
  message at all. There is one `errorMessage` helper now, lifted out of
  the tokens store where a correct version was already hiding, and the
  five call sites use it.

Verified against the previous state view by view: overview and tokens
come out pixel identical, settings differs only in the two bands where
the toast moved from one corner to the other, and the dashboard only in
its live values. Console is the intended redesign.

Also removes five stray semicolons that eslint flagged in the console
store, which the rewrite touched anyway. Errors on the branch drop from
seven to two; both survivors sit in files this change does not open.

Signed-off-by: TheMeinerLP <github@themeinerlp.dev>
@TheMeinerLP
TheMeinerLP merged commit 3585be2 into feat/tailwind-dashboard-ui Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant