diff --git a/web/storyforge-web-v4/assets/app.js b/web/storyforge-web-v4/assets/app.js index 4ea6ed0..629f3e9 100644 --- a/web/storyforge-web-v4/assets/app.js +++ b/web/storyforge-web-v4/assets/app.js @@ -169,34 +169,36 @@ function ensureAuthUi() { modal.className = "auth-modal-backdrop hidden"; modal.innerHTML = `
-
-
-

连接 StoryForge

-

先登录后端,再加载项目、对标、Agent 和生产数据。

+
+
+
+

连接 StoryForge

+

先登录后端,再加载项目、对标、Agent 和生产数据。

+
+
- -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- - -
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
`; document.body.appendChild(modal); @@ -2442,17 +2444,8 @@ document.addEventListener("click", async (event) => { return; } if (name === "submit-auth") { - setBusy(true, "正在登录并加载..."); - try { - await loginWithForm(); - closeAuthModal(); - await bootstrap(); - } catch (error) { - const message = document.querySelector('[data-role="auth-message"]'); - if (message) message.textContent = error.message; - } finally { - setBusy(false, ""); - } + // Auth form submission is handled centrally so clicking the submit + // button and pressing Enter share the same code path. return; } if (name === "auth-refresh" || name === "refresh-data") { @@ -2610,6 +2603,23 @@ document.addEventListener("input", (event) => { } }); +document.addEventListener("submit", async (event) => { + const form = event.target; + if (!(form instanceof HTMLFormElement) || form.dataset.role !== "auth-form") return; + event.preventDefault(); + setBusy(true, "正在登录并加载..."); + try { + await loginWithForm(); + closeAuthModal(); + await bootstrap(); + } catch (error) { + const message = document.querySelector('[data-role="auth-message"]'); + if (message) message.textContent = error.message; + } finally { + setBusy(false, ""); + } +}); + navButtons.forEach((button) => { button.addEventListener("click", () => { const next = button.dataset.screenTarget; diff --git a/web/storyforge-web-v4/assets/styles.css b/web/storyforge-web-v4/assets/styles.css index cb04a3f..941f978 100644 --- a/web/storyforge-web-v4/assets/styles.css +++ b/web/storyforge-web-v4/assets/styles.css @@ -213,6 +213,16 @@ select { min-width: 0; } +.topbar-left { + flex: 1 1 auto; +} + +.topbar-right { + flex: 1 1 auto; + justify-content: flex-end; + flex-wrap: wrap; +} + .workspace-switch, .search, .mini-card { @@ -234,6 +244,8 @@ select { .workspace-switch span { font-size: 12px; color: var(--muted); + display: block; + line-height: 1.4; } .search { @@ -279,6 +291,7 @@ select { display: flex; align-items: center; gap: 10px; + flex-wrap: wrap; } .auth-status { @@ -314,6 +327,11 @@ select { padding: 22px; } +.auth-form { + display: grid; + gap: 0; +} + .action-modal-backdrop { position: fixed; inset: 0; @@ -1144,18 +1162,37 @@ tbody tr:hover { border-radius: 18px; } + .topbar-left .chip-row, + .topbar-right { + width: 100%; + } + + .topbar-left .chip-row { + flex-wrap: nowrap; + overflow-x: auto; + padding-bottom: 2px; + scrollbar-width: none; + } + + .topbar-left .chip-row::-webkit-scrollbar { + display: none; + } + .top-pill { padding: 7px 10px; } .auth-inline { - flex-wrap: wrap; width: 100%; + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; } .auth-status { max-width: none; width: 100%; + grid-column: 1 / -1; } .auth-modal-backdrop, @@ -1332,6 +1369,7 @@ tbody tr:hover { .topbar-right { gap: 8px; + align-items: stretch; } .search { @@ -1339,7 +1377,53 @@ tbody tr:hover { } .action-row .btn, - .btn { + .auth-actions .btn { + width: 100%; + } + + .workspace-switch { + padding: 10px 12px; + } + + .workspace-switch strong { + font-size: 12px; + } + + .workspace-switch span { + font-size: 11px; + } + + .topbar-left .chip-row { + gap: 6px; + } + + .topbar-left .chip, + .top-pill { + font-size: 11px; + } + + .topbar-right > :not(.avatar) { + width: 100%; + } + + .topbar-right .search { + order: 2; + } + + .topbar-right .auth-inline { + order: 1; + } + + .topbar-right .top-pill { + width: auto; + } + + .topbar-right .avatar { + order: 4; + align-self: flex-end; + } + + .auth-inline .btn { width: 100%; } @@ -1383,39 +1467,3 @@ tbody tr:hover { font-size: 12px; text-align: right; } - -@media (max-width: 1320px) { - .grid-main, - .grid-split, - .grid-5, - .grid-4, - .grid-3, - .three-col, - .two-col { - grid-template-columns: 1fr; - } - .calendar { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } -} - -@media (max-width: 1080px) { - .app-shell { - grid-template-columns: 1fr; - } - .sidebar { - position: relative; - height: auto; - } - .topbar { - flex-direction: column; - align-items: stretch; - } - .topbar-left, - .topbar-right { - flex-wrap: wrap; - } - .search { - min-width: 0; - } -}