import { ComparisonOperator, Employee, HeadType, ProjectRole, StepExecutorKind, TemplateRouteStep } from '../models'; import { comparisonOperatorSymbols, headTypeLabels, projectRoleLabels, texts } from '../texts'; import { findEmployeeByEmail } from './employee'; /** Каким из четырёх взаимоисключающих способов у шага задан исполнитель. */ /* eslint-disable @rushstack/no-new-null -- форма зеркалит TemplateRouteStep (nullable JSON-контракт бэкенда) */ export function detectExecutorKind(step: { executorEmail?: string | null; position?: string | null; projectRole?: ProjectRole | null; headType?: HeadType | null; }): StepExecutorKind { /* eslint-enable @rushstack/no-new-null */ if (step.executorEmail) return 'email'; if (step.position) return 'position'; if (step.projectRole && step.projectRole !== ProjectRole.None) return 'projectRole'; return 'headType'; } export interface StepExecutorDisplay { primary: string; /** Email под ФИО — только когда исполнитель задан конкретным сотрудником и тот найден в справочнике. */ secondary?: string; } /** Колонка «Исполнитель» в таблице шагов шаблона маршрута. */ export function describeStepExecutor(step: TemplateRouteStep, employees: Employee[]): StepExecutorDisplay { if (step.executorEmail) { const employee = findEmployeeByEmail(employees, step.executorEmail ?? undefined); return employee ? { primary: employee.fio, secondary: employee.email } : { primary: step.executorEmail }; } if (step.position) return { primary: step.position }; if (step.projectRole && step.projectRole !== ProjectRole.None) { return { primary: texts.routeSteps.executorRole(projectRoleLabels[step.projectRole]) }; } if (step.headType && step.headType !== HeadType.None) { return { primary: texts.routeSteps.executorHead(headTypeLabels[step.headType]) }; } return { primary: texts.common.empty }; } /** Колонка «Условие» в таблице шагов — undefined, если у шага условия нет. */ export function describeStepCondition(step: TemplateRouteStep): string | undefined { if (!step.fieldName || !step.operation || step.operation === ComparisonOperator.None || !step.value) return undefined; return `${step.fieldName} ${comparisonOperatorSymbols[step.operation]} ${step.value}`; }