Changeset 0.10.1 (#57)
This commit is contained in:
223
src/index.html
223
src/index.html
@@ -95,6 +95,10 @@
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
||||
<span>Admin Panel</span>
|
||||
</button>
|
||||
<button class="flyout-item" id="menuTeamAdmin" style="display:none">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
||||
<span>Team Management</span>
|
||||
</button>
|
||||
<button class="flyout-item" id="menuDebug">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 11V6a2 2 0 0 0-2-2h-1a2 2 0 0 0-2 2"/><path d="M9 6a2 2 0 0 0-2 2v3"/><path d="M4 14h4"/><path d="M16 14h4"/><path d="M12 18v-6"/><circle cx="12" cy="14" r="6"/></svg>
|
||||
<span>Debug Log</span>
|
||||
@@ -161,12 +165,21 @@
|
||||
|
||||
<!-- Side Panel (preview + notes) -->
|
||||
<aside class="side-panel" id="sidePanel">
|
||||
<div class="side-panel-resize" id="sidePanelResize"></div>
|
||||
<div class="side-panel-header">
|
||||
<div class="side-panel-tabs" id="sidePanelTabs">
|
||||
<button class="side-panel-tab active" data-tab="preview" onclick="switchSidePanelTab('preview')">Preview</button>
|
||||
<button class="side-panel-tab" data-tab="notes" onclick="switchSidePanelTab('notes')">Notes</button>
|
||||
</div>
|
||||
<button class="side-panel-close" onclick="closeSidePanel()" title="Close panel">✕</button>
|
||||
<div class="side-panel-actions">
|
||||
<button class="side-panel-action-btn" id="sidePanelClearBtn" onclick="clearPreview()" title="Clear preview" style="display:none">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18"/><path d="M8 6V4h8v2"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/></svg>
|
||||
</button>
|
||||
<button class="side-panel-action-btn" id="sidePanelFullscreenBtn" onclick="toggleSidePanelFullscreen()" title="Toggle fullscreen">
|
||||
<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-close" onclick="closeSidePanel()" title="Close panel">✕</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="side-panel-body">
|
||||
<!-- Preview tab -->
|
||||
@@ -321,8 +334,8 @@
|
||||
<button class="settings-tab" data-stab="appearance" onclick="UI.switchSettingsTab('appearance')">Appearance</button>
|
||||
<button class="settings-tab" data-stab="providers" onclick="UI.switchSettingsTab('providers')" id="settingsProvidersTabBtn">Providers</button>
|
||||
<button class="settings-tab" data-stab="models" onclick="UI.switchSettingsTab('models')">Models</button>
|
||||
<button class="settings-tab" data-stab="usage" onclick="UI.switchSettingsTab('usage')">Usage</button>
|
||||
<button class="settings-tab" data-stab="teams" onclick="UI.switchSettingsTab('teams')" id="settingsTeamsTabBtn" style="display:none">Teams</button>
|
||||
<button class="settings-tab" data-stab="personas" onclick="UI.switchSettingsTab('personas')" id="settingsPersonasTabBtn">Personas</button>
|
||||
<button class="settings-tab" data-stab="usage" onclick="UI.switchSettingsTab('usage')" id="settingsUsageTabBtn">Usage</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- General Tab -->
|
||||
@@ -414,12 +427,15 @@
|
||||
<p class="section-hint" style="margin-bottom:8px">Toggle visibility in your model selector. Hidden models are still accessible through presets.</p>
|
||||
<div id="userModelList" class="model-list-grid"><div class="empty-hint">Loading models...</div></div>
|
||||
</section>
|
||||
</div>
|
||||
<!-- Personas Tab (hidden if admin disables user presets) -->
|
||||
<div class="settings-tab-content" id="settingsPersonasTab" style="display:none">
|
||||
<section class="settings-section">
|
||||
<h3 style="font-size:14px;margin-bottom:4px">My Presets</h3>
|
||||
<h3 style="font-size:14px;margin-bottom:4px">My Personas</h3>
|
||||
<p class="section-hint" style="margin-bottom:8px">Personal model presets with custom system prompts and settings.</p>
|
||||
<div id="userPresetList"><div class="empty-hint">Loading...</div></div>
|
||||
<div id="userAddPresetForm" style="display:none;margin-top:8px" class="admin-inline-form"></div>
|
||||
<button class="btn-small" id="userAddPresetBtn" style="margin-top:6px">+ New Preset</button>
|
||||
<button class="btn-small" id="userAddPresetBtn" style="margin-top:6px">+ New Persona</button>
|
||||
</section>
|
||||
</div>
|
||||
<!-- Usage Tab -->
|
||||
@@ -442,102 +458,114 @@
|
||||
<div id="myUsageResults"></div>
|
||||
</section>
|
||||
</div>
|
||||
<!-- Teams Tab (visible to team admins) -->
|
||||
<div class="settings-tab-content" id="settingsTeamsTab" style="display:none">
|
||||
<div id="settingsTeamPicker"></div>
|
||||
<div id="settingsTeamManage" style="display:none">
|
||||
<button class="notes-back-btn" id="settingsTeamBackBtn">← Back to teams</button>
|
||||
<h3 id="settingsTeamManageName" style="margin:8px 0 4px;font-size:15px"></h3>
|
||||
<!-- Members -->
|
||||
<section class="settings-section">
|
||||
<h4 style="font-size:13px;margin-bottom:6px">Members</h4>
|
||||
<div id="settingsTeamMembers"></div>
|
||||
<div id="settingsTeamAddMember" style="display:none;margin-top:8px" class="admin-inline-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>User</label><select id="settingsTeamMemberUser"></select></div>
|
||||
<div class="form-group"><label>Role</label><select id="settingsTeamMemberRole"><option value="member">Member</option><option value="admin">Team Admin</option></select></div>
|
||||
</div>
|
||||
<div class="form-row"><button class="btn-small btn-primary" id="settingsTeamAddMemberSubmit">Add</button><button class="btn-small" id="settingsTeamCancelMember">Cancel</button></div>
|
||||
</div>
|
||||
<button class="btn-small" id="settingsTeamAddMemberBtn" style="margin-top:6px">+ Add Member</button>
|
||||
</section>
|
||||
<!-- Team Providers -->
|
||||
<section class="settings-section">
|
||||
<h4 style="font-size:13px;margin-bottom:4px">Providers</h4>
|
||||
<div id="settingsTeamProviders"></div>
|
||||
<div id="settingsTeamEditProvider" style="display:none;margin-top:8px" class="admin-inline-form">
|
||||
<div class="form-grid-2col">
|
||||
<div class="form-group"><label>Name</label><input id="teamProviderEditName"></div>
|
||||
<div class="form-group"><label>Endpoint</label><input id="teamProviderEditEndpoint"></div>
|
||||
<div class="form-group"><label>API Key</label><input id="teamProviderEditKey" type="password" placeholder="(unchanged)"></div>
|
||||
<div class="form-group"><label>Default Model</label><input id="teamProviderEditDefault" placeholder="optional"></div>
|
||||
</div>
|
||||
<div style="margin:6px 0"><label><input type="checkbox" id="teamProviderEditPrivate"> Private provider (data stays on-prem)</label></div>
|
||||
<div class="form-row">
|
||||
<button class="btn-small btn-primary" id="settingsTeamEditProviderSubmit">Update</button>
|
||||
<button class="btn-small" id="settingsTeamCancelEditProvider">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="settingsTeamAddProvider" style="display:none;margin-top:8px" class="admin-inline-form">
|
||||
<div class="form-grid-2col">
|
||||
<div class="form-group"><label>Name</label><input id="teamProviderName" placeholder="e.g. Team OpenAI"></div>
|
||||
<div class="form-group"><label>Provider</label><select id="teamProviderType"></select></div>
|
||||
<div class="form-group"><label>Endpoint</label><input id="teamProviderEndpoint" placeholder="https://api.openai.com/v1"></div>
|
||||
<div class="form-group"><label>API Key</label><input id="teamProviderKey" type="password" placeholder="sk-..."></div>
|
||||
</div>
|
||||
<div style="margin:6px 0"><label><input type="checkbox" id="teamProviderPrivate"> Private provider (data stays on-prem)</label></div>
|
||||
<div class="form-row">
|
||||
<button class="btn-small btn-primary" id="settingsTeamAddProviderSubmit">Add Provider</button>
|
||||
<button class="btn-small" id="settingsTeamCancelProvider">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn-small" id="settingsTeamAddProviderBtn" style="margin-top:6px">+ Add Provider</button>
|
||||
</section>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn-primary" id="settingsSaveBtn">Save Settings</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Team Presets -->
|
||||
<section class="settings-section">
|
||||
<h4 style="font-size:13px;margin-bottom:6px">Team Presets</h4>
|
||||
<div id="settingsTeamPresets"></div>
|
||||
<div id="settingsTeamAddPreset" style="display:none;margin-top:8px" class="admin-inline-form"></div>
|
||||
<button class="btn-small" id="settingsTeamAddPresetBtn" style="margin-top:6px">+ New Team Preset</button>
|
||||
</section>
|
||||
<!-- Team Usage (team admins only — usage against team-owned providers) -->
|
||||
<section class="settings-section">
|
||||
<h4 style="font-size:13px;margin-bottom:6px">Usage</h4>
|
||||
<div class="form-row" style="gap:6px;margin-bottom:8px">
|
||||
<select id="teamUsagePeriod" style="font-size:12px;padding:3px 6px" onchange="UI.loadTeamUsage()">
|
||||
<option value="7d">7 days</option>
|
||||
<option value="30d" selected>30 days</option>
|
||||
<option value="90d">90 days</option>
|
||||
</select>
|
||||
<select id="teamUsageGroupBy" style="font-size:12px;padding:3px 6px" onchange="UI.loadTeamUsage()">
|
||||
<option value="model">By Model</option>
|
||||
<option value="user">By User</option>
|
||||
<option value="day">By Day</option>
|
||||
</select>
|
||||
<!-- ── Team Management Modal ─────────────────── -->
|
||||
<div class="modal-overlay" id="teamAdminModal">
|
||||
<div class="modal modal-wide">
|
||||
<div class="modal-header">
|
||||
<h2 id="teamAdminTitle">Team Management</h2>
|
||||
<button class="modal-close" id="teamAdminCloseBtn">✕</button>
|
||||
</div>
|
||||
<!-- Team picker (shown when user admins multiple teams) -->
|
||||
<div id="teamAdminPicker" style="display:none">
|
||||
<div class="modal-body" id="teamAdminPickerList"></div>
|
||||
</div>
|
||||
<!-- Tabbed management (shown after selecting a team) -->
|
||||
<div id="teamAdminContent" style="display:none">
|
||||
<div class="modal-tabs admin-tabs" id="teamAdminTabs">
|
||||
<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="presets" onclick="UI.switchTeamTab('presets')">Presets</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>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Members tab -->
|
||||
<div class="team-tab-content" id="teamTabMembers">
|
||||
<div id="settingsTeamMembers"></div>
|
||||
<div id="settingsTeamAddMember" style="display:none;margin-top:8px" class="admin-inline-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>User</label><select id="settingsTeamMemberUser"></select></div>
|
||||
<div class="form-group"><label>Role</label><select id="settingsTeamMemberRole"><option value="member">Member</option><option value="admin">Team Admin</option></select></div>
|
||||
</div>
|
||||
<div id="settingsTeamUsageTotals"></div>
|
||||
<div id="settingsTeamUsageResults"></div>
|
||||
</section>
|
||||
<!-- Team Activity (team admins only — audit scoped to team) -->
|
||||
<section class="settings-section">
|
||||
<h4 style="font-size:13px;margin-bottom:6px">Activity Log</h4>
|
||||
<div class="audit-filters" style="margin-bottom:8px">
|
||||
<select id="teamAuditFilterAction" style="font-size:12px;padding:3px 6px" onchange="UI.loadTeamAuditLog()">
|
||||
<option value="">All actions</option>
|
||||
</select>
|
||||
<div class="form-row"><button class="btn-small btn-primary" id="settingsTeamAddMemberSubmit">Add</button><button class="btn-small" id="settingsTeamCancelMember">Cancel</button></div>
|
||||
</div>
|
||||
<button class="btn-small" id="settingsTeamAddMemberBtn" style="margin-top:6px">+ Add Member</button>
|
||||
</div>
|
||||
<!-- Providers tab -->
|
||||
<div class="team-tab-content" id="teamTabProviders" style="display:none">
|
||||
<div id="settingsTeamProviders"></div>
|
||||
<div id="settingsTeamEditProvider" style="display:none;margin-top:8px" class="admin-inline-form">
|
||||
<div class="form-grid-2col">
|
||||
<div class="form-group"><label>Name</label><input id="teamProviderEditName"></div>
|
||||
<div class="form-group"><label>Endpoint</label><input id="teamProviderEditEndpoint"></div>
|
||||
<div class="form-group"><label>API Key</label><input id="teamProviderEditKey" type="password" placeholder="(unchanged)"></div>
|
||||
<div class="form-group"><label>Default Model</label><input id="teamProviderEditDefault" placeholder="optional"></div>
|
||||
</div>
|
||||
<div id="settingsTeamAudit" style="max-height:300px;overflow-y:auto"></div>
|
||||
<div id="teamAuditPagination" class="audit-pagination" style="display:none">
|
||||
<button class="btn-small" id="teamAuditPrevBtn" onclick="UI.loadTeamAuditLog(UI._teamAuditPage - 1)">← Prev</button>
|
||||
<span id="teamAuditPageInfo" style="font-size:11px;color:var(--text-3)"></span>
|
||||
<button class="btn-small" id="teamAuditNextBtn" onclick="UI.loadTeamAuditLog(UI._teamAuditPage + 1)">Next →</button>
|
||||
<div style="margin:6px 0"><label><input type="checkbox" id="teamProviderEditPrivate"> Private provider (data stays on-prem)</label></div>
|
||||
<div class="form-row">
|
||||
<button class="btn-small btn-primary" id="settingsTeamEditProviderSubmit">Update</button>
|
||||
<button class="btn-small" id="settingsTeamCancelEditProvider">Cancel</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div id="settingsTeamAddProvider" style="display:none;margin-top:8px" class="admin-inline-form">
|
||||
<div class="form-grid-2col">
|
||||
<div class="form-group"><label>Name</label><input id="teamProviderName" placeholder="e.g. Team OpenAI"></div>
|
||||
<div class="form-group"><label>Provider</label><select id="teamProviderType"></select></div>
|
||||
<div class="form-group"><label>Endpoint</label><input id="teamProviderEndpoint" placeholder="https://api.openai.com/v1"></div>
|
||||
<div class="form-group"><label>API Key</label><input id="teamProviderKey" type="password" placeholder="sk-..."></div>
|
||||
</div>
|
||||
<div style="margin:6px 0"><label><input type="checkbox" id="teamProviderPrivate"> Private provider (data stays on-prem)</label></div>
|
||||
<div class="form-row">
|
||||
<button class="btn-small btn-primary" id="settingsTeamAddProviderSubmit">Add Provider</button>
|
||||
<button class="btn-small" id="settingsTeamCancelProvider">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn-small" id="settingsTeamAddProviderBtn" style="margin-top:6px">+ Add Provider</button>
|
||||
</div>
|
||||
<!-- Presets tab -->
|
||||
<div class="team-tab-content" id="teamTabPresets" style="display:none">
|
||||
<div id="settingsTeamPresets"></div>
|
||||
<div id="settingsTeamAddPreset" style="display:none;margin-top:8px" class="admin-inline-form"></div>
|
||||
<button class="btn-small" id="settingsTeamAddPresetBtn" style="margin-top:6px">+ New Team Preset</button>
|
||||
</div>
|
||||
<!-- Usage tab -->
|
||||
<div class="team-tab-content" id="teamTabUsage" style="display:none">
|
||||
<div class="form-row" style="gap:6px;margin-bottom:8px">
|
||||
<select id="teamUsagePeriod" style="font-size:12px;padding:3px 6px" onchange="UI.loadTeamUsage()">
|
||||
<option value="7d">7 days</option>
|
||||
<option value="30d" selected>30 days</option>
|
||||
<option value="90d">90 days</option>
|
||||
</select>
|
||||
<select id="teamUsageGroupBy" style="font-size:12px;padding:3px 6px" onchange="UI.loadTeamUsage()">
|
||||
<option value="model">By Model</option>
|
||||
<option value="user">By User</option>
|
||||
<option value="day">By Day</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="settingsTeamUsageTotals"></div>
|
||||
<div id="settingsTeamUsageResults"></div>
|
||||
</div>
|
||||
<!-- Activity tab -->
|
||||
<div class="team-tab-content" id="teamTabActivity" style="display:none">
|
||||
<div class="audit-filters" style="margin-bottom:8px">
|
||||
<select id="teamAuditFilterAction" style="font-size:12px;padding:3px 6px" onchange="UI.loadTeamAuditLog()">
|
||||
<option value="">All actions</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="settingsTeamAudit" style="max-height:400px;overflow-y:auto"></div>
|
||||
<div id="teamAuditPagination" class="audit-pagination" style="display:none">
|
||||
<button class="btn-small" id="teamAuditPrevBtn" onclick="UI.loadTeamAuditLog(UI._teamAuditPage - 1)">← Prev</button>
|
||||
<span id="teamAuditPageInfo" style="font-size:11px;color:var(--text-3)"></span>
|
||||
<button class="btn-small" id="teamAuditNextBtn" onclick="UI.loadTeamAuditLog(UI._teamAuditPage + 1)">Next →</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn-primary" id="settingsSaveBtn">Save Settings</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -647,6 +675,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="admin-tab-content" id="adminSettingsTab" style="display:none">
|
||||
<section class="settings-section">
|
||||
<h3>System Prompt</h3>
|
||||
<p class="section-hint" style="margin-bottom:6px">Injected into every conversation before user/preset prompts. Users cannot override or disable this.</p>
|
||||
<div class="form-group">
|
||||
<textarea id="adminSystemPrompt" rows="4" placeholder="e.g. You are a helpful assistant for Acme Corp. Always respond professionally."></textarea>
|
||||
</div>
|
||||
</section>
|
||||
<section class="settings-section">
|
||||
<h3>Registration</h3>
|
||||
<label class="checkbox-label"><input type="checkbox" id="adminRegToggle" checked> Allow new user registration</label>
|
||||
|
||||
Reference in New Issue
Block a user