feat(web): B4 枚举标签映射 — labelFor 未知值原样显示
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- 新增 lib/enums.ts:platform/mood 标签 + labelFor(kind,value),未知值原样返回(display-raw 红线),注释标明权威来源是 GET /api/v1/meta/enums
- 4 处 mood 渲染改用标签(Nav/TopBar/chat×2);未动 types.ts 的 MODES/Mode
- 新增纯逻辑测试 enums.test.ts(47 项,esbuild+node,零新依赖)
- 未动 admin channelFields 的第二份 PLATFORM_LABEL(记入待办)
This commit is contained in:
AskaEth committed 2026-10-03 16:55:22 +08:00
1 parent 22e8398110
commit f42ea1e41c
5 files changed
+151 -4

No files matched your search

+2 -1
View File
@@ -1,6 +1,7 @@
import { useState } from "react";
import { applyTheme, readTheme, type ThemeMode } from "../lib/theme";
import { createSubSession, getAuthToken } from "../lib/api";
import { labelFor } from "../lib/enums";
import { useAppStore } from "../store/useAppStore";
import { Icon, type IconName } from "./Icon";
import { Tag } from "./primitives";
@@ -86,7 +87,7 @@ function NavContent({ onNavigate }: { onNavigate: () => void }): React.ReactNode
{mood ? (
<div className="px-2 py-1 text-[11px] text-[var(--mu-text-lo)]">
心情 · {mood}
心情 · {labelFor("mood", mood)}
</div>
) : null}
+2 -1
View File
@@ -3,6 +3,7 @@ import { useAppStore } from "../store/useAppStore";
import { useModeStore } from "../store/useModeStore";
import { applyTheme, readTheme, type ThemeMode } from "../lib/theme";
import { personaAvatar } from "../lib/persona";
import { labelFor } from "../lib/enums";
import type { Mode, WsStatus } from "../lib/types";
import { Tag } from "./primitives";
import { Icon, type IconName } from "./Icon";
@@ -67,7 +68,7 @@ export function TopBar({ onMenu }: { onMenu: () => void }): React.ReactNode {
<div className="flex-1" />
{mood ? <Tag tone="accent" className="hidden sm:inline-flex">心情 · {mood}</Tag> : null}
{mood ? <Tag tone="accent" className="hidden sm:inline-flex">心情 · {labelFor("mood", mood)}</Tag> : null}
<AwakenBadge />
+3 -2
View File
@@ -2,6 +2,7 @@ import { useState } from "react";
import type { ChatMessage, Mode, ToolUsed } from "../lib/types";
import { useAppStore } from "../store/useAppStore";
import { personaAvatar } from "../lib/persona";
import { labelFor } from "../lib/enums";
import { Tag } from "./primitives";
import { Icon, type IconName } from "./Icon";
import { WakePath } from "./status";
@@ -261,7 +262,7 @@ function AssistantParaBubble({
<div className="min-w-0 max-w-[85%]">
{full ? <ModeTag mode={message.mode ?? "chat"} /> : null}
{full && message.mood ? (
<div className="mb-1 text-xs text-[var(--mu-text-lo)]">心情 · {message.mood}</div>
<div className="mb-1 text-xs text-[var(--mu-text-lo)]">心情 · {labelFor("mood", message.mood)}</div>
) : null}
{full ? <SourceLabel deviceId={message.deviceId} role={message.role} /> : null}
{full ? <WakePath active={active} /> : null}
@@ -402,7 +403,7 @@ function AssistantBubble({
<div className="min-w-0 max-w-[85%]">
<ModeTag mode={mode} />
{message.mood ? (
<div className="mb-1 text-xs text-[var(--mu-text-lo)]">心情 · {message.mood}</div>
<div className="mb-1 text-xs text-[var(--mu-text-lo)]">心情 · {labelFor("mood", message.mood)}</div>
) : null}
<SourceLabel deviceId={message.deviceId} role={message.role} />
<WakePath active={active} />