From 1884007161392053643686358290baefcbbc5020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B8=D0=BC=D1=83=D1=80=20=D0=93=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=B4=D0=B5=D1=86=D0=BA=D0=B8=D0=B9?= Date: Thu, 24 Sep 2026 17:58:34 +0500 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B7=D0=B0=D1=8F=D0=B2=D0=BA=D0=B8=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B1=D0=BE=D1=80=20=C2=AB=D0=9F?= =?UTF-8?q?=D0=BE=D0=B4=D0=B1=D0=BE=D1=80=20=E2=80=94=20=D0=94=D0=BE=D0=BB?= =?UTF-8?q?=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20=E2=80=94=20=D0=9F=D1=80?= =?UTF-8?q?=D0=BE=D0=B5=D0=BA=D1=82=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../requestPortal/forms/RecruitingHire/submit.ts | 5 +++-- .../forms/RecruitingSelection/submit.ts | 10 ++++++++-- .../requestPortal/shared/requestTitle.test.ts | 12 ++++++++++++ src/webparts/requestPortal/shared/requestTitle.ts | 12 ++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/webparts/requestPortal/shared/requestTitle.test.ts create mode 100644 src/webparts/requestPortal/shared/requestTitle.ts diff --git a/src/webparts/requestPortal/forms/RecruitingHire/submit.ts b/src/webparts/requestPortal/forms/RecruitingHire/submit.ts index 19814df..bee6fec 100644 --- a/src/webparts/requestPortal/forms/RecruitingHire/submit.ts +++ b/src/webparts/requestPortal/forms/RecruitingHire/submit.ts @@ -1,6 +1,7 @@ import { ApprovalListService, IApproverToWrite, approvalServiceFor, writeRoute } from '../../shared/approval'; import { ISaveItemResult, resolveDataList, saveRequestItem } from '../../shared/dataList'; import { IFieldChange, serializeFieldChanges } from '../../shared/fieldChanges/fieldChanges'; +import { buildRequestTitle } from '../../shared/requestTitle'; import { FORM_ID, IFormData } from './model'; import { APPROVER_CHANGES_FIELD } from './changeTracking'; @@ -16,9 +17,9 @@ export function hireApprovalService(listId?: string): ApprovalListService { return approvalServiceFor(FORM_ID, listId); } -/** Осмысленный заголовок элемента списка (системная колонка Title). */ +/** Название заявки (Title): «Прием — ФИО кандидата — Должность». */ function buildTitle(data: IFormData): string { - return ['Прием', data.HireCandidateName, data.Position].filter(Boolean).join(' — '); + return buildRequestTitle('Прием', [data.HireCandidateName, data.Position]); } /** Поля элемента списка данных из модели формы (текст/выбор/даты/числа), без статуса. */ diff --git a/src/webparts/requestPortal/forms/RecruitingSelection/submit.ts b/src/webparts/requestPortal/forms/RecruitingSelection/submit.ts index 93b8342..8b1950c 100644 --- a/src/webparts/requestPortal/forms/RecruitingSelection/submit.ts +++ b/src/webparts/requestPortal/forms/RecruitingSelection/submit.ts @@ -2,6 +2,7 @@ import { getSP } from '../../shared/pnp/pnpjs'; import { ApprovalListService, IApproverToWrite, approvalServiceFor, writeRoute } from '../../shared/approval'; import { ISaveItemResult, resolveDataList, saveRequestItem } from '../../shared/dataList'; import { IFieldChange, serializeFieldChanges } from '../../shared/fieldChanges/fieldChanges'; +import { buildRequestTitle } from '../../shared/requestTitle'; import { FORM_ID, IFormData } from './model'; import { APPROVER_CHANGES_FIELD } from './changeTracking'; @@ -27,9 +28,14 @@ async function resolveUserId(login: string): Promise { return ensured.Id; } -/** Скалярные/числовые/да-нет поля из модели (людей и статус пропускаем — они отдельно). */ +/** Название заявки (Title): «Подбор — Должность — Объект/Проект». */ +function buildTitle(data: IFormData): string { + return buildRequestTitle('Подбор', [data.Position, data.ObjectProject]); +} + +/** Скалярные/числовые/да-нет поля из модели + название (людей и статус пропускаем — они отдельно). */ function buildScalarBody(data: IFormData): Record { - const item: Record = {}; + const item: Record = { Title: buildTitle(data) }; (Object.keys(data) as (keyof IFormData)[]).forEach((key) => { if (PERSON_FIELDS.indexOf(key) !== -1 || MULTI_PERSON_FIELDS.indexOf(key) !== -1) { return; diff --git a/src/webparts/requestPortal/shared/requestTitle.test.ts b/src/webparts/requestPortal/shared/requestTitle.test.ts new file mode 100644 index 0000000..2497a67 --- /dev/null +++ b/src/webparts/requestPortal/shared/requestTitle.test.ts @@ -0,0 +1,12 @@ +import { buildRequestTitle } from './requestTitle'; + +describe('buildRequestTitle', () => { + it('склеивает тип и части через тире', () => { + expect(buildRequestTitle('Подбор', ['Инженер', 'Проект X'])).toBe('Подбор — Инженер — Проект X'); + }); + + it('пропускает пустые и пробельные части', () => { + expect(buildRequestTitle('Подбор', ['', ' Проект X '])).toBe('Подбор — Проект X'); + expect(buildRequestTitle('Прием', ['', ''])).toBe('Прием'); + }); +}); diff --git a/src/webparts/requestPortal/shared/requestTitle.ts b/src/webparts/requestPortal/shared/requestTitle.ts new file mode 100644 index 0000000..63c7157 --- /dev/null +++ b/src/webparts/requestPortal/shared/requestTitle.ts @@ -0,0 +1,12 @@ +/** Разделитель частей названия заявки. */ +const TITLE_SEPARATOR = ' — '; + +/** + * Название заявки (системная колонка Title списка данных): тип + ключевые + * поля через тире, пустые части пропускаются — «Подбор — Инженер — Проект X». + * По нему заявку узнают в списке SP, в столбце «Заявка» списка согласования + * и в колонке «Название» таблиц портала. + */ +export function buildRequestTitle(typeLabel: string, parts: string[]): string { + return [typeLabel, ...parts.map((p) => p.trim())].filter(Boolean).join(TITLE_SEPARATOR); +}