feat(ui): i18n for team info view; drop now-unused tab label constant

This commit is contained in:
吹雪 2026-06-11 02:57:20 +09:00
parent 4882456643
commit dc538a8a3b
5 changed files with 649 additions and 217 deletions

File diff suppressed because it is too large Load diff

View file

@ -4,21 +4,9 @@ import {
getTeamInfoVisibleTabs,
isTeamInfoTabVisible,
TEAM_INFO_TAB_KEYS,
TEAM_INFO_TAB_LABELS,
} from "./tabVisibilityUtils";
describe("team_info_tabs", () => {
describe("TEAM_INFO_TAB_LABELS", () => {
it("should have label for every tab key", () => {
expect(TEAM_INFO_TAB_LABELS[TEAM_INFO_TAB_KEYS.OVERVIEW]).toBe("Overview");
expect(TEAM_INFO_TAB_LABELS[TEAM_INFO_TAB_KEYS.MY_USER]).toBe("My User");
expect(TEAM_INFO_TAB_LABELS[TEAM_INFO_TAB_KEYS.VIRTUAL_KEYS]).toBe("Virtual Keys");
expect(TEAM_INFO_TAB_LABELS[TEAM_INFO_TAB_KEYS.MEMBERS]).toBe("Members");
expect(TEAM_INFO_TAB_LABELS[TEAM_INFO_TAB_KEYS.MEMBER_PERMISSIONS]).toBe("Member Permissions");
expect(TEAM_INFO_TAB_LABELS[TEAM_INFO_TAB_KEYS.SETTINGS]).toBe("Settings");
});
});
describe("getTeamInfoVisibleTabs", () => {
it("returns overview, my user, and virtual keys when user cannot edit team", () => {
const tabs = getTeamInfoVisibleTabs(false);

View file

@ -12,15 +12,6 @@ export const TEAM_INFO_TAB_KEYS = {
SETTINGS: "settings",
} as const;
export const TEAM_INFO_TAB_LABELS: Record<string, string> = {
[TEAM_INFO_TAB_KEYS.OVERVIEW]: "Overview",
[TEAM_INFO_TAB_KEYS.MY_USER]: "My User",
[TEAM_INFO_TAB_KEYS.VIRTUAL_KEYS]: "Virtual Keys",
[TEAM_INFO_TAB_KEYS.MEMBERS]: "Members",
[TEAM_INFO_TAB_KEYS.MEMBER_PERMISSIONS]: "Member Permissions",
[TEAM_INFO_TAB_KEYS.SETTINGS]: "Settings",
};
/**
* Returns the list of tab keys that should be visible based on permissions.
* - Overview, My User, Virtual Keys: always visible

View file

@ -6247,6 +6247,177 @@
"modelScopeLabel": "Model Scope",
"modelScopeTooltip": "Models you can access within this team.",
"allTeamModels": "All Team Models"
},
"teamInfo": {
"failedToLoadTeam": "Failed to load team information",
"memberAddedSuccess": "Team member added successfully",
"assignAdminsEnterprise": "Assigning admins is an enterprise-only feature. Please upgrade your LiteLLM plan to enable this.",
"failedToAddMember": "Failed to add team member",
"memberUpdatedSuccess": "Team member updated successfully",
"failedToUpdateMember": "Failed to update team member",
"memberRemovedSuccess": "Team member removed successfully",
"failedToRemoveMember": "Failed to remove team member",
"invalidMetadataJson": "Invalid JSON in metadata field",
"invalidSecretManagerJson": "Invalid JSON in secret manager settings",
"teamSettingsUpdatedSuccess": "Team settings updated successfully",
"teamNotFound": "Team not found",
"backToTeams": "Back to Teams",
"tabOverview": "Overview",
"tabMyUser": "My User",
"tabVirtualKeys": "Virtual Keys",
"tabMembers": "Members",
"tabMemberPermissions": "Member Permissions",
"tabSettings": "Settings",
"budgetStatus": "Budget Status",
"unlimited": "Unlimited",
"budgetOf": "of {{value}}",
"budgetReset": "Reset: {{duration}}",
"teamMemberBudget": "Team Member Budget: ${{amount}}",
"rateLimits": "Rate Limits",
"tpmLabel": "TPM: {{value}}",
"rpmLabel": "RPM: {{value}}",
"maxParallelRequests": "Max Parallel Requests: {{value}}",
"perModelLimits": "Per-model limits:",
"perModelEntry": "{{model}}: TPM {{tpm}}, RPM {{rpm}}",
"modelsLabel": "Models",
"allProxyModels": "All proxy models",
"fromAccessGroup": "From access group",
"virtualKeys": "Virtual Keys",
"userKeys": "User Keys: {{count}}",
"serviceAccountKeys": "Service Account Keys: {{count}}",
"totalKeys": "Total: {{count}}",
"loadingGuardrails": "Loading guardrails...",
"resolvedGuardrails": "Resolved Guardrails:",
"noPoliciesConfigured": "No policies configured",
"policiesLabel": "Policies",
"teamSettings": "Team Settings",
"editSettings": "Edit Settings",
"teamNameLabel": "Team Name",
"teamNameRequired": "Please input a team name",
"modelsRequired": "Please select at least one model",
"maxBudgetLabel": "Max Budget (USD)",
"softBudgetLabel": "Soft Budget (USD)",
"softBudgetEmailsLabel": "Soft Budget Alerting Emails",
"softBudgetEmailsTooltip": "Comma-separated email addresses to receive alerts when the soft budget is reached",
"softBudgetEmailsPlaceholder": "example1@test.com, example2@test.com",
"teamMemberSettings": "Team Member Settings",
"teamMemberSettingsDesc": "Optional defaults applied when members join this team. All fields can be overridden per member.",
"teamMemberSettingsTooltip": "These are limits on individual team members",
"defaultModelAccessLabel": "Default Model Access",
"defaultModelAccessTooltip": "Optional. If set, new members can only access these models by default. Must be a subset of the team's models above. Leave empty to give all members access to all team models.",
"defaultModelAccessPlaceholder": "Leave empty — all team models accessible to every member",
"defaultBudgetLabel": "Default Budget (USD)",
"defaultBudgetTooltip": "Default spend budget for each member in this team.",
"defaultBudgetDurationLabel": "Default Budget Duration",
"defaultKeyDurationLabel": "Default Key Duration (eg: 1d, 1mo)",
"defaultKeyDurationTooltip": "Set a limit to the duration of a team member's key. Format: 30s (seconds), 30m (minutes), 30h (hours), 30d (days), 1mo (month)",
"defaultKeyDurationPlaceholder": "e.g., 30d",
"defaultTpmLimitLabel": "Default TPM Limit",
"defaultTpmLimitTooltip": "Default tokens per minute limit for each member. Can be overridden per member.",
"defaultTpmLimitPlaceholder": "e.g., 1000",
"defaultRpmLimitLabel": "Default RPM Limit",
"defaultRpmLimitTooltip": "Default requests per minute limit for each member. Can be overridden per member.",
"defaultRpmLimitPlaceholder": "e.g., 100",
"resetBudgetLabel": "Reset Budget",
"daily": "daily",
"weekly": "weekly",
"monthly": "monthly",
"tpmLimitLabel": "Tokens per minute Limit (TPM)",
"rpmLimitLabel": "Requests per minute Limit (RPM)",
"modelSpecificRateLimitsLabel": "Model-Specific Rate Limits",
"modelSpecificRateLimitsTooltip": "Set per-model TPM/RPM limits that apply across the whole team.",
"missingModel": "Missing model",
"duplicateModel": "Duplicate model",
"setAtLeastOneLimitError": "Set at least one of TPM or RPM",
"selectModelPlaceholder": "Select model",
"tpmLimitPlaceholder": "TPM Limit",
"rpmLimitPlaceholder": "RPM Limit",
"addModelLimitButton": "Add Model Limit",
"routerSettingsLabel": "Router Settings",
"guardrailsLabel": "Guardrails",
"guardrailsTooltip": "Select which guardrails apply to this team. Global guardrails are enabled by default — uncheck to opt out. Other guardrails are opt-in.",
"selectGuardrailsPlaceholder": "Select guardrails",
"globalGuardrailsGroup": "Global",
"otherGuardrailsGroup": "Other",
"disableGlobalGuardrailsLabel": "Disable all global guardrails",
"disableGlobalGuardrailsTooltip": "Kill switch: bypass every global guardrail for this team, including any added in the future. For per-guardrail opt-out instead, use the Guardrails dropdown above.",
"policiesTooltip": "Apply policies to this team to control guardrails and other settings",
"selectPoliciesPlaceholder": "Select or enter policies",
"accessGroupsLabel": "Access Groups",
"accessGroupsTooltip": "Assign access groups to this team. Access groups control which models, MCP servers, and agents this team can use",
"accessGroupsPlaceholder": "Select access groups (optional)",
"vectorStoresLabel": "Vector Stores",
"vectorStoresPlaceholder": "Select vector stores",
"allowedPassThroughLabel": "Allowed Pass Through Routes",
"passThroughPremiumTooltip": "Premium feature - Upgrade to set allowed pass through routes",
"passThroughAdminTooltip": "Only proxy admins can set allowed pass through routes",
"passThroughPlaceholder": "Select pass through routes",
"mcpServersLabel": "MCP Servers / Access Groups",
"mcpServersPlaceholder": "Select MCP servers or access groups (optional)",
"agentsLabel": "Agents / Access Groups",
"agentsPlaceholder": "Select agents or access groups (optional)",
"searchToolSettingsHeader": "Search Tool Settings",
"allowedSearchToolsLabel": "Allowed Search Tools",
"allowedSearchToolsTooltip": "Select which search tools this team can access. Leave empty to allow all search tools.",
"searchToolsPlaceholder": "Select search tools (optional, empty = all allowed)",
"organizationLabel": "Organization",
"organizationPlaceholder": "Select an organization",
"loggingSettingsLabel": "Logging Settings",
"secretManagerSettingsLabel": "Secret Manager Settings",
"secretManagerSettingsHelp": "Enter secret manager configuration as a JSON object.",
"secretManagerSettingsPremiumHelp": "Premium feature - Upgrade to manage secret manager settings.",
"secretManagerSettingsJsonError": "Please enter valid JSON",
"metadataLabel": "Metadata",
"saveChanges": "Save Changes",
"teamIdLabel": "Team ID",
"defaultMemberModels": "Default Member Models",
"teamBudgetLabel": "Team Budget",
"maxBudgetDisplay": "Max Budget: {{value}}",
"softBudgetDisplay": "Soft Budget: {{value}}",
"noLimit": "No Limit",
"budgetResetDisplay": "Budget Reset: {{value}}",
"softBudgetEmailsDisplay": "Soft Budget Alerting Emails: {{emails}}",
"maxBudgetEntry": "Max Budget: {{value}}",
"budgetDurationEntry": "Budget Duration: {{value}}",
"keyDurationEntry": "Key Duration: {{value}}",
"tpmLimitEntry": "TPM Limit: {{value}}",
"rpmLimitEntry": "RPM Limit: {{value}}",
"routingStrategy": "Routing Strategy:",
"numRetries": "Number of Retries: {{value}}",
"allowedFailures": "Allowed Failures: {{value}}",
"cooldownTime": "Cooldown Time: {{value}}s",
"timeout": "Timeout: {{value}}s",
"retryAfter": "Retry After: {{value}}s",
"fallbacksCount": "Fallbacks: {{count}} configured",
"tagFilteringEnabled": "Tag Filtering: Enabled",
"noRouterSettings": "No router settings configured",
"organizationIdLabel": "Organization ID",
"blockedStatus": "Blocked",
"activeStatus": "Active",
"editMemberTitle": "Edit Member",
"adminRole": "Admin",
"userRole": "User",
"teamMemberBudgetLabel": "Team Member Budget (USD)",
"teamMemberBudgetTooltip": "Maximum amount in USD this member can spend within this team. This is separate from any global user budget limits",
"teamMemberBudgetPlaceholder": "Budget limit for this member within this team",
"budgetResetPeriodLabel": "Budget Reset Period",
"budgetResetPeriodTooltip": "How often this member's budget resets within the team. Leave unset and the budget never resets.",
"teamMemberTpmLabel": "Team Member TPM Limit",
"teamMemberTpmTooltip": "Maximum tokens per minute this member can use within this team. This is separate from any global user TPM limit",
"teamMemberTpmPlaceholder": "Tokens per minute limit for this member in this team",
"teamMemberRpmLabel": "Team Member RPM Limit",
"teamMemberRpmTooltip": "Maximum requests per minute this member can make within this team. This is separate from any global user RPM limit",
"teamMemberRpmPlaceholder": "Requests per minute limit for this member in this team",
"allowedModelsLabel": "Allowed Models",
"allowedModelsTooltip": "Models this member can access within this team. Leave empty to inherit all team models.",
"allowedModelsPlaceholder": "Leave empty to inherit all team models",
"deleteMemberTitle": "Delete Team Member",
"deleteMemberAlert": "Removing team members will also delete any keys created by or created for this member.",
"deleteMemberMessage": "Are you sure you want to remove this member from the team? This action cannot be undone.",
"deleteMemberInfoTitle": "Team Member Information",
"userIdLabel": "User ID",
"emailLabel": "Email",
"roleLabel": "Role"
}
}
}

View file

@ -6247,6 +6247,177 @@
"modelScopeLabel": "模型范围",
"modelScopeTooltip": "您在此团队中可访问的模型。",
"allTeamModels": "所有团队模型"
},
"teamInfo": {
"failedToLoadTeam": "加载团队信息失败",
"memberAddedSuccess": "团队成员添加成功",
"assignAdminsEnterprise": "指定管理员是企业专属功能,请升级您的 LiteLLM 套餐以启用此功能。",
"failedToAddMember": "添加团队成员失败",
"memberUpdatedSuccess": "团队成员更新成功",
"failedToUpdateMember": "更新团队成员失败",
"memberRemovedSuccess": "团队成员移除成功",
"failedToRemoveMember": "移除团队成员失败",
"invalidMetadataJson": "元数据字段中的 JSON 无效",
"invalidSecretManagerJson": "密钥管理器设置中的 JSON 无效",
"teamSettingsUpdatedSuccess": "团队设置更新成功",
"teamNotFound": "未找到团队",
"backToTeams": "返回团队列表",
"tabOverview": "概览",
"tabMyUser": "我的用户",
"tabVirtualKeys": "虚拟密钥",
"tabMembers": "成员",
"tabMemberPermissions": "成员权限",
"tabSettings": "设置",
"budgetStatus": "预算状态",
"unlimited": "不限",
"budgetOf": "共 {{value}}",
"budgetReset": "重置:{{duration}}",
"teamMemberBudget": "团队成员预算:${{amount}}",
"rateLimits": "速率限制",
"tpmLabel": "TPM:{{value}}",
"rpmLabel": "RPM:{{value}}",
"maxParallelRequests": "最大并发请求数:{{value}}",
"perModelLimits": "按模型限制:",
"perModelEntry": "{{model}}:TPM {{tpm}},RPM {{rpm}}",
"modelsLabel": "模型",
"allProxyModels": "所有代理模型",
"fromAccessGroup": "来自访问组",
"virtualKeys": "虚拟密钥",
"userKeys": "用户密钥:{{count}}",
"serviceAccountKeys": "服务账号密钥:{{count}}",
"totalKeys": "共计:{{count}}",
"loadingGuardrails": "正在加载护栏...",
"resolvedGuardrails": "已解析护栏:",
"noPoliciesConfigured": "未配置策略",
"policiesLabel": "策略",
"teamSettings": "团队设置",
"editSettings": "编辑设置",
"teamNameLabel": "团队名称",
"teamNameRequired": "请输入团队名称",
"modelsRequired": "请至少选择一个模型",
"maxBudgetLabel": "最大预算(USD)",
"softBudgetLabel": "软预算(USD)",
"softBudgetEmailsLabel": "软预算告警邮箱",
"softBudgetEmailsTooltip": "达到软预算时接收告警的邮箱地址,多个地址以逗号分隔",
"softBudgetEmailsPlaceholder": "example1@test.com, example2@test.com",
"teamMemberSettings": "团队成员设置",
"teamMemberSettingsDesc": "成员加入此团队时应用的可选默认值,所有字段均可按成员单独覆盖。",
"teamMemberSettingsTooltip": "这些是对单个团队成员的限制",
"defaultModelAccessLabel": "默认模型访问权限",
"defaultModelAccessTooltip": "可选。设置后,新成员默认只能访问这些模型,必须是上方团队模型的子集。留空则所有成员可访问全部团队模型。",
"defaultModelAccessPlaceholder": "留空 — 所有成员均可访问全部团队模型",
"defaultBudgetLabel": "默认预算(USD)",
"defaultBudgetTooltip": "此团队中每位成员的默认花费预算。",
"defaultBudgetDurationLabel": "默认预算周期",
"defaultKeyDurationLabel": "默认密钥有效期(如:1d、1mo)",
"defaultKeyDurationTooltip": "设置团队成员密钥的有效期上限。格式:30s(秒)、30m(分钟)、30h(小时)、30d(天)、1mo(月)",
"defaultKeyDurationPlaceholder": "如:30d",
"defaultTpmLimitLabel": "默认 TPM 限制",
"defaultTpmLimitTooltip": "每位成员的默认每分钟 Token 限制,可按成员单独覆盖。",
"defaultTpmLimitPlaceholder": "如:1000",
"defaultRpmLimitLabel": "默认 RPM 限制",
"defaultRpmLimitTooltip": "每位成员的默认每分钟请求限制,可按成员单独覆盖。",
"defaultRpmLimitPlaceholder": "如:100",
"resetBudgetLabel": "重置预算",
"daily": "每日",
"weekly": "每周",
"monthly": "每月",
"tpmLimitLabel": "每分钟 Token 限制(TPM)",
"rpmLimitLabel": "每分钟请求限制(RPM)",
"modelSpecificRateLimitsLabel": "按模型速率限制",
"modelSpecificRateLimitsTooltip": "设置适用于整个团队的按模型 TPM/RPM 限制。",
"missingModel": "缺少模型",
"duplicateModel": "重复模型",
"setAtLeastOneLimitError": "请至少设置 TPM 或 RPM 中的一个",
"selectModelPlaceholder": "选择模型",
"tpmLimitPlaceholder": "TPM 限制",
"rpmLimitPlaceholder": "RPM 限制",
"addModelLimitButton": "添加模型限制",
"routerSettingsLabel": "路由器设置",
"guardrailsLabel": "护栏",
"guardrailsTooltip": "选择适用于此团队的护栏。全局护栏默认启用,取消勾选可退出。其他护栏需手动选入。",
"selectGuardrailsPlaceholder": "选择护栏",
"globalGuardrailsGroup": "全局",
"otherGuardrailsGroup": "其他",
"disableGlobalGuardrailsLabel": "禁用所有全局护栏",
"disableGlobalGuardrailsTooltip": "终止开关:绕过此团队的所有全局护栏,包括未来新增的护栏。如需按护栏单独退出,请使用上方的护栏下拉菜单。",
"policiesTooltip": "为此团队应用策略以控制护栏和其他设置",
"selectPoliciesPlaceholder": "选择或输入策略",
"accessGroupsLabel": "访问组",
"accessGroupsTooltip": "为此团队分配访问组,访问组控制该团队可使用的模型、MCP 服务器和 Agent",
"accessGroupsPlaceholder": "选择访问组(可选)",
"vectorStoresLabel": "向量存储",
"vectorStoresPlaceholder": "选择向量存储",
"allowedPassThroughLabel": "允许的透传路由",
"passThroughPremiumTooltip": "高级功能 - 请升级以设置允许的透传路由",
"passThroughAdminTooltip": "只有代理管理员可以设置允许的透传路由",
"passThroughPlaceholder": "选择透传路由",
"mcpServersLabel": "MCP 服务器 / 访问组",
"mcpServersPlaceholder": "选择 MCP 服务器或访问组(可选)",
"agentsLabel": "Agent / 访问组",
"agentsPlaceholder": "选择 Agent 或访问组(可选)",
"searchToolSettingsHeader": "搜索工具设置",
"allowedSearchToolsLabel": "允许的搜索工具",
"allowedSearchToolsTooltip": "选择此团队可访问的搜索工具,留空则允许所有搜索工具。",
"searchToolsPlaceholder": "选择搜索工具(可选,留空 = 全部允许)",
"organizationLabel": "组织",
"organizationPlaceholder": "选择组织",
"loggingSettingsLabel": "日志设置",
"secretManagerSettingsLabel": "密钥管理器设置",
"secretManagerSettingsHelp": "以 JSON 对象格式输入密钥管理器配置。",
"secretManagerSettingsPremiumHelp": "高级功能 - 请升级以管理密钥管理器设置。",
"secretManagerSettingsJsonError": "请输入有效的 JSON",
"metadataLabel": "元数据",
"saveChanges": "保存更改",
"teamIdLabel": "团队 ID",
"defaultMemberModels": "默认成员模型",
"teamBudgetLabel": "团队预算",
"maxBudgetDisplay": "最大预算:{{value}}",
"softBudgetDisplay": "软预算:{{value}}",
"noLimit": "无限制",
"budgetResetDisplay": "预算重置:{{value}}",
"softBudgetEmailsDisplay": "软预算告警邮箱:{{emails}}",
"maxBudgetEntry": "最大预算:{{value}}",
"budgetDurationEntry": "预算周期:{{value}}",
"keyDurationEntry": "密钥有效期:{{value}}",
"tpmLimitEntry": "TPM 限制:{{value}}",
"rpmLimitEntry": "RPM 限制:{{value}}",
"routingStrategy": "路由策略:",
"numRetries": "重试次数:{{value}}",
"allowedFailures": "允许失败次数:{{value}}",
"cooldownTime": "冷却时间:{{value}}s",
"timeout": "超时:{{value}}s",
"retryAfter": "重试延迟:{{value}}s",
"fallbacksCount": "回退:已配置 {{count}} 个",
"tagFilteringEnabled": "标签过滤:已启用",
"noRouterSettings": "未配置路由器设置",
"organizationIdLabel": "组织 ID",
"blockedStatus": "已封禁",
"activeStatus": "活跃",
"editMemberTitle": "编辑成员",
"adminRole": "管理员",
"userRole": "用户",
"teamMemberBudgetLabel": "团队成员预算(USD)",
"teamMemberBudgetTooltip": "此成员在该团队内可花费的最大 USD 金额,独立于任何全局用户预算限制",
"teamMemberBudgetPlaceholder": "此成员在该团队内的预算上限",
"budgetResetPeriodLabel": "预算重置周期",
"budgetResetPeriodTooltip": "此成员在团队内的预算重置频率,留空则预算永不重置。",
"teamMemberTpmLabel": "团队成员 TPM 限制",
"teamMemberTpmTooltip": "此成员在该团队内可使用的每分钟最大 Token 数,独立于任何全局用户 TPM 限制",
"teamMemberTpmPlaceholder": "此成员在该团队内的每分钟 Token 限制",
"teamMemberRpmLabel": "团队成员 RPM 限制",
"teamMemberRpmTooltip": "此成员在该团队内可发起的每分钟最大请求数,独立于任何全局用户 RPM 限制",
"teamMemberRpmPlaceholder": "此成员在该团队内的每分钟请求限制",
"allowedModelsLabel": "允许的模型",
"allowedModelsTooltip": "此成员在该团队内可访问的模型,留空则继承所有团队模型。",
"allowedModelsPlaceholder": "留空则继承所有团队模型",
"deleteMemberTitle": "删除团队成员",
"deleteMemberAlert": "移除团队成员将同时删除该成员创建的或为其创建的所有密钥。",
"deleteMemberMessage": "确定要将此成员从团队中移除吗?此操作无法撤销。",
"deleteMemberInfoTitle": "团队成员信息",
"userIdLabel": "用户 ID",
"emailLabel": "邮箱",
"roleLabel": "角色"
}
}
}