Andrey Epifancev 5958b07410 fix(web): синхронизация встроенного фронта с arm-web@test (a3c0010) (#139)
Перенесён диапазон arm-web 8345f5e..a3c0010 (3 коммитов, 22 файлов набора
синхронизации) скриптом docs/scripts/sync-web.sh. После переноса web/ и
arm-web@test идентичны по набору. Коммиты arm-web:
- ff1e45c file id as option value for react rendering
- 0242486 fix(#49): зелёный make check и исправления после ревью (AURORA-144)
- 0fdbd80 feat: add comments frontend, checklist modal, files delete, select options in document review

Co-Authored-By: sync-web.sh <noreply@aepif.ru>
2026-10-19 14:54:36 +04:00

63 lines
2.5 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.

import { ApiError, api, apiFetch, apiFetchBlob } from '../../api/client';
import type { FileOut, Page, UploadResult } from '../../types/api';
export function isUploadResult(body: unknown): body is UploadResult {
return (
typeof body === 'object' &&
body !== null &&
Array.isArray((body as UploadResult).accepted) &&
Array.isArray((body as UploadResult).rejected)
);
}
/** Маршрут файлов ЮЛ: с консолидацией — файлы в контексте консолидации, без неё — файлы ЮЛ (design D-2). */
export function filesPath(legalEntityId: string, consolidationId: string | null): string {
return consolidationId
? `/consolidations/${encodeURIComponent(consolidationId)}/legal-entities/${legalEntityId}/files`
: `/legal-entities/${legalEntityId}/files`;
}
/** Загрузка файлов ЮЛ одним запросом (в консолидацию или без контекста); 422 «ни один не принят» возвращается как результат, прочие ошибки — throw. */
export async function uploadFiles(legalEntityId: string, files: File[], consolidationId: string | null): Promise<UploadResult> {
const form = new FormData();
for (const file of files) {
form.append('files', file);
}
try {
return await apiFetch<UploadResult>(filesPath(legalEntityId, consolidationId), { method: 'POST', body: form });
} catch (e: unknown) {
if (e instanceof ApiError && e.status === 422 && isUploadResult(e.body)) {
return e.body;
}
throw e;
}
}
export function summarizeUpload(result: UploadResult): { accepted: string[]; rejected: { name: string; reason: string }[] } {
return {
accepted: result.accepted.map((a) => a.name),
rejected: result.rejected.map((r) => ({ name: r.name, reason: r.message })),
};
}
export async function listLegalEntityFiles(legalEntityId: string, consolidationId: string | null): Promise<FileOut[]> {
const page = await apiFetch<Page<FileOut>>(`${filesPath(legalEntityId, consolidationId)}?limit=100`);
return page.items;
}
export function hasPendingFiles(files: FileOut[]): boolean {
return files.some((f) => f.status === 'UPLOADED' || f.status === 'PROCESSING');
}
export function fetchFileContent(fileId: string): Promise<{ blob: Blob; filename: string | null }> {
return apiFetchBlob(`/files/${fileId}/content?disposition=inline`);
}
export function getFile(id: string): Promise<FileOut> {
return apiFetch<FileOut>(`/files/${id}`);
}
export function removeFile(fileId: string) {
return api.del(`/files/${fileId}`);
}