Compare commits

...

2 Commits

Author SHA1 Message Date
ymy 405312b36b Merge branch 'chore/role-label-zh' 2026-07-27 15:57:42 +08:00
ymy be17f74fc2 chore(filelib-web): 文件库权限名称汉化(VIEW/EDIT/MANAGE → 只读/可编辑/可管理)
统一走新增共享常量 labels.ts ROLE_LABEL(与 OverviewPanel 既有文案一致);
覆盖授权表格与弹窗下拉、详情头 tag、树节点角标;API 传参仍用英文枚举。
2026-07-27 15:57:41 +08:00
5 changed files with 21 additions and 7 deletions
+5 -4
View File
@@ -15,6 +15,7 @@
*/
import { api } from "./api.js";
import { toastOk, toastErr } from "./stores.js";
import { ROLE_LABEL } from "./labels.js";
import type { Grant, MemberGroupSearchResult, NodeDetail, Role, UserSearchResult } from "./types.js";
import Icon from "./Icon.svelte";
import Modal from "./Modal.svelte";
@@ -199,7 +200,7 @@
}
async function revoke(g: Grant): Promise<void> {
if (!confirm(`删除「${g.principalName ?? g.principalId}」的 ${g.role} 授权?`)) return;
if (!confirm(`删除「${g.principalName ?? g.principalId}」的${ROLE_LABEL[g.role]}授权?`)) return;
try {
await api(`/database/api/nodes/${node.id}/grants/${encodeURIComponent(g.id)}`, {
method: "DELETE",
@@ -275,11 +276,11 @@
onchange={(e) => void changeRole(g, e.currentTarget.value as Role)}
>
{#each ROLES as r (r)}
<option value={r}>{r}</option>
<option value={r}>{ROLE_LABEL[r]}</option>
{/each}
</select>
{:else}
<span class="file-meta">{g.role}</span>
<span class="file-meta">{ROLE_LABEL[g.role]}</span>
{/if}
</td>
<td class="file-meta">{fmtDate(g.createdAt)}</td>
@@ -351,7 +352,7 @@
<label class="form-label" for="grant-role">权限</label>
<select id="grant-role" class="select" bind:value={role}>
{#each ROLES as r (r)}
<option value={r}>{r}</option>
<option value={r}>{ROLE_LABEL[r]}</option>
{/each}
</select>
</div>
@@ -2,6 +2,7 @@
import { api } from "./api.js";
import { currentNode, breadcrumb, bumpTree, clearSelectedFile } from "./browser.js";
import { toastOk, toastErr } from "./stores.js";
import { ROLE_LABEL } from "./labels.js";
import OverviewPanel from "./OverviewPanel.svelte";
import FilesPanel from "./FilesPanel.svelte";
import GrantsPanel from "./GrantsPanel.svelte";
@@ -99,7 +100,7 @@
<div class="flex items-center gap-2 text-[17px] font-semibold text-ink">
{node.name}
<span class="tag">{node.kind === "PROJECT" ? "项目" : "文件夹"}</span>
<span class="tag !border-line !text-ink-2">{node.role}</span>
<span class="tag !border-line !text-ink-2">{ROLE_LABEL[node.role]}</span>
</div>
<div class="flex gap-1.5">
{#if canEdit && node.kind === "FOLDER"}
+2 -1
View File
@@ -2,6 +2,7 @@
import { api } from "./api.js";
import { toastOk, toastErr } from "./stores.js";
import { currentNode } from "./browser.js";
import { ROLE_LABEL } from "./labels.js";
import type { ExportJob, NodeDetail } from "./types.js";
import Modal from "./Modal.svelte";
@@ -13,7 +14,7 @@
const canEdit = $derived(node.role === "MANAGE" || node.role === "EDIT");
const canManage = $derived(node.role === "MANAGE");
const roleLabel = $derived(node.role === "MANAGE" ? "可管理" : node.role === "EDIT" ? "可编辑" : "只读");
const roleLabel = $derived(ROLE_LABEL[node.role]);
/** 独立权限开关(仅 PROJECT;关闭时只继承父级权限,创建者除外)。 */
async function toggleIndependent(): Promise<void> {
+2 -1
View File
@@ -3,6 +3,7 @@
import { api } from "./api.js";
import { expanded, currentNode, breadcrumb, toggleExpanded, treeVersion } from "./browser.js";
import { toastErr } from "./stores.js";
import { ROLE_LABEL } from "./labels.js";
import type { BreadcrumbEntry, NodeChild, NodeDetail } from "./types.js";
let { node, depth }: { node: NodeChild; depth: number } = $props();
@@ -64,7 +65,7 @@
</span>
<span class="truncate">{node.name}</span>
{#if node.role !== "MANAGE"}
<span class="ml-auto pr-1 font-mono text-[10px] text-ink-3">{node.role}</span>
<span class="ml-auto pr-1 text-[10px] text-ink-3">{ROLE_LABEL[node.role]}</span>
{/if}
</div>
+10
View File
@@ -0,0 +1,10 @@
/** 展示层文案(与 API 枚举值解耦;传参仍用英文枚举)。 */
import type { Role } from "./types.js";
/** 文件库权限级(契约 8.1 MANAGE>EDIT>VIEW)的中文展示名。 */
export const ROLE_LABEL: Record<Role, string> = {
VIEW: "只读",
EDIT: "可编辑",
MANAGE: "可管理",
};