aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-14 04:26:34 -0400
committerhistoria <[not public]>2026-07-14 04:26:34 -0400
commitb5491f140ebf1099171c932b688303e05d01a06c (patch)
tree2b688ffb4e75a37dbec97796fd1598f56b1ad977
parent430c81bd2056769e1326df9d1dff983afe7f33df (diff)
downloadthehouseoficarus-b5491f140ebf1099171c932b688303e05d01a06c.tar.gz
feat(admin): hide unused mod fields
-rw-r--r--internal/admin/static/cardeditor.js35
-rw-r--r--internal/admin/static/moduleeditor.js60
-rw-r--r--internal/admin/yaml_util.go4
3 files changed, 94 insertions, 5 deletions
diff --git a/internal/admin/static/cardeditor.js b/internal/admin/static/cardeditor.js
index 83eed2e..b29b814 100644
--- a/internal/admin/static/cardeditor.js
+++ b/internal/admin/static/cardeditor.js
@@ -130,6 +130,41 @@ function ced_addKVSearchRow(cardID, subKey, entity) {
ced_setupSearchFields(row);
}
+function ced_renderKVSelect(sec, il, data, getter) {
+ var sectionRoot = data[ced_cardPath(sec)] || data;
+ var map = getter ? getter(sectionRoot, il) : (sectionRoot[il.key] || {});
+ var options = il.options || [];
+ 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 + '" data-options="' + escAttr(JSON.stringify(options)) + '">';
+ Object.keys(map).forEach(function(k, idx) {
+ h += '<div class="obj-kv-row">';
+ h += '<select class="obj-kv-key" style="flex:1">';
+ options.forEach(function(opt) {
+ h += '<option value="' + escAttr(opt) + '"' + (k === opt ? ' selected' : '') + '>' + esc(opt) + '</option>';
+ });
+ h += '</select>';
+ h += '<input value="' + escAttr(String(map[k])) + '" placeholder="qty" class="obj-kv-val">';
+ h += '<button class="btn btn-sm btn-danger" onclick="this.parentElement.remove()">X</button></div>';
+ });
+ h += '</div>';
+ h += '<button class="btn btn-sm obj-sub-add" onclick="ced_addKVSelectRow(\'' + sec.id + '\',\'' + il.key + '\')">+ Add</button>';
+ h += '</div>';
+ return h;
+}
+
+function ced_addKVSelectRow(cardID, subKey) {
+ var el = document.querySelector('.obj-kv-list[data-sec="' + cardID + '"][data-key="' + subKey + '"]');
+ if (!el) return;
+ var opts = [];
+ try { opts = JSON.parse(el.getAttribute('data-options') || '[]'); } catch(e) {}
+ var optsHTML = opts.map(function(opt) { return '<option value="' + escAttr(String(opt)) + '">' + esc(String(opt)) + '</option>'; }).join('');
+ var row = document.createElement('div');
+ row.className = 'obj-kv-row';
+ row.innerHTML = '<select class="obj-kv-key" style="flex:1">' + optsHTML + '</select><input value="" placeholder="qty" class="obj-kv-val"><button class="btn btn-sm btn-danger" onclick="this.parentElement.remove()">X</button>';
+ el.appendChild(row);
+}
+
// ---- Search autocomplete ----
function ced_setupSearchFields(root) {
diff --git a/internal/admin/static/moduleeditor.js b/internal/admin/static/moduleeditor.js
index ff9d8a4..cbdc1c0 100644
--- a/internal/admin/static/moduleeditor.js
+++ b/internal/admin/static/moduleeditor.js
@@ -3,6 +3,7 @@ var moduleID = null;
var expandedCards = {};
var addedSections = {};
var cardWidths = {};
+window._modFieldVis = {};
var MODULE_SECTIONS = [
{
@@ -17,7 +18,7 @@ var MODULE_SECTIONS = [
['destination', 'Destination', 'number', '5', 'narrow'],
],
inline: [
- {label:'Junk Cost', key:'junk_cost', type:'kv_search', searchEntity:'items', valType:'number'},
+ {label:'Junk Cost', key:'junk_cost', type:'kv_select', options: ['biojunk','bloodjunk','chaosjunk','cosmicjunk','deathjunk','ecojunk','hydrojunk','lawjunk','naturejunk','scrap','solarjunk']},
]
},
{
@@ -137,17 +138,50 @@ function renderCard(sec, data) {
h += renderArraySection(sec, data);
} else {
h += '<div class="obj-card-grid">';
- sec.fields.forEach(function(f) {
- h += renderField(sec, f, data, -1);
- });
+ if (sec.id === 'core') {
+ var catVal = data.category || '';
+ var isCombat = catVal === 'combat';
+ var isTransport = catVal === 'transport';
+ h += renderField(sec, sec.fields[0], data, -1); // name
+ h += renderField(sec, sec.fields[1], data, -1); // level
+ if (isCombat) {
+ h += renderField(sec, sec.fields[2], data, -1); // max_hit
+ }
+ h += renderField(sec, sec.fields[3], data, -1); // base_xp
+ h += renderField(sec, sec.fields[4], data, -1); // category
+ if (isCombat) {
+ window._modFieldVis = window._modFieldVis || {};
+ var vis = window._modFieldVis;
+ var elemVal = data.element || '';
+ var showElem = vis.element || (elemVal !== '');
+ var efid = fieldID(sec, 'element', -1);
+ h += '<span id="mod_elem" style="display:' + (showElem ? 'flex' : 'none') + ';gap:4px;align-items:center">';
+ h += renderField(sec, sec.fields[5], data, -1);
+ h += '<button class="btn btn-sm btn-danger" style="padding:2px 6px;font-size:10px;min-width:auto" onclick="hideModField(\'element\')">X</button>';
+ h += '</span>';
+ }
+ if (isTransport) {
+ h += renderField(sec, sec.fields[6], data, -1); // destination
+ }
+ } else {
+ sec.fields.forEach(function(f) {
+ h += renderField(sec, f, data, -1);
+ });
+ }
h += '</div>';
+ if (sec.id === 'core' && typeof isCombat !== 'undefined' && isCombat) {
+ h += '<button class="btn btn-sm" id="mod_elem_btn" style="background:var(--accent);color:var(--text);border:1px solid #1a5a8e;' + (showElem ? 'display:none' : '') + '" onclick="showModField(\'element\')">+ Add Element</button> ';
+ }
+
if (sec.inline) {
sec.inline.forEach(function(il) {
if (il.type === 'kv') {
h += ced_renderKV(sec, il, data);
} else if (il.type === 'kv_search') {
h += ced_renderKVSearch(sec, il, data);
+ } else if (il.type === 'kv_select') {
+ h += ced_renderKVSelect(sec, il, data);
}
});
}
@@ -183,6 +217,22 @@ function toggleCardWidth(id) {
renderCurrent();
}
+function showModField(key) {
+ window._modFieldVis = window._modFieldVis || {};
+ window._modFieldVis[key] = true;
+ renderCurrent();
+}
+
+function hideModField(key) {
+ window._modFieldVis = window._modFieldVis || {};
+ window._modFieldVis[key] = false;
+ ced_syncDOMToData(moduleData);
+ if (key === 'element') {
+ moduleData.element = '';
+ }
+ renderModuleEditor(moduleID, moduleData);
+}
+
function removeSection(id) {
var sec = MODULE_SECTIONS.find(function(s) { return s.id === id; });
if (!sec) return;
@@ -272,7 +322,7 @@ function saveModule() {
if (sec.inline) {
sec.inline.forEach(function(il) {
- if (il.type === 'kv' || il.type === 'kv_search') {
+ if (il.type === 'kv' || il.type === 'kv_search' || il.type === 'kv_select') {
var kvEl = document.querySelector('.obj-kv-list[data-sec="' + sec.id + '"][data-key="' + il.key + '"]');
if (kvEl) {
var map = {};
diff --git a/internal/admin/yaml_util.go b/internal/admin/yaml_util.go
index b869ffe..2d838ad 100644
--- a/internal/admin/yaml_util.go
+++ b/internal/admin/yaml_util.go
@@ -34,6 +34,10 @@ func writeYAMLFile(path string, data any) ([]byte, error) {
func findYAMLFileInSubdirs(dataDir, subdir, id string) ([]byte, string, error) {
base := filepath.Join(dataDir, subdir)
+ rootPath := filepath.Join(base, id+".yaml")
+ if data, err := os.ReadFile(rootPath); err == nil {
+ return data, rootPath, nil
+ }
entries, err := os.ReadDir(base)
if err != nil {
return nil, "", err