| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- "use client";
- import React, { ReactNode, useCallback, useEffect, useState } from "react";
- import { del, get, post } from "../../lib/api";
- export interface Settings {
- [key: string]: any;
- }
- export interface Dataset {
- [path: string]: any;
- }
- export interface DatasetsConfig {
- [datasetName: string]: Dataset;
- }
- export interface QueueConfig {
- maxConcurrent?: number;
- maxRetries?: number;
- [key: string]: any;
- }
- export interface WatcherConfig {
- enabled?: boolean;
- [key: string]: any;
- }
- export interface AppContextType {
- // Data
- settings: Settings | null;
- datasetsConfig: DatasetsConfig | null;
- queueConfig: QueueConfig | null;
- watcherConfig: WatcherConfig | null;
- datasets: string[] | null;
- // Loading states
- isLoading: boolean;
- isInitialized: boolean;
- // Errors
- error: Error | null;
- // Mutation functions
- updateSetting: (key: string, value: any) => Promise<void>;
- deleteSetting: (key: string) => Promise<void>;
- updateDatasets: (datasets: DatasetsConfig) => Promise<void>;
- updateQueueConfig: (config: QueueConfig) => Promise<void>;
- updateWatcherConfig: (config: WatcherConfig) => Promise<void>;
- // Refresh functions
- refreshSettings: () => Promise<void>;
- refreshDatasets: () => Promise<void>;
- refreshAll: () => Promise<void>;
- }
- const AppContext = React.createContext<AppContextType | undefined>(undefined);
- export function AppProvider({ children }: { children: ReactNode }) {
- const [settings, setSettings] = useState<Settings | null>(null);
- const [datasetsConfig, setDatasetsConfig] = useState<DatasetsConfig | null>(
- null
- );
- const [queueConfig, setQueueConfig] = useState<QueueConfig | null>(null);
- const [watcherConfig, setWatcherConfig] = useState<WatcherConfig | null>(
- null
- );
- const [datasets, setDatasets] = useState<string[] | null>(null);
- const [isLoading, setIsLoading] = useState(true);
- const [isInitialized, setIsInitialized] = useState(false);
- const [error, setError] = useState<Error | null>(null);
- // Load all initial data
- const initializeData = useCallback(async () => {
- try {
- setIsLoading(true);
- setError(null);
- // Load settings
- const settingsData = await get("/config/settings");
- setSettings(settingsData || {});
- // Extract specific configs from settings
- if (settingsData) {
- const queue = settingsData.queue || {};
- const watcher = settingsData.watcher || {};
- const datasetsData = settingsData.datasets || {};
- setQueueConfig(queue);
- setWatcherConfig(watcher);
- setDatasetsConfig(datasetsData);
- }
- // Load datasets list
- const datasetsList = await get("/files/all-datasets");
- setDatasets(datasetsList || []);
- setIsInitialized(true);
- } catch (err) {
- const error = err instanceof Error ? err : new Error(String(err));
- setError(error);
- console.error("Failed to initialize app context:", error);
- } finally {
- setIsLoading(false);
- }
- }, []);
- // Initial load
- useEffect(() => {
- initializeData();
- }, [initializeData]);
- // Listen for WebSocket events
- useEffect(() => {
- const handleSettingsUpdate = () => {
- initializeData();
- };
- const handleTaskUpdate = () => {
- // Refetch datasets in case new ones were created
- initializeData();
- };
- const handleFileUpdate = () => {
- // Refetch datasets in case new ones were created
- initializeData();
- };
- window.addEventListener(
- "settingsUpdate",
- handleSettingsUpdate as EventListener
- );
- window.addEventListener("taskUpdate", handleTaskUpdate as EventListener);
- window.addEventListener("fileUpdate", handleFileUpdate as EventListener);
- return () => {
- window.removeEventListener(
- "settingsUpdate",
- handleSettingsUpdate as EventListener
- );
- window.removeEventListener(
- "taskUpdate",
- handleTaskUpdate as EventListener
- );
- window.removeEventListener(
- "fileUpdate",
- handleFileUpdate as EventListener
- );
- };
- }, [initializeData]);
- // Mutation functions
- const updateSetting = useCallback(
- async (key: string, value: any) => {
- try {
- await post("/config/settings", { [key]: value });
- setSettings((prev) =>
- prev ? { ...prev, [key]: value } : { [key]: value }
- );
- await initializeData();
- } catch (err) {
- const error = err instanceof Error ? err : new Error(String(err));
- setError(error);
- throw error;
- }
- },
- [initializeData]
- );
- const deleteSetting = useCallback(
- async (key: string) => {
- try {
- await del(`/config/settings/${key}`);
- setSettings((prev) => {
- if (!prev) return null;
- const updated = { ...prev };
- delete updated[key];
- return updated;
- });
- await initializeData();
- } catch (err) {
- const error = err instanceof Error ? err : new Error(String(err));
- setError(error);
- throw error;
- }
- },
- [initializeData]
- );
- const updateDatasets = useCallback(
- async (datasetsData: DatasetsConfig) => {
- try {
- setDatasetsConfig(datasetsData);
- await updateSetting("datasets", datasetsData);
- } catch (err) {
- const error = err instanceof Error ? err : new Error(String(err));
- setError(error);
- throw error;
- }
- },
- [updateSetting]
- );
- const updateQueueConfig = useCallback(
- async (config: QueueConfig) => {
- try {
- setQueueConfig(config);
- await updateSetting("queue", config);
- } catch (err) {
- const error = err instanceof Error ? err : new Error(String(err));
- setError(error);
- throw error;
- }
- },
- [updateSetting]
- );
- const updateWatcherConfig = useCallback(
- async (config: WatcherConfig) => {
- try {
- setWatcherConfig(config);
- await updateSetting("watcher", config);
- } catch (err) {
- const error = err instanceof Error ? err : new Error(String(err));
- setError(error);
- throw error;
- }
- },
- [updateSetting]
- );
- const refreshSettings = useCallback(async () => {
- try {
- const settingsData = await get("/config/settings");
- setSettings(settingsData || {});
- if (settingsData) {
- setQueueConfig(settingsData.queue || {});
- setWatcherConfig(settingsData.watcher || {});
- setDatasetsConfig(settingsData.datasets || {});
- }
- } catch (err) {
- const error = err instanceof Error ? err : new Error(String(err));
- setError(error);
- throw error;
- }
- }, []);
- const refreshDatasets = useCallback(async () => {
- try {
- const datasetsList = await get("/files/all-datasets");
- setDatasets(datasetsList || []);
- } catch (err) {
- const error = err instanceof Error ? err : new Error(String(err));
- setError(error);
- throw error;
- }
- }, []);
- const refreshAll = useCallback(async () => {
- await initializeData();
- }, [initializeData]);
- const value: AppContextType = {
- settings,
- datasetsConfig,
- queueConfig,
- watcherConfig,
- datasets,
- isLoading,
- isInitialized,
- error,
- updateSetting,
- deleteSetting,
- updateDatasets,
- updateQueueConfig,
- updateWatcherConfig,
- refreshSettings,
- refreshDatasets,
- refreshAll
- };
- return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
- }
- export function useAppContext() {
- const context = React.useContext(AppContext);
- if (context === undefined) {
- throw new Error("useAppContext must be used within an AppProvider");
- }
- return context;
- }
|