mutipart
This commit is contained in:
@@ -406,8 +406,10 @@ export class ApiClient {
|
|||||||
const headers = { ...extraHeaders };
|
const headers = { ...extraHeaders };
|
||||||
let payload;
|
let payload;
|
||||||
if (body !== undefined) {
|
if (body !== undefined) {
|
||||||
if (raw) {
|
if (typeof FormData !== 'undefined' && body instanceof FormData) {
|
||||||
headers['Content-Type'] = contentType;
|
payload = body;
|
||||||
|
} else if (raw) {
|
||||||
|
if (contentType) headers['Content-Type'] = contentType;
|
||||||
payload = body;
|
payload = body;
|
||||||
} else {
|
} else {
|
||||||
headers['Content-Type'] = contentType || 'application/json';
|
headers['Content-Type'] = contentType || 'application/json';
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ function readableHeaders(headers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function http(path, { method = 'GET', body } = {}) {
|
async function http(path, { method = 'GET', body } = {}) {
|
||||||
const headers = { 'Content-Type': 'application/json' };
|
const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;
|
||||||
|
const headers = {};
|
||||||
|
if (!isFormData) {
|
||||||
|
headers['Content-Type'] = 'application/json';
|
||||||
|
}
|
||||||
const url = new URL(path, window.location.origin).href;
|
const url = new URL(path, window.location.origin).href;
|
||||||
|
|
||||||
logApi('request', {
|
logApi('request', {
|
||||||
@@ -38,7 +42,7 @@ async function http(path, { method = 'GET', body } = {}) {
|
|||||||
method,
|
method,
|
||||||
headers,
|
headers,
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
body: body ? JSON.stringify(body) : undefined,
|
body: isFormData ? body : (body ? JSON.stringify(body) : undefined),
|
||||||
});
|
});
|
||||||
|
|
||||||
const responseHeaders = readableHeaders(res.headers);
|
const responseHeaders = readableHeaders(res.headers);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export {
|
|||||||
lineFromApi,
|
lineFromApi,
|
||||||
buildManifestBody,
|
buildManifestBody,
|
||||||
buildFilesForUpload,
|
buildFilesForUpload,
|
||||||
|
collectFilesForUpload,
|
||||||
restoreAttachmentsFromApi,
|
restoreAttachmentsFromApi,
|
||||||
dateInputValue,
|
dateInputValue,
|
||||||
} from './manifestConfig';
|
} from './manifestConfig';
|
||||||
|
|||||||
@@ -344,6 +344,53 @@ export async function restoreAttachmentsFromApi(apiFiles = [], existingAttachmen
|
|||||||
return attachments;
|
return attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect new or modified attachments for multipart upload
|
||||||
|
* @param {Array<{file: File, name: string, type: string, thumbnail?: string, text?: string, parentPdfId?: string|number, isPersisted?: boolean, isDirty?: boolean}>} attachments
|
||||||
|
* @param {{ onlyNew?: boolean }} [options]
|
||||||
|
* @returns {Array<{file: File, name: string, mimetype: string, meta?: object}>}
|
||||||
|
*/
|
||||||
|
export function collectFilesForUpload(attachments = [], { onlyNew = false } = {}) {
|
||||||
|
const files = [];
|
||||||
|
for (const attachment of attachments) {
|
||||||
|
if (!attachment) continue;
|
||||||
|
// Skip already persisted attachments in update mode unless modified
|
||||||
|
if (onlyNew && attachment.isPersisted && !attachment.isDirty) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (attachment.isPersisted && !attachment.isDirty && (!attachment.file || attachment.file.size === 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let fileToUpload = attachment.file;
|
||||||
|
if (!fileToUpload || fileToUpload.size === 0) {
|
||||||
|
if (attachment.text) {
|
||||||
|
fileToUpload = new File([attachment.text], attachment.name || 'file.txt', {
|
||||||
|
type: 'text/plain;charset=utf-8',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const meta = {};
|
||||||
|
if (attachment.parentPdfId) {
|
||||||
|
meta.parentPdfId = String(attachment.parentPdfId);
|
||||||
|
}
|
||||||
|
if (attachment.text) {
|
||||||
|
meta.text = String(attachment.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
files.push({
|
||||||
|
file: fileToUpload,
|
||||||
|
name: attachment.name || fileToUpload.name,
|
||||||
|
mimetype: attachment.type || fileToUpload.type,
|
||||||
|
meta: Object.keys(meta).length > 0 ? meta : undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {{ number: string, externalNumber?: string, date: string, partyId: number|null, lines: object[], attachments?: object[] }} form
|
* @param {{ number: string, externalNumber?: string, date: string, partyId: number|null, lines: object[], attachments?: object[] }} form
|
||||||
* @param {{ partyField: 'supplierId'|'entityId', requireAtLeastOne: boolean, externalNumber?: boolean }} opts
|
* @param {{ partyField: 'supplierId'|'entityId', requireAtLeastOne: boolean, externalNumber?: boolean }} opts
|
||||||
@@ -380,9 +427,22 @@ export async function buildManifestBody(
|
|||||||
// Add files if attachments exist
|
// Add files if attachments exist
|
||||||
if (form.attachments && form.attachments.length > 0) {
|
if (form.attachments && form.attachments.length > 0) {
|
||||||
const isUpdate = !requireAtLeastOne;
|
const isUpdate = !requireAtLeastOne;
|
||||||
const filesToUpload = await buildFilesForUpload(form.attachments, { onlyNew: isUpdate });
|
const filesToUpload = collectFilesForUpload(form.attachments, { onlyNew: isUpdate });
|
||||||
if (filesToUpload.length > 0) {
|
if (filesToUpload.length > 0) {
|
||||||
body.files = filesToUpload;
|
const filesMeta = filesToUpload
|
||||||
|
.filter((f) => f.meta)
|
||||||
|
.map((f) => ({ name: f.name, meta: f.meta }));
|
||||||
|
|
||||||
|
if (filesMeta.length > 0) {
|
||||||
|
body.filesMeta = filesMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('data', JSON.stringify(body));
|
||||||
|
for (const item of filesToUpload) {
|
||||||
|
formData.append('files', item.file, item.name);
|
||||||
|
}
|
||||||
|
return formData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -379,6 +379,7 @@ class LieferungNeuPage extends PureComponent {
|
|||||||
file: txtFile,
|
file: txtFile,
|
||||||
size: txtFile.size,
|
size: txtFile.size,
|
||||||
text,
|
text,
|
||||||
|
isDirty: true,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
deliveryEditorAutomat.actions.addAttachment({
|
deliveryEditorAutomat.actions.addAttachment({
|
||||||
@@ -606,6 +607,7 @@ class LieferungNeuPage extends PureComponent {
|
|||||||
file: newFile,
|
file: newFile,
|
||||||
size: newFile.size,
|
size: newFile.size,
|
||||||
text: newText,
|
text: newText,
|
||||||
|
isDirty: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
|||||||
Reference in New Issue
Block a user