96 lines
4.0 KiB
JavaScript
96 lines
4.0 KiB
JavaScript
import Checkbox from "@mui/material/Checkbox";
|
|
import Drawer from "@mui/material/Drawer";
|
|
import TextField from "@mui/material/TextField";
|
|
import { Button } from "@/shared/ui/Button.jsx";
|
|
|
|
export function RoleFormDrawer({
|
|
abilities,
|
|
editingRole,
|
|
form,
|
|
onClose,
|
|
onSubmit,
|
|
onTogglePermissionGroup,
|
|
onTogglePermission,
|
|
open,
|
|
permissionGroups,
|
|
setForm
|
|
}) {
|
|
return (
|
|
<Drawer anchor="right" open={open} onClose={onClose}>
|
|
<form className="form-drawer form-drawer--wide" onSubmit={onSubmit}>
|
|
<h2>{editingRole ? "编辑角色" : "新增角色"}</h2>
|
|
<section className="form-drawer__section">
|
|
<div className="form-drawer__section-title">基础信息</div>
|
|
<div className="form-drawer__grid">
|
|
<TextField disabled={editingRole ? !abilities.canUpdate : !abilities.canCreate} label="角色名称" required value={form.name} onChange={(event) => setForm({ ...form, name: event.target.value })} />
|
|
<TextField disabled={editingRole ? !abilities.canUpdate : !abilities.canCreate} label="角色编码" required value={form.code} onChange={(event) => setForm({ ...form, code: event.target.value })} />
|
|
<TextField disabled={editingRole ? !abilities.canUpdate : !abilities.canCreate} label="说明" value={form.description} onChange={(event) => setForm({ ...form, description: event.target.value })} />
|
|
</div>
|
|
</section>
|
|
{abilities.canLoadPermissions ? (
|
|
<section className="form-drawer__section">
|
|
<div className="form-drawer__section-title">权限范围</div>
|
|
<div className="permission-menu-list">
|
|
{permissionGroups.map((group) => (
|
|
<PermissionMenuGroup
|
|
abilities={abilities}
|
|
group={group}
|
|
key={group.key}
|
|
permissionIds={form.permissionIds}
|
|
onTogglePermission={onTogglePermission}
|
|
onTogglePermissionGroup={onTogglePermissionGroup}
|
|
/>
|
|
))}
|
|
</div>
|
|
</section>
|
|
) : null}
|
|
<div className="form-drawer__actions">
|
|
<Button onClick={onClose}>取消</Button>
|
|
<Button type="submit" variant="primary">提交</Button>
|
|
</div>
|
|
</form>
|
|
</Drawer>
|
|
);
|
|
}
|
|
|
|
function PermissionMenuGroup({ abilities, group, onTogglePermission, onTogglePermissionGroup, permissionIds }) {
|
|
const groupPermissionIds = group.items.map((permission) => permission.id);
|
|
const selectedCount = groupPermissionIds.filter((permissionId) => permissionIds.includes(permissionId)).length;
|
|
const allSelected = selectedCount === groupPermissionIds.length;
|
|
const partiallySelected = selectedCount > 0 && !allSelected;
|
|
|
|
return (
|
|
<section className="permission-menu-section">
|
|
<div className="permission-menu-header">
|
|
<span className="permission-menu-title">{group.title}</span>
|
|
<div className="permission-menu-actions">
|
|
<span className="permission-menu-count">{selectedCount}/{groupPermissionIds.length}</span>
|
|
<label className="permission-menu-toggle">
|
|
<Checkbox
|
|
checked={allSelected}
|
|
disabled={!abilities.canGrant}
|
|
indeterminate={partiallySelected}
|
|
onChange={(event) => onTogglePermissionGroup(groupPermissionIds, event.target.checked)}
|
|
size="small"
|
|
/>
|
|
<span>全选</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div className="permission-grid permission-grid--compact">
|
|
{group.items.map((permission) => (
|
|
<label className="permission-check" key={permission.id}>
|
|
<Checkbox
|
|
checked={permissionIds.includes(permission.id)}
|
|
disabled={!abilities.canGrant}
|
|
onChange={(event) => onTogglePermission(permission.id, event.target.checked)}
|
|
size="small"
|
|
/>
|
|
<span>{permission.name}</span>
|
|
</label>
|
|
))}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|