arm-core/web/src/utils/download.ts
Andrey Epifancev c3d82bd293 fix(web): желательные пункты ревью шахматки, раунд 3 (ревью #158, AURORA-1538)
- форматтер сумм: проверка числа до сдвига запятой, Intl.StringNumericLiteral (ES2023.Intl) вместо any, без разбора скобок;
- запасные имена выгрузок xlsxFilename, отдельные флаги загрузки у двух «Экспорт»;
- useNotificationApi мемоизирован, загрузки — useCallback, зависимости эффектов полные;
- ячейки: расхождение в скобках, значок пропущенных строк ОСВ, «—» вместо выдуманного нуля;
- «Год»/«Период» версии только для чтения;
- сервис services/api/intercompanyMatrix.ts с withJsonBody, типы шахматки в types/api.ts, Account.kind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 16:42:00 +04:00

45 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** Имя файла из Content-Disposition: `filename*=UTF-8''…` важнее `filename=`. */
export function filenameFromContentDisposition(header: string | null): string | null {
if (!header) {
return null;
}
const star = /filename\*\s*=\s*(?:UTF-8|utf-8)''([^;]+)/.exec(header);
if (star) {
try {
return decodeURIComponent(star[1].trim());
} catch {
return star[1].trim();
}
}
const plain = /filename\s*=\s*"?([^";]+)"?/.exec(header);
return plain ? plain[1].trim() : null;
}
const safeName = (name: string) => name.replace(/[\\/:*?"<>|\s]+/g, '_');
/** Запасное имя экспорта свода, если Content-Disposition недоступен. */
export function exportFilename(groupName: string, year: number, quarter: string): string {
return `Сводная_ОСВ_${safeName(groupName)}_${year}_${quarter}.xlsx`;
}
/** Запасное имя xlsx-выгрузки версии: `<префикс>_<ГК>_<год>_<квартал>.xlsx`, без карточки версии — `<префикс>.xlsx`. */
export function xlsxFilename(prefix: string, version: { groupName: string; year: number; quarter: string } | null): string {
if (!version) {
return `${prefix}.xlsx`;
}
return `${prefix}_${safeName(version.groupName)}_${version.year}_${version.quarter}.xlsx`;
}
/** Сохранить blob файлом через временную ссылку. */
export function saveBlob(blob: Blob, filename: string): void {
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
link.remove();
// не сразу: Safari/Firefox иначе могут оборвать скачивание
setTimeout(() => URL.revokeObjectURL(url), 1000);
}