From e55555d2b74c14c87cba9f3bfc4ece4dc53a3a1b Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 21:49:16 -0400 Subject: [PATCH] Fix AMPP picker: text input, path-based queuing, worker path resolution --- lib/ampp-placement-worker.js | 11 +++-- public/index.html | 83 +++++------------------------------- server.js | 2 +- 3 files changed, 20 insertions(+), 76 deletions(-) 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"),