fix: keep brand and version on one line
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## 状态与路由
|
## 状态与路由
|
||||||
|
|
||||||
应用启动先请求 `system/status`,已初始化时再请求 `auth/me`。未初始化渲染安装页;未登录渲染登录页;登录后由 `BrowserRouter` 提供 `/` 总览和 `/settings` 设置,未知路径回到 `/`。状态响应中的构建版本以 `v<version>` 徽标显示在安装页、登录页和登录后侧栏的品牌区域。这些分支只负责交互,服务端 session 才是安全边界。
|
应用启动先请求 `system/status`,已初始化时再请求 `auth/me`。未初始化渲染安装页;未登录渲染登录页;登录后由 `BrowserRouter` 提供 `/` 总览和 `/settings` 设置,未知路径回到 `/`。状态响应中的构建版本以 `v<version>` 徽标显示在安装页、登录页和登录后侧栏的品牌区域;品牌图标、名称和版本徽标保持单行排列。这些分支只负责交互,服务端 session 才是安全边界。
|
||||||
|
|
||||||
主题以服务端通用设置为持久来源,`localStorage` 仅用于首屏缓存;system 模式会跟随系统主题变化。当前账号 ID 保存到 `localStorage`。总览先加载账号列表,为当前账号加载 Dashboard,并在每轮请求完成 30 秒后刷新;切换账号会取消旧请求并校验响应账号,避免迟到响应覆盖当前账号。手动刷新调用账号级 sync 后重新读取 Dashboard。
|
主题以服务端通用设置为持久来源,`localStorage` 仅用于首屏缓存;system 模式会跟随系统主题变化。当前账号 ID 保存到 `localStorage`。总览先加载账号列表,为当前账号加载 Dashboard,并在每轮请求完成 30 秒后刷新;切换账号会取消旧请求并校验响应账号,避免迟到响应覆盖当前账号。手动刷新调用账号级 sync 后重新读取 Dashboard。
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ const Splash = () => (
|
|||||||
function Brand({ version }: { version?: string }) {
|
function Brand({ version }: { version?: string }) {
|
||||||
return (
|
return (
|
||||||
<div className="logo">
|
<div className="logo">
|
||||||
<Zap /> Codex Helper
|
<Zap /> <span className="brand-name">Codex Helper</span>
|
||||||
{version && <span className="version-badge">v{version}</span>}
|
{version && <span className="version-badge">v{version}</span>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ select {
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
letter-spacing: -0.03em;
|
letter-spacing: -0.03em;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.logo svg {
|
.logo svg {
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { expect, test, type Page } from "@playwright/test";
|
import { expect, test, type Page } from "@playwright/test";
|
||||||
|
|
||||||
const responses: Record<string, unknown> = {
|
const responses: Record<string, unknown> = {
|
||||||
"system/status": { initialized: true, appServer: true, version: "test" },
|
"system/status": {
|
||||||
|
initialized: true,
|
||||||
|
appServer: true,
|
||||||
|
version: "0.3.0-beta.1",
|
||||||
|
},
|
||||||
"auth/me": { username: "admin" },
|
"auth/me": { username: "admin" },
|
||||||
"settings/general": {
|
"settings/general": {
|
||||||
timezone: "America/New_York",
|
timezone: "America/New_York",
|
||||||
@@ -60,9 +64,28 @@ async function openSettings(page: Page) {
|
|||||||
|
|
||||||
test("shows the build version in the authenticated brand", async ({ page }) => {
|
test("shows the build version in the authenticated brand", async ({ page }) => {
|
||||||
await openSettings(page);
|
await openSettings(page);
|
||||||
const badge = page.locator("aside .version-badge");
|
const brand = page.locator("aside .logo");
|
||||||
|
const badge = brand.locator(".version-badge");
|
||||||
await expect(badge).toBeVisible();
|
await expect(badge).toBeVisible();
|
||||||
await expect(badge).toHaveText("vtest");
|
await expect(badge).toHaveText("v0.3.0-beta.1");
|
||||||
|
await expect(brand).toHaveCSS("white-space", "nowrap");
|
||||||
|
const layout = await brand.evaluate((element) => {
|
||||||
|
const badgeElement = element.querySelector(".version-badge");
|
||||||
|
const nameElement = element.querySelector(".brand-name");
|
||||||
|
const iconElement = element.querySelector("svg");
|
||||||
|
if (!badgeElement || !nameElement || !iconElement)
|
||||||
|
throw new Error("brand is incomplete");
|
||||||
|
const badgeRect = badgeElement.getBoundingClientRect();
|
||||||
|
const nameRect = nameElement.getBoundingClientRect();
|
||||||
|
const iconRect = iconElement.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
badgeCenter: badgeRect.top + badgeRect.height / 2,
|
||||||
|
nameCenter: nameRect.top + nameRect.height / 2,
|
||||||
|
iconCenter: iconRect.top + iconRect.height / 2,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
expect(Math.abs(layout.badgeCenter - layout.nameCenter)).toBeLessThan(1);
|
||||||
|
expect(Math.abs(layout.iconCenter - layout.nameCenter)).toBeLessThan(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("shows the build version before setup", async ({ page }) => {
|
test("shows the build version before setup", async ({ page }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user