diff --git a/src/webparts/requestPortal/forms/RecruitingSelection/RecruitingSelectionForm.tsx b/src/webparts/requestPortal/forms/RecruitingSelection/RecruitingSelectionForm.tsx index 262ff0d..06e724d 100644 --- a/src/webparts/requestPortal/forms/RecruitingSelection/RecruitingSelectionForm.tsx +++ b/src/webparts/requestPortal/forms/RecruitingSelection/RecruitingSelectionForm.tsx @@ -121,7 +121,7 @@ const RecruitingSelectionForm: React.FC = ({ }, [editId, editListId, notifyCode, setSubmitError]); // Компании ответственного (Employee/ByEmail.company/companyId) → предзаполнение - // «1.6 Организация» (Companies/CompanyPickerMulti). companyId из Employee/ByEmail + // «1.5 Организация» (Companies/CompanyPickerMulti). companyId из Employee/ByEmail // совпадает с Id из Dictionary/Companies (тот же источник) — доп. запрос не нужен. // Поле остаётся редактируемым: значения только ПРЕДЛАГАЮТСЯ, как и DepartmentName. const toCompanies = (records: IEmployeeOrganization[]): ICompany[] => @@ -450,7 +450,7 @@ const RecruitingSelectionForm: React.FC = ({ editor={matrix} search={(q) => approval.searchUsers(q)} waiting={!matrixReady} - waitingText="Выберите «Объект/Проект» (п. 1.7), чтобы построить маршрут согласования." + waitingText="Выберите «Объект/Проект» (п. 1.6), чтобы построить маршрут согласования." canRemoveRow={canRemoveApprover ? () => true : undefined} /> diff --git a/src/webparts/requestPortal/forms/RecruitingSelection/model.ts b/src/webparts/requestPortal/forms/RecruitingSelection/model.ts index 551080e..1095074 100644 --- a/src/webparts/requestPortal/forms/RecruitingSelection/model.ts +++ b/src/webparts/requestPortal/forms/RecruitingSelection/model.ts @@ -20,7 +20,7 @@ export interface IFormData { SubmitDate: string; ClosingDeadline: string; /** - * 1.5 Причины открытия вакансии. Одна причина — при одной вакансии; при 2.2 > 1 + * 2.3 Причины открытия вакансии. Одна причина — при одной вакансии; при 2.2 > 1 * можно несколько, и у причин с ФИО — несколько сотрудников. Хранится JSON в * колонке VacancyReasonsJson; старые колонки VacancyOpenReason (первая * причина) и VacancyOpenReasonDetails (сводка текстом) заполняются для @@ -83,7 +83,7 @@ export interface IFormData { HiringDecisionMaker: string[]; } -/** Одна причина открытия вакансии (п. 1.5). */ +/** Одна причина открытия вакансии (п. 2.3). */ export interface IVacancyReason { /** Значение из OPEN_REASON_OPTIONS. */ reason: string; diff --git a/src/webparts/requestPortal/forms/RecruitingSelection/sections/ApplicationSection.tsx b/src/webparts/requestPortal/forms/RecruitingSelection/sections/ApplicationSection.tsx index 586787a..8029c66 100644 --- a/src/webparts/requestPortal/forms/RecruitingSelection/sections/ApplicationSection.tsx +++ b/src/webparts/requestPortal/forms/RecruitingSelection/sections/ApplicationSection.tsx @@ -2,12 +2,8 @@ import * as React from 'react'; import { CollapseSection, FormField, TextInput, PeopleField } from '../../../shared/ui'; import { CompanyPickerMulti, ProjectPicker } from '../../../shared/dictionary'; import { ISectionProps, PERSON_PLACEHOLDER } from '../model'; -import { parseVacanciesCount } from '../vacancyReasons'; -import { VacancyReasonsField } from './VacancyReasonsField'; export const ApplicationSection: React.FC = ({ data, set, context, onResponsibleChange }) => { - const vacanciesCount = parseVacanciesCount(data.OpenVacanciesCount); - return ( @@ -38,19 +34,7 @@ export const ApplicationSection: React.FC = ({ data, set, context min={data.SubmitDate || undefined} /> - 1 ? '1.5 Причины открытия вакансий' : '1.5 Причина открытия вакансии'} - fieldKey="VacancyReasons" - required - full - > - set('VacancyReasons', v)} - vacanciesCount={vacanciesCount} - /> - - + = ({ data, set, context placeholder="Начните вводить название организации…" /> - + = ({ data, set, context }) => ( - - - { - set('Department', name); - set('DepartmentId', id); - }} - /> - - - set('OpenVacanciesCount', v !== '' && Number(v) < 0 ? '0' : v)} - /> - - -); +export const DepartmentSection: React.FC = ({ data, set, context }) => { + const vacanciesCount = parseVacanciesCount(data.OpenVacanciesCount); + + return ( + + + { + set('Department', name); + set('DepartmentId', id); + }} + /> + + + set('OpenVacanciesCount', v !== '' && Number(v) < 0 ? '0' : v)} + /> + + {/* Сразу под количеством: от него зависит, одна причина или несколько. */} + 1 ? '2.3 Причины открытия вакансий' : '2.3 Причина открытия вакансии'} + fieldKey="VacancyReasons" + required + full + > + set('VacancyReasons', v)} + vacanciesCount={vacanciesCount} + /> + + + ); +}; diff --git a/src/webparts/requestPortal/forms/RecruitingSelection/sections/VacancyReasonsField.tsx b/src/webparts/requestPortal/forms/RecruitingSelection/sections/VacancyReasonsField.tsx index 7f35144..3b569cf 100644 --- a/src/webparts/requestPortal/forms/RecruitingSelection/sections/VacancyReasonsField.tsx +++ b/src/webparts/requestPortal/forms/RecruitingSelection/sections/VacancyReasonsField.tsx @@ -13,7 +13,7 @@ interface IVacancyReasonsFieldProps { } /** - * 1.5 Причины открытия вакансии. + * 2.3 Причины открытия вакансии. * * Одна вакансия — выпадающий список, одна причина, один сотрудник. Больше одной * — флажки: несколько причин, у причин с ФИО — несколько сотрудников. Если diff --git a/src/webparts/requestPortal/forms/RecruitingSelection/vacancyReasons.ts b/src/webparts/requestPortal/forms/RecruitingSelection/vacancyReasons.ts index d3e3c5f..93d6d28 100644 --- a/src/webparts/requestPortal/forms/RecruitingSelection/vacancyReasons.ts +++ b/src/webparts/requestPortal/forms/RecruitingSelection/vacancyReasons.ts @@ -7,7 +7,7 @@ import { } from './model'; /** - * Причины открытия вакансии (п. 1.5): несколько причин при 2.2 > 1 и несколько + * Причины открытия вакансии (п. 2.3): несколько причин при 2.2 > 1 и несколько * сотрудников на причину. Логика без UI — разбор/сводка/проверки. * * Хранение: полная структура — JSON в VacancyReasonsJson (из неё читает @@ -113,7 +113,7 @@ export function allowsMultipleReasons(vacanciesCount: number): boolean { /** Блокирующая проблема для отправки: несколько причин при одной вакансии. */ export function vacancyReasonsError(reasons: IVacancyReason[], vacanciesCount: number): string | undefined { if (!allowsMultipleReasons(vacanciesCount) && reasons.length > 1) { - return 'При одной вакансии оставьте одну причину открытия (п. 1.5) или увеличьте количество вакансий (п. 2.2).'; + return 'При одной вакансии оставьте одну причину открытия (п. 2.3) или увеличьте количество вакансий (п. 2.2).'; } return undefined; } @@ -122,7 +122,7 @@ export function vacancyReasonsError(reasons: IVacancyReason[], vacanciesCount: n export function vacancyReasonsWarning(reasons: IVacancyReason[], vacanciesCount: number): string | undefined { const employees = cleanVacancyReasons(reasons).reduce((sum, r) => sum + r.employees.length, 0); if (vacanciesCount > 0 && employees > vacanciesCount) { - return `Указано сотрудников: ${employees}, а вакансий: ${vacanciesCount}. Проверьте п. 1.5 и 2.2.`; + return `Указано сотрудников: ${employees}, а вакансий: ${vacanciesCount}. Проверьте п. 2.2 и 2.3.`; } return undefined; } diff --git a/src/webparts/requestPortal/forms/RecruitingSelection/validation.ts b/src/webparts/requestPortal/forms/RecruitingSelection/validation.ts index 28a4dc0..e43d2e6 100644 --- a/src/webparts/requestPortal/forms/RecruitingSelection/validation.ts +++ b/src/webparts/requestPortal/forms/RecruitingSelection/validation.ts @@ -17,10 +17,10 @@ import { parseVacanciesCount, vacancyReasonsError } from './vacancyReasons'; const REQUIRED_FIELDS: ReadonlyArray<{ label: string; ok: (d: IFormData) => boolean }> = [ { label: '1.3 дата подачи заявки', ok: (d) => !!d.SubmitDate }, { label: '1.4 крайний срок закрытия', ok: (d) => !!d.ClosingDeadline }, - { label: '1.5 причина открытия вакансии', ok: (d) => d.VacancyReasons.length > 0 }, - { label: '1.6 организация', ok: (d) => d.Companies.length > 0 }, + { label: '1.5 организация', ok: (d) => d.Companies.length > 0 }, { label: '2.1 подразделение', ok: (d) => !!d.Department.trim() }, { label: '2.2 количество открытых вакансий', ok: (d) => !!d.OpenVacanciesCount.trim() }, + { label: '2.3 причина открытия вакансии', ok: (d) => d.VacancyReasons.length > 0 }, { label: '3.2 характер занятости', ok: (d) => !!d.EmploymentType }, { label: '3.3 функционал', ok: (d) => !!d.JobFunction.trim() }, { label: '3.4 компетенции', ok: (d) => !!d.Competencies.trim() },