Files
ftb-project-management/apps/web/lib/version-members.ts
2026-06-26 15:33:07 +08:00

59 lines
2.3 KiB
TypeScript

import type { Role } from './stage';
export interface VersionMember {
name: string;
role: Role;
}
export interface VersionMemberCandidate {
id: string;
name: string;
departmentName?: string;
}
export const DEFAULT_VERSION_MEMBER_ROLE: Role = 'frontend';
export function inferVersionMemberRole(
member: Partial<VersionMemberCandidate>,
defaultRole: Role = DEFAULT_VERSION_MEMBER_ROLE,
): Role {
const departmentName = member.departmentName?.toLowerCase() ?? '';
if (!departmentName) return defaultRole;
if (departmentName.includes('产品') || departmentName.includes('product')) return 'product';
if (departmentName.includes('设计') || departmentName.includes('ui') || departmentName.includes('ux')) return 'ui';
if (departmentName.includes('测试') || departmentName.includes('质量') || departmentName.includes('qa')) return 'testing';
if (departmentName.includes('后端') || departmentName.includes('backend') || departmentName.includes('server')) return 'backend';
if (departmentName.includes('前端') || departmentName.includes('frontend') || departmentName.includes('web') || departmentName.includes('client')) return 'frontend';
return defaultRole;
}
export function filterVersionMemberCandidates(
allMembers: VersionMemberCandidate[],
currentMembers: VersionMember[],
query: string,
): VersionMemberCandidate[] {
const existingNames = new Set(currentMembers.map((member) => member.name));
const normalizedQuery = query.trim().toLowerCase();
return allMembers.filter((member) => {
if (existingNames.has(member.name)) return false;
if (!normalizedQuery) return true;
return member.name.toLowerCase().includes(normalizedQuery);
});
}
export function addVersionMembers(
currentMembers: VersionMember[],
selectedNames: Iterable<string>,
allMembers: VersionMemberCandidate[],
defaultRole: Role = DEFAULT_VERSION_MEMBER_ROLE,
): VersionMember[] {
const existingNames = new Set(currentMembers.map((member) => member.name));
const selectedNameSet = new Set(selectedNames);
const additions = allMembers
.filter((member) => selectedNameSet.has(member.name) && !existingNames.has(member.name))
.map((member) => ({ name: member.name, role: inferVersionMemberRole(member, defaultRole) }));
return [...currentMembers, ...additions];
}