@musnows/scriverse 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +35 -1
- package/dist/app.js.map +1 -1
- package/dist/collaboration-presence.js +75 -0
- package/dist/collaboration-presence.js.map +1 -0
- package/dist/database.js +19 -0
- package/dist/database.js.map +1 -1
- package/dist/public/app.js +493 -130
- package/dist/public/character-version.js +1 -1
- package/dist/public/display-labels.d.ts +16 -0
- package/dist/public/display-labels.js +81 -0
- package/dist/public/entity-version.js +5 -3
- package/dist/public/index.html +37 -13
- package/dist/public/page-route.js +3 -1
- package/dist/public/styles.css +111 -26
- package/dist/public/work-permissions.js +1 -1
- package/dist/server-runtime.js +5 -1
- package/dist/server-runtime.js.map +1 -1
- package/dist/user-auth.js +77 -3
- package/dist/user-auth.js.map +1 -1
- package/dist/version.js +1 -1
- package/dist/work-permissions.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function settingStatusLabel(value: unknown): string;
|
|
2
|
+
export function characterVisibilityLabel(value: unknown): string;
|
|
3
|
+
export function timelineStatusLabel(value: unknown): string;
|
|
4
|
+
export function levelLabel(value: unknown): string;
|
|
5
|
+
export function foreshadowStatusLabel(value: unknown): string;
|
|
6
|
+
export function outlineStatusLabel(value: unknown): string;
|
|
7
|
+
export function relationshipCategoryLabel(value: unknown): string;
|
|
8
|
+
export function relationshipConfirmationLabel(value: unknown): string;
|
|
9
|
+
export function reviewItemTypeLabel(value: unknown): string;
|
|
10
|
+
export function reviewStatusLabel(value: unknown): string;
|
|
11
|
+
export function taskScopeLabel(value: unknown): string;
|
|
12
|
+
export function providerStatusLabel(value: unknown): string;
|
|
13
|
+
export function providerConnectionLabel(value: unknown): string;
|
|
14
|
+
export function chapterVersionSourceLabel(value: unknown): string;
|
|
15
|
+
export function occurrenceRoleLabel(value: unknown): string;
|
|
16
|
+
export function searchResultTypeLabel(value: unknown): string;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
function enumLabel(labels, value, fallback) {
|
|
2
|
+
const normalized = String(value ?? "").trim();
|
|
3
|
+
if (Object.hasOwn(labels, normalized)) return labels[normalized];
|
|
4
|
+
if (!normalized || /^[a-z][a-z0-9_-]*$/iu.test(normalized)) return fallback;
|
|
5
|
+
return normalized;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function settingStatusLabel(value) {
|
|
9
|
+
return enumLabel({ draft: "草稿", pending: "待确认", confirmed: "已确认", deprecated: "已弃用" }, value, "未知状态");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function characterVisibilityLabel(value) {
|
|
13
|
+
return enumLabel({ public: "公开", author: "仅作者", collaborators: "协作者可见" }, value, "未知范围");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function timelineStatusLabel(value) {
|
|
17
|
+
return enumLabel({ candidate: "候选", pending: "待确认", confirmed: "已确认", deprecated: "已弃用" }, value, "未知状态");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function levelLabel(value) {
|
|
21
|
+
return enumLabel({ low: "低", medium: "中", high: "高" }, value, "未知等级");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function foreshadowStatusLabel(value) {
|
|
25
|
+
return enumLabel({ planned: "计划中", planted: "已埋设", resolved: "已回收", abandoned: "已放弃" }, value, "未知状态");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function outlineStatusLabel(value) {
|
|
29
|
+
return enumLabel({ draft: "草稿", ready: "可执行", completed: "已完成" }, value, "未知状态");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function relationshipCategoryLabel(value) {
|
|
33
|
+
return enumLabel({ family: "亲属", social: "社交", emotional: "情感", conflict: "冲突", uncertain: "未确定" }, value, "其他关系");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function relationshipConfirmationLabel(value) {
|
|
37
|
+
return enumLabel({ pending: "待确认", confirmed: "已确认", rejected: "已拒绝" }, value, "未知状态");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function reviewItemTypeLabel(value) {
|
|
41
|
+
return enumLabel({
|
|
42
|
+
consistency: "一致性问题",
|
|
43
|
+
"character-duplicate": "角色重复",
|
|
44
|
+
"timeline-conflict": "时间线冲突",
|
|
45
|
+
"setting-conflict": "设定冲突",
|
|
46
|
+
"relationship-conflict": "关系冲突",
|
|
47
|
+
"character-conflict": "角色冲突",
|
|
48
|
+
"plot-hole": "剧情漏洞",
|
|
49
|
+
"low-confidence": "低置信度结论",
|
|
50
|
+
chronology: "时间顺序问题",
|
|
51
|
+
factual: "事实问题"
|
|
52
|
+
}, value, "其他审核问题");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function reviewStatusLabel(value) {
|
|
56
|
+
return enumLabel({ pending: "待处理", ignored: "已忽略", fixing: "处理中", fixed: "已修复", exception: "例外保留" }, value, "未知状态");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function taskScopeLabel(value) {
|
|
60
|
+
return enumLabel({ none: "无上下文", selection: "选中文本", chapter: "当前章节", volume: "当前分卷", book: "全书", entities: "指定资料" }, value, "未指定范围");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function providerStatusLabel(value) {
|
|
64
|
+
return enumLabel({ enabled: "已启用", disabled: "已停用", error: "异常" }, value, "未知状态");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function providerConnectionLabel(value) {
|
|
68
|
+
return enumLabel({ unchecked: "未测试", success: "连接正常", failed: "连接失败" }, value, "未知连接状态");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function chapterVersionSourceLabel(value) {
|
|
72
|
+
return enumLabel({ manual: "人工保存", auto: "自动保存", "ai-suggestion": "AI 建议", restore: "历史恢复", import: "文件导入", create: "初始版本" }, value, "其他来源");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function occurrenceRoleLabel(value) {
|
|
76
|
+
return enumLabel({ setup: "埋设", reminder: "提醒", payoff: "回收" }, value, "其他节点");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function searchResultTypeLabel(value) {
|
|
80
|
+
return enumLabel({ chapter: "章节", setting: "设定", character: "角色", race: "种族", organization: "组织" }, value, "其他资料");
|
|
81
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { levelLabel, relationshipCategoryLabel } from "./display-labels.js?v=20260725-enum-labels-zh";
|
|
2
|
+
|
|
1
3
|
export const VERSIONED_ENTITY_LABELS = Object.freeze({
|
|
2
4
|
setting: "世界观设定",
|
|
3
5
|
race: "种族档案",
|
|
@@ -18,7 +20,7 @@ export function entityVersionSourceLabel(source) {
|
|
|
18
20
|
analysis: "AI 分析",
|
|
19
21
|
merge: "事件合并",
|
|
20
22
|
split: "事件拆分"
|
|
21
|
-
})[source] ??
|
|
23
|
+
})[source] ?? "其他来源";
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export function entityVersionSnapshotSummary(type, snapshot = {}) {
|
|
@@ -27,8 +29,8 @@ export function entityVersionSnapshotSummary(type, snapshot = {}) {
|
|
|
27
29
|
if (type === "organization") return `${snapshot.name || "未命名组织"} · ${(snapshot.memberIds ?? []).length} 位成员`;
|
|
28
30
|
if (type === "timeline-track") return `${snapshot.name || "未命名时间轴"} · 排序 ${snapshot.sortOrder ?? 0}`;
|
|
29
31
|
if (type === "timeline-event") return `${snapshot.timeLabel || "时间待定"} · ${snapshot.name || "未命名事件"}`;
|
|
30
|
-
if (type === "relationship") return `${snapshot.category
|
|
32
|
+
if (type === "relationship") return `${relationshipCategoryLabel(snapshot.category)} / ${snapshot.subtype || "未细分"} · ${Math.round(Number(snapshot.confidence ?? 0) * 100)}%`;
|
|
31
33
|
if (type === "chapter-outline") return `目标:${snapshot.goal || "未填写"}`;
|
|
32
|
-
if (type === "foreshadow") return `${snapshot.importance || "medium"} · ${snapshot.title || "未命名伏笔"}`;
|
|
34
|
+
if (type === "foreshadow") return `${levelLabel(snapshot.importance || "medium")} · ${snapshot.title || "未命名伏笔"}`;
|
|
33
35
|
return "历史快照";
|
|
34
36
|
}
|
package/dist/public/index.html
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<link rel="icon" href="/icon.svg?v=20260712" type="image/svg+xml">
|
|
11
11
|
<link rel="manifest" href="/site.webmanifest">
|
|
12
12
|
<link rel="stylesheet" href="/vendor/vditor/dist/index.css?v=3.11.2">
|
|
13
|
-
<link rel="stylesheet" href="/styles.css?v=
|
|
13
|
+
<link rel="stylesheet" href="/styles.css?v=20260725-ui-collaboration">
|
|
14
14
|
</head>
|
|
15
15
|
<body class="auth-pending">
|
|
16
16
|
<section id="auth-view" class="auth-view hidden" aria-labelledby="auth-title">
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
</div>
|
|
26
26
|
<form id="login-form" class="auth-form">
|
|
27
27
|
<label>用户名<input name="username" autocomplete="username" maxlength="100" required></label>
|
|
28
|
-
<label>密码<span class="password-field"><input id="login-password" name="password" type="password" autocomplete="current-password" maxlength="200" required><button class="password-toggle" type="button" data-password-toggle="login-password" aria-label="显示密码" aria-pressed="false" title="显示密码"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M2.5 12s3.3-5.5 9.5-5.5S21.5 12 21.5 12 18.2 17.5 12 17.5 2.5 12 2.5 12Z"/><circle cx="12" cy="12" r="2.8"/></svg></button></span></label>
|
|
28
|
+
<label>密码<span class="password-field"><input id="login-password" name="password" type="password" autocomplete="current-password" maxlength="200" required aria-describedby="login-lock-hint"><button class="password-toggle" type="button" data-password-toggle="login-password" aria-label="显示密码" aria-pressed="false" title="显示密码"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M2.5 12s3.3-5.5 9.5-5.5S21.5 12 21.5 12 18.2 17.5 12 17.5 2.5 12 2.5 12Z"/><circle cx="12" cy="12" r="2.8"/></svg></button></span></label>
|
|
29
|
+
<p id="login-lock-hint" class="auth-security-hint">5 分钟内连续输错 5 次密码,登录将锁定 30 分钟。</p>
|
|
29
30
|
<div class="auth-captcha">
|
|
30
31
|
<label>验证码<input name="captchaAnswer" autocomplete="off" inputmode="text" maxlength="8" spellcheck="false" required aria-describedby="login-captcha-hint"></label>
|
|
31
32
|
<button id="login-captcha-refresh" class="auth-captcha-image" type="button" aria-label="刷新验证码" title="刷新验证码">
|
|
@@ -55,6 +56,10 @@
|
|
|
55
56
|
</form>
|
|
56
57
|
<p id="auth-error" class="auth-error" role="alert"></p>
|
|
57
58
|
</div>
|
|
59
|
+
<footer class="product-footer auth-product-footer" data-product-footer aria-label="叙界项目信息">
|
|
60
|
+
<span class="product-footer-meta"><span>© <time data-product-footer-year></time> <a href="https://github.com/musnows" target="_blank" rel="noopener noreferrer">musnows</a></span><span aria-hidden="true">·</span><span>叙界 <span data-product-footer-version>v—</span></span><span aria-hidden="true">·</span><a href="https://github.com/musnows/Scriverse" target="_blank" rel="noopener noreferrer" aria-label="在 GitHub 查看叙界仓库">GitHub</a></span>
|
|
61
|
+
<span class="product-footer-development hidden" data-product-footer-development>开发模式</span>
|
|
62
|
+
</footer>
|
|
58
63
|
</section>
|
|
59
64
|
<div id="app" class="app-shell">
|
|
60
65
|
<header class="topbar">
|
|
@@ -68,9 +73,16 @@
|
|
|
68
73
|
<div id="work-meta" class="work-meta">尚未选择作品</div>
|
|
69
74
|
<div class="top-actions">
|
|
70
75
|
<span id="save-state" class="save-state">就绪</span>
|
|
76
|
+
<div id="presence-control" class="presence-control hidden">
|
|
77
|
+
<button id="presence-button" class="presence-button" type="button" aria-expanded="false" aria-controls="presence-panel"><span class="presence-status-dot" aria-hidden="true"></span><span id="presence-count">1 人在线</span></button>
|
|
78
|
+
<section id="presence-panel" class="presence-panel hidden" aria-label="当前作品在线协作者">
|
|
79
|
+
<header><strong>正在访问这部作品</strong><small>离开后状态会自动过期</small></header>
|
|
80
|
+
<div id="presence-list" class="presence-list" aria-live="polite"></div>
|
|
81
|
+
</section>
|
|
82
|
+
</div>
|
|
71
83
|
<button id="account-button" class="account-button" type="button" aria-haspopup="menu" aria-expanded="false"><span id="account-avatar" class="user-avatar account-avatar" aria-hidden="true"><span class="user-avatar-fallback">作</span></span><span id="account-name">账户</span></button>
|
|
72
84
|
<div id="account-menu" class="account-menu hidden" role="menu">
|
|
73
|
-
<strong id="account-menu-name">账户</strong><small id="account-menu-role">普通用户</small>
|
|
85
|
+
<strong id="account-menu-name" class="account-menu-name"><span id="account-menu-display-name">账户</span><span id="account-menu-username" class="account-menu-username">@account</span></strong><small id="account-menu-role">普通用户</small>
|
|
74
86
|
<button id="onboarding-menu-button" type="button" role="menuitem">功能导览</button>
|
|
75
87
|
<button id="account-settings-button" type="button" role="menuitem">账户设置</button>
|
|
76
88
|
<button id="logout-button" type="button" role="menuitem">退出登录</button>
|
|
@@ -108,7 +120,7 @@
|
|
|
108
120
|
<button type="button" data-module="organizations"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>组织</button>
|
|
109
121
|
<button type="button" data-module="timeline"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>时间轴</button>
|
|
110
122
|
<button type="button" data-module="relationships"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="m8.59 13.51 6.83 3.98"/><path d="m15.41 6.51-6.82 3.98"/></svg>关系</button>
|
|
111
|
-
<button type="button" data-module="outlines"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/></svg><span class="nav-label"
|
|
123
|
+
<button type="button" data-module="outlines"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/></svg><span class="nav-label">大纲/伏笔</span></button>
|
|
112
124
|
<button class="ai-analysis-entry" type="button" data-module="tasks"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/><path d="M20 3v4"/><path d="M22 5h-4"/><path d="M4 17v2"/><path d="M5 18H3"/></svg>AI 分析</button>
|
|
113
125
|
<button id="module-more-button" type="button" aria-expanded="false"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg><span class="nav-label">更多</span></button>
|
|
114
126
|
<button class="module-nav-secondary hidden" type="button" data-module="races"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="4" r="2"/><circle cx="18" cy="8" r="2"/><circle cx="20" cy="16" r="2"/><path d="M9 10a5 5 0 0 1 5 5v3.5a3.5 3.5 0 0 1-6.84 1.045Q6.52 17.48 4.46 16.84A3.5 3.5 0 0 1 5.5 10Z"/></svg>种族</button>
|
|
@@ -133,6 +145,10 @@
|
|
|
133
145
|
<button id="shelf-new-work" class="primary-button" type="button">新建作品</button>
|
|
134
146
|
</div>
|
|
135
147
|
<div id="book-shelf" class="book-shelf" data-testid="book-shelf"></div>
|
|
148
|
+
<footer class="product-footer" data-product-footer aria-label="叙界项目信息">
|
|
149
|
+
<span class="product-footer-meta"><span>© <time data-product-footer-year></time> <a href="https://github.com/musnows" target="_blank" rel="noopener noreferrer">musnows</a></span><span aria-hidden="true">·</span><span>叙界 <span data-product-footer-version>v—</span></span><span aria-hidden="true">·</span><a href="https://github.com/musnows/Scriverse" target="_blank" rel="noopener noreferrer" aria-label="在 GitHub 查看叙界仓库">GitHub</a></span>
|
|
150
|
+
<span class="product-footer-development hidden" data-product-footer-development>开发模式</span>
|
|
151
|
+
</footer>
|
|
136
152
|
</section>
|
|
137
153
|
|
|
138
154
|
<section id="platform-ai-view" class="shelf-view hidden" aria-labelledby="platform-ai-title">
|
|
@@ -157,6 +173,10 @@
|
|
|
157
173
|
<button id="export-button" class="settings-hub-card" type="button" data-settings-action="export"><span class="settings-card-mark">MD</span><strong>导出作品</strong><small>将当前作品安全导出为 Markdown</small></button>
|
|
158
174
|
</div>
|
|
159
175
|
<p id="settings-work-note" class="settings-work-note"></p>
|
|
176
|
+
<footer class="product-footer settings-product-footer" data-product-footer aria-label="叙界项目信息">
|
|
177
|
+
<span class="product-footer-meta"><span>© <time data-product-footer-year></time> <a href="https://github.com/musnows" target="_blank" rel="noopener noreferrer">musnows</a></span><span aria-hidden="true">·</span><span>叙界 <span data-product-footer-version>v—</span></span><span aria-hidden="true">·</span><a href="https://github.com/musnows/Scriverse" target="_blank" rel="noopener noreferrer" aria-label="在 GitHub 查看叙界仓库">GitHub</a></span>
|
|
178
|
+
<span class="product-footer-development hidden" data-product-footer-development>开发模式</span>
|
|
179
|
+
</footer>
|
|
160
180
|
</section>
|
|
161
181
|
|
|
162
182
|
<section id="welcome-view" class="welcome-view hidden">
|
|
@@ -308,7 +328,7 @@
|
|
|
308
328
|
<dialog id="form-dialog" class="dialog">
|
|
309
329
|
<form id="dynamic-form" method="dialog">
|
|
310
330
|
<div class="dialog-header">
|
|
311
|
-
<div><span id="dialog-eyebrow" class="eyebrow">新增</span><h2 id="dialog-title">创建记录</h2></div>
|
|
331
|
+
<div><span id="dialog-eyebrow" class="eyebrow">新增</span><h2 id="dialog-title">创建记录</h2><p id="dialog-meta" class="dialog-header-meta hidden"></p></div>
|
|
312
332
|
<button class="dialog-close" value="cancel" aria-label="关闭" type="submit">×</button>
|
|
313
333
|
</div>
|
|
314
334
|
<div id="dialog-fields" class="dialog-fields"></div>
|
|
@@ -352,23 +372,25 @@
|
|
|
352
372
|
<header class="entity-editor-header setting-editor-header">
|
|
353
373
|
<button id="setting-editor-back" class="entity-editor-back" type="button">返回设定库</button>
|
|
354
374
|
<div class="entity-editor-heading">
|
|
355
|
-
<span id="setting-editor-eyebrow" class="eyebrow"
|
|
375
|
+
<span id="setting-editor-eyebrow" class="eyebrow">新建设定</span>
|
|
356
376
|
<input id="setting-editor-name" class="setting-editor-title-input" name="title" maxlength="200" placeholder="新建设定" aria-label="设定标题">
|
|
357
377
|
<div class="setting-editor-header-fields">
|
|
358
378
|
<label>分类<select id="setting-editor-category" name="category">
|
|
359
379
|
<option value="世界规则">世界规则</option><option value="历史与年代">历史与年代</option><option value="地点与地图">地点与地图</option><option value="组织与阵营">组织与阵营</option><option value="物种与族群">物种与族群</option><option value="科技与物品">科技与物品</option><option value="术语与称谓">术语与称谓</option><option value="创作约束">创作约束</option>
|
|
360
380
|
</select></label>
|
|
361
381
|
<label class="setting-editor-lock"><input id="setting-editor-locked" name="locked" type="checkbox"><span><b>锁定为 AI 硬约束</b><small>锁定后,AI 续写与校对不能擅自覆盖这条设定。</small></span></label>
|
|
362
|
-
<label id="setting-change-note-field" class="setting-editor-change-note">版本说明<input id="setting-change-note" name="changeNote" maxlength="500" placeholder="可选,例如:补充纪元历法限制"></label>
|
|
363
382
|
</div>
|
|
364
383
|
</div>
|
|
365
|
-
<
|
|
384
|
+
<div class="entity-editor-mode-actions">
|
|
385
|
+
<button id="setting-editor-edit" class="ghost-button hidden" type="button">编辑设定</button>
|
|
386
|
+
<button id="setting-editor-confirm" class="ghost-button hidden" type="button">确认候选</button>
|
|
387
|
+
<button id="setting-editor-deprecate" class="ghost-button hidden" type="button">弃用</button>
|
|
388
|
+
<button id="setting-editor-history" class="ghost-button hidden" type="button">版本历史</button>
|
|
389
|
+
<button id="setting-editor-delete" class="danger-button hidden" type="button">删除设定</button>
|
|
390
|
+
<button id="setting-editor-submit" class="primary-button" type="submit">保存设定</button>
|
|
391
|
+
</div>
|
|
366
392
|
</header>
|
|
367
393
|
<div class="setting-editor-workspace">
|
|
368
|
-
<section id="setting-editor-management" class="entity-editor-management hidden" aria-label="设定档案操作">
|
|
369
|
-
<div><strong>档案操作</strong><small>版本历史和高风险操作集中在编辑面板内。</small></div>
|
|
370
|
-
<div class="entity-editor-management-actions"><button id="setting-editor-confirm" class="ghost-button hidden" type="button">确认候选</button><button id="setting-editor-deprecate" class="ghost-button hidden" type="button">弃用</button><button id="setting-editor-history" class="ghost-button" type="button">版本历史</button><button id="setting-editor-delete" class="danger-button" type="button">删除设定</button></div>
|
|
371
|
-
</section>
|
|
372
394
|
<main class="setting-editor-content">
|
|
373
395
|
<div class="setting-markdown-field" data-vditor-editor-field>
|
|
374
396
|
<div id="setting-editor-markdown" class="vditor-editor-host" data-vditor-editor aria-label="Markdown 编辑器"></div>
|
|
@@ -386,6 +408,7 @@
|
|
|
386
408
|
<div class="character-editor-title-row"><h1 id="character-editor-title">新建角色</h1><span id="character-editor-version" class="character-version-badge">新档案</span></div>
|
|
387
409
|
</div>
|
|
388
410
|
<div class="character-editor-header-actions">
|
|
411
|
+
<button id="character-editor-edit" class="primary-button hidden" type="button">编辑角色</button>
|
|
389
412
|
<button id="character-history-button" class="ghost-button" type="button" aria-controls="character-history-panel" aria-expanded="false">版本历史</button>
|
|
390
413
|
<button id="character-merge-button" class="ghost-button hidden" type="button">合并角色</button>
|
|
391
414
|
<button id="character-delete-button" class="danger-button hidden" type="button">删除角色</button>
|
|
@@ -420,6 +443,7 @@
|
|
|
420
443
|
</div>
|
|
421
444
|
<div class="character-editor-header-actions">
|
|
422
445
|
<span id="knowledge-editor-header-note" class="knowledge-editor-header-note">独立资料页</span>
|
|
446
|
+
<button id="knowledge-editor-edit" class="primary-button hidden" type="button">编辑档案</button>
|
|
423
447
|
<button id="knowledge-editor-history" class="ghost-button hidden" type="button">版本历史</button>
|
|
424
448
|
<button id="knowledge-editor-merge" class="ghost-button hidden" type="button">合并档案</button>
|
|
425
449
|
<button id="knowledge-editor-delete" class="danger-button hidden" type="button">删除档案</button>
|
|
@@ -670,6 +694,6 @@
|
|
|
670
694
|
<div id="auth-loading" class="auth-loading" role="status" aria-label="正在载入工作台"></div>
|
|
671
695
|
<script id="vditorIconScript" src="/vendor/vditor/dist/js/icons/ant.js?v=3.11.2"></script>
|
|
672
696
|
<script src="/vendor/vditor/dist/index.min.js?v=3.11.2"></script>
|
|
673
|
-
<script type="module" src="/app.js?v=
|
|
697
|
+
<script type="module" src="/app.js?v=20260725-ui-collaboration"></script>
|
|
674
698
|
</body>
|
|
675
699
|
</html>
|
|
@@ -47,6 +47,7 @@ export function serializePageRoute(route = {}) {
|
|
|
47
47
|
params.set("work", workId);
|
|
48
48
|
params.set("entity", route.entity);
|
|
49
49
|
if (route.entityId) params.set("id", String(route.entityId));
|
|
50
|
+
if (route.entityMode === "read") params.set("mode", "read");
|
|
50
51
|
} else if (view === "welcome" && workId) {
|
|
51
52
|
params.set("view", "welcome");
|
|
52
53
|
params.set("work", workId);
|
|
@@ -80,7 +81,8 @@ export function parsePageRoute(hash = "") {
|
|
|
80
81
|
const entity = value(params, "entity");
|
|
81
82
|
if (!entityEditorSet.has(entity)) return { view: "shelf" };
|
|
82
83
|
const entityId = value(params, "id");
|
|
83
|
-
|
|
84
|
+
const entityMode = value(params, "mode") === "read" ? "read" : "edit";
|
|
85
|
+
return { view, workId, entity, entityId: entityId || null, entityMode };
|
|
84
86
|
}
|
|
85
87
|
if (view === "welcome" && workId) return { view, workId };
|
|
86
88
|
if (view === "settings" || view === "platform-ai") {
|
package/dist/public/styles.css
CHANGED
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
.pending-shelf-mode .auth-pending .topbar { grid-template-columns: 280px 1fr auto; }
|
|
85
85
|
.pending-shelf-mode .auth-pending .left-panel, .pending-shelf-mode .auth-pending .ai-panel { display: none; }
|
|
86
86
|
.pending-shelf-mode .auth-pending .main-panel { grid-column: 1 / -1; }
|
|
87
|
-
.auth-view { position: fixed; inset: 0; z-index: 1000; display: grid;
|
|
87
|
+
.auth-view { position: fixed; inset: 0; z-index: 1000; display: grid; grid-template-rows: minmax(min-content, 1fr) auto; gap: 18px; place-items: center; padding: 24px; overflow-y: auto; overscroll-behavior: contain; background: radial-gradient(circle at 18% 16%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 34%), var(--paper); }
|
|
88
88
|
.auth-view.hidden { display: none; }
|
|
89
|
-
.auth-card { box-sizing: border-box; width: min(440px, 100%); padding: 34px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); box-shadow: var(--shadow); }
|
|
89
|
+
.auth-card { align-self: center; box-sizing: border-box; width: min(440px, 100%); padding: 34px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); box-shadow: var(--shadow); }
|
|
90
90
|
.auth-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 34px; }
|
|
91
91
|
.auth-brand div { display: grid; }
|
|
92
92
|
.auth-brand small { color: var(--muted); }
|
|
@@ -218,6 +218,7 @@
|
|
|
218
218
|
.auth-captcha-image img[hidden], .auth-captcha-placeholder[hidden] { display: none; }
|
|
219
219
|
.auth-captcha-placeholder { color: var(--muted); font-size: 13px; padding: 0 14px; white-space: nowrap; }
|
|
220
220
|
.auth-captcha-hint { margin: -8px 0 0; color: var(--muted); font-size: 12px; line-height: 1.4; }
|
|
221
|
+
.auth-security-hint { margin: -8px 0 0; color: var(--muted); font-size: 12px; line-height: 1.5; }
|
|
221
222
|
.auth-error { min-height: 20px; margin: 14px 0 0 !important; color: var(--accent-dark) !important; }
|
|
222
223
|
|
|
223
224
|
:root[data-theme="dark"] {
|
|
@@ -284,6 +285,45 @@ html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; }
|
|
|
284
285
|
button, input, textarea, select { font: inherit; color: inherit; }
|
|
285
286
|
button { cursor: pointer; }
|
|
286
287
|
|
|
288
|
+
input[type="checkbox"] {
|
|
289
|
+
appearance: none;
|
|
290
|
+
-webkit-appearance: none;
|
|
291
|
+
display: inline-grid;
|
|
292
|
+
flex: 0 0 16px;
|
|
293
|
+
place-content: center;
|
|
294
|
+
width: 16px;
|
|
295
|
+
height: 16px;
|
|
296
|
+
min-width: 16px;
|
|
297
|
+
margin: 0;
|
|
298
|
+
border: 1px solid var(--line);
|
|
299
|
+
border-radius: 4px;
|
|
300
|
+
background: var(--surface);
|
|
301
|
+
cursor: pointer;
|
|
302
|
+
transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
input[type="checkbox"]::before {
|
|
306
|
+
content: "";
|
|
307
|
+
width: 8px;
|
|
308
|
+
height: 5px;
|
|
309
|
+
border: solid #fff;
|
|
310
|
+
border-width: 0 0 2px 2px;
|
|
311
|
+
transform: translateY(-1px) rotate(-45deg) scale(0);
|
|
312
|
+
transform-origin: center;
|
|
313
|
+
transition: transform .12s ease;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
input[type="checkbox"]:hover:not(:disabled) { border-color: var(--accent); }
|
|
317
|
+
input[type="checkbox"]:checked { border-color: var(--accent); background: var(--accent); }
|
|
318
|
+
input[type="checkbox"]:checked::before { transform: translateY(-1px) rotate(-45deg) scale(1); }
|
|
319
|
+
input[type="checkbox"]:focus-visible {
|
|
320
|
+
outline: none;
|
|
321
|
+
border-color: var(--accent);
|
|
322
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
|
|
323
|
+
}
|
|
324
|
+
input[type="checkbox"]:disabled { cursor: not-allowed; opacity: .48; }
|
|
325
|
+
input[type="checkbox"][hidden] { display: none; }
|
|
326
|
+
|
|
287
327
|
.app-shell {
|
|
288
328
|
display: grid;
|
|
289
329
|
grid-template-columns: var(--left-panel-width) minmax(480px, 1fr) var(--ai-panel-width);
|
|
@@ -311,7 +351,24 @@ button { cursor: pointer; }
|
|
|
311
351
|
.brand-block strong { font-size: 16px; letter-spacing: .16em; }
|
|
312
352
|
.brand-block small { color: var(--muted); font-size: 10px; margin-top: 2px; }
|
|
313
353
|
.work-meta { font-size: 13px; color: var(--muted); padding-left: 26px; }
|
|
314
|
-
.top-actions { display: flex; justify-content: flex-end; gap: 10px; align-items: center; padding-right: 18px; }
|
|
354
|
+
.top-actions { position: relative; display: flex; justify-content: flex-end; gap: 10px; align-items: center; padding-right: 18px; }
|
|
355
|
+
.presence-control { position: relative; }
|
|
356
|
+
.presence-button { display: flex; align-items: center; gap: 7px; min-height: 34px; padding: 0 11px; border: 1px solid var(--line); border-radius: 18px; background: transparent; color: var(--muted); font-size: 11px; }
|
|
357
|
+
.presence-button:hover, .presence-button:focus-visible, .presence-button[aria-expanded="true"] { border-color: var(--accent); background: var(--paper-deep); color: var(--accent-dark); outline: none; }
|
|
358
|
+
.presence-status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 16%, transparent); }
|
|
359
|
+
.presence-panel { position: absolute; top: calc(100% + 10px); right: 0; z-index: 12; width: min(340px, calc(100vw - 24px)); padding: 14px; border: 1px solid var(--line); border-radius: 6px; background: var(--paper); box-shadow: 0 14px 38px rgba(36, 30, 24, .16); }
|
|
360
|
+
.presence-panel > header { display: grid; gap: 3px; padding-bottom: 10px; border-bottom: 1px solid var(--line); }
|
|
361
|
+
.presence-panel > header strong { font-size: 12px; }
|
|
362
|
+
.presence-panel > header small { color: var(--muted); font-size: 10px; }
|
|
363
|
+
.presence-list { display: grid; gap: 5px; padding-top: 8px; }
|
|
364
|
+
.presence-person { display: grid; grid-template-columns: 30px minmax(0, 1fr) auto; align-items: center; gap: 9px; padding: 7px; border-radius: 4px; }
|
|
365
|
+
.presence-person.is-same-page { background: color-mix(in srgb, var(--accent) 8%, transparent); }
|
|
366
|
+
.presence-person .user-avatar { width: 30px; height: 30px; }
|
|
367
|
+
.presence-person-copy { min-width: 0; }
|
|
368
|
+
.presence-person-copy strong, .presence-person-copy small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
369
|
+
.presence-person-copy strong { font-size: 11px; }
|
|
370
|
+
.presence-person-copy small { margin-top: 3px; color: var(--muted); font-size: 10px; }
|
|
371
|
+
.presence-same-page { color: var(--accent-dark); font-size: 9px; white-space: nowrap; }
|
|
315
372
|
.theme-toggle, .settings-button, .topbar-icon-button {
|
|
316
373
|
display: grid;
|
|
317
374
|
flex: 0 0 34px;
|
|
@@ -357,8 +414,11 @@ button { cursor: pointer; }
|
|
|
357
414
|
.user-avatar-fallback { display: grid; width: 100%; height: 100%; place-items: center; }
|
|
358
415
|
.account-button > .account-avatar { width: 26px; height: 26px; font-size: 11px; }
|
|
359
416
|
.account-button > span:last-child { max-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; }
|
|
360
|
-
.account-menu { position: absolute; z-index: 80; top: 48px; right: 84px; display: grid; min-width:
|
|
417
|
+
.account-menu { position: absolute; z-index: 80; top: 48px; right: 84px; display: grid; width: 180px; min-width: 0; gap: 4px; padding: 12px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); box-shadow: var(--shadow); }
|
|
361
418
|
.account-menu.hidden { display: none; }
|
|
419
|
+
.account-menu-name { display: grid; min-width: 0; gap: 2px; }
|
|
420
|
+
.account-menu-name > span { overflow-wrap: anywhere; }
|
|
421
|
+
.account-menu-username { color: var(--muted); font-size: 10px; font-weight: 500; }
|
|
362
422
|
.account-menu small { margin-bottom: 8px; color: var(--muted); }
|
|
363
423
|
.account-menu button { min-height: 30px; padding: 6px 9px; border: 1px solid var(--line); border-radius: 4px; background: transparent; color: var(--muted); text-align: left; font-size: 10px; }
|
|
364
424
|
.account-menu button:hover, .account-menu button:focus-visible { border-color: var(--accent); background: var(--paper-deep); color: var(--accent-dark); outline: none; }
|
|
@@ -444,11 +504,13 @@ body.is-panel-resizing { cursor: col-resize; user-select: none; }
|
|
|
444
504
|
.app-shell.shelf-mode .save-state { display: none; }
|
|
445
505
|
.app-shell.shelf-mode .main-panel { grid-column: 1 / -1; }
|
|
446
506
|
|
|
447
|
-
.shelf-view { height: 100%; overflow-y: auto; padding: 48px clamp(32px, 7vw, 110px) 90px; }
|
|
448
|
-
|
|
507
|
+
.shelf-view { display: flex; flex-direction: column; height: 100%; overflow-y: auto; padding: 48px clamp(32px, 7vw, 110px) 90px; }
|
|
508
|
+
#shelf-view, #settings-hub-view { padding-bottom: 24px; }
|
|
509
|
+
.shelf-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 30px; width: 100%; max-width: 1400px; margin: 0 auto 38px; }
|
|
449
510
|
.shelf-header h1 { margin: 0 0 10px; font-size: clamp(30px, 4vw, 52px); font-weight: 560; letter-spacing: -.04em; }
|
|
450
511
|
.shelf-header p { margin: 0; color: var(--muted); }
|
|
451
512
|
.settings-hub-header { align-items: center; }
|
|
513
|
+
.settings-hub-header h1 { font-size: clamp(26px, 3vw, 36px); line-height: 1.15; letter-spacing: -.02em; }
|
|
452
514
|
.settings-hub-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; max-width: 1000px; margin: 0 auto; }
|
|
453
515
|
.settings-hub-card { display: grid; grid-template-columns: 48px minmax(0, 1fr); grid-template-rows: auto auto; gap: 4px 14px; align-items: center; min-height: 128px; padding: 22px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface-soft); text-align: left; }
|
|
454
516
|
.settings-hub-card:hover, .settings-hub-card:focus-visible { border-color: var(--accent); background: var(--paper-deep); box-shadow: var(--shadow); transform: translateY(-2px); }
|
|
@@ -457,6 +519,13 @@ body.is-panel-resizing { cursor: col-resize; user-select: none; }
|
|
|
457
519
|
.settings-hub-card strong { align-self: end; font-size: 16px; }
|
|
458
520
|
.settings-hub-card small { align-self: start; color: var(--muted); font-size: 10px; line-height: 1.5; }
|
|
459
521
|
.settings-work-note { max-width: 1000px; margin: 18px auto 0; color: var(--muted); font-size: 11px; }
|
|
522
|
+
.product-footer { display: flex; flex: 0 0 auto; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px 12px; width: 100%; max-width: 1400px; margin: auto auto 0; padding-top: 20px; border-top: 1px solid color-mix(in srgb, var(--line) 76%, transparent); color: var(--muted); font-size: 10px; line-height: 1.5; }
|
|
523
|
+
.product-footer-meta { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
|
|
524
|
+
.product-footer a { color: inherit; text-decoration: none; text-underline-offset: 3px; transition: color .14s ease; }
|
|
525
|
+
.product-footer a:hover, .product-footer a:focus-visible { color: var(--accent-dark); text-decoration: underline; }
|
|
526
|
+
.product-footer-development { padding: 2px 8px; border: 1px solid color-mix(in srgb, var(--accent) 48%, var(--line)); border-radius: 999px; background: color-mix(in srgb, var(--accent) 10%, transparent); color: var(--accent-dark); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 9px; font-weight: 700; letter-spacing: .05em; }
|
|
527
|
+
.auth-product-footer { align-self: end; max-width: 440px; margin: 0; padding-top: 14px; }
|
|
528
|
+
.settings-product-footer { max-width: 1000px; }
|
|
460
529
|
.access-dialog-body { display: grid; gap: 16px; max-height: calc(88vh - 82px); overflow-y: auto; padding: 18px 24px 22px; }
|
|
461
530
|
.access-list { display: grid; gap: 8px; max-height: min(34vh, 340px); overflow: auto; padding: 0; }
|
|
462
531
|
.access-row {
|
|
@@ -685,7 +754,7 @@ body.work-viewer-mode .character-editor-actions { display: none !important; }
|
|
|
685
754
|
.api-key-result input { width: 100%; min-height: 38px; padding: 9px 10px; background: var(--surface); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11px; }
|
|
686
755
|
.api-key-result button { min-height: 38px; }
|
|
687
756
|
.book-access-badge { display: inline-flex; width: fit-content; margin-top: 7px; padding: 2px 7px; border-radius: 10px; background: var(--paper-deep); color: var(--accent-dark); font-size: 9px; }
|
|
688
|
-
.book-shelf { display: grid; grid-template-columns: repeat(auto-fill, minmax(205px, 1fr)); gap: clamp(22px, 3vw, 38px); max-width: 1400px; margin: 0 auto; }
|
|
757
|
+
.book-shelf { display: grid; grid-template-columns: repeat(auto-fill, minmax(205px, 1fr)); gap: clamp(22px, 3vw, 38px); width: 100%; min-width: 0; max-width: 1400px; margin: 0 auto; }
|
|
689
758
|
.book-card { position: relative; min-width: 0; border: 0; background: transparent; text-align: left; }
|
|
690
759
|
.book-open { width: 100%; padding: 0; border: 0; background: transparent; text-align: left; }
|
|
691
760
|
.book-cover { position: relative; display: grid; place-items: center; aspect-ratio: 3 / 4.25; overflow: hidden; border-radius: 8px 13px 13px 8px; background: linear-gradient(145deg, #a96350, #612d27); color: rgba(255,255,255,.9); box-shadow: 0 20px 34px rgba(62,39,29,.18), inset 9px 0 0 rgba(0,0,0,.08); transition: transform .2s ease, box-shadow .2s ease; }
|
|
@@ -883,9 +952,11 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
883
952
|
.record-card p { color: var(--muted); font-size: 12px; line-height: 1.55; margin: 0; white-space: pre-wrap; }
|
|
884
953
|
.record-card small { color: var(--accent); font-size: 9px; letter-spacing: .1em; text-transform: uppercase; }
|
|
885
954
|
.settings-layout-toolbar, .module-layout-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-bottom: 0; }
|
|
886
|
-
.settings-layout-hint
|
|
955
|
+
.settings-layout-hint { color: var(--muted); font-size: 10px; }
|
|
887
956
|
.settings-layout-toggle, .module-layout-toggle { display: inline-flex; border: 1px solid var(--line); border-radius: 4px; overflow: hidden; background: var(--surface); }
|
|
888
|
-
.settings-layout-toggle button
|
|
957
|
+
.settings-layout-toggle button { min-height: 34px; padding: 0 12px; border: 0; border-right: 1px solid var(--line); background: transparent; color: var(--muted); font-size: 11px; }
|
|
958
|
+
.module-layout-toggle button { display: inline-grid; place-items: center; width: 36px; min-height: 34px; padding: 0; border: 0; border-right: 1px solid var(--line); background: transparent; color: var(--muted); }
|
|
959
|
+
.module-layout-toggle svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.7; }
|
|
889
960
|
.settings-layout-toggle button:last-child, .module-layout-toggle button:last-child { border-right: 0; }
|
|
890
961
|
.settings-layout-toggle button:hover, .settings-layout-toggle button:focus-visible,
|
|
891
962
|
.module-layout-toggle button:hover, .module-layout-toggle button:focus-visible { color: var(--ink); background: var(--paper-deep); }
|
|
@@ -895,7 +966,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
895
966
|
.setting-row, .module-row { display: grid; grid-template-columns: minmax(108px, .2fr) minmax(120px, .24fr) minmax(0, 1fr) auto; gap: 10px 16px; align-items: center; min-height: 0; padding: 12px 16px; }
|
|
896
967
|
.setting-row h3, .module-row h3 { margin: 0; font-size: 14px; line-height: 1.35; }
|
|
897
968
|
.setting-row p, .module-row p, .module-row-preview { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
898
|
-
.module-row-preview { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.45; }
|
|
969
|
+
.module-row .module-row-preview { display: -webkit-box; max-height: 2.9em; margin: 0; overflow: hidden; color: var(--muted); font-size: 12px; line-height: 1.45; white-space: normal; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
|
|
899
970
|
.module-row-path { display: block; margin-top: 2px; color: var(--accent); font-family: var(--font-latin), monospace; font-size: 11px; font-weight: 500; }
|
|
900
971
|
.module-row-span { grid-column: 1 / -1; }
|
|
901
972
|
.setting-row .card-actions, .module-row .card-actions { margin-top: 0; flex-wrap: wrap; justify-content: flex-end; }
|
|
@@ -916,6 +987,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
916
987
|
.character-duplicate-actions { flex-wrap: wrap; }
|
|
917
988
|
.card-actions { display: flex; gap: 6px; margin-top: 15px; }
|
|
918
989
|
.card-actions button { border: 1px solid var(--line); background: transparent; border-radius: 3px; font-size: 10px; padding: 5px 8px; }
|
|
990
|
+
.card-actions .record-card-edit { padding: 0; }
|
|
919
991
|
.danger-button { border: 1px solid color-mix(in srgb, var(--accent) 52%, var(--line)); border-radius: 4px; background: transparent; color: var(--accent-dark); padding: 8px 13px; font-size: 12px; }
|
|
920
992
|
.danger-button:hover, .danger-button:focus-visible { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, transparent); outline: none; }
|
|
921
993
|
.card-actions .danger-button { border-color: color-mix(in srgb, var(--accent) 52%, var(--line)); color: var(--accent-dark); }
|
|
@@ -945,14 +1017,14 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
945
1017
|
.race-settings .pill { display: inline-flex; align-items: center; gap: 5px; }
|
|
946
1018
|
.race-settings .pill small { color: inherit; font-size: 8px; letter-spacing: 0; text-transform: none; opacity: .72; }
|
|
947
1019
|
.race-settings .pill.inherited { border-style: dashed; }
|
|
948
|
-
.entity-dialog-management
|
|
949
|
-
.entity-dialog-management > div:first-child
|
|
950
|
-
.entity-dialog-management strong
|
|
951
|
-
.entity-dialog-management small
|
|
952
|
-
.entity-dialog-management-actions
|
|
953
|
-
.entity-dialog-management-actions button
|
|
1020
|
+
.entity-dialog-management { display: grid; gap: 10px; padding: 14px; border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--line)); border-radius: 5px; background: color-mix(in srgb, var(--accent) 4%, var(--surface)); }
|
|
1021
|
+
.entity-dialog-management > div:first-child { display: grid; gap: 4px; }
|
|
1022
|
+
.entity-dialog-management strong { color: var(--ink); font-size: 11px; }
|
|
1023
|
+
.entity-dialog-management small { color: var(--muted); font-size: 10px; line-height: 1.5; }
|
|
1024
|
+
.entity-dialog-management-actions { display: flex; flex-wrap: wrap; gap: 7px; }
|
|
1025
|
+
.entity-dialog-management-actions button { min-height: 32px; }
|
|
954
1026
|
.danger-confirm-field { display: grid !important; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: 9px !important; padding: 12px; border: 1px solid color-mix(in srgb, var(--accent) 42%, var(--line)); border-radius: 5px; background: color-mix(in srgb, var(--accent) 5%, var(--surface)); }
|
|
955
|
-
.danger-confirm-field input { width:
|
|
1027
|
+
.danger-confirm-field input { width: 16px !important; margin-top: 3px; }
|
|
956
1028
|
.danger-confirm-field span { display: grid; gap: 4px; }
|
|
957
1029
|
.danger-confirm-field strong { color: var(--ink); font-size: 11px; }
|
|
958
1030
|
.danger-confirm-field small { color: var(--muted); font-size: 10px; line-height: 1.5; }
|
|
@@ -1014,7 +1086,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1014
1086
|
.config-section-header p { margin: 0; color: var(--muted); font-size: 11px; }
|
|
1015
1087
|
.ai-agent-tools { display: grid; gap: 8px; }
|
|
1016
1088
|
.ai-agent-tools label { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 8px; align-items: start; color: var(--muted); font-size: 11px; line-height: 1.45; }
|
|
1017
|
-
.ai-agent-tools input { width:
|
|
1089
|
+
.ai-agent-tools input { width: 16px; margin-top: 2px; }
|
|
1018
1090
|
.ai-agent-tools strong { color: var(--ink); font-size: 12px; font-weight: 600; }
|
|
1019
1091
|
.ai-agent-tools small { display: block; margin-top: 2px; font-size: 10px; }
|
|
1020
1092
|
.default-model-select { min-width: 260px; padding: 7px 9px; font-size: 11px; }
|
|
@@ -1491,6 +1563,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1491
1563
|
}
|
|
1492
1564
|
.toast-confirmation strong { font-size: 12px; }
|
|
1493
1565
|
.toast-confirmation p { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.55; white-space: pre-line; }
|
|
1566
|
+
.toast-input { width: 100%; min-height: 34px; padding: 7px 9px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); color: var(--ink); font-size: 11px; }
|
|
1494
1567
|
.toast-confirmation-actions { display: flex; justify-content: flex-end; gap: 7px; margin-top: 3px; }
|
|
1495
1568
|
.toast-confirmation-actions button { min-height: 30px; padding: 6px 10px; }
|
|
1496
1569
|
.chapter-type-menu { position: fixed; z-index: 80; width: 176px; padding: 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); box-shadow: 0 14px 38px rgba(49,42,32,.22); }
|
|
@@ -1509,6 +1582,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1509
1582
|
.dialog::backdrop { background: rgba(34,30,25,.42); backdrop-filter: blur(3px); }
|
|
1510
1583
|
.dialog-header { display: flex; justify-content: space-between; align-items: flex-start; padding: 22px 24px 16px; border-bottom: 1px solid var(--line); }
|
|
1511
1584
|
.dialog-header h2 { margin: 0; font-size: 23px; font-weight: 500; }
|
|
1585
|
+
.dialog-header-meta { margin: 7px 0 0; color: var(--muted); font-size: 10px; line-height: 1.5; }
|
|
1512
1586
|
.dialog-close {
|
|
1513
1587
|
display: grid;
|
|
1514
1588
|
place-items: center;
|
|
@@ -1573,12 +1647,12 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1573
1647
|
.character-section-count { display: block; margin-top: 8px; color: var(--accent-dark); }
|
|
1574
1648
|
.chip-picker { display: flex; flex-wrap: wrap; gap: 7px; max-height: 190px; overflow-y: auto; padding: 9px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface-soft); }
|
|
1575
1649
|
.dialog-fields .member-chip { position: relative; display: inline-flex !important; width: auto; cursor: pointer; }
|
|
1576
|
-
.member-chip input { position: absolute; width: 1px !important; height: 1px; opacity: 0; }
|
|
1650
|
+
.member-chip input { position: absolute; width: 1px !important; min-width: 1px; height: 1px; opacity: 0; }
|
|
1577
1651
|
.member-chip span { display: inline-flex; align-items: center; min-height: 30px; padding: 5px 10px; border: 1px solid var(--line); border-radius: 16px; background: var(--panel); color: var(--muted); font-size: 10px; transition: background .14s ease, border-color .14s ease, color .14s ease; }
|
|
1578
1652
|
.member-chip input:checked + span { border-color: var(--accent); background: var(--accent); color: #fff; }
|
|
1579
1653
|
.member-chip input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
1580
1654
|
.checkbox-field { display: flex !important; align-items: center; grid-template-columns: 18px 1fr; }
|
|
1581
|
-
.checkbox-field input { width:
|
|
1655
|
+
.checkbox-field input { width: 16px; }
|
|
1582
1656
|
.dialog-actions { display: flex; justify-content: flex-end; gap: 8px; padding: 14px 24px 20px; }
|
|
1583
1657
|
.dialog-actions .reset-button { margin-right: auto; }
|
|
1584
1658
|
.import-mode-dialog { width: min(560px, calc(100vw - 32px)); }
|
|
@@ -1605,6 +1679,14 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1605
1679
|
.import-mode-dialog .dialog-actions { flex-wrap: wrap; }
|
|
1606
1680
|
}
|
|
1607
1681
|
.entity-editor-open { overflow: hidden; }
|
|
1682
|
+
.preview-record-card { cursor: pointer; }
|
|
1683
|
+
.preview-record-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
1684
|
+
.entity-editor-mode-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
|
|
1685
|
+
.entity-editor-mode-actions button { min-height: 36px; }
|
|
1686
|
+
.module-pagination { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px 0 4px; }
|
|
1687
|
+
.module-pagination span { color: var(--muted); font-size: 10px; }
|
|
1688
|
+
.module-pagination button { min-width: 58px; min-height: 28px; padding: 5px 9px; border: 1px solid var(--line); border-radius: 4px; background: transparent; color: var(--muted); font-size: 10px; }
|
|
1689
|
+
.module-pagination button:disabled { cursor: default; opacity: .46; }
|
|
1608
1690
|
.entity-editor-view { position: fixed; z-index: 700; inset: 0; overflow: hidden; background: var(--panel); color: var(--ink); }
|
|
1609
1691
|
.entity-editor-view.hidden, .entity-editor-page.hidden { display: none; }
|
|
1610
1692
|
.entity-editor-page { width: 100%; height: 100%; min-height: 0; }
|
|
@@ -1625,16 +1707,16 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1625
1707
|
.setting-editor-title-input:focus { border-color: var(--accent); box-shadow: none; }
|
|
1626
1708
|
.setting-editor-header-fields { display: flex; align-items: center; justify-content: center; gap: 14px; min-width: 0; }
|
|
1627
1709
|
.setting-editor-header-fields > label:not(.setting-editor-lock) { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: 10px; white-space: nowrap; }
|
|
1628
|
-
.setting-editor-header-fields select
|
|
1710
|
+
.setting-editor-header-fields select { min-width: 0; padding: 5px 8px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); color: var(--ink); font-size: 11px; }
|
|
1629
1711
|
.setting-editor-lock { display: inline-flex; grid-template-columns: none; align-items: center; gap: 6px; padding: 0; border: 0; background: transparent; white-space: nowrap; }
|
|
1630
|
-
.setting-editor-lock input { width:
|
|
1631
|
-
.setting-editor-lock span { display:
|
|
1632
|
-
.setting-editor-lock b { color: var(--ink); font-size: 10px; }
|
|
1712
|
+
.setting-editor-lock input { width: 16px; margin: 0; }
|
|
1713
|
+
.setting-editor-lock span { display: inline-flex; align-items: center; min-height: 16px; line-height: 16px; }
|
|
1714
|
+
.setting-editor-lock b { display: block; color: var(--ink); font-size: 10px; line-height: 16px; }
|
|
1633
1715
|
.setting-editor-lock small { display: none; }
|
|
1634
|
-
.setting-editor-
|
|
1635
|
-
.setting-editor-workspace { display: grid; grid-template-rows: auto minmax(0, 1fr); min-height: 0; overflow: hidden; }
|
|
1716
|
+
.setting-editor-workspace { display: grid; grid-template-rows: minmax(0, 1fr); min-height: 0; overflow: hidden; }
|
|
1636
1717
|
.setting-editor-content { height: 100%; min-height: 0; padding: 16px clamp(16px, 2vw, 32px) 24px; overflow: hidden; }
|
|
1637
1718
|
.setting-markdown-field { display: grid; grid-template-rows: minmax(0, 1fr); height: 100%; min-height: 0; }
|
|
1719
|
+
.entity-editor-page.is-read-only .vditor-ir pre.vditor-reset[contenteditable="false"], .entity-editor-page.is-read-only .vditor-wysiwyg pre.vditor-reset[contenteditable="false"], .entity-editor-page.is-read-only .vditor-sv[contenteditable="false"] { opacity: 1; cursor: default; }
|
|
1638
1720
|
.setting-markdown-heading, .markdown-editor-field-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; color: var(--ink); font-size: 14px; }
|
|
1639
1721
|
.setting-markdown-heading small, .markdown-editor-field-heading small { color: var(--muted); font-size: 10px; }
|
|
1640
1722
|
.markdown-editor-field { display: grid; gap: 10px; min-width: 0; }
|
|
@@ -1749,6 +1831,9 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1749
1831
|
.character-section-editor-header .entity-editor-back { grid-column: 1; grid-row: 1; z-index: 1; }
|
|
1750
1832
|
.character-section-editor-header h2 { margin: 3px 0 0; font-size: 22px; font-weight: 600; }
|
|
1751
1833
|
.character-markdown-editor { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 12px; min-height: 0; padding: 16px 22px 18px; overflow: hidden; background: var(--surface-soft); }
|
|
1834
|
+
.character-markdown-editor > .vditor-editor-host { width: 100%; max-width: 960px; justify-self: center; }
|
|
1835
|
+
.character-markdown-editor > .vditor-editor-host.vditor { border-color: color-mix(in srgb, var(--accent) 22%, var(--line)); box-shadow: 0 12px 34px color-mix(in srgb, var(--ink) 12%, transparent); transition: border-color .16s ease, box-shadow .16s ease; }
|
|
1836
|
+
.character-markdown-editor > .vditor-editor-host.vditor:focus-within { border-color: color-mix(in srgb, var(--accent) 62%, var(--line)); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 15%, transparent), 0 16px 42px color-mix(in srgb, var(--ink) 16%, transparent); }
|
|
1752
1837
|
.character-markdown-editor-meta { display: grid; grid-template-columns: minmax(140px, .55fr) minmax(220px, 1fr) minmax(280px, 1.45fr); gap: 12px; }
|
|
1753
1838
|
.character-markdown-editor label { display: grid; gap: 6px; color: var(--muted); font-size: 10px; }
|
|
1754
1839
|
.character-markdown-editor input, .character-markdown-editor select, .character-markdown-editor textarea { width: 100%; padding: 9px 10px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); color: var(--ink); font-size: 12px; }
|
|
@@ -6,7 +6,7 @@ export const WORK_PERMISSION_MODULES = Object.freeze([
|
|
|
6
6
|
{ id: "organizations", uiModule: "organizations", label: "组织" },
|
|
7
7
|
{ id: "timeline", uiModule: "timeline", label: "时间轴" },
|
|
8
8
|
{ id: "relationships", uiModule: "relationships", label: "关系" },
|
|
9
|
-
{ id: "outlines", uiModule: "outlines", label: "
|
|
9
|
+
{ id: "outlines", uiModule: "outlines", label: "大纲/伏笔" },
|
|
10
10
|
{ id: "reviews", uiModule: "reviews", label: "审核" },
|
|
11
11
|
{ id: "ai-chat", uiModule: null, label: "AI 对话" },
|
|
12
12
|
{ id: "ai-analysis", uiModule: "tasks", label: "AI 分析" },
|