Compare commits
2 Commits
b236386273
...
f7fd41b88f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7fd41b88f | ||
|
|
6f8edcec33 |
105
docs/superpowers/plans/2026-03-24-nav-swap.md
Normal file
105
docs/superpowers/plans/2026-03-24-nav-swap.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Nav Swap Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Swap the sidebar order so `连接列表` appears above `传输` without changing routing or behavior.
|
||||
|
||||
**Architecture:** This is a template-only frontend change in the shared main layout. The implementation keeps the existing `RouterLink` blocks, active-state logic, click handlers, icons, and labels intact, and only reorders the two navigation entries in `frontend/src/layouts/MainLayout.vue`.
|
||||
|
||||
**Tech Stack:** Vue 3, TypeScript, Vite, Tailwind CSS, vue-tsc
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
- Modify: `frontend/src/layouts/MainLayout.vue`
|
||||
- Contains the sidebar navigation template.
|
||||
- Only the relative position of the `/connections` and `/transfers` `RouterLink` blocks should change.
|
||||
- Verify: `frontend/src/router/index.ts`
|
||||
- Confirms the default redirect remains `/connections` and does not need modification.
|
||||
- Verify: `docs/superpowers/specs/2026-03-24-nav-swap-design.md`
|
||||
- Source of truth for this tiny UI change.
|
||||
|
||||
### Task 1: Reorder Sidebar Navigation Entries
|
||||
|
||||
**Files:**
|
||||
- Modify: `frontend/src/layouts/MainLayout.vue`
|
||||
- Verify: `frontend/src/router/index.ts`
|
||||
- Verify: `docs/superpowers/specs/2026-03-24-nav-swap-design.md`
|
||||
|
||||
- [ ] **Step 1: Check workspace state before editing**
|
||||
|
||||
Review `git status` and confirm there are no unrelated user changes in `frontend/src/layouts/MainLayout.vue` that must be preserved. Do not revert unrelated modifications.
|
||||
|
||||
- [ ] **Step 2: Inspect the existing sidebar navigation blocks**
|
||||
|
||||
Confirm that `frontend/src/layouts/MainLayout.vue` currently renders the `RouterLink` for `/transfers` before the `RouterLink` for `/connections`, and verify that both links already contain the correct label, icon, `aria-label`, active-state class, and `@click="closeSidebar"` behavior.
|
||||
|
||||
- [ ] **Step 3: Write the minimal implementation by swapping the two blocks**
|
||||
|
||||
Move the entire `/connections` `RouterLink` block so it appears before the `/transfers` `RouterLink` block.
|
||||
|
||||
Keep all existing content unchanged:
|
||||
|
||||
```vue
|
||||
<RouterLink
|
||||
to="/connections"
|
||||
@click="closeSidebar"
|
||||
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-slate-300 hover:bg-slate-700 hover:text-slate-100 transition-colors duration-200 cursor-pointer min-h-[44px] focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:ring-inset"
|
||||
:class="{ 'bg-slate-700 text-cyan-400': route.path === '/connections' }"
|
||||
aria-label="连接列表"
|
||||
>
|
||||
<Server class="w-5 h-5 flex-shrink-0" aria-hidden="true" />
|
||||
<span>连接列表</span>
|
||||
</RouterLink>
|
||||
```
|
||||
|
||||
```vue
|
||||
<RouterLink
|
||||
to="/transfers"
|
||||
@click="closeSidebar"
|
||||
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-slate-300 hover:bg-slate-700 hover:text-slate-100 transition-colors duration-200 cursor-pointer min-h-[44px] focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:ring-inset"
|
||||
:class="{ 'bg-slate-700 text-cyan-400': route.path === '/transfers' }"
|
||||
aria-label="传输"
|
||||
>
|
||||
<ArrowLeftRight class="w-5 h-5 flex-shrink-0" aria-hidden="true" />
|
||||
<span>传输</span>
|
||||
</RouterLink>
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Verify no route behavior changed**
|
||||
|
||||
Read `frontend/src/router/index.ts` and confirm these lines are still untouched:
|
||||
|
||||
```ts
|
||||
{
|
||||
path: '',
|
||||
name: 'Home',
|
||||
redirect: '/connections',
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Run the frontend verification build**
|
||||
|
||||
Run: `npm run build` in `frontend/`
|
||||
|
||||
Expected:
|
||||
- `vue-tsc -b` passes
|
||||
- Vite production build completes successfully
|
||||
|
||||
- [ ] **Step 6: Manually verify the UI behavior**
|
||||
|
||||
Check the sidebar in the app and confirm:
|
||||
- `连接列表` is above `传输`
|
||||
- Clicking each item still opens the same page
|
||||
- Active highlighting still matches the current route
|
||||
- Mobile sidebar uses the same order
|
||||
|
||||
- [ ] **Step 7: Commit the focused change if requested**
|
||||
|
||||
Only if the user asks for a commit:
|
||||
|
||||
```bash
|
||||
git add frontend/src/layouts/MainLayout.vue
|
||||
git commit -m "fix: reorder sidebar navigation items"
|
||||
```
|
||||
60
docs/superpowers/specs/2026-03-24-nav-swap-design.md
Normal file
60
docs/superpowers/specs/2026-03-24-nav-swap-design.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# 2026-03-24 Nav Swap: Transfers and Connections
|
||||
|
||||
## Background
|
||||
|
||||
The user wants to swap the visual order of the `传输` and `连接列表` entries in the left sidebar navigation.
|
||||
|
||||
## Goal
|
||||
|
||||
- Show `连接列表` above `传输` in the sidebar.
|
||||
- Keep the order consistent on desktop and mobile sidebar layouts.
|
||||
- Preserve existing navigation behavior, active-state highlighting, labels, and icons.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Do not change routing structure or auth behavior.
|
||||
- Do not change the default redirect to `/connections`.
|
||||
- Do not refactor the sidebar into config-driven navigation.
|
||||
- Do not make unrelated UI or style changes.
|
||||
|
||||
## Current State
|
||||
|
||||
In `frontend/src/layouts/MainLayout.vue`, the sidebar navigation currently renders:
|
||||
|
||||
1. `RouterLink` to `/transfers`
|
||||
2. `RouterLink` to `/connections`
|
||||
|
||||
The default app entry remains `/connections` via `frontend/src/router/index.ts`.
|
||||
|
||||
## Selected Approach
|
||||
|
||||
Use the smallest possible template-only change:
|
||||
|
||||
- In `frontend/src/layouts/MainLayout.vue`, move the `RouterLink` block for `/connections` so it appears before the `RouterLink` block for `/transfers`.
|
||||
|
||||
This is preferred because it:
|
||||
|
||||
- solves the request directly,
|
||||
- avoids unnecessary abstraction,
|
||||
- keeps behavior unchanged,
|
||||
- minimizes regression risk.
|
||||
|
||||
## Behavior Kept Unchanged
|
||||
|
||||
- `closeSidebar` still runs on click.
|
||||
- Active-state classes based on `route.path` stay the same.
|
||||
- `aria-label` values stay the same.
|
||||
- Existing icons (`Server`, `ArrowLeftRight`) stay paired with the same entries.
|
||||
- Terminal tab section remains below the main navigation items.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- The sidebar shows `连接列表` first and `传输` second.
|
||||
- Clicking either item still navigates to the same route.
|
||||
- Active highlighting still works for both routes.
|
||||
- Mobile sidebar uses the same order.
|
||||
|
||||
## Verification
|
||||
|
||||
- Run `npm run build` in `frontend/`.
|
||||
- Manually confirm the sidebar order and route highlighting.
|
||||
@@ -58,16 +58,6 @@ function handleTabClose(tabId: string, event: Event) {
|
||||
<p class="text-sm text-slate-400">{{ authStore.displayName || authStore.username }}</p>
|
||||
</div>
|
||||
<nav class="flex-1 p-4 space-y-1 pt-16 lg:pt-4 overflow-y-auto">
|
||||
<RouterLink
|
||||
to="/transfers"
|
||||
@click="closeSidebar"
|
||||
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-slate-300 hover:bg-slate-700 hover:text-slate-100 transition-colors duration-200 cursor-pointer min-h-[44px] focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:ring-inset"
|
||||
:class="{ 'bg-slate-700 text-cyan-400': route.path === '/transfers' }"
|
||||
aria-label="传输"
|
||||
>
|
||||
<ArrowLeftRight class="w-5 h-5 flex-shrink-0" aria-hidden="true" />
|
||||
<span>传输</span>
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/connections"
|
||||
@click="closeSidebar"
|
||||
@@ -78,6 +68,16 @@ function handleTabClose(tabId: string, event: Event) {
|
||||
<Server class="w-5 h-5 flex-shrink-0" aria-hidden="true" />
|
||||
<span>连接列表</span>
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/transfers"
|
||||
@click="closeSidebar"
|
||||
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-slate-300 hover:bg-slate-700 hover:text-slate-100 transition-colors duration-200 cursor-pointer min-h-[44px] focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:ring-inset"
|
||||
:class="{ 'bg-slate-700 text-cyan-400': route.path === '/transfers' }"
|
||||
aria-label="传输"
|
||||
>
|
||||
<ArrowLeftRight class="w-5 h-5 flex-shrink-0" aria-hidden="true" />
|
||||
<span>传输</span>
|
||||
</RouterLink>
|
||||
|
||||
<!-- 终端标签区域 -->
|
||||
<div v-if="terminalTabs.length > 0" class="pt-4 mt-4 border-t border-slate-700">
|
||||
|
||||
Reference in New Issue
Block a user