diff options
| author | historia <[not public]> | 2026-07-13 18:36:29 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-13 18:36:29 -0400 |
| commit | 1bedf06969b8ab8e51dd4301a0831200df5c8f59 (patch) | |
| tree | acdcbcc3a26896c678edeffad0cb0d8ec9b2857b /internal/admin/static/itemeditor.js | |
| parent | 8952653be9bfeeb9aadf59f845de507630d65dc4 (diff) | |
| download | thehouseoficarus-1bedf06969b8ab8e51dd4301a0831200df5c8f59.tar.gz | |
feat(admin): tooltips added for confusing fields, hide more optional fields with buttons
Diffstat (limited to 'internal/admin/static/itemeditor.js')
| -rw-r--r-- | internal/admin/static/itemeditor.js | 74 |
1 files changed, 59 insertions, 15 deletions
diff --git a/internal/admin/static/itemeditor.js b/internal/admin/static/itemeditor.js index 04ad20b..2283c91 100644 --- a/internal/admin/static/itemeditor.js +++ b/internal/admin/static/itemeditor.js @@ -52,7 +52,7 @@ var SECTIONS = [ ['level', 'Level', 'number', '', 'narrow'], ['xp', 'XP', 'number', '', 'narrow'], ['ticks_per_cycle', 'Ticks/Cycle', 'number', '', 'narrow'], - ['output_qty', 'Output Qty', 'number', '', 'narrow'], + ['output_qty', 'Output Qty', 'number', '', 'narrow', null, null, 'Quantity produced per cycle, only relevant for stackable items.'], ['station', 'Station', 'select', 'dyn:stations'], ['tool', 'Tool', 'select', 'dyn:tools'], ['fail', 'Fail Item', 'search', 'burnt_fish', '', null, 'items'], @@ -65,10 +65,9 @@ var SECTIONS = [ ['end_message', 'End Message', 'text', 'You\'ve finished smithing.', 'wide'], ], fieldGroups: [ - ['type', 'subtype', 'level', 'xp', 'ticks_per_cycle', 'output_qty'], - {note: 'Output Qty is the quantity produced per cycle, only relevant for stackable items.'}, + ['type', 'subtype', 'level', 'xp', 'ticks_per_cycle', 'output_qty'], ['station', 'tool'], - {label: 'Success', fields: ['success_base', 'success_per_level', 'success_cap', 'fail']}, + {label: 'Success', fields: ['success_base', 'success_per_level', 'success_cap']}, ['start_message', 'success_message', 'fail_message', 'end_message'], ], subSubtables: [ @@ -120,6 +119,7 @@ var SECTIONS = [ ] }, ]; +var SKILL_KEYS = ['accuracy','strength','defense','hitpoints','ranged','science','technology','fishing','cooking','woodcutting','firemaking','mining','smithing','crafting','fletching','pharmacy','thieving','agility','construction','scavenging','hacking','assassin','farming']; function initItemEditor() { window._ieRenderCurrent = renderCurrent; @@ -220,7 +220,7 @@ function renderItemEditor(id, data) { setupCraftTypeChange(); setupEquipTypeChange(); updateOutputQtyVisibility(); - DropView.setupAllInter(); + if (typeof DropView !== 'undefined') DropView.setupAllInter(); setTimeout(function() { document.querySelectorAll('.color-field').forEach(function(el) { bindColorField(el); }); }, 50); @@ -333,7 +333,16 @@ function renderCoreCard(data) { h += renderField(sec, sec.fields[3], data, -1); h += '</div>'; h += '<div style="display:flex;gap:8px;margin-left:auto">'; + var qualFid = fieldID(sec, 'max_quality', -1); + var qualVal = data.max_quality; + var qgid = 'qg_core_quality'; + var qShow = qualVal ? '' : 'display:none;'; + var qBtnShow = qualVal ? 'display:none;' : ''; + h += '<span id="' + qgid + '" style="display:flex;gap:4px;align-items:center;' + qShow + '">'; h += renderField(sec, sec.fields[4], data, -1); + h += '<button class="btn btn-sm btn-danger" style="padding:2px 6px;font-size:10px;min-width:auto" onclick="var g=document.getElementById(\'' + qgid + '\');g.style.display=\'none\';var b=document.getElementById(\'' + qgid + '_btn\');b.style.display=\'inline-block\';var inp=document.getElementById(\'' + qualFid + '\');if(inp)inp.value=\'\'">X</button>'; + h += '</span>'; + h += '<button class="btn btn-sm" id="' + qgid + '_btn" style="padding:2px 8px;font-size:11px;background:var(--accent);color:var(--text);border:1px solid #1a5a8e;border-radius:3px;cursor:pointer;' + qBtnShow + '" onclick="var b=document.getElementById(\'' + qgid + '_btn\');b.style.display=\'none\';var g=document.getElementById(\'' + qgid + '\');g.style.display=\'flex\'">+ Add Quality</button>'; h += '</div>'; h += '</div>'; var descFid = fieldID(sec, 'description', -1); @@ -509,7 +518,7 @@ function renderEquipmentCard(data) { // Requirements KV (at root level, stored in itemData.requirements) h += '<div style="margin-top:8px">'; - h += renderKV({id: 'equipment_req'}, {label:'Requirements', key:'requirements', type:'kv', valType:'number'}, data); + h += renderKV({id: 'equipment_req'}, {label:'Requirements', key:'requirements', type:'kv', valType:'number'}, data, SKILL_KEYS); h += '</div>'; return h; @@ -763,6 +772,13 @@ function renderSubtable(sec, st, data) { h += '<div class="obj-sub-row-line">'; renderGroup(group.fields); h += '</div>'; + var failF = st.fields.find(function(sf) { return sf[0] === 'fail'; }); + if (failF) { + var failVal = item.fail || ''; + var fgid = 'fg_' + sec.id + '_' + st.key + '_' + idx; + h += '<div id="' + fgid + '" style="margin-top:4px' + (failVal ? '' : ';display:none') + '"><div style="display:flex;align-items:center;gap:4px"><div style="flex:1">' + renderSubFieldHTML(sec, st.key, idx, failF, failVal) + '</div><button class="btn btn-sm btn-danger" style="padding:2px 6px;font-size:10px;min-width:auto;align-self:flex-start;margin-top:18px" onclick="var g=document.getElementById(\'' + fgid + '\');g.style.display=\'none\';var b=document.getElementById(\'' + fgid + '_btn\');b.style.display=\'\';var inp=g.querySelector(\'input\');if(inp)inp.value=\'\'">X</button></div></div>'; + h += '<button class="btn btn-sm obj-sub-add" id="' + fgid + '_btn" style="margin-top:4px' + (failVal ? ';display:none' : '') + '" onclick="var b=document.getElementById(\'' + fgid + '_btn\');b.style.display=\'none\';var g=document.getElementById(\'' + fgid + '\');g.style.display=\'\'">+ Add Fail Item</button>'; + } h += '</div>'; h += '<button class="btn btn-sm obj-sub-add" id="' + gid + '_btn" style="margin:2px 0' + (hasSuccess ? ';display:none' : '') + '" onclick="var b=document.getElementById(\'' + gid + '_btn\');b.style.display=\'none\';var g=document.getElementById(\'' + gid + '\');g.style.display=\'\'">+ Add Success Rates</button>'; } else { @@ -832,6 +848,7 @@ function addConsumePair(secID, subKey, rowIdx, subSubKey, subIdx) { var btnRow = document.querySelector('.ingredients-pair-add[data-sec="' + secID + '"][data-subkey="' + subKey + '"][data-row="' + rowIdx + '"][data-subsub="' + subSubKey + '"][data-subidx="' + subIdx + '"]'); var itemFid = ingredientPairID(sec, subKey, rowIdx, subSubKey, subIdx, pairIdx, 'items'); var bypFid = ingredientPairID(sec, subKey, rowIdx, subSubKey, subIdx, pairIdx, 'byproducts'); + var bpgid = 'bp_' + secID + '_' + subKey + '_' + rowIdx + '_' + subSubKey + '_' + subIdx + '_' + pairIdx; var row = document.createElement('div'); row.className = 'ingredients-pair'; row.setAttribute('data-sec', secID); @@ -843,7 +860,7 @@ function addConsumePair(secID, subKey, rowIdx, subSubKey, subIdx) { row.innerHTML = '<div class="ingredients-col ingredients-col-num"></div>' + '<div class="ingredients-col ingredients-col-qty"></div>' + '<div class="ingredients-col ingredients-col-items">' + renderConsumeSearchHTML(itemFid, '', 'items', 'Search items...') + '</div>' - + '<div class="ingredients-col ingredients-col-byproducts">' + renderConsumeSearchHTML(bypFid, '', 'items', '(optional)') + '</div>' + + '<div class="ingredients-col ingredients-col-byproducts"><div id="' + bpgid + '" style="display:none;align-items:center;gap:2px">' + renderConsumeSearchHTML(bypFid, '', 'items', '(optional)') + '<button class="btn btn-sm btn-danger" style="padding:2px 4px;font-size:10px;min-width:auto;flex-shrink:0" onclick="var g=document.getElementById(\'' + bpgid + '\');g.style.display=\'none\';var b=document.getElementById(\'' + bpgid + '_btn\');b.style.display=\'block\';var inp=g.querySelector(\'input\');if(inp)inp.value=\'\'">Remove</button></div><button class="btn btn-sm obj-sub-add" id="' + bpgid + '_btn" style="margin-top:0;display:block" onclick="var b=document.getElementById(\'' + bpgid + '_btn\');b.style.display=\'none\';var g=document.getElementById(\'' + bpgid + '\');g.style.display=\'flex\'">+ Add Byproduct</button></div>' + '<div class="ingredients-col ingredients-col-x"><button class="btn btn-sm btn-danger" style="padding:2px 6px;font-size:10px;background:var(--danger);color:#fff;border:none;border-radius:3px;cursor:pointer" onclick="removeConsumePair(\'' + secID + '\',\'' + subKey + '\',' + rowIdx + ',\'' + subSubKey + '\',' + subIdx + ',' + pairIdx + ')">X</button></div>'; btnRow.parentNode.insertBefore(row, btnRow); setupSearchFields(); @@ -914,7 +931,12 @@ function renderSubSubtable(sec, st, rowIdx, sst, parentItem) { var bypVal = bypArr[p] || ''; var bypFid = ingredientPairID(sec, st.key, rowIdx, sst.key, subIdx, p, 'byproducts'); - h += '<div class="ingredients-col ingredients-col-byproducts">' + renderConsumeSearchHTML(bypFid, bypVal, 'items', '(optional)') + '</div>'; + var bpgid = 'bp_' + sec.id + '_' + st.key + '_' + rowIdx + '_' + sst.key + '_' + subIdx + '_' + p; + if (bypVal) { + h += '<div class="ingredients-col ingredients-col-byproducts"><div id="' + bpgid + '" style="display:flex;align-items:center;gap:2px">' + renderConsumeSearchHTML(bypFid, bypVal, 'items', '(optional)') + '<button class="btn btn-sm btn-danger" style="padding:2px 4px;font-size:10px;min-width:auto;flex-shrink:0" onclick="var g=document.getElementById(\'' + bpgid + '\');g.style.display=\'none\';var b=document.getElementById(\'' + bpgid + '_btn\');b.style.display=\'block\';var inp=g.querySelector(\'input\');if(inp)inp.value=\'\'">Remove</button></div><button class="btn btn-sm obj-sub-add" id="' + bpgid + '_btn" style="margin-top:0;display:none" onclick="var b=document.getElementById(\'' + bpgid + '_btn\');b.style.display=\'none\';var g=document.getElementById(\'' + bpgid + '\');g.style.display=\'flex\'">+ Add Byproduct</button></div>'; + } else { + h += '<div class="ingredients-col ingredients-col-byproducts"><div id="' + bpgid + '" style="display:none;align-items:center;gap:2px">' + renderConsumeSearchHTML(bypFid, '', 'items', '(optional)') + '<button class="btn btn-sm btn-danger" style="padding:2px 4px;font-size:10px;min-width:auto;flex-shrink:0" onclick="var g=document.getElementById(\'' + bpgid + '\');g.style.display=\'none\';var b=document.getElementById(\'' + bpgid + '_btn\');b.style.display=\'block\';var inp=g.querySelector(\'input\');if(inp)inp.value=\'\'">Remove</button></div><button class="btn btn-sm obj-sub-add" id="' + bpgid + '_btn" style="margin-top:0;display:block" onclick="var b=document.getElementById(\'' + bpgid + '_btn\');b.style.display=\'none\';var g=document.getElementById(\'' + bpgid + '\');g.style.display=\'flex\'">+ Add Byproduct</button></div>'; + } h += '<div class="ingredients-col ingredients-col-x"><button class="btn btn-sm btn-danger" style="padding:2px 6px;font-size:10px;background:var(--danger);color:#fff;border:none;border-radius:3px;cursor:pointer" onclick="removeConsumePair(\'' + sec.id + '\',\'' + st.key + '\',' + rowIdx + ',\'' + sst.key + '\',' + subIdx + ',' + p + ')">X</button></div>'; @@ -974,15 +996,28 @@ function renderTags(sec, il, data) { return '<label class="obj-field obj-wide"><span>' + esc(il.label) + '</span><input id="' + fid + '" value="' + escAttr(str) + '" placeholder="comma separated"></label>'; } -function renderKV(sec, il, data) { +function renderKV(sec, il, data, keyOptions) { var p = cardPath(sec); var sectionRoot = p ? (itemData[p] || {}) : itemData; var map = sectionRoot[il.key] || {}; + var hasKeyOpts = Array.isArray(keyOptions) && keyOptions.length > 0; var h = '<div class="obj-inline-group">'; h += '<span class="obj-inline-label">' + esc(il.label) + '</span>'; - h += '<div class="obj-kv-list" data-sec="' + sec.id + '" data-key="' + il.key + '">'; + h += '<div class="obj-kv-list" data-sec="' + sec.id + '" data-key="' + il.key + '"' + (hasKeyOpts ? ' data-key-options="' + escAttr(keyOptions.join(',')) + '"' : '') + '>'; Object.keys(map).forEach(function(k, idx) { - h += '<div class="obj-kv-row"><input value="' + escAttr(k) + '" placeholder="key" class="obj-kv-key">'; + h += '<div class="obj-kv-row">'; + if (hasKeyOpts) { + var keyOpts = keyOptions.slice(); + if (k && keyOptions.indexOf(k) === -1) keyOpts.unshift(k); + h += '<select class="obj-kv-key">'; + h += '<option value="">(none)</option>'; + keyOpts.forEach(function(o) { + h += '<option value="' + escAttr(o) + '"' + (k === o ? ' selected' : '') + '>' + esc(o) + '</option>'; + }); + h += '</select>'; + } else { + h += '<input value="' + escAttr(k) + '" placeholder="key" class="obj-kv-key">'; + } h += '<input value="' + escAttr(String(map[k])) + '" placeholder="val" class="obj-kv-val">'; h += '<button class="btn btn-sm btn-danger" onclick="this.parentElement.remove()">X</button></div>'; }); @@ -1192,7 +1227,19 @@ function addKVRow(cardID, subKey) { if (!el) return; var row = document.createElement('div'); row.className = 'obj-kv-row'; - row.innerHTML = '<input value="" placeholder="key" class="obj-kv-key"><input value="0" placeholder="val" class="obj-kv-val"><button class="btn btn-sm btn-danger" onclick="this.parentElement.remove()">X</button>'; + var keyOptsStr = el.getAttribute('data-key-options'); + if (keyOptsStr) { + var keyOpts = keyOptsStr.split(','); + var selHTML = '<select class="obj-kv-key">'; + selHTML += '<option value="">(none)</option>'; + keyOpts.forEach(function(o) { + selHTML += '<option value="' + escAttr(o) + '">' + esc(o) + '</option>'; + }); + selHTML += '</select>'; + row.innerHTML = selHTML + '<input value="0" placeholder="val" class="obj-kv-val"><button class="btn btn-sm btn-danger" onclick="this.parentElement.remove()">X</button>'; + } else { + row.innerHTML = '<input value="" placeholder="key" class="obj-kv-key"><input value="0" placeholder="val" class="obj-kv-val"><button class="btn btn-sm btn-danger" onclick="this.parentElement.remove()">X</button>'; + } el.appendChild(row); } @@ -1292,9 +1339,6 @@ function updateOutputQtyVisibility() { var lbl = el.closest('.obj-field'); if (lbl) lbl.style.display = isStackable ? '' : 'none'; }); - document.querySelectorAll('.output-qty-note').forEach(function(el) { - el.style.display = isStackable ? '' : 'none'; - }); } function setupSearchFields() { ced_setupSearchFields(); } |
