Fix demo/showcase toggle: separate buttons, distinct modes
Problem: plain toggle set showcase=true, so demo always became showcase. No way to enable basic demo mode separately. Fix: - Three explicit buttons: [Demo] [Showcase] [Off] - Demo mode: active=true, showcase=false (team UI only) - Showcase mode: active=true, showcase=true (full read-only admin) - Off: both false - Plain toggle cycles demo on/off without touching showcase - Clear status text shows which mode and what it means Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
732f29d836
commit
ffd5e43709
@ -461,7 +461,7 @@ def demo_toggle():
|
||||
if not session.get("user_id") or not is_admin():
|
||||
return jsonify({"error": "admin only"}), 403
|
||||
data = request.json if request.is_json else {}
|
||||
mode = data.get("mode", "toggle") # toggle, showcase, off
|
||||
mode = data.get("mode", "toggle") # demo, showcase, off
|
||||
if mode == "off":
|
||||
_demo_mode["active"] = False
|
||||
_demo_mode["showcase"] = False
|
||||
@ -470,10 +470,20 @@ def demo_toggle():
|
||||
_demo_mode["active"] = True
|
||||
_demo_mode["showcase"] = True
|
||||
_demo_mode["started_by"] = session.get("username")
|
||||
elif mode == "demo":
|
||||
_demo_mode["active"] = True
|
||||
_demo_mode["showcase"] = False
|
||||
_demo_mode["started_by"] = session.get("username")
|
||||
else:
|
||||
_demo_mode["active"] = not _demo_mode["active"]
|
||||
_demo_mode["showcase"] = _demo_mode["active"]
|
||||
_demo_mode["started_by"] = session.get("username") if _demo_mode["active"] else None
|
||||
# plain toggle: cycle off → demo → off
|
||||
if _demo_mode["active"]:
|
||||
_demo_mode["active"] = False
|
||||
_demo_mode["showcase"] = False
|
||||
_demo_mode["started_by"] = None
|
||||
else:
|
||||
_demo_mode["active"] = True
|
||||
_demo_mode["showcase"] = False
|
||||
_demo_mode["started_by"] = session.get("username")
|
||||
return jsonify({"active": _demo_mode["active"], "showcase": _demo_mode["showcase"]})
|
||||
|
||||
|
||||
@ -3000,13 +3010,15 @@ ADMIN_HTML = r"""
|
||||
<!-- DEMO & SECURITY TAB -->
|
||||
<div id="tab-security" class="tab-content">
|
||||
<div class="card" style="border-color:rgba(217,70,239,0.3)">
|
||||
<h3 style="color:#d946ef">Showcase Mode
|
||||
<div style="margin-left:auto;display:flex;gap:6px">
|
||||
<button class="btn" id="admin-showcase-btn" onclick="toggleShowcase()">Enable Showcase</button>
|
||||
<button class="btn btn-r" id="admin-demo-off" onclick="demoOff()" style="display:none">Turn Off</button>
|
||||
<h3 style="color:#d946ef">Demo / Showcase
|
||||
<div style="margin-left:auto;display:flex;gap:6px" id="demo-controls">
|
||||
<button class="btn btn-g" onclick="setDemoMode('demo')">Demo</button>
|
||||
<button class="btn" style="border-color:rgba(217,70,239,0.3);color:#d946ef" onclick="setDemoMode('showcase')">Showcase</button>
|
||||
<button class="btn btn-r" onclick="setDemoMode('off')">Off</button>
|
||||
</div>
|
||||
</h3>
|
||||
<p style="font-size:12px;color:var(--text2);margin-bottom:10px"><strong>Showcase mode</strong> gives visitors full read-only access to everything — Admin, Monitor, Logs, Threat Intel, Lab, History. They can run teams, view enrichments, and trigger self-analysis reports. They <strong>cannot</strong> change settings, ban IPs, delete data, or modify configs. Perfect for demos.</p>
|
||||
<p style="font-size:12px;color:var(--text2);margin-bottom:6px"><strong>Demo</strong> — public can use Team UI and run modes. No admin access.</p>
|
||||
<p style="font-size:12px;color:var(--text2);margin-bottom:10px"><strong>Showcase</strong> — full read-only access to everything: Admin, Monitor, Logs, Threat Intel, Lab, History. Cannot change settings or delete data.</p>
|
||||
<div id="demo-status-admin" style="font-size:13px">Status: <strong style="color:var(--text2)">Off</strong></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
@ -3251,39 +3263,21 @@ function switchTab(name) {
|
||||
async function loadDemoStatus() {
|
||||
var r = await fetch('/api/demo/status');
|
||||
var d = await r.json();
|
||||
var btn = document.getElementById('admin-showcase-btn');
|
||||
var offBtn = document.getElementById('admin-demo-off');
|
||||
var st = document.getElementById('demo-status-admin');
|
||||
if (d.active && d.showcase) {
|
||||
btn.textContent = 'Showcase Active';
|
||||
btn.className = 'btn';
|
||||
btn.style.cssText = 'margin-left:auto;border-color:#d946ef;color:#d946ef';
|
||||
offBtn.style.display = '';
|
||||
st.innerHTML = 'Status: <strong style="color:#d946ef">SHOWCASE MODE</strong> — full read-only access for visitors' + (d.started_by ? ' (by ' + d.started_by + ')' : '');
|
||||
st.innerHTML = 'Status: <strong style="color:#d946ef">SHOWCASE</strong> — full read-only admin access' + (d.started_by ? ' (by ' + d.started_by + ')' : '');
|
||||
} else if (d.active) {
|
||||
btn.textContent = 'Demo Active';
|
||||
btn.className = 'btn btn-g';
|
||||
offBtn.style.display = '';
|
||||
st.innerHTML = 'Status: <strong style="color:var(--green)">DEMO ON</strong>' + (d.started_by ? ' (by ' + d.started_by + ')' : '');
|
||||
st.innerHTML = 'Status: <strong style="color:var(--green)">DEMO</strong> — team UI only' + (d.started_by ? ' (by ' + d.started_by + ')' : '');
|
||||
} else {
|
||||
btn.textContent = 'Enable Showcase';
|
||||
btn.className = 'btn';
|
||||
btn.style.cssText = 'border-color:rgba(217,70,239,0.3);color:#d946ef';
|
||||
offBtn.style.display = 'none';
|
||||
st.innerHTML = 'Status: <strong style="color:var(--text2)">Off</strong>';
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleShowcase() {
|
||||
await fetch('/api/demo/toggle', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({mode:'showcase'})});
|
||||
async function setDemoMode(mode) {
|
||||
await fetch('/api/demo/toggle', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({mode:mode})});
|
||||
loadDemoStatus();
|
||||
toast('Showcase mode enabled', true);
|
||||
}
|
||||
|
||||
async function demoOff() {
|
||||
await fetch('/api/demo/toggle', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({mode:'off'})});
|
||||
loadDemoStatus();
|
||||
toast('Demo mode disabled', true);
|
||||
var labels = {demo:'Demo enabled',showcase:'Showcase enabled',off:'Turned off'};
|
||||
toast(labels[mode] || mode, true);
|
||||
}
|
||||
|
||||
async function loadAllowlist() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user