diff --git a/frontend/src/melodies/MelodyForm.jsx b/frontend/src/melodies/MelodyForm.jsx
index b4cf00f..d07c8c8 100644
--- a/frontend/src/melodies/MelodyForm.jsx
+++ b/frontend/src/melodies/MelodyForm.jsx
@@ -197,12 +197,15 @@ export default function MelodyForm() {
lastEditedBy: userName,
adminNotes,
};
- return {
+ const body = {
information: { ...infoWithoutNotes, totalActiveBells },
default_settings: settings,
- type, url, uid, pid,
+ type, uid, pid,
metadata,
};
+ // Only send url if non-empty — avoids overwriting a backend-set URL with an empty string
+ if (url) body.url = url;
+ return body;
};
const uploadFiles = async (melodyId) => {
@@ -562,7 +565,7 @@ export default function MelodyForm() {
setPid(e.target.value)} placeholder="eg. builtin_festive_vesper" className={inputClass} />
- {isEdit && url && (
+ {url && (
@@ -804,7 +807,24 @@ export default function MelodyForm() {
setShowSelectBuilt(false);
setAssignedBinaryName(archetype.name);
if (!pid.trim() && archetype.pid) setPid(archetype.pid);
- if (isEdit) loadMelody();
+ if (archetype.steps != null) updateInfo("steps", archetype.steps);
+ if (archetype.totalNotes != null) updateInfo("totalNotes", archetype.totalNotes);
+ if (archetype.archetype_csv != null) updateInfo("archetype_csv", archetype.archetype_csv);
+ if (isEdit) {
+ loadMelody();
+ } else {
+ // Refresh files so binary_url and url are shown
+ const mid = savedMelodyId;
+ if (mid) {
+ Promise.all([
+ api.get(`/melodies/${mid}/files`),
+ api.get(`/melodies/${mid}`),
+ ]).then(([files, m]) => {
+ setExistingFiles(files);
+ if (m.url) setUrl(m.url);
+ }).catch(() => {});
+ }
+ }
}}
/>
{
+ setExistingFiles(files);
+ if (m.url) setUrl(m.url);
+ }).catch(() => {});
+ }
+ }
}}
/>
>