Files
alterdb/.zcode/plans/plan-sess_981c23fb-2298-41a2-b22c-23908fd42a92.md
2026-10-02 13:12:49 +08:00

3.2 KiB
Raw Permalink Blame History

獨立的 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 全綠;伺服器 + 瀏覽器走完整流程(臨時資料庫,測完清理)。