From 4f0d02fe5916b2406d4f6529ce39b3adbba7199f 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: Fri, 16 Oct 2026 15:44:35 +0500 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=B2=20=D0=B7=D0=B0=D1=8F=D0=B2=D0=BA?= =?UTF-8?q?=D0=B5=201=D0=A1=20=D0=B4=D0=B0=D1=82=D0=B0=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BF=D1=80=D0=B5=D1=82=D0=B0=20=D0=BF=D0=BE=20=D0=90=D0=A2?= =?UTF-8?q?=D0=9F=20=D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D1=8F=D0=B5=D1=82?= =?UTF-8?q?=D1=81=D1=8F=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B1=D0=B0=D0=B7=D1=83=20=D0=90=D0=A2=D0=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit При виде работ «Дата запрета (открытие/закрытие)» и выбранной базе АТП остальные базы снимаются и добавить их нельзя — дата запрета по АТП открывается/закрывается отдельно. Над полем «База 1С» при этом виде работ показывается предупреждение. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../requestPortal/forms/Ticket1C/config.ts | 7 +++ .../forms/Ticket1C/model.test.ts | 17 +++++++ .../requestPortal/forms/Ticket1C/model.ts | 21 +++++++++ .../sections/RequestSection.module.scss | 4 ++ .../Ticket1C/sections/RequestSection.tsx | 46 +++++++++++++++---- 5 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 src/webparts/requestPortal/forms/Ticket1C/model.test.ts create mode 100644 src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.module.scss diff --git a/src/webparts/requestPortal/forms/Ticket1C/config.ts b/src/webparts/requestPortal/forms/Ticket1C/config.ts index 534356c..8442a53 100644 --- a/src/webparts/requestPortal/forms/Ticket1C/config.ts +++ b/src/webparts/requestPortal/forms/Ticket1C/config.ts @@ -10,6 +10,13 @@ export const CHOICES_LOADING_PLACEHOLDER = 'Загрузка вариантов export const CHOICES_EMPTY_PLACEHOLDER = 'Нет вариантов — обратитесь к администратору'; export const CHOICES_ERROR_PREFIX = 'Не удалось загрузить варианты полей'; +// Подсказка в поле «База 1С», когда сработало правило «дата запрета по АТП». +export const DB1C_ATP_ONLY_HINT = 'Для даты запрета по АТП другие базы не выбираются'; +// Предупреждение над полем «База 1С» при виде работ «Дата запрета». +export const DB1C_ATP_ONLY_WARNING = + 'Для даты запрета (открытие/закрытие) по базе АТП можно выбрать только АТП — ' + + 'дополнительные базы недоступны.'; + // Значения из property pane старой web part (см. живую страницу SharePoint). export const PLANNER_PLAN_ID = '168WqDV8CEKkW3cL6olCRZgACwYa'; export const PLANNER_BUCKET_NAME = 'Входящие неотсортированные'; diff --git a/src/webparts/requestPortal/forms/Ticket1C/model.test.ts b/src/webparts/requestPortal/forms/Ticket1C/model.test.ts new file mode 100644 index 0000000..4e8c228 --- /dev/null +++ b/src/webparts/requestPortal/forms/Ticket1C/model.test.ts @@ -0,0 +1,17 @@ +import { DB1C_ATP_OPTION, WORK_TYPE_BAN_DATE, restrictDatabases } from './model'; + +const ZUP = '1С: Зарплата и управление персоналом (ЗУП)'; + +describe('Ticket1C restrictDatabases', () => { + it('дата запрета + АТП — остаётся только АТП', () => { + expect(restrictDatabases(WORK_TYPE_BAN_DATE, [ZUP, DB1C_ATP_OPTION])).toEqual([DB1C_ATP_OPTION]); + }); + + it('дата запрета без АТП — базы не трогаем', () => { + expect(restrictDatabases(WORK_TYPE_BAN_DATE, [ZUP])).toEqual([ZUP]); + }); + + it('другой вид работ — АТП можно сочетать с другими базами', () => { + expect(restrictDatabases('Прочее', [ZUP, DB1C_ATP_OPTION])).toEqual([ZUP, DB1C_ATP_OPTION]); + }); +}); diff --git a/src/webparts/requestPortal/forms/Ticket1C/model.ts b/src/webparts/requestPortal/forms/Ticket1C/model.ts index 988ad14..acfe458 100644 --- a/src/webparts/requestPortal/forms/Ticket1C/model.ts +++ b/src/webparts/requestPortal/forms/Ticket1C/model.ts @@ -44,6 +44,27 @@ export function hasOtherDatabase(data: IFormData): boolean { return data.DB1C.indexOf(DB1C_OTHER_OPTION) !== -1; } +/** + * Варианты колонок SP, для которых действует правило «дата запрета по АТП — + * только одна база». Должны дословно совпадать с вариантами колонок + * WorkType и DB1C в SharePoint (варианты читаются из SP, см. useFieldChoices). + */ +export const WORK_TYPE_BAN_DATE = 'Дата запрета (открытие/закрытие)'; +export const DB1C_ATP_OPTION = '1С: Автотранспортное предприятие (АТП)'; + +/** + * Дата запрета в АТП открывается/закрывается отдельно от остальных баз, + * поэтому в такой заявке база АТП может быть только одна. + */ +export function isAtpOnlyBanDate(workType: string, databases: string[]): boolean { + return workType === WORK_TYPE_BAN_DATE && databases.indexOf(DB1C_ATP_OPTION) !== -1; +} + +/** Применяет правило isAtpOnlyBanDate: при его срабатывании оставляет только АТП. */ +export function restrictDatabases(workType: string, databases: string[]): string[] { + return isAtpOnlyBanDate(workType, databases) ? [DB1C_ATP_OPTION] : databases; +} + /** Обновление одного поля формы с сохранением типа значения. */ export type SetField = (key: K, value: IFormData[K]) => void; diff --git a/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.module.scss b/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.module.scss new file mode 100644 index 0000000..72d7a3f --- /dev/null +++ b/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.module.scss @@ -0,0 +1,4 @@ +// Строка на обе колонки сетки секции — как FormField с full. +.fullRow { + grid-column: 1 / -1; +} diff --git a/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.tsx b/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.tsx index 805d44d..0cd2e8e 100644 --- a/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.tsx +++ b/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.tsx @@ -1,10 +1,21 @@ import * as React from 'react'; +import styles from './RequestSection.module.scss'; import { Alert, CollapseSection, FormField, MultiChoiceField, Select, TextArea, TextInput, ISelectOption } from '../../../shared/ui'; import { useFieldChoices, IFieldChoicesState } from '../../../shared/fieldChoices'; import { dataListTitle } from '../../../shared/listTitles'; -import { DB1C_OTHER_OPTION, FORM_ID, ISectionProps, hasOtherDatabase } from '../model'; +import { + DB1C_OTHER_OPTION, + FORM_ID, + WORK_TYPE_BAN_DATE, + ISectionProps, + hasOtherDatabase, + isAtpOnlyBanDate, + restrictDatabases +} from '../model'; import { QUESTION_MAX, + DB1C_ATP_ONLY_HINT, + DB1C_ATP_ONLY_WARNING, CHOICES_LOADING_PLACEHOLDER, CHOICES_EMPTY_PLACEHOLDER, CHOICES_ERROR_PREFIX @@ -30,6 +41,16 @@ export const RequestSection: React.FC = ({ data, set }) => { const organizations = useFieldChoices(listTitle, 'Organization'); const databases = useFieldChoices(listTitle, 'DB1C'); const choicesError = workTypes.error || organizations.error || databases.error; + const isAtpOnly = isAtpOnlyBanDate(data.WorkType, data.DB1C); + + // Правило «дата запрета по АТП» зависит и от вида работ, и от баз — поэтому + // применяется при смене любого из двух полей. + const setDatabases = (workType: string, values: string[]): void => { + const restricted = restrictDatabases(workType, values); + set('DB1C', restricted); + // Сняли «Другое» — вписанное название больше не относится к заявке. + if (restricted.indexOf(DB1C_OTHER_OPTION) === -1) set('DB1COther', ''); + }; return ( @@ -41,7 +62,10 @@ export const RequestSection: React.FC = ({ data, set }) => {