diff --git a/ui/src/pages/Admin/AppConfigDetailPage.module.css b/ui/src/pages/Admin/AppConfigDetailPage.module.css index 6536bedf..b5a2bde9 100644 --- a/ui/src/pages/Admin/AppConfigDetailPage.module.css +++ b/ui/src/pages/Admin/AppConfigDetailPage.module.css @@ -90,3 +90,13 @@ color: var(--text-muted); font-family: var(--font-body); } + +.editBanner { + padding: 8px 16px; + background: color-mix(in srgb, var(--amber) 8%, transparent); + border: 1px solid var(--amber); + border-radius: var(--radius-sm); + font-size: 13px; + color: var(--text-primary); + margin-bottom: 16px; +} diff --git a/ui/src/pages/Admin/AppConfigDetailPage.tsx b/ui/src/pages/Admin/AppConfigDetailPage.tsx index 3e4463d4..b8584e24 100644 --- a/ui/src/pages/Admin/AppConfigDetailPage.tsx +++ b/ui/src/pages/Admin/AppConfigDetailPage.tsx @@ -317,6 +317,12 @@ export default function AppConfigDetailPage() { )} + {editing && ( +
+ Editing configuration. Changes are not saved until you click Save. +
+ )} +

{appId}

diff --git a/ui/src/pages/Admin/EnvironmentsPage.tsx b/ui/src/pages/Admin/EnvironmentsPage.tsx index 30d80f5b..678c129a 100644 --- a/ui/src/pages/Admin/EnvironmentsPage.tsx +++ b/ui/src/pages/Admin/EnvironmentsPage.tsx @@ -392,6 +392,11 @@ function DefaultResourcesSection({ environment, onSave, saving }: { return (
Default Resource Limits + {editing && ( +
+ Editing resource defaults. Changes are not saved until you click Save. +
+ )}

These defaults apply to new apps in this environment unless overridden per-app.

@@ -485,6 +490,11 @@ function JarRetentionSection({ environment, onSave, saving }: { return (
JAR Retention + {editing && ( +
+ Editing resource defaults. Changes are not saved until you click Save. +
+ )}

Old JAR versions are cleaned up nightly. Currently deployed versions are never deleted.

diff --git a/ui/src/pages/Admin/OidcConfigPage.tsx b/ui/src/pages/Admin/OidcConfigPage.tsx index 1dd316c2..c630a787 100644 --- a/ui/src/pages/Admin/OidcConfigPage.tsx +++ b/ui/src/pages/Admin/OidcConfigPage.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from 'react'; +import { Eye, EyeOff } from 'lucide-react'; import { Button, Input, Toggle, FormField, SectionHeader, Tag, ConfirmDialog, } from '@cameleer/design-system'; @@ -41,6 +42,7 @@ export default function OidcConfigPage() { const [editing, setEditing] = useState(false); const [formDraft, setFormDraft] = useState(null); const [newRole, setNewRole] = useState(''); + const [showSecret, setShowSecret] = useState(false); const [deleteOpen, setDeleteOpen] = useState(false); const [saving, setSaving] = useState(false); const [testing, setTesting] = useState(false); @@ -200,13 +202,25 @@ export default function OidcConfigPage() { /> - updateDraft('clientSecret', e.target.value)} - disabled={!editing} - /> +
+ updateDraft('clientSecret', e.target.value)} + disabled={!editing} + /> + {editing && ( + + )} +
Deployments
{deploymentRows.length === 0 - ?

No deployments yet.

+ ? : columns={deploymentColumns} data={deploymentRows} flush /> }
@@ -726,7 +727,7 @@ function OverviewSubTab({ app, deployments, versions, environments, envMap, sele ))} Versions ({versions.length}) - {versions.length === 0 &&

No versions uploaded yet.

} + {versions.length === 0 && } {versions.map((v) => ( onDeploy(v.id, envId)} /> ))} @@ -1005,7 +1006,7 @@ function ConfigSubTab({ app, environment }: { app: App; environment?: Environmen {editing && ( )} - {envVars.length === 0 && !editing &&

No environment variables configured.

} + {envVars.length === 0 && !editing && }
)} @@ -1075,7 +1076,7 @@ function ConfigSubTab({ app, environment }: { app: App; environment?: Environmen {tracedCount} traced · {tapCount} taps {tracedTapRows.length > 0 ? columns={tracedTapColumns} data={tracedTapRows} pageSize={20} flush /> - :

No processor traces or taps configured.

} + : }
)} @@ -1085,7 +1086,7 @@ function ConfigSubTab({ app, environment }: { app: App; environment?: Environmen {recordingCount} of {routeRecordingRows.length} routes recording {routeRecordingRows.length > 0 ? columns={routeRecordingColumns} data={routeRecordingRows} pageSize={20} flush /> - :

No routes found for this application.

} + : } )} diff --git a/ui/src/pages/Routes/RouteDetail.tsx b/ui/src/pages/Routes/RouteDetail.tsx index 1ae332c6..1f9637ee 100644 --- a/ui/src/pages/Routes/RouteDetail.tsx +++ b/ui/src/pages/Routes/RouteDetail.tsx @@ -6,6 +6,7 @@ import { Badge, StatusDot, DataTable, + EmptyState, Tabs, AreaChart, LineChart, @@ -702,9 +703,7 @@ export default function RouteDetail() { {diagramFlows.length > 0 ? ( ) : ( -
- No diagram available for this route. -
+ )}
@@ -714,9 +713,7 @@ export default function RouteDetail() { ) : processorRows.length > 0 ? ( ) : ( -
- No processor data available. -
+ )}
@@ -819,9 +816,7 @@ export default function RouteDetail() { {activeTab === 'errors' && (
{errorPatterns.length === 0 ? ( -
- No error patterns found in the selected time range. -
+ ) : ( errorPatterns.map((ep, i) => (
@@ -841,9 +836,7 @@ export default function RouteDetail() {
{routeTaps.length === 0 ? ( -
- No taps configured for this route. Add a tap to extract business attributes from exchange data. -
+ ) : (