# 獨立的 Database 新增 / 編輯頁面 沿用既定的 JS + REST API 架構,把目前內嵌在列表頁的伸縮式表單拆成兩個獨立頁面;編輯頁改為**服務端預填**(Askama 直接渲染現值,無需 JS 先取數據),提交仍走 `fetch` POST/PUT,成功後跳回 `/databases`。 ## 1. 路由(`src/controllers/pages.rs`) | 路徑 | 說明 | | --- | --- | | `GET /databases` | 列表頁(保留):渲染表格 + 刪除(JS confirm + DELETE)| | `GET /databases/new` | 新增頁:空表單 | | `GET /databases/{id}/edit` | 編輯頁:服務端 `get_by_id` 預填表單;不存在 → 404「數據庫連接不存在」| 三個頁面均以 `CurrentUser` 守衛(未登入 303 → `/login`)。`/databases/new`(一段路徑)與 `/databases/{id}/edit`(兩段)無路由衝突。 處理器:`database_new_page(user)` 直接渲染空表單;`database_edit_page(State, user, Path)` 查存儲層後渲染。共用一個 `render` 輔助(已存在)。 ## 2. 模板 **`templates/database_form.html`(新,新增/編輯共用)**: - 內容:session bar + 標題(`新增連接` / `編輯連接:{name}`)+ `role="alert"` 錯誤條 + 表單(name、type 下拉、host、port、username、password、database_name)+ 提示文字 - 上下文:`editing: Option`。Askama 條件渲染:各欄位 `value="{% if let Some(db) = editing %}{{ db.name }}{% endif %}"`(自動轉義);type 下拉按 `db.db_type.as_str()` 標記 selected;密碼一律不輸出值,placeholder 按模式顯示「可留空」/「留空保留原密碼」 - `
` - 內嵌 JS:提交時按 `data-mode` 構造 payload(埠留空省略 → 後端補默認;密碼留空:新增=空密碼、編輯=省略鍵保留原值),`POST /api/databases` 或 `PUT /api/databases/{id}`;成功 `location.assign('/databases')`,失敗顯示 API 錯誤訊息。埠 placeholder 提示隨 type 切換(沿用現有邏輯) - 表單樣式從 `databases.html` 遷移至此;「取消」按鈕為返回 `/databases` 的連結 **`templates/databases.html`(列表頁簡化)**: - 移除整個內嵌表單區塊與其 JS;「新增連接」改為連結按鈕 → `/databases/new`;每行「編輯」改為連結 → `/databases/{id}/edit`(`renderRow` 中以 `setAttribute('href', ...)` 構造) - 保留:列表載入、空狀態、刪除(confirm + DELETE)、列表錯誤條 ## 3. 測試 - `pages.rs`:新增頁渲染測試(表單存在、無預填);編輯頁預填測試(test_pool + storage 建一條 → 斷言 `value="shop-prod"`、type selected、密碼無值);編輯頁 404 測試(不存在的 id) - `controllers/mod.rs` 集成測試補:未登入 `GET /databases/new`、`GET /databases/1/edit` → 303 `/login` - 瀏覽器實測:列表 → 新增頁建立 → 編輯頁修改(密碼留空保留)→ 刪除 ## 4. README 「Web 管理介面」小節的路徑表更新為三個頁面;結構樹補 `database_form.html`、調整 `databases.html` 描述。 ## 5. 驗證 `cargo build` + `cargo test` 全綠;伺服器 + 瀏覽器走完整流程(臨時資料庫,測完清理)。