diff --git a/src/webparts/requestPortal/forms/RecruitingHire/RecruitingHireForm.tsx b/src/webparts/requestPortal/forms/RecruitingHire/RecruitingHireForm.tsx index 52b249f..d0d8f9d 100644 --- a/src/webparts/requestPortal/forms/RecruitingHire/RecruitingHireForm.tsx +++ b/src/webparts/requestPortal/forms/RecruitingHire/RecruitingHireForm.tsx @@ -158,7 +158,8 @@ const RecruitingHireForm: React.FC = ({ // найден». Сейчас в маршруте условий по проекту нет, но проверка projectId на // бэкенде не подтверждена снятой — поэтому передаём ПЕРВЫЙ выбранный проект // (поле — мультивыбор) и ждём его выбора, как раньше. - const projectId = data.Projects.length > 0 ? data.Projects[0].Id : null; + // Пустой Id — проект старой заявки, введённый вручную (см. projectsFromItem). + const projectId = (data.Projects.length > 0 && data.Projects[0].Id) || null; const matrixReady = !!editId || (!!projectId && !!requestTypeId); // Несколько шагов маршрута условны по компании (см. панель «Маршруты»: // «CompaniesJson = TOO QAZGEOMAX», «CompaniesJson = TOO CT Global», шаг с diff --git a/src/webparts/requestPortal/forms/RecruitingHire/projects.test.ts b/src/webparts/requestPortal/forms/RecruitingHire/projects.test.ts index 2a93cc4..ef0ef0a 100644 --- a/src/webparts/requestPortal/forms/RecruitingHire/projects.test.ts +++ b/src/webparts/requestPortal/forms/RecruitingHire/projects.test.ts @@ -35,8 +35,15 @@ describe('RecruitingHire projects', () => { expect(projectsFromItem({ Project: 'КЭС Курчатов', ProjectId: 'g-kes', ProjectCode: 'БК0000068' })).toEqual([KES]); }); - it('старая заявка с проектом, введённым вручную (без Id), — проектов нет', () => { - expect(projectsFromItem({ Project: 'что-то вручную', ProjectId: null })).toEqual([]); + it('старая заявка с проектом, введённым вручную (без Id), — проект сохраняется по тексту', () => { + const projects = projectsFromItem({ Project: 'что-то вручную', ProjectId: null }); + expect(projects).toEqual([{ Id: '', Name: 'что-то вручную', Code: '' }]); + // Пересохранение не стирает текст и не пишет пустой Id. + expect(projectColumns(projects)).toMatchObject({ Project: 'что-то вручную', ProjectId: null }); + }); + + it('старая заявка без проекта — проектов нет', () => { + expect(projectsFromItem({ Project: null, ProjectId: null })).toEqual([]); }); it('битый JSON не роняет загрузку', () => { diff --git a/src/webparts/requestPortal/forms/RecruitingHire/projects.ts b/src/webparts/requestPortal/forms/RecruitingHire/projects.ts index 13a26c1..cdd993a 100644 --- a/src/webparts/requestPortal/forms/RecruitingHire/projects.ts +++ b/src/webparts/requestPortal/forms/RecruitingHire/projects.ts @@ -30,7 +30,8 @@ export function projectColumns(projects: IProjectRef[]): IProjectColumns { return { ProjectsJson: JSON.stringify(projects), Project: truncateSpText(projectNames(projects)), - ProjectId: projects[0].Id, + // Пустой Id — проект из старой заявки, введённый вручную (см. projectsFromItem). + ProjectId: projects[0].Id || null, ProjectCode: codes.length > 0 ? truncateSpText(codes.join(LEGACY_SEPARATOR)) : null }; } @@ -42,22 +43,21 @@ export function projectNames(projects: IProjectRef[]): string { /** * Проекты из элемента списка. Заявки, поданные до мультивыбора, ProjectsJson не - * имеют — тогда собираем один проект из старых колонок (если он был выбран из - * справочника, т.е. есть ProjectId). + * имеют — тогда собираем один проект из старых колонок. + * + * Старый одиночный пикер допускал ручной ввод без выбора из справочника (Id + * пустой). Такой проект тоже сохраняем — с пустым Id: иначе поле открылось бы + * пустым, а пересохранение заявки (например, правка всех полей согласующим) + * стёрло бы текст проекта в колонке Project. */ export function projectsFromItem(item: Record): IProjectRef[] { const fromJson = parseProjectsJson(item.ProjectsJson); if (fromJson.length > 0) return fromJson; const id = typeof item.ProjectId === 'string' ? item.ProjectId : ''; - if (!id) return []; - return [ - { - Id: id, - Name: typeof item.Project === 'string' ? item.Project : '', - Code: typeof item.ProjectCode === 'string' ? item.ProjectCode : '' - } - ]; + const name = typeof item.Project === 'string' ? item.Project.trim() : ''; + if (!id && !name) return []; + return [{ Id: id, Name: name, Code: typeof item.ProjectCode === 'string' ? item.ProjectCode : '' }]; } function parseProjectsJson(raw: unknown): IProjectRef[] {