feat(web): hosts tab in settings (read-only roster: self + peers)#255
feat(web): hosts tab in settings (read-only roster: self + peers)#255mgabor3141 wants to merge 1 commit into
Conversation
Try this PRcurl -sSfL https://gmux.app/install-pr.sh | sh -s -- 255Built from |
|
| Filename | Overview |
|---|---|
| apps/gmux-web/src/settings.tsx | Adds SettingsModal tab bar (Projects/Hosts) and a read-only HostsTab/HostRow roster; normalization of unknown tab values is correct; minor: error truncation lacks hover title, ARIA panel wiring is incomplete |
| apps/gmux-web/src/main.tsx | Plumbs tab/onSelectTab props to SettingsModal; replace-vs-push logic is correct — alreadyActive guard prevents duplicate history entries |
| apps/gmux-web/src/mock-data/index.ts | Adds MOCK_PEERS and MOCK_HEALTH fixtures covering all HostRow states; bespin omits version to exercise the optional render branch |
| apps/gmux-web/src/store.ts | Wire-up of MOCK_PEERS/MOCK_HEALTH into _setRawWorld is correct; peers and health remain independent signal projections |
| apps/gmux-web/src/styles.css | New host-list/host-row/host-meta/host-error styles; min-width:0 on .host-name is present; host-error ellipsis works correctly as a block element |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
URL["URL: ?settings=hosts / ?settings=projects"] --> SM["SettingsModal\n(tab prop + onSelectTab)"]
SM --> |"activeTab === 'hosts'"| HT["HostsTab"]
SM --> |"activeTab === 'projects'"| PT["Projects tab body\n(unchanged)"]
HT --> SelfRow["HostRow (self)\nname=health.hostname / status=connected"]
HT --> PeerRows["HostRow × N\n(peers signal)"]
PeerRows --> Connected["status=connected: dot green"]
PeerRows --> Disconnected["status≠connected: dot grey + last_error"]
OT["openSettings(tab, replace)\nin main.tsx"] --> |"replace=true (tab switch)"| HIST["loc.route replace"]
OT --> |"push (open modal)"| HISTPUSH["loc.route push"]
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
apps/gmux-web/src/settings.tsx:361-363
The `host-error` div truncates long errors via `text-overflow: ellipsis` but there is no way to see the full message — no tooltip, no expand affordance. A `last_error` like a TLS handshake trace or a long hostname can be truncated past the useful part.
```suggestion
{!connected && lastError && (
<div class="host-error" title={lastError}>{lastError}</div>
)}
```
### Issue 2 of 2
apps/gmux-web/src/settings.tsx:179-214
**ARIA tab panel wiring incomplete**
The `role="tablist"` / `role="tab"` / `aria-selected` pattern is present, but the complementary panel side is missing: the rendered panels (`modal-body` divs) have no `role="tabpanel"`, no `id`, and the tab buttons have no `aria-controls` linking to them. Screen-readers that follow the APG tabs pattern won't be able to associate the selected tab with its content region.
Reviews (3): Last reviewed commit: "feat(web): hosts tab in settings (read-o..." | Re-trigger Greptile
df03045 to
8783e9e
Compare
83bf5e3 to
4fc0682
Compare
|
@greptile review |
Closes #251.
Summary
Third slice of the home/settings restructure (#251): add a Hosts tab to Settings — the read-only "dig" companion to the at-a-glance host status the sidebar pills already give.
Changes
?settingsvalue;?settings=hostsdeep-links straight to the roster. Tab switches useroute(..., replace)so Back closes the modal rather than cycling tabs. Bare?settings/ unknown values normalize to Projects.health: hostname, version, local session count), then the tailnet-discovered + configured peers. Each row: status dot +PeerLabelchip (self gets the "this host" tag) + name (+ "local" tag for Local peers), withstatus · N sessions · vXmeta. A host'slast_errorrenders inline below the row when it isn't connected.MOCK_PEERS+MOCK_HEALTHadded to mock mode so the Hosts tab (and the existing peer/host-suffix/version-footer surfaces) are exercisable in the?mock=1playground. Covers connected, a Local devcontainer, and a disconnected host with alast_error.Testing
?settings=hostsopens the roster (self + 4 peers, dots/versions/counts, bespin showing its disconnect error); switching Projects↔Hosts updates the param and preservesmock=1.Notes