FIx config

This commit is contained in:
Louis Knight-Webb
2025-06-21 22:19:25 +01:00
parent 5405fac819
commit 290d128220
3 changed files with 99 additions and 26 deletions

View File

@@ -7,52 +7,37 @@ import { TaskDetailsPage } from "@/pages/task-details";
import { TaskAttemptComparePage } from "@/pages/task-attempt-compare";
import { Settings } from "@/pages/Settings";
import { DisclaimerDialog } from "@/components/DisclaimerDialog";
import { ConfigProvider, useConfig } from "@/components/config-provider";
import type { Config, ApiResponse } from "shared/types";
function AppContent() {
const [config, setConfig] = useState<Config | null>(null);
const [loading, setLoading] = useState(true);
const { config, updateConfig, loading } = useConfig();
const [showDisclaimer, setShowDisclaimer] = useState(false);
const showNavbar = true;
useEffect(() => {
const loadConfig = async () => {
try {
const response = await fetch("/api/config");
const data: ApiResponse<Config> = await response.json();
if (data.success && data.data) {
setConfig(data.data);
setShowDisclaimer(!data.data.disclaimer_acknowledged);
}
} catch (err) {
console.error("Error loading config:", err);
} finally {
setLoading(false);
}
};
loadConfig();
}, []);
if (config) {
setShowDisclaimer(!config.disclaimer_acknowledged);
}
}, [config]);
const handleDisclaimerAccept = async () => {
if (!config) return;
const updatedConfig = { ...config, disclaimer_acknowledged: true };
updateConfig({ disclaimer_acknowledged: true });
try {
const response = await fetch("/api/config", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(updatedConfig),
body: JSON.stringify({ ...config, disclaimer_acknowledged: true }),
});
const data: ApiResponse<Config> = await response.json();
if (data.success) {
setConfig(updatedConfig);
setShowDisclaimer(false);
}
} catch (err) {
@@ -102,7 +87,9 @@ function AppContent() {
function App() {
return (
<BrowserRouter>
<AppContent />
<ConfigProvider>
<AppContent />
</ConfigProvider>
</BrowserRouter>
);
}

View File

@@ -0,0 +1,77 @@
import React, { createContext, useContext, useState, useEffect, ReactNode } from "react";
import type { Config, ApiResponse } from "shared/types";
interface ConfigContextType {
config: Config | null;
updateConfig: (updates: Partial<Config>) => void;
saveConfig: () => Promise<boolean>;
loading: boolean;
}
const ConfigContext = createContext<ConfigContextType | undefined>(undefined);
interface ConfigProviderProps {
children: ReactNode;
}
export function ConfigProvider({ children }: ConfigProviderProps) {
const [config, setConfig] = useState<Config | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const loadConfig = async () => {
try {
const response = await fetch("/api/config");
const data: ApiResponse<Config> = await response.json();
if (data.success && data.data) {
setConfig(data.data);
}
} catch (err) {
console.error("Error loading config:", err);
} finally {
setLoading(false);
}
};
loadConfig();
}, []);
const updateConfig = (updates: Partial<Config>) => {
setConfig((prev) => prev ? { ...prev, ...updates } : null);
};
const saveConfig = async (): Promise<boolean> => {
if (!config) return false;
try {
const response = await fetch("/api/config", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(config),
});
const data: ApiResponse<Config> = await response.json();
return data.success;
} catch (err) {
console.error("Error saving config:", err);
return false;
}
};
return (
<ConfigContext.Provider value={{ config, updateConfig, saveConfig, loading }}>
{children}
</ConfigContext.Provider>
);
}
export function useConfig() {
const context = useContext(ConfigContext);
if (context === undefined) {
throw new Error("useConfig must be used within a ConfigProvider");
}
return context;
}

View File

@@ -29,6 +29,7 @@ import {
getTaskPanelClasses,
getBackdropClasses,
} from "@/lib/responsive-config";
import { useConfig } from "@/components/config-provider";
import type {
TaskStatus,
TaskAttempt,
@@ -132,7 +133,8 @@ export function TaskDetailsPanel({
const [loading, setLoading] = useState(false);
const [followUpMessage, setFollowUpMessage] = useState("");
const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false);
const [selectedExecutor, setSelectedExecutor] = useState("claude");
const [selectedExecutor, setSelectedExecutor] = useState<string>("claude");
const { config } = useConfig();
// Available executors
const availableExecutors = [
@@ -162,6 +164,13 @@ export function TaskDetailsPanel({
return () => clearInterval(interval);
}, [isAttemptRunning, task?.id, selectedAttempt?.id]);
// Set default executor from config
useEffect(() => {
if (config) {
setSelectedExecutor(config.executor.type);
}
}, [config]);
useEffect(() => {
if (task && isOpen) {
fetchTaskAttempts();