fix: delete asset actually deletes

Trash icon in the library was firing PATCH /assets/:id with {status:"deleted"}. The PATCH route only accepts display_name/tags/notes so it returned "No fields to update" and the asset stayed put.

* api.js: add deleteAsset(id, {hard}) helper hitting the real DELETE route.
* index.html: deleteAssetPrompt now calls deleteAsset (soft archive). Confirm dialog reworded to match.
* mam-api/routes/assets.js: list endpoint hides status=archived by default. Pass ?include_archived=true to see them in a future restore-from-trash view. Filtering by ?status=archived still works for power users.
* All HTML: bump api.js cache-buster v=4 -> v=5 so the new helper is fetched.
This commit is contained in:
Zac Gaetano 2026-05-17 12:55:36 -04:00
parent ea28c5189d
commit 72545126c4
7 changed files with 19 additions and 7 deletions

View file

@ -30,6 +30,7 @@ router.get('/', async (req, res, next) => {
media_type, media_type,
limit = 50, limit = 50,
offset = 0, offset = 0,
include_archived,
} = req.query; } = req.query;
let query = ` let query = `
@ -41,6 +42,12 @@ router.get('/', async (req, res, next) => {
const params = []; const params = [];
let paramCount = 1; let paramCount = 1;
// Hide archived rows unless explicitly asked for, or unless the caller is
// already filtering by status=archived.
if (!status && include_archived !== 'true') {
query += ` AND a.status <> 'archived'`;
}
if (project_id) { if (project_id) {
query += ` AND a.project_id = $${paramCount++}`; query += ` AND a.project_id = $${paramCount++}`;
params.push(project_id); params.push(project_id);

View file

@ -312,7 +312,7 @@
<div class="toast-container" id="toastContainer" aria-live="polite"></div> <div class="toast-container" id="toastContainer" aria-live="polite"></div>
<script src="js/api.js?v=4"></script> <script src="js/api.js?v=5"></script>
<script> <script>
const cState = { const cState = {
devices: [], devices: [],

View file

@ -457,7 +457,7 @@
</div> </div>
</div> </div>
<script src="js/api.js?v=4"></script> <script src="js/api.js?v=5"></script>
<script src="js/preview.js?v=1"></script> <script src="js/preview.js?v=1"></script>
<script> <script>
const state = { const state = {
@ -668,8 +668,8 @@
async function deleteAssetPrompt(id, e) { async function deleteAssetPrompt(id, e) {
e.stopPropagation(); e.stopPropagation();
if (!confirm('Delete this asset? This cannot be undone.')) return; if (!confirm('Delete this asset? It will be archived and hidden from the library.')) return;
const r = await updateAsset(id, { status: 'deleted' }); const r = await deleteAsset(id);
if (r.success) { toast('Asset deleted', '', 'success'); loadAssets(); } if (r.success) { toast('Asset deleted', '', 'success'); loadAssets(); }
else toast('Delete failed', r.error, 'error'); else toast('Delete failed', r.error, 'error');
} }

View file

@ -106,6 +106,11 @@ async function getAssetMetadata(assetId) {
return api(`/assets/${assetId}`); return api(`/assets/${assetId}`);
} }
async function deleteAsset(assetId, { hard = false } = {}) {
const qs = hard ? '?hard=true' : '';
return api(`/assets/${assetId}${qs}`, { method: 'DELETE' });
}
// ============================================================ // ============================================================
// PROJECT API CALLS // PROJECT API CALLS
// ============================================================ // ============================================================

View file

@ -304,7 +304,7 @@
</footer> </footer>
</div> </div>
<script src="/js/api.js?v=4"></script> <script src="/js/api.js?v=5"></script>
<script> <script>
// ============================================================ // ============================================================
// STATE MANAGEMENT // STATE MANAGEMENT

View file

@ -357,7 +357,7 @@
<div class="toast-container" id="toastContainer" aria-live="polite"></div> <div class="toast-container" id="toastContainer" aria-live="polite"></div>
<script src="js/api.js?v=4"></script> <script src="js/api.js?v=5"></script>
<script> <script>
const pState = { recorders: [], timers: {}, sourceType: 'srt', mode: 'caller', projects: [], signals: {} }; const pState = { recorders: [], timers: {}, sourceType: 'srt', mode: 'caller', projects: [], signals: {} };

View file

@ -249,7 +249,7 @@
<div class="toast-container" id="toastContainer" aria-live="polite"></div> <div class="toast-container" id="toastContainer" aria-live="polite"></div>
<script src="js/api.js?v=4"></script> <script src="js/api.js?v=5"></script>
<script> <script>
const CHUNK = 10 * 1024 * 1024; // 10 MB chunks const CHUNK = 10 * 1024 * 1024; // 10 MB chunks
const state = { projects: [], bins: [], queue: [], uploading: false }; const state = { projects: [], bins: [], queue: [], uploading: false };