完成五人团队正式内用最小收口(07-18-small-team-internal-readiness)

这个提交包含在:
2026-07-18 15:46:14 +08:00
父节点 58c8decef9
当前提交 5d0a5f9a38
共修改 134 个文件,包含 10790 行新增和 1413 行删除
@@ -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>