feat: «Скачать все» для вложений заявки
Над списком вложений (от двух файлов) — кнопка «Скачать все»: файлы скачиваются по очереди, без архива, через download.aspx SharePoint, чтобы PDF и картинки не открывались в просмотре. Обёртка над AttachmentList из ui-kit подменена в shared/ui, поэтому кнопка появилась во всех формах и карточках без правок в них; в чате выключена. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
@import '../../../../../styles/design-tokens';
|
||||
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $sp-2;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Кнопка над списком, прижата вправо — не спорит с именами файлов.
|
||||
.toolbar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import * as React from 'react';
|
||||
import { AttachmentList as KitAttachmentList, Button, Icon } from '@tnsu/ui-kit';
|
||||
import { downloadAllFiles } from '../../attachments/downloadAll';
|
||||
import styles from './AttachmentList.module.scss';
|
||||
|
||||
interface Props {
|
||||
items: Array<{ url: string; fileName: string }>;
|
||||
/** Если задан — рядом с файлом кнопка удаления (режим правки), как в ui-kit. */
|
||||
onRemove?: (fileName: string) => void;
|
||||
/** Кнопка «Скачать все». По умолчанию есть; false — не показывать (напр. в чате). */
|
||||
downloadAll?: boolean;
|
||||
}
|
||||
|
||||
// Меньше двух файлов — «скачать все» ничем не отличается от клика по ссылке.
|
||||
const MIN_FILES_FOR_DOWNLOAD_ALL = 2;
|
||||
|
||||
const TEXT = {
|
||||
downloadAll: (n: number): string => `Скачать все (${n})`,
|
||||
downloading: 'Скачиваю…',
|
||||
hint: 'Файлы скачаются по одному. Если браузер спросит про несколько файлов — разрешите.',
|
||||
};
|
||||
|
||||
/**
|
||||
* Список вложений из ui-kit + кнопка «Скачать все». Та же обёртка для всех
|
||||
* форм и просмотров (экспорт из shared/ui подменён на неё), поэтому кнопка
|
||||
* появляется везде без правок в самих формах.
|
||||
*/
|
||||
export const AttachmentList: React.FC<Props> = ({ items, onRemove, downloadAll = true }) => {
|
||||
const [downloading, setDownloading] = React.useState<boolean>(false);
|
||||
const showDownloadAll = downloadAll && items.length >= MIN_FILES_FOR_DOWNLOAD_ALL;
|
||||
|
||||
const handleDownloadAll = (): void => {
|
||||
setDownloading(true);
|
||||
downloadAllFiles(items)
|
||||
.then(() => setDownloading(false))
|
||||
.catch(() => setDownloading(false));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
{showDownloadAll && (
|
||||
<div className={styles.toolbar}>
|
||||
<Button variant="ghost" size="sm" onClick={handleDownloadAll} disabled={downloading} title={TEXT.hint}>
|
||||
<Icon name="download" size="sm" />
|
||||
{downloading ? TEXT.downloading : TEXT.downloadAll(items.length)}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
<KitAttachmentList items={items} onRemove={onRemove} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -19,7 +19,6 @@ export {
|
||||
CollapseSection,
|
||||
FormActions,
|
||||
FileDropzone,
|
||||
AttachmentList,
|
||||
FormModeProvider,
|
||||
useFormReadOnly,
|
||||
Icon,
|
||||
@@ -34,6 +33,8 @@ export type { ISelectOption, IConfirmOptions } from '@tnsu/ui-kit';
|
||||
// FormField — обёртка над ui-kit с подсветкой правок согласующего (журнал в
|
||||
// FieldChangesProvider); без журнала ведёт себя как FormField из ui-kit.
|
||||
export { FormField } from './FormField/FormField';
|
||||
// AttachmentList — обёртка над ui-kit с кнопкой «Скачать все» (без архива, файлы по очереди).
|
||||
export { AttachmentList } from './AttachmentList/AttachmentList';
|
||||
export { FieldChangesProvider } from './FieldChanges/FieldChangesContext';
|
||||
export { FieldChangesBanner } from './FieldChanges/FieldChangesBanner';
|
||||
export { MultiChoiceField } from './MultiChoiceField/MultiChoiceField';
|
||||
|
||||
Reference in New Issue
Block a user