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;
|
||||
}
|
||||
|
||||
.app-shell.shell-locked,
|
||||
.sidebar.shell-locked,
|
||||
.workspace.shell-locked {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
@ -683,7 +689,7 @@ html[data-theme='dark'] button.ghost-danger:hover {
|
||||
|
||||
.providers-layout,
|
||||
.aliases-layout {
|
||||
grid-template-columns: minmax(360px, 0.92fr) minmax(0, 1.08fr);
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.editor-column,
|
||||
@ -784,6 +790,36 @@ html[data-theme='dark'] button.ghost-danger:hover {
|
||||
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 {
|
||||
align-items: flex-start;
|
||||
}
|
||||
@ -1207,6 +1243,15 @@ dd {
|
||||
.settings-side-panel {
|
||||
position: static;
|
||||
}
|
||||
|
||||
.detail-backdrop {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.detail-sheet {
|
||||
width: min(100%, 760px);
|
||||
height: calc(100vh - 1.5rem);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
@ -1264,6 +1309,18 @@ dd {
|
||||
flex-direction: column;
|
||||
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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user