Changeset 0.4.3 (#32)

This commit is contained in:
2026-02-18 17:47:21 +00:00
parent 2fc4f6980c
commit c98eb80950
14 changed files with 1134 additions and 17 deletions

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat Switchboard</title>
<link rel="stylesheet" href="css/styles.css?v=0.3.4">
<link rel="stylesheet" href="css/styles.css?v=0.4.2">
</head>
<body>
<div id="appContainer" class="app-hidden" style="display:none">
@@ -117,6 +117,9 @@
<button class="modal-close" id="closeModalBtn"></button>
</div>
<div class="modal-body">
<!-- Mode indicator -->
<div class="settings-mode-badge" id="settingsModeBadge"></div>
<!-- Profile (managed mode only) -->
<div class="settings-section" id="profileSection" style="display:none">
<h3 class="settings-section-title">Profile</h3>
@@ -160,6 +163,45 @@
</div>
</div> <!-- /unmanagedSettings -->
<!-- API Providers (managed mode only) -->
<div id="managedProviders" style="display:none">
<h3 class="settings-section-title">API Providers</h3>
<div id="providerList" class="provider-list"></div>
<div class="provider-add-toggle">
<button class="btn btn-secondary btn-small" id="providerShowAddBtn">+ Add Provider</button>
</div>
<div class="provider-add-form" id="providerAddForm" style="display:none">
<div class="form-group">
<label for="providerName">Name</label>
<input type="text" id="providerName" placeholder="e.g. My OpenAI Key">
</div>
<div class="form-group">
<label for="providerType">Provider</label>
<select id="providerType">
<option value="openai">OpenAI-compatible</option>
<option value="anthropic">Anthropic</option>
</select>
</div>
<div class="form-group">
<label for="providerEndpoint">Endpoint</label>
<input type="text" id="providerEndpoint" placeholder="https://api.openai.com/v1">
</div>
<div class="form-group">
<label for="providerApiKey">API Key</label>
<input type="password" id="providerApiKey" placeholder="sk-...">
</div>
<div class="form-group">
<label for="providerDefaultModel">Default Model (optional)</label>
<input type="text" id="providerDefaultModel" placeholder="gpt-4o">
</div>
<div class="admin-form-row">
<button class="btn btn-primary btn-small" id="providerCreateBtn">Save</button>
<button class="btn btn-secondary btn-small" id="providerCancelBtn">Cancel</button>
</div>
</div>
<hr class="settings-divider">
</div>
<div class="form-group">
<label for="model">Default Model</label>
<div style="display: flex; gap: 0.5rem;">
@@ -243,6 +285,8 @@
<div class="modal-body">
<div class="admin-tabs">
<button class="admin-tab active" data-tab="users">Users</button>
<button class="admin-tab" data-tab="models">Models</button>
<button class="admin-tab" data-tab="providers">Providers</button>
<button class="admin-tab" data-tab="settings">Settings</button>
<button class="admin-tab" data-tab="stats">Stats</button>
</div>
@@ -273,7 +317,7 @@
<div id="adminUserList" class="admin-user-list">Loading...</div>
</div>
<!-- Reset Password Dialog (inline) -->
<!-- Reset Password Dialog (inline overlay) -->
<div class="admin-reset-dialog" id="adminResetDialog" style="display:none">
<div class="admin-reset-card">
<h3>Reset Password</h3>
@@ -286,6 +330,55 @@
</div>
</div>
<!-- Models Tab -->
<div class="admin-tab-content" id="adminModelsTab" style="display:none">
<div class="admin-models-header">
<p class="admin-hint">Manage which models are available to users. Fetch from configured providers, then enable/disable and tag capabilities.</p>
<button class="btn btn-primary btn-small" id="adminFetchModelsBtn">🔄 Fetch Models</button>
</div>
<div id="adminModelList" class="admin-model-list">
<div class="admin-empty">No models configured. Add a provider first, then fetch models.</div>
</div>
</div>
<!-- Providers Tab -->
<div class="admin-tab-content" id="adminProvidersTab" style="display:none">
<p class="admin-hint">Global providers are available to all users. Users can also add their own.</p>
<div id="adminProviderList" class="provider-list"></div>
<div class="provider-add-toggle">
<button class="btn btn-secondary btn-small" id="adminProviderShowAddBtn">+ Add Global Provider</button>
</div>
<div class="provider-add-form" id="adminProviderAddForm" style="display:none">
<div class="form-group">
<label for="adminProviderName">Name</label>
<input type="text" id="adminProviderName" placeholder="e.g. Shared OpenAI">
</div>
<div class="form-group">
<label for="adminProviderType">Provider</label>
<select id="adminProviderType">
<option value="openai">OpenAI-compatible</option>
<option value="anthropic">Anthropic</option>
</select>
</div>
<div class="form-group">
<label for="adminProviderEndpoint">Endpoint</label>
<input type="text" id="adminProviderEndpoint" placeholder="https://api.openai.com/v1">
</div>
<div class="form-group">
<label for="adminProviderApiKey">API Key</label>
<input type="password" id="adminProviderApiKey" placeholder="sk-...">
</div>
<div class="form-group">
<label for="adminProviderDefaultModel">Default Model (optional)</label>
<input type="text" id="adminProviderDefaultModel" placeholder="gpt-4o">
</div>
<div class="admin-form-row">
<button class="btn btn-primary btn-small" id="adminProviderCreateBtn">Save</button>
<button class="btn btn-secondary btn-small" id="adminProviderCancelBtn">Cancel</button>
</div>
</div>
</div>
<!-- Settings Tab -->
<div class="admin-tab-content" id="adminSettingsTab" style="display:none">
<div class="form-group">
@@ -365,12 +458,12 @@
<div class="toast-container" id="toastContainer"></div>
<script src="js/storage.js?v=0.3.4"></script>
<script src="js/backend.js?v=0.3.4"></script>
<script src="js/state.js?v=0.3.4"></script>
<script src="js/api.js?v=0.3.4"></script>
<script src="js/ui.js?v=0.3.4"></script>
<script src="js/admin.js?v=0.3.4"></script>
<script src="js/app.js?v=0.3.4"></script>
<script src="js/storage.js?v=0.4.2"></script>
<script src="js/backend.js?v=0.4.2"></script>
<script src="js/state.js?v=0.4.2"></script>
<script src="js/api.js?v=0.4.2"></script>
<script src="js/ui.js?v=0.4.2"></script>
<script src="js/admin.js?v=0.4.2"></script>
<script src="js/app.js?v=0.4.2"></script>
</body>
</html>