Agent_PDF / web /src /components /studio /StudioContext.jsx
MohamedSameh77i's picture
Add selection padding slider + cell ops + non-blocking upload prep
295679f verified
/* eslint-disable react-refresh/only-export-components */
import { createContext, useContext, useMemo, useReducer } from 'react'
function getDefaultActiveTable(annotation, activePage) {
const tables = annotation?.tables || []
const first = tables.find((table) => (table.page || 0) === activePage)
return first?.table_id ?? null
}
function buildInitialState(annotation) {
const activePage = 0
return {
activePage,
activeCell: null,
activeTable: getDefaultActiveTable(annotation, activePage),
tdThreshold: 0,
selectionPadding: 0,
showTableGrid: true,
showTextBoxes: false,
showHeatmap: false,
toast: null,
errorCount: 0,
undoStack: [],
redoStack: [],
activeTool: 'pointer',
selection: null,
cellSelection: null,
}
}
function studioReducer(state, action) {
switch (action.type) {
case 'setActivePage':
return {
...state,
activePage: action.page,
}
case 'setActiveTable':
return {
...state,
activeTable: action.tableId,
}
case 'setActiveCell':
return {
...state,
activeCell: action.cell,
}
case 'setThreshold':
return {
...state,
tdThreshold: action.value,
}
case 'setPadding':
return {
...state,
selectionPadding: action.value,
}
case 'toggleFlag':
return {
...state,
[action.flag]: !state[action.flag],
}
case 'showToast':
return {
...state,
toast: action.toast,
}
case 'clearToast':
return {
...state,
toast: null,
}
case 'incrementErrors':
return {
...state,
errorCount: state.errorCount + 1,
}
case 'recordEdit':
return {
...state,
undoStack: [...state.undoStack, action.edit],
redoStack: [],
}
case 'completeUndo':
if (!state.undoStack.length) {
return state
}
return {
...state,
undoStack: state.undoStack.slice(0, -1),
redoStack: [...state.redoStack, state.undoStack[state.undoStack.length - 1]],
}
case 'completeRedo':
if (!state.redoStack.length) {
return state
}
return {
...state,
undoStack: [...state.undoStack, state.redoStack[state.redoStack.length - 1]],
redoStack: state.redoStack.slice(0, -1),
}
case 'setTool':
return {
...state,
activeTool: action.tool,
selection: null,
}
case 'setSelection':
return {
...state,
selection: action.selection,
}
case 'setCellSelection':
return {
...state,
cellSelection: action.selection,
}
default:
return state
}
}
const StudioContext = createContext(null)
export function StudioProvider({ annotation, children }) {
const [state, dispatch] = useReducer(studioReducer, annotation, buildInitialState)
const value = useMemo(() => ({ state, dispatch }), [state])
return <StudioContext.Provider value={value}>{children}</StudioContext.Provider>
}
export function useStudio() {
const value = useContext(StudioContext)
if (!value) {
throw new Error('useStudio must be used within StudioProvider')
}
return value
}