From 038ad4ed1bb739ebe56de8301c5c2a88b3f94e30 Mon Sep 17 00:00:00 2001 From: Mondo Diaz Date: Thu, 29 Jan 2026 14:25:19 -0600 Subject: [PATCH] Simplify cache management UI and improve test status display (#107) --- CHANGELOG.md | 8 +- frontend/src/api.ts | 20 ---- frontend/src/pages/AdminCachePage.css | 113 +++++-------------- frontend/src/pages/AdminCachePage.tsx | 152 ++++++-------------------- frontend/src/types.ts | 12 -- 5 files changed, 66 insertions(+), 239 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c07ef7..fe82356 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,10 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Upstream source connectivity test no longer follows redirects, fixing "Exceeded maximum allowed redirects" error with Artifactory proxies (#107) -- Upstream sources table now has dedicated "Test" column with OK/Error status badges (#107) - Test runs automatically after saving a new or updated upstream source (#107) -- Error states in upstream sources table are now clickable to show full error details in a modal (#107) +- Test status now shows as colored dots (green=success, red=error) instead of text badges (#107) +- Clicking red dot shows error details in a modal (#107) - Source name column no longer wraps text for better table layout (#107) +- Renamed "Cache Management" page to "Upstream Sources" (#107) +- Moved Delete button from table row to edit modal for cleaner table layout (#107) ### Removed - Removed `is_public` field from upstream sources - all sources are now treated as internal/private (#107) @@ -22,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed seeding of public registry URLs (npm-public, pypi-public, maven-central, docker-hub) (#107) - Removed "Public" badge and checkbox from upstream sources UI (#107) - Removed "Allow Public Internet" toggle from cache settings UI (#107) +- Removed "Global Settings" section from cache management UI - auto-create system projects is always enabled (#107) +- Removed unused CacheSettings frontend types and API functions (#107) ### Added - Added `ORCHARD_PURGE_SEED_DATA` environment variable support to stage helm values to remove seed data from long-running deployments (#107) diff --git a/frontend/src/api.ts b/frontend/src/api.ts index 844a9f7..4c556c1 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -46,8 +46,6 @@ import { UpstreamSourceCreate, UpstreamSourceUpdate, UpstreamSourceTestResult, - CacheSettings, - CacheSettingsUpdate, } from './types'; const API_BASE = '/api/v1'; @@ -748,21 +746,3 @@ export async function testUpstreamSource(id: string): Promise(response); } - -// Cache Settings Admin API -export async function getCacheSettings(): Promise { - const response = await fetch(`${API_BASE}/admin/cache-settings`, { - credentials: 'include', - }); - return handleResponse(response); -} - -export async function updateCacheSettings(data: CacheSettingsUpdate): Promise { - const response = await fetch(`${API_BASE}/admin/cache-settings`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(data), - credentials: 'include', - }); - return handleResponse(response); -} diff --git a/frontend/src/pages/AdminCachePage.css b/frontend/src/pages/AdminCachePage.css index b247d0d..50598db 100644 --- a/frontend/src/pages/AdminCachePage.css +++ b/frontend/src/pages/AdminCachePage.css @@ -34,74 +34,6 @@ margin-bottom: 1rem; } -/* Settings Section */ -.settings-section { - background: var(--bg-secondary); - border: 1px solid var(--border-color); - border-radius: 8px; - padding: 1.5rem; - margin-bottom: 2rem; -} - -.settings-grid { - display: flex; - flex-direction: column; - gap: 1rem; -} - -.setting-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem; - background: var(--bg-primary); - border: 1px solid var(--border-color); - border-radius: 4px; -} - -.toggle-label { - display: flex; - flex-direction: column; - gap: 0.25rem; -} - -.setting-name { - font-weight: 500; - color: var(--text-primary); - display: flex; - align-items: center; - gap: 0.5rem; -} - -.setting-description { - font-size: 0.85rem; - color: var(--text-secondary); -} - -.toggle-button { - padding: 0.5rem 1rem; - border: none; - border-radius: 4px; - cursor: pointer; - font-weight: 500; - min-width: 100px; -} - -.toggle-button.on { - background-color: #28a745; - color: white; -} - -.toggle-button.off { - background-color: #dc3545; - color: white; -} - -.toggle-button:disabled { - opacity: 0.6; - cursor: not-allowed; -} - /* Sources Section */ .sources-section { background: var(--bg-secondary); @@ -207,35 +139,37 @@ margin-right: 0; } -.test-result { - display: inline-flex; - align-items: center; - gap: 0.25rem; - padding: 0.2rem 0.5rem; - border-radius: 4px; - font-size: 0.75rem; - font-weight: 500; - white-space: nowrap; +.test-cell { + text-align: center; + width: 2rem; } -.test-result.success { - background-color: #e8f5e9; +.test-dot { + font-size: 1rem; + cursor: default; +} + +.test-dot.success { color: #2e7d32; } -.test-result.failure { - background-color: #ffebee; +.test-dot.failure { color: #c62828; cursor: pointer; } -.test-result.failure:hover { - background-color: #ffcdd2; +.test-dot.failure:hover { + color: #b71c1c; } -.test-result.testing { - background-color: #e3f2fd; +.test-dot.testing { color: #1976d2; + animation: pulse 1s infinite; +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.4; } } /* Error Modal */ @@ -406,9 +340,14 @@ .form-actions { display: flex; - justify-content: flex-end; - gap: 0.5rem; + justify-content: space-between; + align-items: center; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--border-color); } + +.form-actions-right { + display: flex; + gap: 0.5rem; +} diff --git a/frontend/src/pages/AdminCachePage.tsx b/frontend/src/pages/AdminCachePage.tsx index 7f4194f..5e1fbb0 100644 --- a/frontend/src/pages/AdminCachePage.tsx +++ b/frontend/src/pages/AdminCachePage.tsx @@ -7,10 +7,8 @@ import { updateUpstreamSource, deleteUpstreamSource, testUpstreamSource, - getCacheSettings, - updateCacheSettings, } from '../api'; -import { UpstreamSource, CacheSettings, SourceType, AuthType } from '../types'; +import { UpstreamSource, SourceType, AuthType } from '../types'; import './AdminCachePage.css'; const SOURCE_TYPES: SourceType[] = ['npm', 'pypi', 'maven', 'docker', 'helm', 'nuget', 'deb', 'rpm', 'generic']; @@ -25,11 +23,6 @@ function AdminCachePage() { const [loadingSources, setLoadingSources] = useState(true); const [sourcesError, setSourcesError] = useState(null); - // Cache settings state - const [settings, setSettings] = useState(null); - const [loadingSettings, setLoadingSettings] = useState(true); - const [settingsError, setSettingsError] = useState(null); - // Create/Edit form state const [showForm, setShowForm] = useState(false); const [editingSource, setEditingSource] = useState(null); @@ -53,9 +46,6 @@ function AdminCachePage() { // Delete confirmation state const [deletingId, setDeletingId] = useState(null); - // Settings update state - const [updatingSettings, setUpdatingSettings] = useState(false); - // Success message const [successMessage, setSuccessMessage] = useState(null); @@ -72,7 +62,6 @@ function AdminCachePage() { useEffect(() => { if (user && user.is_admin) { loadSources(); - loadSettings(); } }, [user]); @@ -96,19 +85,6 @@ function AdminCachePage() { } } - async function loadSettings() { - setLoadingSettings(true); - setSettingsError(null); - try { - const data = await getCacheSettings(); - setSettings(data); - } catch (err) { - setSettingsError(err instanceof Error ? err.message : 'Failed to load settings'); - } finally { - setLoadingSettings(false); - } - } - function openCreateForm() { setEditingSource(null); setFormData({ @@ -255,30 +231,6 @@ function AdminCachePage() { setShowErrorModal(true); } - async function handleSettingsToggle(field: 'auto_create_system_projects') { - if (!settings) return; - - // Check if env override is active - const isOverridden = field === 'auto_create_system_projects' && settings.auto_create_system_projects_env_override !== null; - - if (isOverridden) { - alert('This setting is overridden by an environment variable and cannot be changed via UI.'); - return; - } - - setUpdatingSettings(true); - try { - const update = { [field]: !settings[field] }; - const newSettings = await updateCacheSettings(update); - setSettings(newSettings); - setSuccessMessage(`Setting "${field}" updated`); - } catch (err) { - setSettingsError(err instanceof Error ? err.message : 'Failed to update settings'); - } finally { - setUpdatingSettings(false); - } - } - if (authLoading) { return
Loading...
; } @@ -293,49 +245,13 @@ function AdminCachePage() { return (
-

Cache Management

+

Upstream Sources

{successMessage &&
{successMessage}
} - {/* Cache Settings Section */} -
-

Global Settings

- {loadingSettings ? ( -

Loading settings...

- ) : settingsError ? ( -
{settingsError}
- ) : settings ? ( -
-
- - -
-
- ) : null} -
- {/* Upstream Sources Section */}
-

Upstream Sources

@@ -357,7 +273,7 @@ function AdminCachePage() { Priority Status Source - Test + Actions @@ -384,26 +300,20 @@ function AdminCachePage() { 'Database' )} - + {testingId === source.id ? ( - Testing... + ) : testResults[source.id] ? ( testResults[source.id].success ? ( - - OK - + ) : ( showError(source.name, testResults[source.id].message)} - > - Error - + >● ) - ) : ( - - )} + ) : null} - - + )} @@ -561,12 +462,27 @@ function AdminCachePage() { )}
- - + {editingSource && ( + + )} +
+ + +
diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 8c6d76a..8469560 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -557,15 +557,3 @@ export interface UpstreamSourceTestResult { source_id: string; source_name: string; } - -// Cache Settings types -export interface CacheSettings { - auto_create_system_projects: boolean; - auto_create_system_projects_env_override: boolean | null; - created_at: string | null; - updated_at: string | null; -} - -export interface CacheSettingsUpdate { - auto_create_system_projects?: boolean; -}