Files
model-platform/frontend/app/features/admin/PermissionEditDialog.tsx
T
2026-09-02 10:10:41 +08:00

109 lines
2.9 KiB
TypeScript

import { useEffect, useState } from "react";
import type { PlatformPermission, Role } from "../../services/api";
import {
AppFormDialog,
dialogPrimaryButtonClass,
dialogSecondaryButtonClass,
} from "~/components/common/AppFormDialog";
import { Button } from "~/components/ui/button";
import { modalFormClass } from "../platform/modalUi";
import { PermissionCheckboxList } from "./PermissionCheckboxList";
import { roleErrorClass } from "./adminUi";
export function PermissionEditDialog({
open,
target,
permissions,
currentCodes,
saving,
onSubmit,
onClose,
}: {
open: boolean;
target: Role | null;
permissions: PlatformPermission[];
currentCodes: string[];
saving: boolean;
onSubmit: (codes: string[]) => void;
onClose: () => void;
}) {
const [selectedCodes, setSelectedCodes] = useState<string[]>(() => {
if (!open || !target) return [];
const initial = [...currentCodes];
if (target.role_code === "admin" && !initial.includes("system:view")) {
initial.push("system:view");
}
return initial;
});
useEffect(() => {
const initial = [...currentCodes];
if (target?.role_code === "admin" && !initial.includes("system:view")) {
initial.push("system:view");
}
setSelectedCodes(initial);
}, [open, target, currentCodes]);
const togglePermission = (code: string): void => {
if (!target) return;
const locked = target.role_code === "admin"
? code === "system:view"
: code.startsWith("system:");
if (locked) return;
setSelectedCodes((current) =>
current.includes(code)
? current.filter((item) => item !== code)
: [...current, code],
);
};
return (
<AppFormDialog
open={open && target !== null}
onOpenChange={(nextOpen) => {
if (!nextOpen) onClose();
}}
eyebrow="PERMISSIONS"
title={target ? `权限配置 · ${target.role_name}` : "权限配置"}
footer={
<>
<Button
variant="outline"
size="sm"
type="button"
onClick={onClose}
className={dialogSecondaryButtonClass}
>
取消
</Button>
<Button
variant="default"
size="sm"
type="button"
disabled={saving}
onClick={() => onSubmit(selectedCodes)}
className={dialogPrimaryButtonClass}
>
{saving ? "保存中…" : "保存权限"}
</Button>
</>
}
>
<div className={modalFormClass}>
{target?.role_code === "admin" && (
<p className={roleErrorClass}>admin 角色必须保留 system:view 权限。</p>
)}
{target ? (
<PermissionCheckboxList
permissions={permissions}
selected={selectedCodes}
targetRoleCode={target.role_code}
onToggle={togglePermission}
/>
) : null}
</div>
</AppFormDialog>
);
}