diff --git a/web/src/widgets/CatalogueCompanyGroup/ImportCompanyGroupsModal/Counter.tsx b/web/src/widgets/CatalogueCompanyGroup/ImportCompanyGroupsModal/Counter.tsx new file mode 100644 index 0000000..5c8880d --- /dev/null +++ b/web/src/widgets/CatalogueCompanyGroup/ImportCompanyGroupsModal/Counter.tsx @@ -0,0 +1,16 @@ +import { Typography } from 'antd'; + +type Props = { + label: string; + value: number; +}; + +/** Строка карточки: подпись серым, число справа — чёрным, если не 0. */ +export function Counter({ label, value }: Props) { + return ( +
+ {label} + {value} +
+ ); +} diff --git a/web/src/widgets/CatalogueCompanyGroup/ImportCompanyGroupsModal/CounterCard.tsx b/web/src/widgets/CatalogueCompanyGroup/ImportCompanyGroupsModal/CounterCard.tsx new file mode 100644 index 0000000..577ba6c --- /dev/null +++ b/web/src/widgets/CatalogueCompanyGroup/ImportCompanyGroupsModal/CounterCard.tsx @@ -0,0 +1,19 @@ +import { Card } from 'antd'; +import { Counter } from './Counter'; + +type Props = { + title: string; + items: { label: string; value: number }[]; +}; + +export function CounterCard({ title, items }: Props) { + return ( + +
+ {items.map((item) => ( + + ))} +
+
+ ); +} diff --git a/web/src/widgets/CatalogueCompanyGroup/ImportCompanyGroupsModal/ImportCompanyGroupsModal.tsx b/web/src/widgets/CatalogueCompanyGroup/ImportCompanyGroupsModal/ImportCompanyGroupsModal.tsx index 420bb53..0e3ff9e 100644 --- a/web/src/widgets/CatalogueCompanyGroup/ImportCompanyGroupsModal/ImportCompanyGroupsModal.tsx +++ b/web/src/widgets/CatalogueCompanyGroup/ImportCompanyGroupsModal/ImportCompanyGroupsModal.tsx @@ -1,4 +1,4 @@ -import { FileAddOutlined } from '@ant-design/icons'; +import { ArrowLeftOutlined, FileAddOutlined } from '@ant-design/icons'; import { Button, Checkbox, Form, Select, Upload } from 'antd'; import type { UploadFile } from 'antd/es/upload/interface'; import type React from 'react'; @@ -6,8 +6,9 @@ import { useState } from 'react'; import { ApiError } from '../../../api/client'; import { AppModal } from '../../../components/AppModal/AppModal'; import { importDirectory } from '../../../services/api/directories/directory_import'; -import type { OnExisting } from '../../../types/api'; +import type { ImportReportOut, OnExisting } from '../../../types/api'; import { useNotificationApi } from '../../../utils/useNotification'; +import { ImportSummary } from './ImportSummary'; type Props = { open: boolean; @@ -26,8 +27,8 @@ const ON_EXISTING_OPTIONS: { value: OnExisting; label: string }[] = [ ]; /** - * Импорт выгрузки ЕЦП CRM. Сценарий двухшаговый: после пробного прогона форма и файл остаются, чтобы снять галочку - * и записать тем же файлом; после записи — уведомление и закрытие окна. + * Импорт выгрузки ЕЦП CRM. Пробный прогон заменяет форму сводкой: из неё — закрытие окна или возврат к форме + * («К загрузке файла», файл и значения формы сохраняются); после записи — уведомление и закрытие окна. */ export const ImportCompanyGroupsModal: React.FC = ({ open, onCancel, onImported }) => { const [form] = Form.useForm(); @@ -35,6 +36,7 @@ export const ImportCompanyGroupsModal: React.FC = ({ open, onCancel, onIm const [fileList, setFileList] = useState([]); const [loading, setLoading] = useState(false); + const [dryRunReport, setDryRunReport] = useState(null); const handleOk = async () => { const file = fileList[0]?.originFileObj; @@ -44,9 +46,9 @@ export const ImportCompanyGroupsModal: React.FC = ({ open, onCancel, onIm const values = form.getFieldsValue(); setLoading(true); try { - await importDirectory(file, values.dry_run, values.on_existing); + const report = await importDirectory(file, values.dry_run, values.on_existing); if (values.dry_run) { - notification.info({ description: 'Пробный прогон завершён: в справочник ничего не записано' }); + setDryRunReport(report); return; } notification.success({ description: 'Импорт завершён' }); @@ -67,7 +69,7 @@ export const ImportCompanyGroupsModal: React.FC = ({ open, onCancel, onIm return ( = ({ open, onCancel, onIm okButtonProps={{ disabled: fileList.length === 0 }} cancelText='Отмена' cancelButtonProps={{ disabled: loading }} + footer={ + dryRunReport ? ( +
+ + +
+ ) : undefined + } confirmLoading={loading} closable={!loading} destroyOnHidden - width={720}> -
+ width={dryRunReport ? 880 : 720}> +