feat: split config into 4 tabs and fix JAR upload 413
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m19s
CI / docker (push) Successful in 1m5s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 37s

Config sub-tabs are now: Monitoring | Traces & Taps | Route Recording | Resources
(renamed from Agent/Infrastructure, with traces and recording as their own tabs).

Also increase Spring multipart max-file-size and max-request-size to 200MB
to fix HTTP 413 on JAR uploads.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-08 18:22:39 +02:00
parent 7503641afe
commit 0b2d231b6b
2 changed files with 69 additions and 63 deletions

View File

@@ -2,6 +2,10 @@ server:
port: 8081 port: 8081
spring: spring:
servlet:
multipart:
max-file-size: 200MB
max-request-size: 200MB
datasource: datasource:
url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/cameleer3?currentSchema=tenant_${cameleer.tenant.id}} url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/cameleer3?currentSchema=tenant_${cameleer.tenant.id}}
username: ${SPRING_DATASOURCE_USERNAME:cameleer} username: ${SPRING_DATASOURCE_USERNAME:cameleer}

View File

@@ -471,7 +471,7 @@ function ConfigSubTab({ app, environment }: { app: App; environment?: Environmen
const { data: processorToRoute = {} } = useProcessorRouteMapping(app.slug); const { data: processorToRoute = {} } = useProcessorRouteMapping(app.slug);
const isProd = environment?.production ?? false; const isProd = environment?.production ?? false;
const [editing, setEditing] = useState(false); const [editing, setEditing] = useState(false);
const [configTab, setConfigTab] = useState<'agent' | 'infra'>('agent'); const [configTab, setConfigTab] = useState<'monitoring' | 'traces' | 'recording' | 'resources'>('monitoring');
const appRoutes: RouteSummary[] = useMemo(() => { const appRoutes: RouteSummary[] = useMemo(() => {
if (!catalog) return []; if (!catalog) return [];
@@ -664,14 +664,13 @@ function ConfigSubTab({ app, environment }: { app: App; environment?: Environmen
)} )}
<div className={styles.subTabs}> <div className={styles.subTabs}>
<button className={`${styles.subTab} ${configTab === 'agent' ? styles.subTabActive : ''}`} onClick={() => setConfigTab('agent')}>Agent</button> <button className={`${styles.subTab} ${configTab === 'monitoring' ? styles.subTabActive : ''}`} onClick={() => setConfigTab('monitoring')}>Monitoring</button>
<button className={`${styles.subTab} ${configTab === 'infra' ? styles.subTabActive : ''}`} onClick={() => setConfigTab('infra')}>Infrastructure</button> <button className={`${styles.subTab} ${configTab === 'traces' ? styles.subTabActive : ''}`} onClick={() => setConfigTab('traces')}>Traces & Taps</button>
<button className={`${styles.subTab} ${configTab === 'recording' ? styles.subTabActive : ''}`} onClick={() => setConfigTab('recording')}>Route Recording</button>
<button className={`${styles.subTab} ${configTab === 'resources' ? styles.subTabActive : ''}`} onClick={() => setConfigTab('resources')}>Resources</button>
</div> </div>
{configTab === 'agent' && ( {configTab === 'monitoring' && (
<>
{/* Observability Settings */}
<SectionHeader>Observability</SectionHeader>
<div className={styles.configGrid}> <div className={styles.configGrid}>
<span className={styles.configLabel}>Engine Level</span> <span className={styles.configLabel}>Engine Level</span>
<Select disabled={!editing} value={engineLevel} onChange={(e) => setEngineLevel(e.target.value)} <Select disabled={!editing} value={engineLevel} onChange={(e) => setEngineLevel(e.target.value)}
@@ -726,16 +725,19 @@ function ConfigSubTab({ app, environment }: { app: App; environment?: Environmen
<span className={routeControlEnabled ? styles.toggleEnabled : styles.toggleDisabled}>{routeControlEnabled ? 'Enabled' : 'Disabled'}</span> <span className={routeControlEnabled ? styles.toggleEnabled : styles.toggleDisabled}>{routeControlEnabled ? 'Enabled' : 'Disabled'}</span>
</div> </div>
</div> </div>
)}
{/* Traces & Taps */} {configTab === 'traces' && (
<SectionHeader>Traces & Taps</SectionHeader> <>
<span className={styles.sectionSummary}>{tracedCount} traced &middot; {tapCount} taps</span> <span className={styles.sectionSummary}>{tracedCount} traced &middot; {tapCount} taps</span>
{tracedTapRows.length > 0 {tracedTapRows.length > 0
? <DataTable<TracedTapRow> columns={tracedTapColumns} data={tracedTapRows} pageSize={20} flush /> ? <DataTable<TracedTapRow> columns={tracedTapColumns} data={tracedTapRows} pageSize={20} flush />
: <p className={styles.emptyNote}>No processor traces or taps configured.</p>} : <p className={styles.emptyNote}>No processor traces or taps configured.</p>}
</>
)}
{/* Route Recording */} {configTab === 'recording' && (
<SectionHeader>Route Recording</SectionHeader> <>
<span className={styles.sectionSummary}>{recordingCount} of {routeRecordingRows.length} routes recording</span> <span className={styles.sectionSummary}>{recordingCount} of {routeRecordingRows.length} routes recording</span>
{routeRecordingRows.length > 0 {routeRecordingRows.length > 0
? <DataTable<RouteRecordingRow> columns={routeRecordingColumns} data={routeRecordingRows} pageSize={20} flush /> ? <DataTable<RouteRecordingRow> columns={routeRecordingColumns} data={routeRecordingRows} pageSize={20} flush />
@@ -743,7 +745,7 @@ function ConfigSubTab({ app, environment }: { app: App; environment?: Environmen
</> </>
)} )}
{configTab === 'infra' && ( {configTab === 'resources' && (
<> <>
{/* Container Resources */} {/* Container Resources */}
<SectionHeader>Container Resources</SectionHeader> <SectionHeader>Container Resources</SectionHeader>