From 2b102b8772dda5dda94776b6772b842bf85974bb 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, 1 Oct 2026 16:18:02 +0500 Subject: [PATCH] =?UTF-8?q?fix(ct):=20=C2=AB=D0=94=D0=BE=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=B0=D1=8F=20=D0=B8?= =?UTF-8?q?=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8F=C2=BB=20?= =?UTF-8?q?=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D1=8F=D0=B5=D1=82=D1=81?= =?UTF-8?q?=D1=8F=20=D0=B2=20SP;=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BE=D0=BF=D0=BB=D0=B0=D1=82=D1=8B,=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BA=D0=B8,=20=D1=81?= =?UTF-8?q?=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ручные правки условий и свои строки («Добавить условие») жили только в браузере: saveCriteria не вызывался, и согласующий, PDF и автор в новой вкладке видели лишь то, что распознал ИИ. Теперь по «Сохранить» шага 3 «Критерии» этой СТ заменяются текущими (replaceCriteria), а при открытии грузятся по СТ, а не по поставщику из всех СТ (loadCriteriaForCt). Свои строки хранятся в новой колонке criteriaLabel, значение — в comment, как в ОИД. По просьбе заказчика: «Условия оплаты» — готовые варианты (частые формулировки из SP) или свой вариант; «Сертификаты» — Да/Нет; «Условия поставки» можно сменить и после заполнения ИИ (раньше заполненное показывалось текстом без выбора). --- provisioning/manifests/ct.provisioning.json | 5 + .../CriteriaChoiceCell.tsx | 33 +++++ .../Step3ComparisonTable/CriteriaTable.tsx | 44 ++++--- .../Step3ComparisonTable/PaymentTypeCell.tsx | 59 +++++++++ .../Step3ComparisonTable/matrixHelpers.ts | 13 ++ .../Step3ComparisonTable/useStep3Matrix.ts | 30 ++--- .../ct/components/utils/criteria.test.ts | 98 +++++++++++++++ .../forms/ct/components/utils/criteria.ts | 117 ++++++++++++++++++ .../forms/ct/services/CtService.ts | 84 +++++++------ 9 files changed, 405 insertions(+), 78 deletions(-) create mode 100644 src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/CriteriaChoiceCell.tsx create mode 100644 src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/PaymentTypeCell.tsx create mode 100644 src/webparts/ctFormsPortal/forms/ct/components/utils/criteria.test.ts create mode 100644 src/webparts/ctFormsPortal/forms/ct/components/utils/criteria.ts diff --git a/provisioning/manifests/ct.provisioning.json b/provisioning/manifests/ct.provisioning.json index c917f72..e550a7c 100644 --- a/provisioning/manifests/ct.provisioning.json +++ b/provisioning/manifests/ct.provisioning.json @@ -255,6 +255,11 @@ "type": "Lookup", "lookupList": "Поставщики", "lookupShowField": "name" + }, + { + "internalName": "criteriaLabel", + "title": "Название доп.условия", + "type": "Text" } ] }, diff --git a/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/CriteriaChoiceCell.tsx b/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/CriteriaChoiceCell.tsx new file mode 100644 index 0000000..e902ab3 --- /dev/null +++ b/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/CriteriaChoiceCell.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; +import styles from './Step3ComparisonTable.module.scss'; + +export interface CriteriaChoiceOption { + value: string; + label: string; +} + +interface Props { + value: string; + options: CriteriaChoiceOption[]; + onChange: (value: string) => void; + ariaLabel: string; +} + +// Ячейка-выбор «Дополнительной информации» (условия поставки, сертификаты). Значение не из списка +// (напр. свободный текст от ИИ) показываем отдельным пунктом — чтобы не потерялось и его можно было сменить. +export const CriteriaChoiceCell: React.FC = ({ value, options, onChange, ariaLabel }) => { + const current = value.trim(); + const isKnown = current === '' || options.some(o => o.value === current); + return ( + + ); +}; diff --git a/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/CriteriaTable.tsx b/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/CriteriaTable.tsx index 274d900..0d96352 100644 --- a/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/CriteriaTable.tsx +++ b/src/webparts/ctFormsPortal/forms/ct/components/Step3ComparisonTable/CriteriaTable.tsx @@ -2,13 +2,21 @@ import * as React from 'react'; import { Button, IconButton, TextInput, TextArea, Icon } from '@tnsu/ui-kit'; import { Step3Matrix } from './useStep3Matrix'; import { CriteriaEntry } from './matrixTypes'; -import { DELIVERY_TYPE_OPTIONS } from './matrixHelpers'; +import { CERTIFICATE_OPTIONS, DELIVERY_TYPE_OPTIONS } from './matrixHelpers'; +import { CriteriaChoiceCell, CriteriaChoiceOption } from './CriteriaChoiceCell'; +import { PaymentTypeCell } from './PaymentTypeCell'; import styles from './Step3ComparisonTable.module.scss'; interface Props { matrix: Step3Matrix; } +// Поля-выбор: условия поставки (Incoterms — в списке описание, храним код) и сертификаты Да/Нет. +const CHOICE_OPTIONS: Partial> = { + deliveryType: DELIVERY_TYPE_OPTIONS.map(o => ({ value: o.code, label: o.label })), + sertificates: CERTIFICATE_OPTIONS.map(o => ({ value: o, label: o })), +}; + // Блок «Дополнительная информация» (условия оплаты/поставки/сроки/сертификаты + произвольные условия). // Перенесено 1:1 из Step3ComparisonTable (§стайл-гайд: чистая вёрстка, логика — в useStep3Matrix). export function CriteriaTable({ matrix }: Props): JSX.Element | null { @@ -54,24 +62,22 @@ export function CriteriaTable({ matrix }: Props): JSX.Element | null { return ( {!isReadOnly ? ( - row.key === 'deliveryType' ? ( - (criteriaMap[s.id]?.deliveryType ?? '').trim() ? ( - // Уже заполнено (в т.ч. ИИ) — показываем как текст, без селекта. - criteriaMap[s.id]?.deliveryType - ) : ( - // Пусто — даём выбрать условие поставки из списка. - - ) + CHOICE_OPTIONS[row.key] ? ( + // Выбор из списка — всегда, даже если поле уже заполнено (в т.ч. ИИ): раньше + // заполненное условие поставки показывалось текстом и его нельзя было сменить. + updateCriteriaValue(s.id, row.key, val)} + ariaLabel={`${row.label} — ${s.name}`} + /> + ) : row.key === 'paymentType' ? ( + updateCriteriaValue(s.id, 'paymentType', val)} + ariaLabel={`${row.label} — ${s.name}`} + isRequiredEmpty={Boolean(row.required) && isEmpty} + /> ) : (