Changeset 0.28.3.2 (#189)
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<p class="section-hint">AI provider configurations. Each provider connects to an API endpoint.</p>
|
||||
|
||||
<div class="admin-toolbar">
|
||||
<button class="btn-small btn-primary" onclick="Pages.showProviderForm()">+ Add Provider</button>
|
||||
<button class="btn-small btn-primary" onclick="sb.call('Pages.showProviderForm')">+ Add Provider</button>
|
||||
</div>
|
||||
|
||||
<div id="providerFormWrap" style="display:none;">
|
||||
@@ -34,8 +34,8 @@
|
||||
<td>{{.ModelCount}}</td>
|
||||
<td style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-secondary);">{{.Endpoint}}</td>
|
||||
<td>
|
||||
<button class="btn-small" onclick="Pages.syncProvider('{{.ID}}')">Sync</button>
|
||||
<button class="btn-small" onclick="Pages.editProvider('{{.ID}}')">Edit</button>
|
||||
<button class="btn-small" onclick="sb.call('Pages.syncProvider','{{.ID}}')">Sync</button>
|
||||
<button class="btn-small" onclick="sb.call('Pages.editProvider','{{.ID}}')">Edit</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
@@ -90,8 +90,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;margin-top:8px;">
|
||||
<button class="btn-small btn-primary" onclick="Pages.saveProvider()">Save</button>
|
||||
<button class="btn-small" onclick="Pages.hideProviderForm()">Cancel</button>
|
||||
<button class="btn-small btn-primary" onclick="sb.call('Pages.saveProvider')">Save</button>
|
||||
<button class="btn-small" onclick="sb.call('Pages.hideProviderForm')">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn-small btn-primary" onclick="Pages.saveRole('{{$roleName}}')">Save</button>
|
||||
<button class="btn-small btn-primary" onclick="sb.call('Pages.saveRole','{{$roleName}}')">Save</button>
|
||||
</div>
|
||||
</section>
|
||||
{{end}}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<p class="section-hint">Define rules for model selection, cost limits, and team-specific routing.</p>
|
||||
|
||||
<div style="margin-bottom:12px">
|
||||
<button class="btn-small btn-primary" onclick="Pages.showRoutingForm()">+ New Policy</button>
|
||||
<button class="btn-small btn-primary" onclick="sb.call('Pages.showRoutingForm')">+ New Policy</button>
|
||||
</div>
|
||||
|
||||
<div id="routingPolicyForm" style="display:none" class="admin-inline-form">
|
||||
@@ -66,8 +66,8 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-row" style="gap:8px;margin-top:8px">
|
||||
<button class="btn-small btn-primary" onclick="Pages.saveRoutingPolicy()">Save</button>
|
||||
<button class="btn-small" onclick="Pages.hideRoutingForm()">Cancel</button>
|
||||
<button class="btn-small btn-primary" onclick="sb.call('Pages.saveRoutingPolicy')">Save</button>
|
||||
<button class="btn-small" onclick="sb.call('Pages.hideRoutingForm')">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
</div>
|
||||
|
||||
<div style="margin-top:16px;">
|
||||
<button class="btn-small btn-primary" onclick="Pages.saveSettings()">Save Settings</button>
|
||||
<button class="btn-small btn-primary" onclick="sb.call('Pages.saveSettings')">Save Settings</button>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<p class="section-hint">Organize users into teams for scoped access to providers, personas, and policies.</p>
|
||||
|
||||
<div class="admin-toolbar">
|
||||
<button class="btn-small btn-primary" onclick="Pages.showTeamForm()">+ Create Team</button>
|
||||
<button class="btn-small btn-primary" onclick="sb.call('Pages.showTeamForm')">+ Create Team</button>
|
||||
</div>
|
||||
|
||||
<div id="teamFormWrap" style="display:none;">
|
||||
@@ -24,8 +24,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;margin-top:8px;">
|
||||
<button class="btn-small btn-primary" onclick="Pages.saveTeam()">Save</button>
|
||||
<button class="btn-small" onclick="Pages.hideTeamForm()">Cancel</button>
|
||||
<button class="btn-small btn-primary" onclick="sb.call('Pages.saveTeam')">Save</button>
|
||||
<button class="btn-small" onclick="sb.call('Pages.hideTeamForm')">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@
|
||||
<td>{{.MemberCount}}</td>
|
||||
<td><span class="admin-badge admin-badge-{{if .IsActive}}active{{else}}inactive{{end}}">{{if .IsActive}}active{{else}}inactive{{end}}</span></td>
|
||||
<td>
|
||||
<button class="btn-small" onclick="Pages.editTeam('{{.ID}}','{{.Name}}','{{.Description}}')">Edit</button>
|
||||
<button class="btn-small" onclick="sb.call('Pages.editTeam','{{.ID}}','{{.Name}}','{{.Description}}')">Edit</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
<td><span class="admin-badge admin-badge-{{.Role}}">{{.Role}}</span></td>
|
||||
<td><span class="admin-badge admin-badge-{{if .IsActive}}active{{else}}inactive{{end}}">{{if .IsActive}}active{{else}}inactive{{end}}</span></td>
|
||||
<td>
|
||||
<button class="btn-small" onclick="Pages.editUserRole('{{.ID}}','{{.Username}}','{{.Role}}')">Role</button>
|
||||
<button class="btn-small" onclick="sb.call('Pages.editUserRole','{{.ID}}','{{.Username}}','{{.Role}}')">Role</button>
|
||||
{{if .IsActive}}
|
||||
<button class="btn-small" onclick="Pages.toggleUser('{{.ID}}',false)">Disable</button>
|
||||
<button class="btn-small" onclick="sb.call('Pages.toggleUser','{{.ID}}',false)">Disable</button>
|
||||
{{else}}
|
||||
<button class="btn-small" onclick="Pages.toggleUser('{{.ID}}',true)">Enable</button>
|
||||
<button class="btn-small" onclick="sb.call('Pages.toggleUser','{{.ID}}',true)">Enable</button>
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -92,30 +92,30 @@
|
||||
</script>
|
||||
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/sb.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/app-state.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/api.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}">
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/app-state.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/api.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}">
|
||||
// Hydrate auth tokens for all surfaces (chat surface also calls this in init)
|
||||
API.loadTokens();
|
||||
</script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/events.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-primitives.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/events.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-primitives.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/vendor/marked.min.js"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/vendor/purify.min.js"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-format.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-core.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/pages.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-format.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-core.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/pages.js?v={{.Version}}"></script>
|
||||
{{/* v0.25.0: Component scripts — available on all surfaces */}}
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/user-menu.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/model-selector.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/file-tree.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/code-editor.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/note-editor.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/drag-resize.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/pane-container.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/user-menu.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/model-selector.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/file-tree.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/code-editor.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/note-editor.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/drag-resize.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/pane-container.js?v={{.Version}}"></script>
|
||||
|
||||
{{/* ── Universal init: theme + appearance for ALL surfaces ── */}}
|
||||
<script nonce="{{.CSPNonce}}">
|
||||
<script type="module" nonce="{{.CSPNonce}}">
|
||||
// Theme must init on every surface, not just chat.
|
||||
if (typeof Theme !== 'undefined') Theme.init();
|
||||
// Appearance (zoom + font size) must restore on every surface.
|
||||
@@ -131,6 +131,8 @@
|
||||
if (typeof API !== 'undefined' && API.logout) API.logout();
|
||||
location.reload();
|
||||
}
|
||||
// Register fallback — app.js re-registers with a richer version.
|
||||
sb.register('handleLogout', handleLogout);
|
||||
</script>
|
||||
|
||||
{{if eq .Surface "chat"}}{{template "scripts-chat" .}}{{end}}
|
||||
@@ -140,7 +142,7 @@
|
||||
{{if eq .Surface "settings"}}{{template "scripts-settings" .}}{{end}}
|
||||
{{/* v0.27.0: Extension surface JS — loaded from /surfaces/{id}/js/main.js */}}
|
||||
{{if and .Manifest (eq .Manifest.Source "extension")}}
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/surfaces/{{.Surface}}/js/main.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/surfaces/{{.Surface}}/js/main.js?v={{.Version}}"></script>
|
||||
{{end}}
|
||||
|
||||
{{/* ── v0.28.0: Universal UserMenu hydration ──────────────────
|
||||
@@ -151,29 +153,28 @@
|
||||
richer behavior (team admin refresh). Chat migration to UserMenu
|
||||
component is tracked as tech debt (Pre-1.0 sweep).
|
||||
*/}}
|
||||
<script nonce="{{.CSPNonce}}">
|
||||
(function () {
|
||||
if (typeof UserMenu === 'undefined') return;
|
||||
if (UserMenu.primary) return;
|
||||
if ((window.__SURFACE__ || '') === 'chat') return;
|
||||
|
||||
<script type="module" nonce="{{.CSPNonce}}">
|
||||
if (typeof UserMenu === 'undefined') { /* noop */ }
|
||||
else if (UserMenu.primary) { /* noop */ }
|
||||
else if ((window.__SURFACE__ || '') === 'chat') { /* noop */ }
|
||||
else {
|
||||
var btn = document.getElementById('userMenuBtn');
|
||||
if (!btn) return;
|
||||
if (btn) {
|
||||
var menu = UserMenu.create({ id: '' });
|
||||
UserMenu.primary = menu;
|
||||
menu.setUser(window.__USER__ || {});
|
||||
|
||||
var menu = UserMenu.create({ id: '' });
|
||||
UserMenu.primary = menu;
|
||||
menu.setUser(window.__USER__ || {});
|
||||
var user = window.__USER__ || {};
|
||||
menu.showAdmin(user.role === 'admin');
|
||||
|
||||
var user = window.__USER__ || {};
|
||||
menu.showAdmin(user.role === 'admin');
|
||||
|
||||
menu.bind({
|
||||
onSettings: function () { window.location.href = (window.__BASE__ || '') + '/settings'; },
|
||||
onAdmin: function () { window.location.href = (window.__BASE__ || '') + '/admin'; },
|
||||
onDebug: function () { if (typeof openDebugModal === 'function') openDebugModal(); },
|
||||
onSignout: function () { handleLogout(); },
|
||||
});
|
||||
})();
|
||||
menu.bind({
|
||||
onSettings: function () { window.location.href = (window.__BASE__ || '') + '/settings'; },
|
||||
onAdmin: function () { window.location.href = (window.__BASE__ || '') + '/admin'; },
|
||||
onDebug: function () { sb.call('openDebugModal'); },
|
||||
onSignout: function () { sb.call('handleLogout'); },
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{{/* ── Debug Log Modal (all surfaces) ───── */}}
|
||||
@@ -181,13 +182,13 @@
|
||||
<div class="modal modal-wide">
|
||||
<div class="modal-header">
|
||||
<h2>Debug Log</h2>
|
||||
<button class="modal-close" onclick="closeModal('debugModal')">✕</button>
|
||||
<button class="modal-close" onclick="sb.call('closeModal','debugModal')">✕</button>
|
||||
</div>
|
||||
<div class="modal-tabs">
|
||||
<button class="debug-tab active" data-tab="console" onclick="switchDebugTab('console')">Console <span id="debugConsoleCount" class="badge">0</span></button>
|
||||
<button class="debug-tab" data-tab="network" onclick="switchDebugTab('network')">Network <span id="debugNetworkCount" class="badge">0</span></button>
|
||||
<button class="debug-tab" data-tab="state" onclick="switchDebugTab('state')">State</button>
|
||||
<button class="debug-tab" data-tab="repl" onclick="switchDebugTab('repl')">REPL</button>
|
||||
<button class="debug-tab active" data-tab="console" onclick="sb.call('switchDebugTab','console')">Console <span id="debugConsoleCount" class="badge">0</span></button>
|
||||
<button class="debug-tab" data-tab="network" onclick="sb.call('switchDebugTab','network')">Network <span id="debugNetworkCount" class="badge">0</span></button>
|
||||
<button class="debug-tab" data-tab="state" onclick="sb.call('switchDebugTab','state')">State</button>
|
||||
<button class="debug-tab" data-tab="repl" onclick="sb.call('switchDebugTab','repl')">REPL</button>
|
||||
</div>
|
||||
<div class="modal-body" style="padding:0;overflow:hidden;display:flex;flex-direction:column;min-height:0;">
|
||||
<div id="debugConsoleTab" class="debug-tab-content" style="display:flex;flex-direction:column;flex:1;min-height:0;">
|
||||
@@ -212,19 +213,19 @@
|
||||
</div>
|
||||
<div class="modal-footer" style="display:flex;justify-content:space-between;align-items:center;">
|
||||
<div style="display:flex;gap:8px;">
|
||||
<button class="btn-danger btn-small" onclick="runDebugDiagnostics()">Diagnostics</button>
|
||||
<button class="btn-danger btn-small" onclick="purgeCache()">Purge Cache</button>
|
||||
<button class="btn-danger btn-small" onclick="sb.call('runDebugDiagnostics')">Diagnostics</button>
|
||||
<button class="btn-danger btn-small" onclick="sb.call('purgeCache')">Purge Cache</button>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;">
|
||||
<button class="btn-secondary btn-small" onclick="clearDebugLog()">Clear</button>
|
||||
<button class="btn-secondary btn-small" onclick="copyDebugLog()">Copy</button>
|
||||
<button class="btn-secondary btn-small" onclick="exportDebugLog()">Export</button>
|
||||
<button class="btn-secondary btn-small" onclick="sb.call('clearDebugLog')">Clear</button>
|
||||
<button class="btn-secondary btn-small" onclick="sb.call('copyDebugLog')">Copy</button>
|
||||
<button class="btn-secondary btn-small" onclick="sb.call('exportDebugLog')">Export</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/debug.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/repl.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/debug.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/repl.js?v={{.Version}}"></script>
|
||||
<div id="toastContainer" class="toast-container"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<div class="modal" style="max-width:440px;">
|
||||
<div class="modal-header">
|
||||
<h2>Create User</h2>
|
||||
<button class="modal-close" onclick="closeModal('createUserModal')">✕</button>
|
||||
<button class="modal-close" onclick="sb.call('closeModal','createUserModal')">✕</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group"><label>Username</label><input type="text" id="adminNewUsername" placeholder="username" autocomplete="off"></div>
|
||||
@@ -87,7 +87,7 @@
|
||||
<div class="form-group"><label>Role</label><select id="adminNewRole"><option value="user">User</option><option value="admin">Admin</option></select></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn-md btn-ghost" onclick="closeModal('createUserModal')">Cancel</button>
|
||||
<button class="btn-md btn-ghost" onclick="sb.call('closeModal','createUserModal')">Cancel</button>
|
||||
<button class="btn-md btn-primary" id="adminCreateUserBtn">Create User</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -98,7 +98,7 @@
|
||||
<div class="modal" style="max-width:440px;">
|
||||
<div class="modal-header">
|
||||
<h2>Reset Password</h2>
|
||||
<button class="modal-close" onclick="closeModal('resetPwModal')">✕</button>
|
||||
<button class="modal-close" onclick="sb.call('closeModal','resetPwModal')">✕</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p id="resetPwUser" style="font-weight:600;margin-bottom:8px;"></p>
|
||||
@@ -108,7 +108,7 @@
|
||||
<div class="form-group"><label>New Password</label><input type="password" id="resetPwInput" placeholder="min 8 chars" autocomplete="new-password"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn-md btn-ghost" onclick="closeModal('resetPwModal')">Cancel</button>
|
||||
<button class="btn-md btn-ghost" onclick="sb.call('closeModal','resetPwModal')">Cancel</button>
|
||||
<button class="btn-md btn-danger" id="resetPwConfirmBtn">Reset Password & Destroy Vault</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -119,14 +119,14 @@
|
||||
<div class="modal" style="max-width:440px;">
|
||||
<div class="modal-header">
|
||||
<h2 id="approveUserTitle">Approve User</h2>
|
||||
<button class="modal-close" onclick="closeModal('approveUserModal')">✕</button>
|
||||
<button class="modal-close" onclick="sb.call('closeModal','approveUserModal')">✕</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" id="approveUserId">
|
||||
<div id="approveTeamsList"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn-md btn-ghost" onclick="closeModal('approveUserModal')">Cancel</button>
|
||||
<button class="btn-md btn-ghost" onclick="sb.call('closeModal','approveUserModal')">Cancel</button>
|
||||
<button class="btn-md btn-primary" id="approveUserSubmitBtn">Activate User</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -137,14 +137,14 @@
|
||||
<div class="modal" style="max-width:440px;">
|
||||
<div class="modal-header">
|
||||
<h2>Create Team</h2>
|
||||
<button class="modal-close" onclick="closeModal('createTeamModal')">✕</button>
|
||||
<button class="modal-close" onclick="sb.call('closeModal','createTeamModal')">✕</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group"><label>Name</label><input type="text" id="adminTeamName" placeholder="Team name"></div>
|
||||
<div class="form-group"><label>Description</label><input type="text" id="adminTeamDesc" placeholder="Optional description"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn-md btn-ghost" onclick="closeModal('createTeamModal')">Cancel</button>
|
||||
<button class="btn-md btn-ghost" onclick="sb.call('closeModal','createTeamModal')">Cancel</button>
|
||||
<button class="btn-md btn-primary" id="adminCreateTeamBtn">Create Team</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -155,7 +155,7 @@
|
||||
<div class="modal" style="max-width:440px;">
|
||||
<div class="modal-header">
|
||||
<h2>Create Group</h2>
|
||||
<button class="modal-close" onclick="closeModal('createGroupModal')">✕</button>
|
||||
<button class="modal-close" onclick="sb.call('closeModal','createGroupModal')">✕</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group"><label>Name</label><input type="text" id="adminGroupName" placeholder="Group name"></div>
|
||||
@@ -166,7 +166,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn-md btn-ghost" onclick="closeModal('createGroupModal')">Cancel</button>
|
||||
<button class="btn-md btn-ghost" onclick="sb.call('closeModal','createGroupModal')">Cancel</button>
|
||||
<button class="btn-md btn-primary" id="adminCreateGroupBtn">Create Group</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -177,11 +177,11 @@
|
||||
<div class="modal" style="max-width:520px;">
|
||||
<div class="modal-header">
|
||||
<h2 id="providerFormTitle">Add Provider</h2>
|
||||
<button class="modal-close" onclick="closeModal('providerFormModal')">✕</button>
|
||||
<button class="modal-close" onclick="sb.call('closeModal','providerFormModal')">✕</button>
|
||||
</div>
|
||||
<div class="modal-body" id="adminAddProviderForm"></div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn-md btn-ghost" onclick="closeModal('providerFormModal')">Cancel</button>
|
||||
<button class="btn-md btn-ghost" onclick="sb.call('closeModal','providerFormModal')">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -191,11 +191,11 @@
|
||||
<div class="modal" style="max-width:520px;">
|
||||
<div class="modal-header">
|
||||
<h2 id="personaFormTitle">Create Persona</h2>
|
||||
<button class="modal-close" onclick="closeModal('personaFormModal')">✕</button>
|
||||
<button class="modal-close" onclick="sb.call('closeModal','personaFormModal')">✕</button>
|
||||
</div>
|
||||
<div class="modal-body" id="adminAddPersonaForm"></div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn-md btn-ghost" onclick="closeModal('personaFormModal')">Cancel</button>
|
||||
<button class="btn-md btn-ghost" onclick="sb.call('closeModal','personaFormModal')">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -206,20 +206,20 @@
|
||||
|
||||
{{/* Scripts */}}
|
||||
{{define "scripts-admin"}}
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-settings.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-admin.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/admin-handlers.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-settings.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-admin.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/admin-handlers.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/settings-handlers.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/knowledge-ui.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/persona-kb.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/memory-ui.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/notifications.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/files.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/admin-scaffold.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/workflow-api.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/workflow-admin.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/task-admin.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/admin-surfaces.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/knowledge-ui.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/persona-kb.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/memory-ui.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/notifications.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/files.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/admin-scaffold.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/workflow-api.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/workflow-admin.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/task-admin.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/admin-surfaces.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}">
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// ── Admin navigation: don't pollute browser history ──
|
||||
|
||||
@@ -25,19 +25,19 @@
|
||||
<div class="splash-auth">
|
||||
<div id="splashError" class="splash-error" style="display:none;"></div>
|
||||
<div class="auth-tabs">
|
||||
<button id="authTabLogin" class="auth-tab active" onclick="switchAuthTab('login')">Sign In</button>
|
||||
<button id="authTabRegister" class="auth-tab" onclick="switchAuthTab('register')">Register</button>
|
||||
<button id="authTabLogin" class="auth-tab active" onclick="sb.call('switchAuthTab','login')">Sign In</button>
|
||||
<button id="authTabRegister" class="auth-tab" onclick="sb.call('switchAuthTab','register')">Register</button>
|
||||
</div>
|
||||
<div id="authLoginForm">
|
||||
<input type="text" id="authLogin" placeholder="Username or email" autocomplete="username">
|
||||
<input type="password" id="authPassword" placeholder="Password" autocomplete="current-password">
|
||||
<button id="authLoginBtn" onclick="handleLogin()">Sign In</button>
|
||||
<button id="authLoginBtn" onclick="sb.call('handleLogin')">Sign In</button>
|
||||
</div>
|
||||
<div id="authRegisterForm" style="display:none;">
|
||||
<input type="text" id="authUsername" placeholder="Username" autocomplete="username">
|
||||
<input type="text" id="authEmail" placeholder="Email" autocomplete="email">
|
||||
<input type="password" id="authRegPassword" placeholder="Password" autocomplete="new-password">
|
||||
<button id="authRegisterBtn" onclick="handleRegister()">Create Account</button>
|
||||
<button id="authRegisterBtn" onclick="sb.call('handleRegister')">Create Account</button>
|
||||
</div>
|
||||
<div id="authError" class="auth-error"></div>
|
||||
<div id="brandAuthFooter" class="auth-footer"></div>
|
||||
@@ -80,7 +80,7 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
<div id="sidebar" class="sidebar">
|
||||
<div class="sidebar-top">
|
||||
{{/* Brand — click toggles sidebar */}}
|
||||
<div class="sb-brand" onclick="UI.toggleSidebar()" role="button" tabindex="0">
|
||||
<div class="sb-brand" onclick="sb.call('UI.toggleSidebar')" role="button" tabindex="0">
|
||||
<div id="brandSidebarLogo" class="sb-logo">
|
||||
<img src="{{.BasePath}}/favicon-32.png" alt="" class="brand-logo-img">
|
||||
</div>
|
||||
@@ -89,7 +89,7 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
</div>
|
||||
|
||||
{{/* New Chat button */}}
|
||||
<button id="newChatBtn" class="sb-btn" onclick="newChat()" title="New chat">
|
||||
<button id="newChatBtn" class="sb-btn" onclick="sb.call('newChat')" title="New chat">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
<span class="sb-label">New Chat</span>
|
||||
</button>
|
||||
@@ -118,11 +118,11 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
<div id="sidebarNav" class="sidebar-nav sidebar-tab-panel" data-tab-panel="chats">
|
||||
{{/* Projects section */}}
|
||||
<div class="sb-section" id="sbSectionProjects">
|
||||
<div class="sb-section-header" onclick="UI.toggleSidebarSection('projects')">
|
||||
<div class="sb-section-header" onclick="sb.call('UI.toggleSidebarSection','projects')">
|
||||
<span class="sb-section-arrow" id="sbArrowProjects">▾</span>
|
||||
<span class="sb-section-label">Projects</span>
|
||||
<button class="sb-section-add" title="New project"
|
||||
onclick="event.stopPropagation();if(typeof createProject==='function')createProject();">
|
||||
onclick="sb.callEvent(event,'createProject')">
|
||||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -133,11 +133,11 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
|
||||
{{/* Channels section (DMs + named channels) */}}
|
||||
<div class="sb-section" id="sbSectionChannels">
|
||||
<div class="sb-section-header" onclick="UI.toggleSidebarSection('channels')">
|
||||
<div class="sb-section-header" onclick="sb.call('UI.toggleSidebarSection','channels')">
|
||||
<span class="sb-section-arrow" id="sbArrowChannels">▾</span>
|
||||
<span class="sb-section-label">Channels</span>
|
||||
<button class="sb-section-add" title="New channel"
|
||||
onclick="event.stopPropagation();newChannelOrDM();">
|
||||
onclick="sb.callEvent(event,'newChannelOrDM')">
|
||||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -148,14 +148,14 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
|
||||
{{/* Chats section (personal AI chats + folders) */}}
|
||||
<div class="sb-section" id="sbSectionChats">
|
||||
<div class="sb-section-header" onclick="UI.toggleSidebarSection('chats')">
|
||||
<div class="sb-section-header" onclick="sb.call('UI.toggleSidebarSection','chats')">
|
||||
<span class="sb-section-arrow" id="sbArrowChats">▾</span>
|
||||
<span class="sb-section-label">Chats</span>
|
||||
<div class="sb-section-add-group" onclick="event.stopPropagation();">
|
||||
<button class="sb-section-add" title="New chat" onclick="newChat();">
|
||||
<button class="sb-section-add" title="New chat" onclick="sb.call('newChat');">
|
||||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
</button>
|
||||
<button class="sb-section-add" title="New folder" onclick="newFolder();">
|
||||
<button class="sb-section-add" title="New folder" onclick="sb.call('newFolder');">
|
||||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -223,12 +223,12 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
|
||||
</button>
|
||||
{{/* Panel toggle */}}
|
||||
<button id="panelToggleBtn" class="action-btn" title="Toggle side panel" onclick="if(typeof PanelRegistry!=='undefined')PanelRegistry.toggle('preview')">
|
||||
<button id="panelToggleBtn" class="action-btn" title="Toggle side panel" onclick="sb.call('PanelRegistry.toggle','preview')">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="15" y1="3" x2="15" y2="21"/></svg>
|
||||
</button>
|
||||
{{/* Notification bell (inline, not fixed) */}}
|
||||
<div id="notifWrap" class="notif-wrap">
|
||||
<button class="notif-bell" onclick="Notifications.toggleDropdown()">
|
||||
<button class="notif-bell" onclick="sb.call('Notifications.toggleDropdown')">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
|
||||
<span id="notifBadge" class="notif-badge" style="display:none;">0</span>
|
||||
</button>
|
||||
@@ -318,10 +318,10 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
<span id="sidePanelLabel" class="side-panel-label"></span>
|
||||
<div class="side-panel-header-actions">
|
||||
<span id="sidePanelPanelActions"></span>
|
||||
<button id="sidePanelFullscreenBtn" class="side-panel-btn" title="Toggle fullscreen" onclick="toggleSidePanelFullscreen()">
|
||||
<button id="sidePanelFullscreenBtn" class="side-panel-btn" title="Toggle fullscreen" onclick="sb.call('toggleSidePanelFullscreen')">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>
|
||||
</button>
|
||||
<button class="side-panel-btn" title="Close panel" onclick="PanelRegistry.closeAll()">
|
||||
<button class="side-panel-btn" title="Close panel" onclick="sb.call('PanelRegistry.closeAll')">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -345,7 +345,7 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
<div id="sidePanelOverlay" class="side-panel-overlay" style="display:none;"></div>
|
||||
|
||||
{{/* ── Lightbox ────────────────────────────── */}}
|
||||
<div id="lightbox" class="lightbox" onclick="closeLightbox()">
|
||||
<div id="lightbox" class="lightbox" onclick="sb.call('closeLightbox')">
|
||||
<img id="lightboxImg" src="" alt="">
|
||||
</div>
|
||||
|
||||
@@ -377,14 +377,14 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
<div id="teamAdminContent" class="team-admin-content" style="display:none;">
|
||||
{{/* Tab bar */}}
|
||||
<div id="teamAdminTabs" style="display:flex;gap:2px;padding:8px 16px;border-bottom:1px solid var(--border);flex-shrink:0;overflow-x:auto;">
|
||||
<button class="admin-tab active" data-ttab="members" onclick="UI.switchTeamTab('members')">Members</button>
|
||||
<button class="admin-tab" data-ttab="providers" onclick="UI.switchTeamTab('providers')">Providers</button>
|
||||
<button class="admin-tab" data-ttab="personas" onclick="UI.switchTeamTab('personas')">Personas</button>
|
||||
<button class="admin-tab" data-ttab="knowledge" onclick="UI.switchTeamTab('knowledge')">Knowledge</button>
|
||||
<button class="admin-tab" data-ttab="groups" onclick="UI.switchTeamTab('groups')">Groups</button>
|
||||
<button class="admin-tab" data-ttab="settings" onclick="UI.switchTeamTab('settings')">Settings</button>
|
||||
<button class="admin-tab" data-ttab="usage" onclick="UI.switchTeamTab('usage')">Usage</button>
|
||||
<button class="admin-tab" data-ttab="activity" onclick="UI.switchTeamTab('activity')">Activity</button>
|
||||
<button class="admin-tab active" data-ttab="members" onclick="sb.call('UI.switchTeamTab','members')">Members</button>
|
||||
<button class="admin-tab" data-ttab="providers" onclick="sb.call('UI.switchTeamTab','providers')">Providers</button>
|
||||
<button class="admin-tab" data-ttab="personas" onclick="sb.call('UI.switchTeamTab','personas')">Personas</button>
|
||||
<button class="admin-tab" data-ttab="knowledge" onclick="sb.call('UI.switchTeamTab','knowledge')">Knowledge</button>
|
||||
<button class="admin-tab" data-ttab="groups" onclick="sb.call('UI.switchTeamTab','groups')">Groups</button>
|
||||
<button class="admin-tab" data-ttab="settings" onclick="sb.call('UI.switchTeamTab','settings')">Settings</button>
|
||||
<button class="admin-tab" data-ttab="usage" onclick="sb.call('UI.switchTeamTab','usage')">Usage</button>
|
||||
<button class="admin-tab" data-ttab="activity" onclick="sb.call('UI.switchTeamTab','activity')">Activity</button>
|
||||
</div>
|
||||
|
||||
{{/* Tab content panels */}}
|
||||
@@ -482,8 +482,8 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
<div class="form-group"><label>Config (JSON)</label><textarea id="rpConfig" rows="4">{}</textarea></div>
|
||||
<div class="form-group"><label><input type="checkbox" id="rpActive" checked> Active</label></div>
|
||||
<div style="display:flex;gap:8px;">
|
||||
<button id="rpSaveBtn" class="btn-primary" onclick="Pages.saveRoutingPolicy()">Save</button>
|
||||
<button id="rpCancelBtn" class="btn-secondary" onclick="Pages.hideRoutingForm()">Cancel</button>
|
||||
<button id="rpSaveBtn" class="btn-primary" onclick="sb.call('Pages.saveRoutingPolicy')">Save</button>
|
||||
<button id="rpCancelBtn" class="btn-secondary" onclick="sb.call('Pages.hideRoutingForm')">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -510,28 +510,28 @@ window.addEventListener('unhandledrejection', function(e) {
|
||||
{{/* CM6 bundle — chat-specific (code input, extension editor) */}}
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/vendor/codemirror/codemirror.bundle.js?v={{$.Version}}" onerror="console.warn('[CM6] Bundle not available — falling back to textarea')"></script>
|
||||
{{/* App JS — order matches index.html (minus api/events/ui-primitives/ui-format already in base) */}}
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/extensions.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/panels.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/ui-settings.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/ui-admin.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/tokens.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/notes.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/note-graph.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/files.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/tools-toggle.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/knowledge-ui.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/memory-ui.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/persona-kb.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/extensions.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/panels.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/ui-settings.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/ui-admin.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/tokens.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/notes.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/note-graph.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/files.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/tools-toggle.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/knowledge-ui.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/memory-ui.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/persona-kb.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/projects-ui.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/channel-models.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/notification-prefs.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/notifications.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/chat.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/channel-models.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/notification-prefs.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/notifications.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/chat.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/settings-handlers.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/admin-handlers.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/workflow-api.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/workflow-admin.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/workflow-queue.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/task-sidebar.js?v={{$.Version}}"></script>
|
||||
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/app.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/admin-handlers.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/workflow-api.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/workflow-admin.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/workflow-queue.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/task-sidebar.js?v={{$.Version}}"></script>
|
||||
<script type="module" nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/js/app.js?v={{$.Version}}"></script>
|
||||
{{end}}
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
{{/* ── Scripts ─────────────────────────────── */}}
|
||||
{{define "scripts-editor"}}
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/vendor/codemirror/codemirror.bundle.js?v={{.Version}}" onerror="console.warn('[CM6] Bundle not available')"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/chat-pane.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/editor-surface.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/app.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/chat-pane.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/editor-surface.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/app.js?v={{.Version}}"></script>
|
||||
{{end}}
|
||||
|
||||
@@ -24,21 +24,21 @@
|
||||
{{end}}
|
||||
|
||||
{{define "scripts-notes"}}
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/chat.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/files.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/channel-models.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/tokens.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/extensions.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/notes.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/note-graph.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/knowledge-ui.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/persona-kb.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/memory-ui.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/notifications.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/panels.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/chat.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/files.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/channel-models.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/tokens.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/extensions.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/notes.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/note-graph.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/knowledge-ui.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/persona-kb.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/memory-ui.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/notifications.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/panels.js?v={{.Version}}"></script>
|
||||
{{/* debug.js now loaded in base.html for all surfaces */}}
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/projects-ui.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/app.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/app.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}">
|
||||
// Notes surface boot: open notes panel in standalone mode
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
@@ -112,20 +112,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn-md btn-primary" onclick="if(typeof UI!=='undefined')UI.saveAppearance?.()">Save</button>
|
||||
<button class="btn-md btn-primary" onclick="sb.call('UI.saveAppearance')">Save</button>
|
||||
{{else if eq .Section "profile"}}
|
||||
<div class="settings-section">
|
||||
<h3>Profile</h3>
|
||||
<div class="form-group"><label>Display Name</label><input type="text" id="profileDisplayName" placeholder="Your display name"></div>
|
||||
<div class="form-group"><label>Email</label><input type="email" id="profileEmail" disabled></div>
|
||||
<button class="btn-md btn-primary" onclick="if(typeof Pages!=='undefined')Pages.saveProfile?.()">Save Profile</button>
|
||||
<button class="btn-md btn-primary" onclick="sb.call('Pages.saveProfile')">Save Profile</button>
|
||||
</div>
|
||||
<div class="settings-section" style="margin-top:20px;">
|
||||
<h3>Change Password</h3>
|
||||
<div class="form-group"><label>Current Password</label><input type="password" id="settingsCurrentPw" autocomplete="current-password"></div>
|
||||
<div class="form-group"><label>New Password</label><input type="password" id="settingsNewPw" autocomplete="new-password"></div>
|
||||
<div class="form-group"><label>Confirm New Password</label><input type="password" id="settingsConfirmPw" autocomplete="new-password"></div>
|
||||
<button class="btn-md btn-primary" onclick="if(typeof Pages!=='undefined')Pages.changePassword?.()">Update Password</button>
|
||||
<button class="btn-md btn-primary" onclick="sb.call('Pages.changePassword')">Update Password</button>
|
||||
</div>
|
||||
{{else if eq .Section "providers"}}
|
||||
<div id="userProvidersDisabled" style="display:none;">
|
||||
@@ -170,15 +170,15 @@
|
||||
|
||||
{{/* Scripts */}}
|
||||
{{define "scripts-settings"}}
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-settings.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/ui-settings.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/settings-handlers.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/task-settings.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/knowledge-ui.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/persona-kb.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/memory-ui.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/notifications.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/notification-prefs.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/channel-models.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/task-settings.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/knowledge-ui.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/persona-kb.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/memory-ui.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/notifications.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/notification-prefs.js?v={{.Version}}"></script>
|
||||
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/channel-models.js?v={{.Version}}"></script>
|
||||
<script nonce="{{.CSPNonce}}">
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const section = document.getElementById('settingsSection')?.dataset.section;
|
||||
|
||||
Reference in New Issue
Block a user