first commit
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
import type { JobResponse, ServerInstanceResponse, ServerMetricsResponse, UserContactProfile, UserStatus, UserThemePreferenceResponse } from "../api/types";
|
||||
|
||||
export type WorkspaceRole = "platformAdmin" | "serverOwner" | "serverAdmin";
|
||||
|
||||
export type WorkspaceCapability =
|
||||
| "profile.settings.manage"
|
||||
| "platform.overview.read"
|
||||
| "servers.read"
|
||||
| "servers.manage"
|
||||
| "plugins.market.read"
|
||||
| "users.manage"
|
||||
| "aiProviders.manage"
|
||||
| "system.maintenance";
|
||||
|
||||
export interface CurrentUserView {
|
||||
id: string;
|
||||
displayName: string;
|
||||
email?: string;
|
||||
status: UserStatus;
|
||||
roles: WorkspaceRole[];
|
||||
capabilities: WorkspaceCapability[];
|
||||
profile: UserContactProfile;
|
||||
themePreference?: UserThemePreferenceResponse;
|
||||
source: "api" | "local";
|
||||
}
|
||||
|
||||
const roleCapabilities: Record<WorkspaceRole, WorkspaceCapability[]> = {
|
||||
platformAdmin: [
|
||||
"profile.settings.manage",
|
||||
"platform.overview.read",
|
||||
"servers.read",
|
||||
"servers.manage",
|
||||
"plugins.market.read",
|
||||
"users.manage",
|
||||
"aiProviders.manage",
|
||||
"system.maintenance"
|
||||
],
|
||||
serverOwner: ["profile.settings.manage", "servers.read", "servers.manage"],
|
||||
serverAdmin: ["profile.settings.manage", "servers.read", "servers.manage"]
|
||||
};
|
||||
|
||||
export function capabilitiesForRoles(roles: WorkspaceRole[]): WorkspaceCapability[] {
|
||||
const set = new Set<WorkspaceCapability>();
|
||||
for (const role of roles) {
|
||||
for (const capability of roleCapabilities[role] ?? []) {
|
||||
set.add(capability);
|
||||
}
|
||||
}
|
||||
return [...set];
|
||||
}
|
||||
|
||||
export function isPlatformAdmin(user: CurrentUserView): boolean {
|
||||
return user.roles.includes("platformAdmin");
|
||||
}
|
||||
|
||||
export function rolesFromBackendRoles(roles: string[]): WorkspaceRole[] {
|
||||
const mapped = new Set<WorkspaceRole>();
|
||||
for (const role of roles) {
|
||||
const normalized = role.toLowerCase();
|
||||
if (normalized === "admin" || normalized === "platform-admin" || normalized === "platformadmin") {
|
||||
mapped.add("platformAdmin");
|
||||
}
|
||||
if (normalized === "server-owner" || normalized === "owner") {
|
||||
mapped.add("serverOwner");
|
||||
}
|
||||
if (normalized === "server-admin" || normalized === "operator") {
|
||||
mapped.add("serverAdmin");
|
||||
}
|
||||
}
|
||||
return mapped.size > 0 ? [...mapped] : ["serverAdmin"];
|
||||
}
|
||||
|
||||
export type OperationStatus = "pending" | "succeeded" | "failed";
|
||||
|
||||
export interface OperationRecord {
|
||||
id: string;
|
||||
intent: string;
|
||||
targetKind: "server" | "plugin" | "config" | "llm" | "platform";
|
||||
targetId: string;
|
||||
requester: string;
|
||||
status: OperationStatus;
|
||||
jobId?: string;
|
||||
jobState?: JobResponse["state"];
|
||||
message?: string;
|
||||
errorReason?: string;
|
||||
diagnosticId?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface ServerCardView {
|
||||
instance: ServerInstanceResponse;
|
||||
metrics?: ServerMetricsResponse;
|
||||
pendingJobs: number;
|
||||
}
|
||||
|
||||
export type ServerStatusFilter = "all" | "online" | "offline" | "attention";
|
||||
|
||||
export function serverIsOnline(state: ServerInstanceResponse["state"]): boolean {
|
||||
return state === "running";
|
||||
}
|
||||
|
||||
export function serverNeedsAttention(state: ServerInstanceResponse["state"]): boolean {
|
||||
return state === "failed" || state === "installing";
|
||||
}
|
||||
|
||||
export function filterServerCards(cards: ServerCardView[], keyword: string, status: ServerStatusFilter): ServerCardView[] {
|
||||
const query = keyword.trim().toLowerCase();
|
||||
return cards.filter((card) => {
|
||||
if (query && !`${card.instance.name} ${card.instance.id} ${card.instance.pluginId}`.toLowerCase().includes(query)) {
|
||||
return false;
|
||||
}
|
||||
if (status === "online") {
|
||||
return serverIsOnline(card.instance.state);
|
||||
}
|
||||
if (status === "offline") {
|
||||
return !serverIsOnline(card.instance.state);
|
||||
}
|
||||
if (status === "attention") {
|
||||
return serverNeedsAttention(card.instance.state);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export interface GameTypeDistributionEntry {
|
||||
serverType: string;
|
||||
label: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface PlatformOverviewSignal {
|
||||
id: string;
|
||||
kind: "log" | "fault" | "plugin" | "aiProvider" | "job";
|
||||
summary: string;
|
||||
detail: string;
|
||||
targetPage: "servers" | "plugins" | "aiProviders" | "maintenance";
|
||||
targetId?: string;
|
||||
tone: "info" | "warning" | "error";
|
||||
at: string;
|
||||
}
|
||||
|
||||
export type ServerDetailSection = "overview" | "logs" | "config" | "plugins" | "llm" | "history";
|
||||
|
||||
export const serverDetailSections: Array<{ id: ServerDetailSection; label: string }> = [
|
||||
{ id: "overview", label: "概览" },
|
||||
{ id: "logs", label: "日志" },
|
||||
{ id: "config", label: "配置" },
|
||||
{ id: "plugins", label: "插件控制" },
|
||||
{ id: "llm", label: "AI 助手" },
|
||||
{ id: "history", label: "操作历史" }
|
||||
];
|
||||
|
||||
export interface PluginControlDescriptor {
|
||||
key: string;
|
||||
label: string;
|
||||
description: string;
|
||||
capability: string;
|
||||
lifecycleAction?: "start" | "stop";
|
||||
dangerous: boolean;
|
||||
}
|
||||
|
||||
export interface PluginControlGroupView {
|
||||
pluginId: string;
|
||||
pluginName: string;
|
||||
version: string;
|
||||
status: string;
|
||||
controls: PluginControlDescriptor[];
|
||||
}
|
||||
|
||||
export interface DiffLine {
|
||||
kind: "same" | "added" | "removed";
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface ConfigDiffView {
|
||||
serverInstanceId: string;
|
||||
configVersion?: number;
|
||||
key?: string;
|
||||
source?: string;
|
||||
summary: string;
|
||||
lines: DiffLine[];
|
||||
nextContent: string;
|
||||
proposedContentInputRef?: string;
|
||||
}
|
||||
|
||||
export interface LlmSuggestionView {
|
||||
serverInstanceId: string;
|
||||
source: "api" | "local";
|
||||
recommendation: string;
|
||||
diff?: ConfigDiffView;
|
||||
}
|
||||
Reference in New Issue
Block a user