fix(desktop): streamline detail drawers
This commit is contained in:
parent
a1eb4e244c
commit
5bd04b6a07
93
.trellis/tasks/04-19-desktop-log-network-views/prd.md
Normal file
93
.trellis/tasks/04-19-desktop-log-network-views/prd.md
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# Desktop Log, Network, And List-First Forms
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Desktop shell already contains provider and alias management pages with inline split-view editing, plus dedicated log and network tabs. Current provider and alias pages always reserve detail-pane space and automatically select first list item. This makes browsing feel heavy and wastes space when user only wants to inspect list.
|
||||||
|
|
||||||
|
This task keeps current data flow and form logic, but changes page behavior to a list-first layout:
|
||||||
|
|
||||||
|
- provider page shows only list by default
|
||||||
|
- alias route page shows only list by default
|
||||||
|
- clicking a list item opens edit panel
|
||||||
|
- clicking new opens create form panel
|
||||||
|
- import and bind target flows stay modal-based
|
||||||
|
|
||||||
|
## Product Goal
|
||||||
|
|
||||||
|
Make provider and alias route management feel lighter and more focused by separating browsing from editing, while preserving existing CRUD behavior and minimizing architectural churn.
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
|
||||||
|
### Already done
|
||||||
|
|
||||||
|
- `frontend/src/App.tsx` contains provider and alias list, search, filter, create, edit, delete, import, and bind-target flows.
|
||||||
|
- provider and alias forms already reuse local state and existing API calls.
|
||||||
|
- desktop shell already uses modal overlays for provider import, alias target binding, and confirm dialogs.
|
||||||
|
|
||||||
|
### Problems
|
||||||
|
|
||||||
|
- provider and alias tabs default to split-view with always-visible detail panel.
|
||||||
|
- first filtered item is auto-selected, so page never rests in pure list mode.
|
||||||
|
- empty detail area still occupies layout width before user chooses an action.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Provider page
|
||||||
|
|
||||||
|
- Default state shows only provider list and list controls.
|
||||||
|
- No provider detail panel should be visible until user clicks a provider row or `New provider`.
|
||||||
|
- Clicking provider row opens edit panel for that provider.
|
||||||
|
- Clicking `New provider` opens create panel with empty form.
|
||||||
|
|
||||||
|
### Alias route page
|
||||||
|
|
||||||
|
- Default state shows only alias list and list controls.
|
||||||
|
- No alias detail panel should be visible until user clicks alias row or `New alias`.
|
||||||
|
- Clicking alias row opens edit panel for that alias.
|
||||||
|
- Clicking `New alias` opens create panel with empty form.
|
||||||
|
|
||||||
|
### Interaction and reuse
|
||||||
|
|
||||||
|
- Reuse existing provider and alias form logic as much as possible.
|
||||||
|
- Reuse current modal/backdrop interaction patterns already used in desktop shell.
|
||||||
|
- Keep import-provider modal and bind-target modal unchanged unless minor adjustments are required for consistency.
|
||||||
|
- Keep existing backend/API contracts unchanged.
|
||||||
|
|
||||||
|
## Design Decisions
|
||||||
|
|
||||||
|
### Detail presentation
|
||||||
|
|
||||||
|
Use conditional overlay detail panel instead of always-mounted split-view pane.
|
||||||
|
|
||||||
|
Why:
|
||||||
|
|
||||||
|
- smallest frontend-only change that matches requested behavior
|
||||||
|
- consistent with existing modal/backdrop interaction already present in app
|
||||||
|
- preserves current form structure, submit handlers, and confirmation flows
|
||||||
|
|
||||||
|
### Selection behavior
|
||||||
|
|
||||||
|
Do not auto-select first filtered provider or alias.
|
||||||
|
|
||||||
|
Why:
|
||||||
|
|
||||||
|
- page should remain in pure list mode until explicit user action
|
||||||
|
- prevents accidental context switching when search/filter changes
|
||||||
|
|
||||||
|
## Non-Goals
|
||||||
|
|
||||||
|
1. No backend changes for providers, aliases, logs, or network.
|
||||||
|
2. No redesign of import-provider or bind-target workflows.
|
||||||
|
3. No new global state layer or routing changes.
|
||||||
|
4. No visual redesign outside provider and alias page layout adjustments needed for list-first behavior.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
1. Provider tab initially renders list without visible edit pane.
|
||||||
|
2. Alias tab initially renders list without visible edit pane.
|
||||||
|
3. Clicking provider row opens provider edit panel.
|
||||||
|
4. Clicking alias row opens alias edit panel.
|
||||||
|
5. Clicking provider create button opens provider create panel.
|
||||||
|
6. Clicking alias create button opens alias create panel.
|
||||||
|
7. Search/filter changes do not auto-open a detail panel.
|
||||||
|
8. Existing save, delete, import, bind, and toggle actions still work.
|
||||||
69
.trellis/tasks/04-19-desktop-log-network-views/task.json
Normal file
69
.trellis/tasks/04-19-desktop-log-network-views/task.json
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"id": "desktop-log-network-views",
|
||||||
|
"name": "desktop-log-network-views",
|
||||||
|
"title": "Design and implement desktop log and network views",
|
||||||
|
"description": "",
|
||||||
|
"status": "completed",
|
||||||
|
"dev_type": "feature",
|
||||||
|
"scope": "desktop",
|
||||||
|
"package": null,
|
||||||
|
"priority": "P2",
|
||||||
|
"creator": "OpenCode",
|
||||||
|
"assignee": "OpenCode",
|
||||||
|
"createdAt": "2026-04-19",
|
||||||
|
"completedAt": "2026-04-20",
|
||||||
|
"branch": "master",
|
||||||
|
"base_branch": "master",
|
||||||
|
"worktree_path": null,
|
||||||
|
"current_phase": 6,
|
||||||
|
"next_action": [
|
||||||
|
{
|
||||||
|
"phase": 1,
|
||||||
|
"action": "brainstorm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": 2,
|
||||||
|
"action": "research"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": 3,
|
||||||
|
"action": "implement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": 4,
|
||||||
|
"action": "check"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": 5,
|
||||||
|
"action": "update-spec"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"phase": 6,
|
||||||
|
"action": "record-session"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"commit": null,
|
||||||
|
"pr_url": null,
|
||||||
|
"subtasks": [],
|
||||||
|
"children": [],
|
||||||
|
"parent": null,
|
||||||
|
"relatedFiles": [
|
||||||
|
".trellis/tasks/04-19-desktop-log-network-views/prd.md",
|
||||||
|
"frontend/src/App.tsx",
|
||||||
|
"frontend/src/styles.css"
|
||||||
|
],
|
||||||
|
"notes": "Completed desktop provider, alias, log, and network view refresh to use list-first layouts with on-demand detail drawers instead of default split panes. Added keyboard-accessible drawer close flows, automatic first-field focus, shell scroll locking while drawers are open, list-header status/close affordances, and independent log/network detail selection. Fixed a GUI theme regression by preventing routine data refresh after proxy start/stop from overwriting in-memory desktop preferences. Verified with `npm run build` in `frontend`.",
|
||||||
|
"meta": {
|
||||||
|
"tests": [
|
||||||
|
"npm run build"
|
||||||
|
],
|
||||||
|
"uiPatterns": [
|
||||||
|
"list-first detail drawers",
|
||||||
|
"shared drawer close interactions",
|
||||||
|
"drawer-only scrolling"
|
||||||
|
],
|
||||||
|
"regressions": [
|
||||||
|
"proxy start/stop no longer resets theme presentation"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
1219
frontend/src/App.tsx
1219
frontend/src/App.tsx
File diff suppressed because it is too large
Load Diff
@ -243,6 +243,12 @@ h4 {
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-shell.shell-locked,
|
||||||
|
.sidebar.shell-locked,
|
||||||
|
.workspace.shell-locked {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -683,7 +689,7 @@ html[data-theme='dark'] button.ghost-danger:hover {
|
|||||||
|
|
||||||
.providers-layout,
|
.providers-layout,
|
||||||
.aliases-layout {
|
.aliases-layout {
|
||||||
grid-template-columns: minmax(360px, 0.92fr) minmax(0, 1.08fr);
|
grid-template-columns: minmax(0, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-column,
|
.editor-column,
|
||||||
@ -784,6 +790,36 @@ html[data-theme='dark'] button.ghost-danger:hover {
|
|||||||
align-content: start;
|
align-content: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.detail-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 25;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding: 1rem;
|
||||||
|
background: rgba(7, 16, 29, 0.28);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-sheet {
|
||||||
|
width: min(100%, 720px);
|
||||||
|
height: calc(100vh - 2rem);
|
||||||
|
overflow: auto;
|
||||||
|
padding: 1.3rem;
|
||||||
|
border: 1px solid var(--border-strong);
|
||||||
|
border-radius: 28px;
|
||||||
|
background: var(--panel);
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-sheet-header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
background: var(--panel);
|
||||||
|
}
|
||||||
|
|
||||||
.compact-inline-meta {
|
.compact-inline-meta {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
@ -1207,6 +1243,15 @@ dd {
|
|||||||
.settings-side-panel {
|
.settings-side-panel {
|
||||||
position: static;
|
position: static;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.detail-backdrop {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-sheet {
|
||||||
|
width: min(100%, 760px);
|
||||||
|
height: calc(100vh - 1.5rem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
@media (max-width: 900px) {
|
||||||
@ -1264,6 +1309,18 @@ dd {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.detail-backdrop {
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: stretch;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-sheet {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user