From 5ea48c1f91298b42924f6865ffc30810cceec2d3 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Mon, 13 Jul 2026 20:36:26 -0400 Subject: feat(admin): triggers organized by directory, support duplicate and delete --- internal/admin/static/triggerseditor.js | 165 ++++++++++++++++++++++++++++---- 1 file changed, 146 insertions(+), 19 deletions(-) (limited to 'internal/admin/static/triggerseditor.js') diff --git a/internal/admin/static/triggerseditor.js b/internal/admin/static/triggerseditor.js index 7cb5d9e..0c18ce4 100644 --- a/internal/admin/static/triggerseditor.js +++ b/internal/admin/static/triggerseditor.js @@ -19,31 +19,80 @@ function initTriggerEditor() { } function loadTriggerList() { - API.get('/api/triggers').then(function(data) { - allIDs = (data || []).map(function(e) { return e.id || e; }); - window._triggerEntries = data || []; - renderTriggerList(''); - }).catch(function(e) { - notify('Failed to load list: ' + e.message, 'error'); - }); + loadList(); } function renderTriggerList(filter) { + renderList(filter); +} + +function renderList(filter) { var el = $('#listEntries'); var f = (filter || '').toLowerCase(); - var entries = window._triggerEntries || []; + var t = treeData; + + function filterIDs(ids) { + if (!f) return ids; + return ids.filter(function(id) { return String(id).toLowerCase().indexOf(f) >= 0; }); + } + + function renderItems(ids) { + var h = ''; + (ids || []).forEach(function(id) { + h += '
' + esc(id) + '
'; + }); + return h; + } + var html = ''; - entries.forEach(function(entry) { - var id = entry.id || entry; - if (f && id.toLowerCase().indexOf(f) === -1) return; - var badge = entry.kind === 'player' ? ' [Player]' : (entry.kind === 'global' ? ' [Global]' : ''); - var badgeClass = entry.kind === 'player' ? 'dc-item' : (entry.kind === 'global' ? 'dc-item' : ''); - html += '
'; - html += '' + esc(id) + ''; - html += '' + esc(badge) + ''; - html += '
'; - }); + var hasDirs = Object.keys(t.dirs).length > 0; + + if (t.root.length > 0 || !hasDirs) { + if (hasDirs) { + var filtered = filterIDs(t.root); + if (filtered.length > 0) { + var open = !!f || dirOpenState['Root'] === true; + html += '
'; + html += ''; + html += ''; + html += 'Root'; + html += '' + (f ? filtered.length + '/' + t.root.length : t.root.length) + ''; + html += ''; + html += '
' + renderItems(filtered) + '
'; + html += '
'; + } + } else { + html += renderItems(filterIDs(t.root)); + } + } + + if (hasDirs) { + Object.keys(t.dirs).sort().forEach(function(dir) { + var ids = t.dirs[dir] || []; + if (ids.length === 0 && !f) return; + var filtered = filterIDs(ids); + if (f && filtered.length === 0) return; + + var open = !!f || dirOpenState[dir] === true; + html += '
'; + html += ''; + html += ''; + html += '' + esc(dir) + ''; + html += '' + (f ? filtered.length + '/' + ids.length : ids.length) + ''; + html += ''; + html += '
' + renderItems(filtered) + '
'; + html += '
'; + }); + } + el.innerHTML = html || '

No triggers

'; + + el.querySelectorAll('details.dir-group').forEach(function(d) { + d.addEventListener('toggle', function() { + var n = d.getAttribute('data-name'); + if (n) dirOpenState[n] = d.open; + }); + }); } function loadTriggerItem(id) { @@ -170,7 +219,8 @@ function renderTriggerEditor(id, data) { html += '
'; html += ''; - html += ''; + html += ''; + html += ''; html += '
'; $('#editorMain').innerHTML = html; @@ -214,6 +264,83 @@ function saveTrigger() { }).catch(function(e) { notify('Save failed: ' + e.message, 'error'); }); } +function duplicateTrigger(sourceID) { + var src = sourceID || triggerID; + if (!src) return; + + var done = function(data) { + var allTriggerIDs = (treeData.root || []).slice(); + var dirs = treeData.dirs || {}; + Object.keys(dirs).forEach(function(d) { + allTriggerIDs = allTriggerIDs.concat(dirs[d] || []); + }); + + var baseID = src + '_copy'; + var newID = baseID; + var counter = 2; + while (allTriggerIDs.indexOf(newID) >= 0) { + newID = baseID + '_' + counter; + counter++; + } + + var copy = JSON.parse(JSON.stringify(data)); + delete copy._raw; + delete copy._path; + delete copy._kind; + copy.id = newID; + ced_cleanOutput(copy); + + API.post('/api/triggers', {id: newID, on_player_flag: '', steps: []}).then(function() { + return API.put('/api/triggers/' + encodeURIComponent(newID), copy); + }).then(function() { + notify('Duplicated as ' + newID, 'success'); + updateUndoBar(); + loadTriggerList(); + loadTrigger(newID); + }).catch(function(e) { notify('Duplicate failed: ' + e.message, 'error'); }); + }; + + if (sourceID) { + API.get('/api/triggers/' + encodeURIComponent(sourceID)).then(done).catch(function(e) { notify('Duplicate failed: ' + e.message, 'error'); }); + } else { + var flagTypeEl = document.querySelector('input[name="trigFlagType"]:checked'); + if (flagTypeEl) { + delete triggerData.on_player_flag; + delete triggerData.on_global_flag; + var n = $('#trigFlagName'); + if (flagTypeEl.value === 'player') triggerData.on_player_flag = n ? n.value.trim() : ''; + else triggerData.on_global_flag = n ? n.value.trim() : ''; + } + window._ieSyncAll(window._editorData); + mergeTriggerFromEditor(); + done(triggerData); + } +} + +function showItemContextMenu(e, id) { + var items = [ + {label: 'Duplicate', handler: function() { duplicateTrigger(id); }}, + {label: 'Delete Trigger', cls: 'danger', handler: function() { deleteTriggerByID(id); }}, + ]; + openContextMenu(e, items); +} + +function deleteTriggerByID(id) { + if (!confirm('Delete trigger "' + id + '"?')) return; + API.del('/api/triggers/' + encodeURIComponent(id)).then(function() { + notify('Trigger ' + id + ' deleted', 'success'); + updateUndoBar(); + if (triggerID === id) { + triggerID = null; + currentID = null; + triggerData = null; + triggerKind = ''; + $('#editorMain').innerHTML = '

Deleted

'; + } + loadTriggerList(); + }).catch(function(e) { notify('Delete failed: ' + e.message, 'error'); }); +} + function deleteTrigger() { if (!confirm('Delete trigger "' + triggerID + '"?')) return; API.del('/api/triggers/' + encodeURIComponent(triggerID)).then(function() { -- cgit v1.2.3