diff options
| author | historia <[not public]> | 2026-06-29 22:31:11 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-29 22:31:11 -0400 |
| commit | 069d3c1c81d71042706372df153254487a765dfc (patch) | |
| tree | d83a4a3954d2b8304f49d83e365f4c2b075b91eb /internal/admin/static/talktree.js | |
| parent | 6c5271fb085b4571a10f106391974c249cd84317 (diff) | |
| download | thehouseoficarus-069d3c1c81d71042706372df153254487a765dfc.tar.gz | |
feat: wip web admin for mapping and crud
Diffstat (limited to 'internal/admin/static/talktree.js')
| -rw-r--r-- | internal/admin/static/talktree.js | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/internal/admin/static/talktree.js b/internal/admin/static/talktree.js new file mode 100644 index 0000000..f254c21 --- /dev/null +++ b/internal/admin/static/talktree.js @@ -0,0 +1,92 @@ +function renderTalkTree(data) { + var container = document.getElementById('talktree'); + if (!container) return; + if (!data || !data.talk || !data.talk.nodes) { + container.innerHTML = '<p style="color:#888">No conversation tree defined.</p>'; + return; + } + window._talkData = data; + var nodes = data.talk.nodes; + var html = '<div class="talk-tree">'; + html += renderTreeNodes(nodes, 'start', {}); + html += '</div>'; + container.innerHTML = html; +} + +function renderTreeNodes(nodes, rootKey, seen) { + var node = nodes[rootKey]; + if (!node) return ''; + if (seen[rootKey]) { + return '<div class="node ref"><span class="key">' + esc(rootKey) + '</span> <span class="preview">(already shown)</span></div>'; + } + seen[rootKey] = true; + + var html = ''; + html += '<div class="node root' + (rootKey === 'start' ? ' open' : '') + '">'; + html += '<div class="node-header" onclick="this.parentElement.classList.toggle(\'open\')">'; + html += '<span class="arrow"></span>'; + html += '<span class="key">' + esc(rootKey) + '</span>'; + html += '<span class="preview">' + esc((node.message || '').substring(0, 60)) + '</span>'; + html += '</div>'; + html += '<div class="node-children">'; + + html += '<div style="margin-left:8px;font-size:11px">'; + if (node.message) html += '<div><b>Message:</b> ' + esc(node.message) + '</div>'; + if (node.condition) html += '<div><b>Condition:</b> ' + esc(JSON.stringify(node.condition)) + '</div>'; + if (node.goto) html += '<div><b>Goto:</b> ' + esc(node.goto) + '</div>'; + html += '</div>'; + + html += '<div style="margin-left:10px"><b style="font-size:11px;color:#aaa">Options:</b>'; + if (node.options && node.options.length > 0) { + node.options.forEach(function(opt, idx) { + html += '<div class="option">'; + html += '<span>' + esc(opt.text || '') + '</span> \u2192 <span style="color:#8cf">' + esc(opt.goto || '') + '</span>'; + if (opt.condition) html += ' <span style="color:#888;font-size:10px">[cond]</span>'; + if (opt.action) html += ' <span style="color:#888;font-size:10px">[action]</span>'; + html += ' <button class="btn btn-danger btn-sm" onclick="deleteOption(event,\'' + escAttr(rootKey) + '\',' + idx + ')">Delete Option</button>'; + html += '</div>'; + }); + } else { + html += '<div class="option" style="color:#888">No options</div>'; + } + html += '<div style="margin-top:4px"><button class="btn btn-primary btn-sm" onclick="addOption(event,\'' + escAttr(rootKey) + '\')">+ Add Option</button></div>'; + html += '</div>'; + + html += '</div></div>'; + + if (node.options) { + node.options.forEach(function(opt) { + if (opt.goto && nodes[opt.goto]) { + html += renderTreeNodes(nodes, opt.goto, seen); + } + }); + } + + return html; +} + +function addOption(e, nodeKey) { + if (e) e.stopPropagation(); + var data = window._talkData; + if (!data || !data.talk || !data.talk.nodes || !data.talk.nodes[nodeKey]) return; + var text = prompt('Option text:'); + if (text === null) return; + var dest = prompt('Goto node key:') || ''; + var node = data.talk.nodes[nodeKey]; + if (!node.options) node.options = []; + node.options.push({ text: text, goto: dest }); + renderTalkTree(data); + if (typeof window.onTalkTreeChange === 'function') window.onTalkTreeChange(data); +} + +function deleteOption(e, nodeKey, idx) { + if (e) e.stopPropagation(); + var data = window._talkData; + if (!data || !data.talk || !data.talk.nodes || !data.talk.nodes[nodeKey]) return; + var node = data.talk.nodes[nodeKey]; + if (!node.options || idx < 0 || idx >= node.options.length) return; + if (!confirm('Delete this option?')) return; + node.options.splice(idx, 1); + renderTalkTree(data); + if (typeof window.onTalkTreeChange === 'function') window.onTalkTreeChange(data); +} |
