var dropData = null; var dropID = null; var expandedCards = {}; var cardWidths = {}; var DROP_SECTIONS = [ { id: 'drops', label: 'Drops', always: true, path: 'drops', isArray: true, fields: [ ['item_id', 'Item ID', 'search', '', '', null, 'items'], ['table', 'Table', 'search', '', '', null, 'drops'], ['weight', 'Weight', 'number', '', 'narrow'], ['quantity', 'Quantity', 'number', '1', 'narrow'], ['level', 'Level', 'number', '', 'narrow'], ['xp', 'XP', 'number', '', 'narrow'], ['depletes', 'Depletes', 'checkbox'], ['success_message', 'Success Message', 'text', '', 'wide'], ] } ]; function initDropEditor() { editorType = 'drops'; editorFields = []; loadList(); if (window.location.hash) loadDropEditor(window.location.hash.substring(1)); } function cardPath(sec) { return sec.path || ''; } function getVal(data, sec, key) { return ced_getVal(data, sec, key); } function fieldID(sec, key, idx) { return ced_fieldID(sec, key, idx); } function setupSearchFields() { ced_setupSearchFields(); } function collectFieldValue(el, type) { return ced_collectFieldValue(el, type); } function loadDropEditor(id) { dropID = id; currentID = id; renderList(''); window.location.hash = id; API.get('/api/drops/' + encodeURIComponent(id)).then(function(data) { dropData = data; renderDropEditor(id, data); }).catch(function(e) { $('#editorMain').innerHTML = '

Failed to load: ' + esc(e.message) + '

'; }); } function loadItem(id) { loadDropEditor(id); } function renderDropEditor(id, data) { var html = '

Drop Table: ' + esc(id) + '

'; html += '
'; html += '
'; html += '
'; html += '
'; DROP_SECTIONS.forEach(function(sec) { html += renderCard(sec, data); }); html += '
'; html += '
'; html += ''; html += '
'; html += ''; html += ''; html += '
'; $('#editorMain').innerHTML = html; setupSearchFields(); } function renderCurrent() { if (!dropData || !dropID) return; renderDropEditor(dropID, dropData); } function renderCard(sec, data) { var collapsed = expandedCards[sec.id] === false; var isFull = cardWidths[sec.id] !== undefined ? cardWidths[sec.id] : (sec.fullWidth || false); var fullClass = isFull ? ' obj-card-full' : ''; var h = '
'; h += '
'; h += '' + (collapsed ? '▶' : '▼') + ''; h += ''; h += '' + sec.label + ''; h += '
'; if (!collapsed) { h += '
'; h += renderArraySection(sec, data); h += '
'; } h += '
'; return h; } function renderArraySection(sec, data) { var arr = dropData[cardPath(sec)] || []; var h = ''; arr.forEach(function(item, idx) { h += '
'; h += '
'; sec.fields.forEach(function(f) { h += renderField(sec, f, data, idx); }); h += '
'; h += ''; h += '
'; }); h += ''; return h; } function renderField(sec, f, data, idx) { return ced_renderField(sec, f, data, idx, null, null, cardPath, fieldID, getVal); } function toggleCard(id) { expandedCards[id] = expandedCards[id] === false ? true : false; renderCurrent(); } function toggleCardWidth(id) { cardWidths[id] = !cardWidths[id]; renderCurrent(); } function addArrayItem(cardID) { var sec = DROP_SECTIONS.find(function(s) { return s.id === cardID; }); if (!sec || !sec.isArray) return; var arr = dropData[sec.path] || []; var empty = {}; sec.fields.forEach(function(f) { empty[f[0]] = f[2] === 'checkbox' ? false : (f[2] === 'number' ? 0 : ''); }); arr.push(empty); dropData[sec.path] = arr; renderCurrent(); } function removeArrayItem(cardID, idx) { var sec = DROP_SECTIONS.find(function(s) { return s.id === cardID; }); if (!sec || !sec.isArray) return; var arr = dropData[sec.path] || []; arr.splice(idx, 1); renderCurrent(); } function saveDrop() { if (!ced_validateFields(DROP_SECTIONS, fieldID, null)) return; var out = {}; DROP_SECTIONS.forEach(function(sec) { if (sec.isArray) { var arr = []; var card = document.querySelector('.obj-card[data-card="' + sec.id + '"]'); if (!card) return; var rows = card.querySelectorAll('.obj-sub-row'); rows.forEach(function(row, idx) { var item = {}; sec.fields.forEach(function(f) { var fid = fieldID(sec, f[0], idx); var el = document.getElementById(fid); if (el) item[f[0]] = collectFieldValue(el, f[2]); }); if (Object.keys(item).length > 0) arr.push(item); }); if (arr.length > 0) out[sec.path] = arr; return; } var sectionObj = {}; sec.fields.forEach(function(f) { var fid = fieldID(sec, f[0]); var el = document.getElementById(fid); if (!el) return; sectionObj[f[0]] = collectFieldValue(el, f[2]); }); if (sec.always && sec.path) { out[sec.path] = sectionObj; } else if (sec.always) { Object.keys(sectionObj).forEach(function(k) { out[k] = sectionObj[k]; }); } else if (sec.path) { out[sec.path] = sectionObj; } else { Object.keys(sectionObj).forEach(function(k) { out[k] = sectionObj[k]; }); } }); ced_cleanOutput(out); out.id = dropID; API.put('/api/drops/' + encodeURIComponent(dropID), out).then(function(resp) { notify('Drop table ' + dropID + ' saved', 'success'); updateUndoBar(); if (resp && resp._raw) dropData._raw = resp._raw; }).catch(function(e) { notify('Save failed: ' + e.message, 'error'); }); } function deleteDrop() { if (!confirm('Delete drop table "' + dropID + '"?')) return; API.del('/api/drops/' + encodeURIComponent(dropID)).then(function() { notify('Drop table ' + dropID + ' deleted', 'success'); updateUndoBar(); dropID = null; currentID = null; dropData = null; $('#editorMain').innerHTML = '

Deleted

'; loadList(); }).catch(function(e) { notify('Delete failed: ' + e.message, 'error'); }); }