diff --git a/lib/ampp-placement-worker.js b/lib/ampp-placement-worker.js
index 0409274..6845d2a 100644
--- a/lib/ampp-placement-worker.js
+++ b/lib/ampp-placement-worker.js
@@ -1,6 +1,6 @@
"use strict";
-const { placeAssetInFolderById } = require("./ampp-folder-placer");
+const { placeAssetInFolderById, getOrCreateFolderByPath } = require("./ampp-folder-placer");
// ================================================================
// AMPP Placement Worker — lib/ampp-placement-worker.js
@@ -128,9 +128,14 @@ class AmppPlacementWorker {
continue;
}
- console.log(`[placement-worker] Placing '${placement.filename}' → folder ${placement.amppFolderId} (asset ${assetId})`);
+ let targetFolderId = placement.amppFolderId;
+ if (!targetFolderId && placement.amppFolderName) {
+ try { targetFolderId = await getOrCreateFolderByPath(this._getAmppBase(), placement.amppFolderName, token); }
+ catch(e) { placement.status='failed'; placement.error=e.message; changed=true; continue; }
+ }
+ console.log(`[placement-worker] Placing '${placement.filename}' → folder ${targetFolderId} (asset ${assetId})`);
try {
- await placeAssetInFolderById(this._getAmppBase(), assetId, placement.amppFolderId, token);
+ await placeAssetInFolderById(this._getAmppBase(), assetId, targetFolderId, token);
placement.status = "placed";
placement.assetId = assetId;
placement.placedAt = new Date().toISOString();
diff --git a/public/index.html b/public/index.html
index 33ac30c..2f39f71 100644
--- a/public/index.html
+++ b/public/index.html
@@ -485,17 +485,17 @@ body::before{content:'';position:fixed;inset:0;background:radial-gradient(ellips
+
AMPP Destination Folder
- — optional
-
+ — optional
-
-
-
Click ↻ Refresh to load AMPP folders
-
-
+
+
AMPP folder: (none — skip placement)
@@ -879,7 +879,6 @@ function showApp() {
loadS3Config(); loadRelayConfig(); loadAmppConfig(); loadUsers(); loadShareLinks(); populateSlFolderSelect();
}
loadFolders();
- loadAmppFolders();
loadAmppJobs();
}
@@ -1087,70 +1086,10 @@ async function deleteFolder(pathArr) {
// ============================================================
// AMPP FOLDER PICKER
// ============================================================
-async function loadAmppFolders() {
- const box = document.getElementById('ampp-folder-box');
- const statusEl = document.getElementById('ampp-folder-status');
- if (!box) return;
- box.innerHTML = '
Loading AMPP folders…
';
- if (statusEl) statusEl.textContent = '— loading…';
- try {
- const d = await api('GET', '/api/ampp/folders/list');
- if (!d.success) {
- if (d.error && d.error.toLowerCase().includes('not configured')) {
- box.innerHTML = '
AMPP not configured — set up in Admin → AMPP
';
- if (statusEl) statusEl.textContent = '— not configured';
- } else {
- box.innerHTML = `
Error: ${esc(d.error||'Failed to load folders')}
`;
- if (statusEl) statusEl.textContent = '— error';
- }
- return;
- }
- amppFolderCache = d.folders || [];
- if (statusEl) statusEl.textContent = `— ${amppFolderCache.length} folder${amppFolderCache.length!==1?'s':''}`;
- renderAmppFolderList();
- } catch(e) {
- box.innerHTML = `
Error: ${esc(e.message)}
`;
- if (statusEl) statusEl.textContent = '— error';
- }
-}
-
-function renderAmppFolderList() {
- const box = document.getElementById('ampp-folder-box');
- if (!box) return;
- box.innerHTML = '';
- const searchEl = document.getElementById('ampp-folder-search');
- const filter = (searchEl ? searchEl.value.trim().toLowerCase() : '');
- const folders = amppFolderCache.filter(f => !filter || (f.path||f.name||'').toLowerCase().includes(filter));
-
- // "None" row — always first
- const noneRow = document.createElement('div');
- noneRow.className = 'folder-tree-row' + (selectedAmppFolderId === '' ? ' active' : '');
- noneRow.innerHTML = `
🚫(no AMPP placement)`;
- noneRow.onclick = () => { selectedAmppFolderId = ''; selectedAmppFolderName = ''; updateAmppFolderDisplay(); renderAmppFolderList(); };
- box.appendChild(noneRow);
-
- if (!folders.length && amppFolderCache.length > 0) {
- box.innerHTML += '
No folders match your search
';
- return;
- }
-
- // Sort by path/name
- const sorted = [...folders].sort((a, b) => (a.path||a.name||'').localeCompare(b.path||b.name||''));
- sorted.forEach(f => {
- const id = f.id || f['folder:id'] || '';
- const displayName = f.path || f.name || f['name:text'] || id;
- const depth = (displayName.match(/\//g)||[]).length;
- const row = document.createElement('div');
- row.className = 'folder-tree-row' + (selectedAmppFolderId === id ? ' active' : '');
- row.style.paddingLeft = (0.75 + depth * 1.0) + 'rem';
- row.innerHTML = `
📁${esc(displayName)}`;
- row.onclick = () => { selectedAmppFolderId = id; selectedAmppFolderName = displayName; updateAmppFolderDisplay(); renderAmppFolderList(); };
- box.appendChild(row);
- });
-}
-
-function updateAmppFolderDisplay() {
- const el = document.getElementById('ampp-folder-display');
+function updateAmppFolderFromInput(val) {
+ selectedAmppFolderName = val.trim();
+ selectedAmppFolderId = '';
+ var el = document.getElementById('ampp-folder-display');
if (el) el.textContent = selectedAmppFolderName || '(none — skip placement)';
}
diff --git a/server.js b/server.js
index 9d0c816..f2a7b30 100644
--- a/server.js
+++ b/server.js
@@ -625,7 +625,7 @@ app.post("/api/presigned/complete", requireAuth, (req, res) => {
saveData(db);
}
// Record AMPP placement if a folder was selected
- if (amppFolderId && filename) {
+ if ((amppFolderId || amppFolderName) && filename) {
if (!db.pendingPlacements) db.pendingPlacements = [];
db.pendingPlacements.push({
id: require("crypto").randomBytes(8).toString("hex"),