From 17f9dec39b83aa3f42d183c7a53dea683ced99f2 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: Wed, 28 Oct 2026 14:43:35 +0500 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=BF=D0=BE=D0=BB=D1=8F=20=D0=B2=D0=B8?= =?UTF-8?q?=D0=B4=D0=B0=20=C2=AB=D0=9F=D0=BE=D0=B2=D1=8B=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B4=D0=BE=D0=BB=D0=B6=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BE=D0=BA=D0=BB=D0=B0=D0=B4=D0=B0?= =?UTF-8?q?=C2=BB=20=D0=B2=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B8=20=D1=83=D1=81=D0=BB=D0=BE=D0=B2=D0=B8=D0=B9=20?= =?UTF-8?q?=D0=A2=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Первый разобранный с кадрами вид: текущий и новый оклад, дата, причина (испытательный срок / расширение функционала / иное) и обоснование — оно же текст причины «иное». Всё необязательно. Поля вида живут в своей секции byType/, а колонки невыбранного вида при сохранении очищаются, чтобы после смены вида в заявке не оставалось скрытых значений. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../ContractChange/ContractChangeForm.tsx | 2 + .../ContractChange/ContractChangeView.tsx | 2 + .../forms/ContractChange/README.md | 13 ++++- .../byType/ChangeTypeSections.tsx | 23 ++++++++ .../SalaryIncrease/SalaryIncreaseSection.tsx | 56 +++++++++++++++++++ .../byType/SalaryIncrease/reasons.ts | 16 ++++++ .../forms/ContractChange/load.ts | 21 ++++++- .../forms/ContractChange/model.ts | 19 ++++++- .../forms/ContractChange/provisioning.json | 12 +++- .../forms/ContractChange/submit.ts | 32 ++++++++++- 10 files changed, 190 insertions(+), 6 deletions(-) create mode 100644 src/webparts/requestPortal/forms/ContractChange/byType/ChangeTypeSections.tsx create mode 100644 src/webparts/requestPortal/forms/ContractChange/byType/SalaryIncrease/SalaryIncreaseSection.tsx create mode 100644 src/webparts/requestPortal/forms/ContractChange/byType/SalaryIncrease/reasons.ts diff --git a/src/webparts/requestPortal/forms/ContractChange/ContractChangeForm.tsx b/src/webparts/requestPortal/forms/ContractChange/ContractChangeForm.tsx index 10e5097..b317840 100644 --- a/src/webparts/requestPortal/forms/ContractChange/ContractChangeForm.tsx +++ b/src/webparts/requestPortal/forms/ContractChange/ContractChangeForm.tsx @@ -47,6 +47,7 @@ import { saveContractChangeRequest, contractChangeApprovalService } from './subm import { loadContractChangeRequest } from './load'; import { useSelfEmployee } from './useSelfEmployee'; import { RequestSection } from './sections/RequestSection'; +import { ChangeTypeSections } from './byType/ChangeTypeSections'; import { useStableCallback } from '../../shared/useStableCallback'; const ContractChangeForm: React.FC = ({ @@ -258,6 +259,7 @@ const ContractChangeForm: React.FC = ({ + = ({ context, itemI > + diff --git a/src/webparts/requestPortal/forms/ContractChange/README.md b/src/webparts/requestPortal/forms/ContractChange/README.md index ab64438..551a720 100644 --- a/src/webparts/requestPortal/forms/ContractChange/README.md +++ b/src/webparts/requestPortal/forms/ContractChange/README.md @@ -39,13 +39,24 @@ RequestTypeId» в `docs/forms.md`). Тип и маршрут в админке менять только вместе с `provisioning.json`. - **Заголовок элемента** (`Title`): `Изменение условий ТД — {ФИО} — дд.мм.гггг`. +## Поля по видам +Каждый вид — своя секция в `byType/<Вид>/`, подключается строкой в +`byType/ChangeTypeSections.tsx`; ключи модели и колонки SP — с префиксом вида. +Колонки невыбранного вида при сохранении очищаются (`null`), чтобы в заявке не +оставалось скрытых значений после смены вида. + +| Вид | Секция | Поля (все необязательные, без ограничений) | +| --- | --- | --- | +| Повышение должностного оклада | `SalaryIncrease` | текущий оклад, новый оклад (`MoneyInput`, Number), дата изменения, причина (испытательный срок / расширение функционала / иное), обоснование — при «иное» это и есть текст причины | +| Остальные 9 | — | ещё не разобраны с кадрами | + ## Открытые вопросы (проверить на тесте) - Выдаёт ли бэкенд (вебхуки) права на элемент по People-колонке `Employee`? Если да — сотрудник, за которого подали заявку, её не увидит (такой колонки здесь нет). - `Employee/FullBase`: ищет ли `Fio` по подстроке; что фильтрует `Status`. ## Секции формы -RequestSection (сотрудник · вид изменения) +RequestSection (сотрудник · вид изменения) · ChangeTypeSections (секция выбранного вида, см. «Поля по видам») ## Точки входа - rptype: `hr-contract-change` diff --git a/src/webparts/requestPortal/forms/ContractChange/byType/ChangeTypeSections.tsx b/src/webparts/requestPortal/forms/ContractChange/byType/ChangeTypeSections.tsx new file mode 100644 index 0000000..5f8ed6b --- /dev/null +++ b/src/webparts/requestPortal/forms/ContractChange/byType/ChangeTypeSections.tsx @@ -0,0 +1,23 @@ +import * as React from 'react'; +import { ChangeType } from '../changeTypes'; +import { ISectionProps } from '../model'; +import { SalaryIncreaseSection } from './SalaryIncrease/SalaryIncreaseSection'; + +/** + * Вид изменения → секция с его полями. Partial: поля видов добавляются по мере + * согласования с кадрами; у вида без секции под выбором просто ничего не появится. + * Новый вид = папка byType/<Вид>/ + строка здесь. + */ +const SECTION_BY_TYPE: Partial>> = { + 'salary-increase': SalaryIncreaseSection +}; + +/** Секции всех выбранных видов, в порядке выбора (сейчас вид один — см. MAX_CHANGE_TYPES). */ +export const ChangeTypeSections: React.FC = (props) => ( + <> + {props.data.ChangeTypes.map((type) => { + const Section = SECTION_BY_TYPE[type]; + return Section ?
: undefined; + })} + +); diff --git a/src/webparts/requestPortal/forms/ContractChange/byType/SalaryIncrease/SalaryIncreaseSection.tsx b/src/webparts/requestPortal/forms/ContractChange/byType/SalaryIncrease/SalaryIncreaseSection.tsx new file mode 100644 index 0000000..c094885 --- /dev/null +++ b/src/webparts/requestPortal/forms/ContractChange/byType/SalaryIncrease/SalaryIncreaseSection.tsx @@ -0,0 +1,56 @@ +import * as React from 'react'; +import { CollapseSection, FormField, MoneyInput, TextInput, TextArea, Select } from '../../../../shared/ui'; +import { CHANGE_TYPE_LABELS } from '../../changeTypes'; +import { ISectionProps } from '../../model'; +import { SALARY_INCREASE_REASONS } from './reasons'; + +/** + * Поля вида «Повышение должностного оклада». Состав согласован с Тимуром по ТЗ + * кадров: было/стало, дата, причина (а/б/в) и обоснование. Все необязательные, + * без ограничений — по решению от 2026-10-28. + * + * Поля — прямо в CollapseSection, без FormGrid: тело секции само является + * двухколоночной сеткой, вложенная FormGrid сжала бы всё в одну её ячейку. + */ +export const SalaryIncreaseSection: React.FC = ({ data, set }) => ( + + + set('SalaryIncreaseCurrent', v)} + /> + + + set('SalaryIncreaseNew', v)} + /> + + + set('SalaryIncreaseDate', v)} + /> + + +