Spaces:
Sleeping
Sleeping
| import { createContext, useContext, useReducer, useCallback } from 'react'; | |
| import { DEFAULT_CONFIG } from '../utils/constants.js'; | |
| const AppContext = createContext(null); | |
| const AppDispatch = createContext(null); | |
| const initialState = { | |
| // Step 1 | |
| files: { d: null, p: null, r: null }, | |
| dictCSV: null, | |
| panelCSV: null, | |
| selectedPanels: new Set(), | |
| p1ColFilters: {}, | |
| fromPastResult: false, | |
| // Restore buffers from past result | |
| _rPanels: null, _rVars: null, _rC: null, _rMap: null, _rFix: null, | |
| // Step 2 | |
| allRows: [], // dict rows with _sel flag | |
| _dictToken: null, | |
| // Step 3 | |
| contributions: {}, // { actKey: { panelKey: {min,max} } } | |
| // Step 4 | |
| panelMap: {}, // { panelKey: { varName: bool } } | |
| // Step 5 | |
| fixedVars: {}, // { panelKey: varName[] } | |
| // Step 6 | |
| modelParams: {}, // { "pk|var": {min_Adstock, ...} } | |
| // Step 7 | |
| config: JSON.parse(JSON.stringify(DEFAULT_CONFIG)), | |
| }; | |
| function reducer(state, action) { | |
| switch (action.type) { | |
| case 'SET_DICT_CSV': return { ...state, dictCSV: action.payload }; | |
| case 'SET_PANEL_CSV': return { ...state, panelCSV: action.payload }; | |
| case 'SET_FILE': return { ...state, files: { ...state.files, [action.key]: action.value } }; | |
| case 'SET_SELECTED_PANELS': return { ...state, selectedPanels: action.payload }; | |
| case 'SET_P1_COL_FILTERS': return { ...state, p1ColFilters: action.payload }; | |
| case 'SET_ALL_ROWS': return { ...state, allRows: action.payload, _dictToken: action.token }; | |
| case 'TOGGLE_VAR_SEL': { | |
| const rows = state.allRows.map(r => r.__id === action.id ? { ...r, _sel: !r._sel } : r); | |
| return { ...state, allRows: rows }; | |
| } | |
| case 'SET_ALL_VARS_SEL': { | |
| const rows = state.allRows.map(r => action.ids.has(r.__id) ? { ...r, _sel: action.on } : r); | |
| return { ...state, allRows: rows }; | |
| } | |
| case 'SET_CONTRIBUTIONS': return { ...state, contributions: action.payload }; | |
| case 'SET_PANEL_MAP': return { ...state, panelMap: action.payload }; | |
| case 'SET_FIXED_VARS': return { ...state, fixedVars: action.payload }; | |
| case 'SET_MODEL_PARAMS': return { ...state, modelParams: action.payload }; | |
| case 'SET_CONFIG': return { ...state, config: action.payload }; | |
| case 'SET_RESTORE_BUFFERS': return { ...state, ...action.payload }; | |
| case 'SET_FROM_PAST_RESULT': return { ...state, fromPastResult: action.payload }; | |
| case 'RESET_ALL': return { ...initialState, config: JSON.parse(JSON.stringify(DEFAULT_CONFIG)) }; | |
| default: return state; | |
| } | |
| } | |
| export function AppProvider({ children }) { | |
| const [state, dispatch] = useReducer(reducer, initialState); | |
| return ( | |
| <AppContext.Provider value={state}> | |
| <AppDispatch.Provider value={dispatch}> | |
| {children} | |
| </AppDispatch.Provider> | |
| </AppContext.Provider> | |
| ); | |
| } | |
| export function useAppState() { return useContext(AppContext); } | |
| export function useAppDispatch() { return useContext(AppDispatch); } | |
| // Derived helpers | |
| export function useSelPanelRows() { | |
| const { panelCSV, selectedPanels } = useAppState(); | |
| if (!panelCSV) return []; | |
| return panelCSV.rows.filter(r => selectedPanels.has(String(r.__id))); | |
| } | |
| export function useSelVars() { | |
| const { allRows } = useAppState(); | |
| return allRows.filter(r => r._sel).map(r => r.VARIABLE); | |
| } | |
| export function useActivityGroups() { | |
| const { allRows } = useAppState(); | |
| const g = {}; | |
| allRows.filter(r => r._sel).forEach(r => { | |
| const a = r.SN_ACTIVITY_LEVEL_1 || '(Unassigned)'; | |
| if (!g[a]) g[a] = []; | |
| g[a].push(r.VARIABLE); | |
| }); | |
| return g; | |
| } | |