update:Dialog替换
This commit is contained in:
@@ -1,24 +1,22 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { X } from "lucide-react";
|
||||
import type {
|
||||
PlatformPermission,
|
||||
Role,
|
||||
RoleCreatePayload,
|
||||
RoleUpdatePayload,
|
||||
} from "../../services/api";
|
||||
import {
|
||||
AppFormDialog,
|
||||
dialogPrimaryButtonClass,
|
||||
dialogSecondaryButtonClass,
|
||||
} from "~/components/common/AppFormDialog";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import {
|
||||
formFieldClass,
|
||||
formInputClass,
|
||||
formTextareaClass,
|
||||
modalBackdropClass,
|
||||
modalCompactClass,
|
||||
modalEyebrowClass,
|
||||
modalFooterClass,
|
||||
modalFormClass,
|
||||
modalHeaderClass,
|
||||
modalTitleClass,
|
||||
} from "../platform/modalUi";
|
||||
import { PermissionCheckboxList } from "./PermissionCheckboxList";
|
||||
|
||||
@@ -39,7 +37,6 @@ const EMPTY_FORM: RoleFormState = {
|
||||
permission_codes: [],
|
||||
};
|
||||
|
||||
/** 实时校验 role_code:空值不报错,提交时由必填拦截兜底。 */
|
||||
function validateRoleCode(value: string): string {
|
||||
const code = value.trim();
|
||||
if (!code) return "";
|
||||
@@ -58,13 +55,6 @@ function validateRoleCode(value: string): string {
|
||||
return "";
|
||||
}
|
||||
|
||||
const CLOSE_BUTTON_CLASS =
|
||||
"size-[34px] rounded-[7px] border border-[#dfe6ed] bg-white hover:bg-[#f7faff] hover:border-[#b9c9da]";
|
||||
const SECONDARY_BUTTON_CLASS =
|
||||
"h-[37px] gap-[7px] rounded-md border-[#d8e1e9] bg-white px-[15px] text-xs font-[650] text-[#56687c]";
|
||||
const PRIMARY_BUTTON_CLASS =
|
||||
"h-[37px] gap-[7px] rounded-md border border-[#126ac3] bg-gradient-to-br from-[#1881e7] to-[#1268c9] px-[15px] text-xs font-[650] text-white shadow-[0_6px_15px_rgb(20_111_202/18%)] enabled:hover:from-[#1175d8] enabled:hover:to-[#0e5bad]";
|
||||
|
||||
export function RoleEditDialog({
|
||||
open,
|
||||
editing,
|
||||
@@ -117,7 +107,6 @@ export function RoleEditDialog({
|
||||
};
|
||||
|
||||
const toggleCreatePermission = (code: string): void => {
|
||||
// 新建角色为非 admin,system:* 由后端守卫禁止;此处防御性拦截
|
||||
if (code.startsWith("system:")) return;
|
||||
setForm((current) => ({
|
||||
...current,
|
||||
@@ -143,7 +132,6 @@ export function RoleEditDialog({
|
||||
}
|
||||
const payload: RoleCreatePayload | RoleUpdatePayload = editing
|
||||
? {
|
||||
// 内置角色 role_name 锁定;description 可改
|
||||
...(editing.is_builtin ? {} : { role_name: form.role_name.trim() }),
|
||||
description: form.description.trim() || null,
|
||||
}
|
||||
@@ -156,108 +144,91 @@ export function RoleEditDialog({
|
||||
onSubmit(payload);
|
||||
};
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
return (
|
||||
<div className={modalBackdropClass} role="presentation">
|
||||
<section className={modalCompactClass} role="dialog" aria-modal="true">
|
||||
<div className={modalHeaderClass}>
|
||||
<div>
|
||||
<span className={modalEyebrowClass}>ROLE</span>
|
||||
<h2 className={modalTitleClass}>{editing ? "编辑角色" : "新建角色"}</h2>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
type="button"
|
||||
aria-label="关闭"
|
||||
onClick={onClose}
|
||||
className={CLOSE_BUTTON_CLASS}
|
||||
>
|
||||
<X size={16} />
|
||||
</Button>
|
||||
</div>
|
||||
<form className={`${modalFormClass} role-create-form`} onSubmit={(event) => void handleSubmit(event)}>
|
||||
{editing ? (
|
||||
<label className={formFieldClass}>
|
||||
<span>角色编码</span>
|
||||
<input
|
||||
className={formInputClass}
|
||||
disabled
|
||||
value={form.role_code}
|
||||
/>
|
||||
</label>
|
||||
) : (
|
||||
<label className={formFieldClass}>
|
||||
<span>角色编码<span className="text-[#e74c3c]">*</span></span>
|
||||
<input
|
||||
className={formInputClass}
|
||||
autoFocus
|
||||
value={form.role_code}
|
||||
onChange={handleRoleCodeChange}
|
||||
placeholder="例如:qa_engineer"
|
||||
/>
|
||||
<span className="form-hint">
|
||||
以小写字母开头,仅含小写字母/数字/下划线/连字符(2~64 字符)
|
||||
</span>
|
||||
{roleCodeError && <span className="role-error">{roleCodeError}</span>}
|
||||
</label>
|
||||
)}
|
||||
<AppFormDialog
|
||||
open={open}
|
||||
onOpenChange={(nextOpen) => {
|
||||
if (!nextOpen) onClose();
|
||||
}}
|
||||
eyebrow="ROLE"
|
||||
title={editing ? "编辑角色" : "新建角色"}
|
||||
>
|
||||
<form className={`${modalFormClass} role-create-form`} onSubmit={(event) => void handleSubmit(event)}>
|
||||
{editing ? (
|
||||
<label className={formFieldClass}>
|
||||
<span>角色名称<span className="text-[#e74c3c]">*</span></span>
|
||||
<span>角色编码</span>
|
||||
<input className={formInputClass} disabled value={form.role_code} />
|
||||
</label>
|
||||
) : (
|
||||
<label className={formFieldClass}>
|
||||
<span>角色编码<span className="text-[#e74c3c]">*</span></span>
|
||||
<input
|
||||
className={formInputClass}
|
||||
value={form.role_name}
|
||||
disabled={editing !== null && editing.is_builtin}
|
||||
onChange={(event) => setForm({ ...form, role_name: event.target.value })}
|
||||
placeholder="请输入角色名称"
|
||||
autoFocus
|
||||
value={form.role_code}
|
||||
onChange={handleRoleCodeChange}
|
||||
placeholder="例如:qa_engineer"
|
||||
/>
|
||||
{editing !== null && editing.is_builtin && (
|
||||
<span className="form-hint">内置角色名称不可修改,描述可编辑</span>
|
||||
)}
|
||||
<span className="form-hint">
|
||||
以小写字母开头,仅含小写字母/数字/下划线/连字符(2~64 字符)
|
||||
</span>
|
||||
{roleCodeError && <span className="role-error">{roleCodeError}</span>}
|
||||
</label>
|
||||
<label className={formFieldClass}>
|
||||
<span>描述</span>
|
||||
<textarea
|
||||
className={formTextareaClass}
|
||||
value={form.description}
|
||||
onChange={(event) => setForm({ ...form, description: event.target.value })}
|
||||
placeholder="请输入角色描述(可选)"
|
||||
/>
|
||||
</label>
|
||||
{!editing && (
|
||||
<div className="permission-groups">
|
||||
<div className="permission-group__title">初始权限</div>
|
||||
<PermissionCheckboxList
|
||||
permissions={permissions}
|
||||
selected={form.permission_codes}
|
||||
targetRoleCode=""
|
||||
onToggle={toggleCreatePermission}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<label className={formFieldClass}>
|
||||
<span>角色名称<span className="text-[#e74c3c]">*</span></span>
|
||||
<input
|
||||
className={formInputClass}
|
||||
value={form.role_name}
|
||||
disabled={editing !== null && editing.is_builtin}
|
||||
onChange={(event) => setForm({ ...form, role_name: event.target.value })}
|
||||
placeholder="请输入角色名称"
|
||||
/>
|
||||
{editing !== null && editing.is_builtin && (
|
||||
<span className="form-hint">内置角色名称不可修改,描述可编辑</span>
|
||||
)}
|
||||
<div className={modalFooterClass}>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
className={SECONDARY_BUTTON_CLASS}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className={PRIMARY_BUTTON_CLASS}
|
||||
>
|
||||
{saving ? "保存中…" : "保存"}
|
||||
</Button>
|
||||
</label>
|
||||
<label className={formFieldClass}>
|
||||
<span>描述</span>
|
||||
<textarea
|
||||
className={formTextareaClass}
|
||||
value={form.description}
|
||||
onChange={(event) => setForm({ ...form, description: event.target.value })}
|
||||
placeholder="请输入角色描述(可选)"
|
||||
/>
|
||||
</label>
|
||||
{!editing && (
|
||||
<div className="permission-groups">
|
||||
<div className="permission-group__title">初始权限</div>
|
||||
<PermissionCheckboxList
|
||||
permissions={permissions}
|
||||
selected={form.permission_codes}
|
||||
targetRoleCode=""
|
||||
onToggle={toggleCreatePermission}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-[3px] flex shrink-0 justify-end gap-2 border-t border-[#e8edf2] bg-white -mx-[22px] px-[22px] py-3.5">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
className={dialogSecondaryButtonClass}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className={dialogPrimaryButtonClass}
|
||||
>
|
||||
{saving ? "保存中…" : "保存"}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</AppFormDialog>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user