diff --git a/web_interface/static/v3/js/widgets/custom-feeds.js b/web_interface/static/v3/js/widgets/custom-feeds.js index 62ed412b..7f52d335 100644 --- a/web_interface/static/v3/js/widgets/custom-feeds.js +++ b/web_interface/static/v3/js/widgets/custom-feeds.js @@ -404,9 +404,15 @@ if (!file) return; const formData = new FormData(); - formData.append('file', file); + // Backend contract (see api_v3.upload_plugin_asset): the request + // field must be named "files" (it does request.files.getlist('files') + // and 400s with "No files provided" otherwise), and the response + // carries the result in a top-level "uploaded_files" key, not nested + // under "data". file-upload-single.js's working upload flow uses this + // same contract. + formData.append('files', file); formData.append('plugin_id', pluginId); - + fetch('/api/v3/plugins/assets/upload', { method: 'POST', body: formData @@ -421,8 +427,8 @@ return response.json(); }) .then(data => { - if (data.status === 'success' && data.data && data.data.files && data.data.files.length > 0) { - const uploadedFile = data.data.files[0]; + if (data.status === 'success' && data.uploaded_files && data.uploaded_files.length > 0) { + const uploadedFile = data.uploaded_files[0]; const row = document.querySelector(`#${fieldId}_tbody tr[data-index="${index}"]`); if (row) { const logoCell = row.querySelector('td:nth-child(3)');