3.2 KiB
3.2 KiB
獨立的 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<i64>) 查存儲層後渲染。共用一個 render 輔助(已存在)。
2. 模板
templates/database_form.html(新,新增/編輯共用):
- 內容:session bar + 標題(
新增連接/編輯連接:{name})+role="alert"錯誤條 + 表單(name、type 下拉、host、port、username、password、database_name)+ 提示文字 - 上下文:
editing: Option<Database>。Askama 條件渲染:各欄位value="{% if let Some(db) = editing %}{{ db.name }}{% endif %}"(自動轉義);type 下拉按db.db_type.as_str()標記 selected;密碼一律不輸出值,placeholder 按模式顯示「可留空」/「留空保留原密碼」 <form data-mode="{% if editing %}edit{% else %}create{% endif %}" {% if ... %}data-id="{{ db.id }}"{% endif %}>- 內嵌 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 全綠;伺服器 + 瀏覽器走完整流程(臨時資料庫,測完清理)。