FIx config
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
77
frontend/src/components/config-provider.tsx
Normal file
77
frontend/src/components/config-provider.tsx
Normal 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;
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user