From e9b0df48228b5772b66c6d30d4679f27743e5b31 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, 25 Sep 2026 14:37:42 +0500 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=B2=D0=B0=D1=80=D0=B8=D0=B0=D0=BD?= =?UTF-8?q?=D1=82=D1=8B=20=D0=BF=D0=BE=D0=BB=D0=B5=D0=B9=20=D0=B7=D0=B0?= =?UTF-8?q?=D1=8F=D0=B2=D0=BA=D0=B8=201=D0=A1=20=D0=B8=D0=B7=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BB=D0=BE=D0=BD=D0=BE=D0=BA=20SP=20+=20=D0=B2=D0=B8?= =?UTF-8?q?=D0=B4=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=20=C2=AB=D0=9C=D0=B0?= =?UTF-8?q?=D1=80=D1=88=D1=80=D1=83=D1=82=D1=8B=20=D0=B2=20=D0=94=D0=9E?= =?UTF-8?q?=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit «Виды работ», «Организация» и «База 1С» теперь читаются из колонок списка (общий хук shared/fieldChoices), а не из констант: новый пункт добавляется в параметрах столбца без правки кода и деплоя. Пилот — на форме 1С, при успехе переводим остальные формы. В стартовые варианты provisioning.json добавлен «Маршруты в ДО». Co-Authored-By: Claude Opus 5.5 (1M context) --- .../requestPortal/forms/Ticket1C/config.ts | 48 ++----- .../forms/Ticket1C/provisioning.json | 3 +- .../Ticket1C/sections/RequestSection.tsx | 120 +++++++++++------- .../fieldChoices/fieldChoices.service.ts | 40 ++++++ .../shared/fieldChoices/index.ts | 3 + .../shared/fieldChoices/useFieldChoices.ts | 36 ++++++ 6 files changed, 162 insertions(+), 88 deletions(-) create mode 100644 src/webparts/requestPortal/shared/fieldChoices/fieldChoices.service.ts create mode 100644 src/webparts/requestPortal/shared/fieldChoices/index.ts create mode 100644 src/webparts/requestPortal/shared/fieldChoices/useFieldChoices.ts diff --git a/src/webparts/requestPortal/forms/Ticket1C/config.ts b/src/webparts/requestPortal/forms/Ticket1C/config.ts index 986d05b..534356c 100644 --- a/src/webparts/requestPortal/forms/Ticket1C/config.ts +++ b/src/webparts/requestPortal/forms/Ticket1C/config.ts @@ -1,45 +1,15 @@ -// Варианты Choice-полей — см. forms/Ticket1C/provisioning.json (единый источник правды). - -export const WORK_TYPE_OPTIONS: string[] = [ - 'Создание пользователя в 1С', - 'Расширение прав доступа / предоставление доступа к документам других пользователей', - 'Открытие даты запрета', - 'Прочее', - 'Не работает 1С', - 'Блокировка пользователя', -]; - -export const ORGANIZATION_OPTIONS: string[] = [ - 'AFL Engineering', - 'CL MANAGEMENT', - 'KazPromService', - 'QAZGEOMAX', - 'TANSU Construction', - 'АСТЕЛ-К', - 'ГеоТрек', - 'Монтажник-Т', - 'ОСН Беркут', - 'CT Global', -]; - -export const DB1C_OPTIONS: string[] = [ - '1С: Зарплата и управление персоналом (ЗУП)', - '1С: Документооборот (ДО)', - '1С: Автотранспортное предприятие (АТП)', - '1С: БСО TANSU Construction', - '1С: Бухгалтерия AFL Engineering', - '1С: Бухгалтерия CL MANAGEMENT', - '1С: Бухгалтерия KazPromService', - '1С: Бухгалтерия QAZGEOMAX', - '1С: Бухгалтерия АСТЕЛ-К', - '1С: Бухгалтерия ГеоТрек', - '1С: Бухгалтерия Монтажник-Т', - '1С: Бухгалтерия ОСН Беркут', - '1С: Бухгалтерия CT Global', -]; +// Варианты «Видов работ», «Организации» и «Базы 1С» в коде не хранятся — форма +// читает их из колонок списка SP (см. shared/fieldChoices). Чтобы добавить пункт, +// допишите его в параметрах столбца списка. Варианты в provisioning.json — +// только стартовые, для создания списка с нуля. export const QUESTION_MAX = 1000; +// Пользовательские тексты состояний загрузки вариантов полей. +export const CHOICES_LOADING_PLACEHOLDER = 'Загрузка вариантов…'; +export const CHOICES_EMPTY_PLACEHOLDER = 'Нет вариантов — обратитесь к администратору'; +export const CHOICES_ERROR_PREFIX = 'Не удалось загрузить варианты полей'; + // Значения из property pane старой web part (см. живую страницу SharePoint). export const PLANNER_PLAN_ID = '168WqDV8CEKkW3cL6olCRZgACwYa'; export const PLANNER_BUCKET_NAME = 'Входящие неотсортированные'; diff --git a/src/webparts/requestPortal/forms/Ticket1C/provisioning.json b/src/webparts/requestPortal/forms/Ticket1C/provisioning.json index 26f9524..936392c 100644 --- a/src/webparts/requestPortal/forms/Ticket1C/provisioning.json +++ b/src/webparts/requestPortal/forms/Ticket1C/provisioning.json @@ -11,7 +11,8 @@ "Открытие даты запрета", "Прочее", "Не работает 1С", - "Блокировка пользователя" + "Блокировка пользователя", + "Маршруты в ДО" ] }, { "internalName": "Organization", "title": "Организация", "type": "Choice", "required": true, "choices": [ "AFL Engineering", diff --git a/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.tsx b/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.tsx index db82bd5..bd5f117 100644 --- a/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.tsx +++ b/src/webparts/requestPortal/forms/Ticket1C/sections/RequestSection.tsx @@ -1,52 +1,76 @@ import * as React from 'react'; -import { CollapseSection, FormField, MultiChoiceField, Select, TextArea, TextInput, ISelectOption } from '../../../shared/ui'; -import { ISectionProps } from '../model'; -import { WORK_TYPE_OPTIONS, ORGANIZATION_OPTIONS, DB1C_OPTIONS, QUESTION_MAX } from '../config'; +import { Alert, CollapseSection, FormField, MultiChoiceField, Select, TextArea, TextInput, ISelectOption } from '../../../shared/ui'; +import { useFieldChoices, IFieldChoicesState } from '../../../shared/fieldChoices'; +import { dataListTitle } from '../../../shared/listTitles'; +import { FORM_ID, ISectionProps } from '../model'; +import { + QUESTION_MAX, + CHOICES_LOADING_PLACEHOLDER, + CHOICES_EMPTY_PLACEHOLDER, + CHOICES_ERROR_PREFIX +} from '../config'; -const toOptions = (values: string[]): ISelectOption[] => values.map((v) => ({ value: v, label: v })); +function choicesPlaceholder(state: IFieldChoicesState, readyText: string): string { + if (state.isLoading) return CHOICES_LOADING_PLACEHOLDER; + if (state.options.length === 0) return CHOICES_EMPTY_PLACEHOLDER; + return readyText; +} -const WORK_TYPE_SELECT_OPTIONS = toOptions(WORK_TYPE_OPTIONS); -const ORGANIZATION_SELECT_OPTIONS = toOptions(ORGANIZATION_OPTIONS); -const DB1C_SELECT_OPTIONS = toOptions(DB1C_OPTIONS); +// Сохранённое значение могли убрать из вариантов колонки — без этого Select +// показал бы пустое поле, и заявитель не увидел бы, что было выбрано. +function withCurrentValue(options: ISelectOption[], value: string): ISelectOption[] { + if (!value || options.some((o) => o.value === value)) return options; + return [{ value, label: value }, ...options]; +} -export const RequestSection: React.FC = ({ data, set }) => ( - - - set('TaskName', v)} /> - - - set('Organization', v)} - options={ORGANIZATION_SELECT_OPTIONS} - placeholder="— выберите —" - /> - - - set('DB1C', v)} - options={DB1C_SELECT_OPTIONS} - placeholder="Выберите одну или несколько баз" - /> - - -