完成五人团队正式内用最小收口(07-18-small-team-internal-readiness)
这个提交包含在:
@@ -27,14 +27,14 @@ export interface CreateUserDialogProps {
|
||||
isPending: boolean;
|
||||
departments: { isLoading: boolean; items: Array<{ id: string; name: string }> };
|
||||
managers: { isLoading: boolean; items: Array<{ id: string; name: string; employeeNo: string }> };
|
||||
roleOptions: Array<{ code: string; label: string }>;
|
||||
roleOptions: Array<{ code: string; label: string; disabled?: boolean }>;
|
||||
}
|
||||
|
||||
const ROLE_PRESETS = [
|
||||
{ key: "owner", label: "老板", roles: ["ceo"] },
|
||||
{ key: "admin", label: "管理员", roles: ["admin"] },
|
||||
{ key: "employee", label: "员工", roles: ["employee"] },
|
||||
{ key: "manager", label: "主管", roles: ["manager"] },
|
||||
{ key: "manager", label: "直属经理", roles: ["employee", "manager"] },
|
||||
{ key: "owner", label: "公司负责人", roles: ["employee", "ceo"] },
|
||||
{ key: "finance", label: "财务", roles: ["employee", "finance"] },
|
||||
];
|
||||
|
||||
export function CreateUserDialog({
|
||||
@@ -192,6 +192,7 @@ export function CreateUserDialog({
|
||||
<input
|
||||
data-testid={`users-create-role-${item.code}`}
|
||||
type="checkbox"
|
||||
disabled={item.disabled}
|
||||
checked={createRoles.has(item.code)}
|
||||
onChange={(event) => {
|
||||
setCreateRoles((prev) => {
|
||||
@@ -205,7 +206,7 @@ export function CreateUserDialog({
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<span>{item.label}</span>
|
||||
<span className={item.disabled ? "text-zinc-400" : undefined}>{item.label}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -13,18 +13,25 @@ export interface UserRoleDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
user: UserSummary | null;
|
||||
roleOptions: Array<{ code: string; label: string }>;
|
||||
roleOptions: Array<{ code: string; label: string; disabled?: boolean }>;
|
||||
onSubmit: (roles: string[]) => void;
|
||||
isPending: boolean;
|
||||
}
|
||||
|
||||
const ROLE_PRESETS = [
|
||||
{ key: "owner", label: "老板", roles: ["ceo"] },
|
||||
{ key: "admin", label: "管理员", roles: ["admin"] },
|
||||
{ key: "employee", label: "员工", roles: ["employee"] },
|
||||
{ key: "manager", label: "主管", roles: ["manager"] },
|
||||
{ key: "manager", label: "直属经理", roles: ["employee", "manager"] },
|
||||
{ key: "owner", label: "公司负责人", roles: ["employee", "ceo"] },
|
||||
{ key: "finance", label: "财务", roles: ["employee", "finance"] },
|
||||
];
|
||||
|
||||
const DAILY_ROLE_CODES = new Set(["employee", "manager", "ceo", "finance"]);
|
||||
|
||||
export function mergeDailyRolePreset(currentRoles: Iterable<string>, presetRoles: string[]) {
|
||||
const preservedRoles = Array.from(currentRoles).filter((roleCode) => !DAILY_ROLE_CODES.has(roleCode));
|
||||
return new Set([...preservedRoles, ...presetRoles]);
|
||||
}
|
||||
|
||||
export function UserRoleDialog({
|
||||
open,
|
||||
onOpenChange,
|
||||
@@ -47,6 +54,10 @@ export function UserRoleDialog({
|
||||
onOpenChange(false);
|
||||
}
|
||||
|
||||
function applyPreset(roles: string[]) {
|
||||
setRoleDraft((current) => mergeDailyRolePreset(current, roles));
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
@@ -67,7 +78,7 @@ export function UserRoleDialog({
|
||||
<div className="space-y-3">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{ROLE_PRESETS.map((preset) => (
|
||||
<Button key={preset.key} size="sm" variant="secondary" type="button" onClick={() => setRoleDraft(new Set(preset.roles))}>
|
||||
<Button key={preset.key} size="sm" variant="secondary" type="button" onClick={() => applyPreset(preset.roles)}>
|
||||
预设:{preset.label}
|
||||
</Button>
|
||||
))}
|
||||
@@ -79,6 +90,7 @@ export function UserRoleDialog({
|
||||
<input
|
||||
data-testid={`users-role-${item.code}`}
|
||||
type="checkbox"
|
||||
disabled={item.disabled}
|
||||
checked={roleDraft.has(item.code)}
|
||||
onChange={(event) => {
|
||||
setRoleDraft((prev) => {
|
||||
@@ -92,7 +104,7 @@ export function UserRoleDialog({
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<span>{item.label}</span>
|
||||
<span className={item.disabled ? "text-zinc-400" : undefined}>{item.label}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
|
||||
在新工单中引用
屏蔽一个用户