mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 10:16:49 +00:00
fix(ui): handle 404 errors in profile settings fetch
- throw on non-OK responses in ProfileEditor queryFn - add isError state with user-friendly message and retry button - add defensive null check for data.path before .replace() call - apply same defensive check to provider-editor.tsx Fixes blank screen when API profile settings file doesn't exist.
This commit is contained in:
@@ -566,7 +566,7 @@ export function ProviderEditor({
|
||||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
<h2 className="text-lg font-semibold">{displayName}</h2>
|
||||
{data && (
|
||||
{data?.path && (
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{data.path.replace(/^.*\//, '')}
|
||||
</Badge>
|
||||
|
||||
@@ -46,9 +46,15 @@ export function ProfileEditor({ profileName, onDelete }: ProfileEditorProps) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// Fetch settings for selected profile
|
||||
const { data, isLoading, refetch } = useQuery<SettingsResponse>({
|
||||
const { data, isLoading, isError, refetch } = useQuery<SettingsResponse>({
|
||||
queryKey: ['settings', profileName],
|
||||
queryFn: () => fetch(`/api/settings/${profileName}/raw`).then((r) => r.json()),
|
||||
queryFn: async () => {
|
||||
const res = await fetch(`/api/settings/${profileName}/raw`);
|
||||
if (!res.ok) {
|
||||
throw new Error(`Failed to load settings: ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
},
|
||||
});
|
||||
|
||||
// Derive raw JSON content
|
||||
@@ -427,7 +433,7 @@ export function ProfileEditor({ profileName, onDelete }: ProfileEditorProps) {
|
||||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
<h2 className="text-lg font-semibold">{profileName}</h2>
|
||||
{data && (
|
||||
{data?.path && (
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{data.path.replace(/^.*\//, '')}
|
||||
</Badge>
|
||||
@@ -473,6 +479,18 @@ export function ProfileEditor({ profileName, onDelete }: ProfileEditorProps) {
|
||||
<Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
|
||||
<span className="ml-3 text-muted-foreground">Loading settings...</span>
|
||||
</div>
|
||||
) : isError ? (
|
||||
<div className="flex-1 flex items-center justify-center">
|
||||
<div className="text-center space-y-3">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Failed to load settings for this profile.
|
||||
</p>
|
||||
<Button variant="outline" size="sm" onClick={() => refetch()}>
|
||||
<RefreshCw className="w-4 h-4 mr-1" />
|
||||
Retry
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
// Split Layout (40% Left / 60% Right)
|
||||
<div className="flex-1 grid grid-cols-[40%_60%] divide-x overflow-hidden">
|
||||
|
||||
Reference in New Issue
Block a user