File size: 4,285 Bytes
42da440
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import React, { createContext, useState, useContext, useCallback } from 'react';
import { fetchInputStructure, fetchOutputStructure } from '../api'; // Assuming API functions exist

const FileManagerContext = createContext();

export const useFileManager = () => useContext(FileManagerContext);

/**
 * Adapts API data structure to the structure expected by react-arborist.
 * Sorts directories first, then alphabetically.
 * @param {Array<object>} apiData - Data from the API
 * @returns {Array<object>} Adapted and sorted data
 */
const adaptAndSortApiData = (apiData) => {
    if (!Array.isArray(apiData)) return [];
    const adapted = apiData.map(item => ({
        id: item.path,
        name: item.path.split('/').pop() || item.path,
        relativePath: item.path,
        is_dir: item.is_dir,
        children: item.is_dir ? (item.children ? adaptAndSortApiData(item.children) : null) : undefined,
    }));
    // Sort: directories first, then alphabetically
    adapted.sort((a, b) => {
        if (a.is_dir !== b.is_dir) return a.is_dir ? -1 : 1;
        return a.name.localeCompare(b.name);
    });
    return adapted;
};


export const FileManagerProvider = ({ children }) => {
    // --- Input State ---
    const [inputTreeData, setInputTreeData] = useState(null);
    const [isInputLoading, setIsInputLoading] = useState(false);
    const [inputError, setInputError] = useState(null);

    // --- Output State ---
    const [outputTreeData, setOutputTreeData] = useState(null);
    const [isOutputLoading, setIsOutputLoading] = useState(false);
    const [outputError, setOutputError] = useState(null);

    // --- Fetch Input Data (with caching) ---
    const fetchInputData = useCallback(async (forceRefresh = false) => {
        if (inputTreeData && !forceRefresh) {
            // console.log("Using cached input data");
            return; // Use cached data if available and not forcing refresh
        }
        // console.log("Fetching input data...", { forceRefresh });
        setIsInputLoading(true);
        setInputError(null);
        try {
            const structure = await fetchInputStructure();
            const adaptedData = adaptAndSortApiData(structure);
            setInputTreeData(adaptedData);
        } catch (e) {
            console.error("Failed to fetch input structure:", e);
            setInputError(e.message || 'Failed to load input files structure.');
            setInputTreeData([]); // Set empty on error to stop loading indicators
        } finally {
            setIsInputLoading(false);
        }
    }, [inputTreeData]); // Re-run if cached data changes (relevant for forceRefresh logic)

    // --- Fetch Output Data (with caching) ---
    const fetchOutputData = useCallback(async (forceRefresh = false) => {
        if (outputTreeData && !forceRefresh) {
            // console.log("Using cached output data");
            return; // Use cached data
        }
        // console.log("Fetching output data...", { forceRefresh });
        setIsOutputLoading(true);
        setOutputError(null);
        try {
            const structure = await fetchOutputStructure();
            const adaptedData = adaptAndSortApiData(structure);
            setOutputTreeData(adaptedData);
        } catch (e) {
            console.error("Failed to fetch output structure:", e);
            setOutputError(e.message || 'Failed to load output files structure.');
            setOutputTreeData([]); // Set empty on error
        } finally {
            setIsOutputLoading(false);
        }
    }, [outputTreeData]); // Re-run if cached data changes

    // --- Refresh Functions ---
    // These simply call the fetch functions with forceRefresh=true
    const refreshInputData = useCallback(() => fetchInputData(true), [fetchInputData]);
    const refreshOutputData = useCallback(() => fetchOutputData(true), [fetchOutputData]);


    const value = {
        inputTreeData,
        isInputLoading,
        inputError,
        fetchInputData,
        refreshInputData,

        outputTreeData,
        isOutputLoading,
        outputError,
        fetchOutputData,
        refreshOutputData,
    };

    return (
        <FileManagerContext.Provider value={value}>
            {children}
        </FileManagerContext.Provider>
    );
};