update:css样式拆分
This commit is contained in:
@@ -4,6 +4,21 @@ import { ApiRequestError, type Employee, type Workspace, type WorkspaceMember }
|
||||
import { useApi, useAuth } from "../../context/AuthContext";
|
||||
import Icon from "../../components/common/Icon";
|
||||
import { UserMultiSelect } from "./UserMultiSelect";
|
||||
import {
|
||||
formFieldClass,
|
||||
formInputClass,
|
||||
formTextareaClass,
|
||||
iconButtonClass,
|
||||
modalBackdropClass,
|
||||
modalCompactClass,
|
||||
modalEyebrowClass,
|
||||
modalFooterClass,
|
||||
modalFormClass,
|
||||
modalHeaderClass,
|
||||
modalTitleClass,
|
||||
primaryButtonClass,
|
||||
secondaryButtonClass,
|
||||
} from "../platform/modalUi";
|
||||
|
||||
import "../../styles/admin.css";
|
||||
|
||||
@@ -199,24 +214,6 @@ export function ProjectManagementPage({
|
||||
}
|
||||
};
|
||||
|
||||
const updateMemberRole = async (userId: string, roleCode: "admin" | "developer"): Promise<void> => {
|
||||
if (!selectedProject) return;
|
||||
try {
|
||||
const updated = await api.updateWorkspaceMember(selectedProject.workspace_id, userId, {
|
||||
role_code: roleCode,
|
||||
});
|
||||
setCurrentProjectMembers((current) =>
|
||||
current.map((m) => (m.user_id === userId ? { ...m, role_code: roleCode, role_name: roleCode === "admin" ? "管理员" : "开发人员" } : m))
|
||||
);
|
||||
onNotify({ tone: "success", message: "成员角色已更新" });
|
||||
} catch (error) {
|
||||
onNotify({
|
||||
tone: "error",
|
||||
message: error instanceof ApiRequestError ? error.message : "更新成员角色失败",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const importMember = async (): Promise<void> => {
|
||||
if (!selectedProject || selectedUserIds.length === 0) {
|
||||
onNotify({ tone: "error", message: "请选择要添加的用户" });
|
||||
@@ -327,20 +324,23 @@ export function ProjectManagementPage({
|
||||
</div>
|
||||
|
||||
{projectDialogOpen && (
|
||||
<div className="modal-backdrop">
|
||||
<section className="modal modal--compact" role="dialog" aria-modal="true">
|
||||
<div className="modal__header">
|
||||
<div className={modalBackdropClass} role="presentation">
|
||||
<section className={modalCompactClass} role="dialog" aria-modal="true">
|
||||
<div className={modalHeaderClass}>
|
||||
<div>
|
||||
<span className="modal__eyebrow">PROJECT</span>
|
||||
<h2>{editingProject ? "编辑项目" : "新建项目"}</h2>
|
||||
<span className={modalEyebrowClass}>PROJECT</span>
|
||||
<h2 className={modalTitleClass}>{editingProject ? "编辑项目" : "新建项目"}</h2>
|
||||
</div>
|
||||
<button className="icon-button" type="button" onClick={() => setProjectDialogOpen(false)}><Icon name="close" /></button>
|
||||
<button className={iconButtonClass} type="button" aria-label="关闭" onClick={() => setProjectDialogOpen(false)}>
|
||||
<Icon name="close" />
|
||||
</button>
|
||||
</div>
|
||||
<form onSubmit={(event) => void submitProject(event)}>
|
||||
<form className={modalFormClass} onSubmit={(event) => void submitProject(event)}>
|
||||
{!editingProject && (
|
||||
<label className="form-field">
|
||||
<span>项目编码<span className="required">*</span></span>
|
||||
<label className={formFieldClass}>
|
||||
<span>项目编码<span className="text-[#e74c3c]">*</span></span>
|
||||
<input
|
||||
className={formInputClass}
|
||||
autoFocus
|
||||
value={projectForm.workspace_code}
|
||||
onChange={(event) => setProjectForm({ ...projectForm, workspace_code: event.target.value })}
|
||||
@@ -348,35 +348,38 @@ export function ProjectManagementPage({
|
||||
/>
|
||||
</label>
|
||||
)}
|
||||
<label className="form-field">
|
||||
<span>项目名称<span className="required">*</span></span>
|
||||
<label className={formFieldClass}>
|
||||
<span>项目名称<span className="text-[#e74c3c]">*</span></span>
|
||||
<input
|
||||
className={formInputClass}
|
||||
value={projectForm.workspace_name}
|
||||
onChange={(event) => setProjectForm({ ...projectForm, workspace_name: event.target.value })}
|
||||
placeholder="请输入项目名称"
|
||||
/>
|
||||
</label>
|
||||
<label className="form-field">
|
||||
<label className={formFieldClass}>
|
||||
<span>配额(字节)</span>
|
||||
<input
|
||||
className={formInputClass}
|
||||
type="number"
|
||||
value={projectForm.quota_bytes}
|
||||
onChange={(event) => setProjectForm({ ...projectForm, quota_bytes: parseInt(event.target.value) || 0 })}
|
||||
placeholder="0 表示无配额限制"
|
||||
/>
|
||||
</label>
|
||||
<label className="form-field">
|
||||
<label className={formFieldClass}>
|
||||
<span>项目描述</span>
|
||||
<textarea
|
||||
className={formTextareaClass}
|
||||
value={projectForm.description}
|
||||
onChange={(event) => setProjectForm({ ...projectForm, description: event.target.value })}
|
||||
placeholder="请输入项目描述(可选)"
|
||||
rows={4}
|
||||
/>
|
||||
</label>
|
||||
<div className="modal__footer">
|
||||
<button className="secondary-button" type="button" onClick={() => setProjectDialogOpen(false)}>取消</button>
|
||||
<button className="primary-button" type="submit" disabled={saving}>{saving ? "保存中…" : "保存"}</button>
|
||||
<div className={modalFooterClass}>
|
||||
<button className={secondaryButtonClass} type="button" onClick={() => setProjectDialogOpen(false)}>取消</button>
|
||||
<button className={primaryButtonClass} type="submit" disabled={saving}>{saving ? "保存中…" : "保存"}</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
@@ -384,18 +387,20 @@ export function ProjectManagementPage({
|
||||
)}
|
||||
|
||||
{importMemberDialogOpen && (
|
||||
<div className="modal-backdrop">
|
||||
<section className="modal modal--compact" role="dialog" aria-modal="true">
|
||||
<div className="modal__header">
|
||||
<div className={modalBackdropClass} role="presentation">
|
||||
<section className={modalCompactClass} role="dialog" aria-modal="true">
|
||||
<div className={modalHeaderClass}>
|
||||
<div>
|
||||
<span className="modal__eyebrow">IMPORT MEMBER</span>
|
||||
<h2>导入成员到 {selectedProject?.workspace_name ?? "项目"}</h2>
|
||||
<span className={modalEyebrowClass}>IMPORT MEMBER</span>
|
||||
<h2 className={modalTitleClass}>导入成员到 {selectedProject?.workspace_name ?? "项目"}</h2>
|
||||
</div>
|
||||
<button className="icon-button" type="button" onClick={() => setImportMemberDialogOpen(false)}><Icon name="close" /></button>
|
||||
<button className={iconButtonClass} type="button" aria-label="关闭" onClick={() => setImportMemberDialogOpen(false)}>
|
||||
<Icon name="close" />
|
||||
</button>
|
||||
</div>
|
||||
<form >
|
||||
<label className="form-field" style={{ paddingBottom: 120 }}>
|
||||
<span>选择用户<span className="required">*</span></span>
|
||||
<form className={modalFormClass}>
|
||||
<label className={`${formFieldClass} pb-[120px]`}>
|
||||
<span>选择用户<span className="text-[#e74c3c]">*</span></span>
|
||||
<UserMultiSelect
|
||||
users={availableUsers}
|
||||
selectedUserIds={selectedUserIds}
|
||||
@@ -403,9 +408,9 @@ export function ProjectManagementPage({
|
||||
existingMemberIds={currentProjectMembers.map((m) => m.user_id)}
|
||||
/>
|
||||
</label>
|
||||
<div className="modal__footer">
|
||||
<button className="secondary-button" type="button" onClick={() => setImportMemberDialogOpen(false)}>取消</button>
|
||||
<button className="primary-button" type="button" disabled={saving || selectedUserIds.length === 0} onClick={() => void importMember()}>
|
||||
<div className={modalFooterClass}>
|
||||
<button className={secondaryButtonClass} type="button" onClick={() => setImportMemberDialogOpen(false)}>取消</button>
|
||||
<button className={primaryButtonClass} type="button" disabled={saving || selectedUserIds.length === 0} onClick={() => void importMember()}>
|
||||
{saving ? "添加中…" : `添加 (${selectedUserIds.length})`}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user