feat: прежняя заявка на оплату открывается в панели справа, а не в новой вкладке
Tests / frontend-test (pull_request) Successful in 1m27s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gorbenko.pavel
2026-10-28 10:17:53 +05:00
parent f654db9bcf
commit 22e37b6e36
3 changed files with 57 additions and 10 deletions
@@ -2,15 +2,18 @@ import * as React from 'react';
import styles from './PaymentSections.module.scss';
import { FormField, TextInput, TextArea } from '../../../shared/ui';
import { formatAmount, overLimitAmount, previousPaymentsTotal } from '../amounts';
import { FORM_ID, ISectionProps } from '../model';
import { routeUrl } from '../../../shared/routing';
import { IPreviousPayment, ISectionProps } from '../model';
import { AmountInput } from './AmountInput';
import { RequestDrawer } from './RequestDrawer';
/**
* Суммы платежа. Сумма всех оплат по СТ (прежние заявки + эта) не может превышать
* общую сумму СТ — при превышении сумма оплаты подсвечивается, отправку это не блокирует.
*/
export const AmountsSection: React.FC<ISectionProps> = ({ data, set }) => {
export const AmountsSection: React.FC<ISectionProps> = ({ data, set, context }) => {
// Прежняя заявка, открытая в панели справа; undefined — панель закрыта.
const [opened, setOpened] = React.useState<IPreviousPayment | undefined>(undefined);
const close = React.useCallback(() => setOpened(undefined), []);
const over = overLimitAmount(data);
const previousTotal = previousPaymentsTotal(data.PreviousPayments);
@@ -61,14 +64,9 @@ export const AmountsSection: React.FC<ISectionProps> = ({ data, set }) => {
<tr key={p.code}>
<td>
{p.id ? (
<a
className={styles.link}
href={routeUrl({ mode: 'approve', nav: 'new', formKey: FORM_ID, itemId: p.id, listId: p.listId || undefined })}
target="_blank"
rel="noopener noreferrer"
>
<button type="button" className={styles.link} onClick={() => setOpened(p)}>
{p.code}
</a>
</button>
) : (
p.code
)}
@@ -87,6 +85,9 @@ export const AmountsSection: React.FC<ISectionProps> = ({ data, set }) => {
</table>
</div>
)}
{opened && opened.id && (
<RequestDrawer context={context} itemId={opened.id} listId={opened.listId || ''} code={opened.code} onClose={close} />
)}
</>
);
};
@@ -110,6 +110,11 @@
}
.link {
padding: 0;
border: 0;
background: none;
font: inherit;
cursor: pointer;
color: $navy-700;
font-weight: 600;
text-decoration: underline;
@@ -0,0 +1,41 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import type { WebPartContext } from '@microsoft/sp-webpart-base';
import { Drawer } from '../../../components/Drawer/Drawer';
import { Spinner } from '@tnsu/ui-kit';
import portalStyles from '../../../components/RequestPortal.module.scss';
import { FORM_ID } from '../model';
// Лениво: ApproveFeature через реестр просмотров тянет PaymentRequestView, а тот —
// эту же секцию. Статический импорт замкнул бы цикл модулей.
const ApproveFeature = React.lazy(() => import(/* webpackChunkName: 'approve-feature' */ '../../../features/approve/ApproveFeature'));
interface IRequestDrawerProps {
context: WebPartContext;
itemId: number;
/** Партиция, где лежит заявка; '' — текущая. */
listId: string;
code: string;
onClose: () => void;
}
/**
* Прежняя заявка на оплату в выезжающей панели — той же, что у таблиц портала.
* Открываем её здесь, а не переходом на rpmode=approve: смена маршрута
* пересоздала бы открытую форму, и всё введённое пропало бы.
*
* Через портал в body: форма сама бывает открыта в панели (черновик), а
* fixed-слой внутри неё ограничивался бы её рамками. Корневой класс портала
* возвращает шрифт и цвет, которые в body не наследуются.
*/
export const RequestDrawer: React.FC<IRequestDrawerProps> = ({ context, itemId, listId, code, onClose }) =>
ReactDOM.createPortal(
<div className={portalStyles.requestPortal}>
<Drawer title={`Заявка №${code}`} onClose={onClose}>
<React.Suspense fallback={<Spinner block label="Загружаем заявку…" />}>
<ApproveFeature context={context} formKey={FORM_ID} itemId={itemId} listId={listId || undefined} />
</React.Suspense>
</Drawer>
</div>,
document.body
);