From 2960a23a6338849acdfabb2ad1a2e417c1d39ba5 Mon Sep 17 00:00:00 2001 From: EthanHealy01 Date: Wed, 8 Oct 2025 00:34:54 +0100 Subject: [PATCH] cleanups --- .../src/components/shared/QuickAccessBar.tsx | 6 +- frontend/src/components/tools/ToolPanel.tsx | 11 -- .../components/tools/ToolPanelModePrompt.tsx | 3 +- .../src/constants/convertSupportedFornats.ts | 21 +++ frontend/src/contexts/ToolWorkflowContext.tsx | 126 ++---------------- frontend/src/contexts/toolWorkflow/state.ts | 114 ++++++++++++++++ .../src/data/useTranslatedToolRegistry.tsx | 80 +---------- 7 files changed, 152 insertions(+), 209 deletions(-) create mode 100644 frontend/src/constants/convertSupportedFornats.ts create mode 100644 frontend/src/contexts/toolWorkflow/state.ts diff --git a/frontend/src/components/shared/QuickAccessBar.tsx b/frontend/src/components/shared/QuickAccessBar.tsx index f87476806..d41812b8d 100644 --- a/frontend/src/components/shared/QuickAccessBar.tsx +++ b/frontend/src/components/shared/QuickAccessBar.tsx @@ -24,7 +24,7 @@ const QuickAccessBar = forwardRef((_, ref) => { const { t } = useTranslation(); const { isRainbowMode } = useRainbowThemeContext(); const { openFilesModal, isFilesModalOpen } = useFilesModalContext(); - const { handleReaderToggle, handleBackToTools: _handleBackToTools, handleToolSelect, selectedToolKey, leftPanelView, toolRegistry, readerMode, resetTool, setToolPanelMode: _setToolPanelMode } = useToolWorkflow(); + const { handleReaderToggle, handleToolSelect, selectedToolKey, leftPanelView, toolRegistry, readerMode, resetTool } = useToolWorkflow(); const { getToolNavigation } = useSidebarNavigation(); const { config } = useAppConfig(); const [configModalOpen, setConfigModalOpen] = useState(false); @@ -68,7 +68,8 @@ const QuickAccessBar = forwardRef((_, ref) => { onClick: (e: React.MouseEvent) => handleClick(e), 'aria-label': config.name } : { - onClick: () => handleClick() + onClick: () => handleClick(), + 'aria-label': config.name })} size={isActive ? (config.size || 'lg') : 'lg'} variant="subtle" @@ -228,6 +229,7 @@ const QuickAccessBar = forwardRef((_, ref) => { onClick={config.onClick} style={getNavButtonStyle(config, activeButton, isFilesModalOpen, configModalOpen, selectedToolKey, leftPanelView)} className={isNavButtonActive(config, activeButton, isFilesModalOpen, configModalOpen, selectedToolKey, leftPanelView) ? 'activeIconScale' : ''} + aria-label={config.name} data-testid={`${config.id}-button`} > diff --git a/frontend/src/components/tools/ToolPanel.tsx b/frontend/src/components/tools/ToolPanel.tsx index 6a88befcd..101af1649 100644 --- a/frontend/src/components/tools/ToolPanel.tsx +++ b/frontend/src/components/tools/ToolPanel.tsx @@ -51,17 +51,6 @@ export default function ToolPanel() { const fullscreenExpanded = isFullscreenMode && leftPanelView === 'toolPicker' && !isMobile && toolPickerVisible; - // Debug logging for troubleshooting - React.useEffect(() => { - console.log('ToolPanel debug:', { - isFullscreenMode, - leftPanelView, - isMobile, - toolPickerVisible, - fullscreenExpanded - }); - }, [isFullscreenMode, leftPanelView, isMobile, toolPickerVisible, fullscreenExpanded]); - // Disable right rail buttons when fullscreen mode is active React.useEffect(() => { setAllRightRailButtonsDisabled(fullscreenExpanded); diff --git a/frontend/src/components/tools/ToolPanelModePrompt.tsx b/frontend/src/components/tools/ToolPanelModePrompt.tsx index 97a384cab..d0c26936e 100644 --- a/frontend/src/components/tools/ToolPanelModePrompt.tsx +++ b/frontend/src/components/tools/ToolPanelModePrompt.tsx @@ -1,7 +1,8 @@ import { useEffect, useState } from 'react'; import { Badge, Button, Card, Group, Modal, Stack, Text } from '@mantine/core'; import { useTranslation } from 'react-i18next'; -import { useToolWorkflow, TOOL_PANEL_MODE_STORAGE_KEY } from '../../contexts/ToolWorkflowContext'; +import { useToolWorkflow } from '../../contexts/ToolWorkflowContext'; +import { TOOL_PANEL_MODE_STORAGE_KEY } from '../../contexts/toolWorkflow/state'; import './ToolPanelModePrompt.css'; type ToolPanelModeOption = 'sidebar' | 'fullscreen'; diff --git a/frontend/src/constants/convertSupportedFornats.ts b/frontend/src/constants/convertSupportedFornats.ts new file mode 100644 index 000000000..b9bea3227 --- /dev/null +++ b/frontend/src/constants/convertSupportedFornats.ts @@ -0,0 +1,21 @@ +// Central list of formats supported by Convert operations +export const CONVERT_SUPPORTED_FORMATS = [ + // Microsoft Office + 'doc', 'docx', 'dot', 'dotx', 'csv', 'xls', 'xlsx', 'xlt', 'xltx', 'slk', 'dif', 'ppt', 'pptx', + // OpenDocument + 'odt', 'ott', 'ods', 'ots', 'odp', 'otp', 'odg', 'otg', + // Text formats + 'txt', 'text', 'xml', 'rtf', 'html', 'lwp', 'md', + // Images + 'bmp', 'gif', 'jpeg', 'jpg', 'png', 'tif', 'tiff', 'pbm', 'pgm', 'ppm', 'ras', 'xbm', 'xpm', 'svg', 'svm', 'wmf', 'webp', + // StarOffice + 'sda', 'sdc', 'sdd', 'sdw', 'stc', 'std', 'sti', 'stw', 'sxd', 'sxg', 'sxi', 'sxw', + // Email formats + 'eml', + // Archive formats + 'zip', + // Other + 'dbf', 'fods', 'vsd', 'vor', 'vor3', 'vor4', 'uop', 'pct', 'ps', 'pdf', +]; + + diff --git a/frontend/src/contexts/ToolWorkflowContext.tsx b/frontend/src/contexts/ToolWorkflowContext.tsx index ac67b500c..72c3e4fc1 100644 --- a/frontend/src/contexts/ToolWorkflowContext.tsx +++ b/frontend/src/contexts/ToolWorkflowContext.tsx @@ -13,123 +13,18 @@ import { useNavigationUrlSync } from '../hooks/useUrlSync'; import { getDefaultWorkbench } from '../types/workbench'; import { filterToolRegistryByQuery } from '../utils/toolSearch'; import { useToolHistory } from '../hooks/tools/useToolHistory'; -import { FullscreenToolStyleSettings, defaultFullscreenToolSettings } from '../components/tools/FullscreenToolSettings'; +import { FullscreenToolStyleSettings } from '../components/tools/FullscreenToolSettings'; +import { + ToolWorkflowState, + TOOL_PANEL_MODE_STORAGE_KEY, + FULLSCREEN_TOOL_SETTINGS_STORAGE_KEY, + createInitialState, + toolWorkflowReducer, + ToolPanelMode, +} from './toolWorkflow/state'; // State interface -type ToolPanelMode = 'sidebar' | 'fullscreen'; - -interface ToolWorkflowState { - // UI State - sidebarsVisible: boolean; - leftPanelView: 'toolPicker' | 'toolContent' | 'hidden'; - readerMode: boolean; - toolPanelMode: ToolPanelMode; - fullscreenToolSettings: FullscreenToolStyleSettings; - - // File/Preview State - previewFile: File | null; - pageEditorFunctions: PageEditorFunctions | null; - - // Search State - searchQuery: string; -} - -// Actions -type ToolWorkflowAction = - | { type: 'SET_SIDEBARS_VISIBLE'; payload: boolean } - | { type: 'SET_LEFT_PANEL_VIEW'; payload: 'toolPicker' | 'toolContent' | 'hidden' } - | { type: 'SET_READER_MODE'; payload: boolean } - | { type: 'SET_TOOL_PANEL_MODE'; payload: ToolPanelMode } - | { type: 'SET_FULLSCREEN_TOOL_SETTINGS'; payload: FullscreenToolStyleSettings } - | { type: 'SET_PREVIEW_FILE'; payload: File | null } - | { type: 'SET_PAGE_EDITOR_FUNCTIONS'; payload: PageEditorFunctions | null } - | { type: 'SET_SEARCH_QUERY'; payload: string } - | { type: 'RESET_UI_STATE' }; - -// Initial state -export const TOOL_PANEL_MODE_STORAGE_KEY = 'toolPanelModePreference'; -export const FULLSCREEN_TOOL_SETTINGS_STORAGE_KEY = 'fullscreenToolStyleSettings'; -export const LEGACY_TOOL_SETTINGS_STORAGE_KEY = 'legacyToolStyleSettings'; - -const getStoredToolPanelMode = (): ToolPanelMode => { - if (typeof window === 'undefined') { - return 'sidebar'; - } - - const stored = window.localStorage.getItem(TOOL_PANEL_MODE_STORAGE_KEY); - if (stored === 'legacy' || stored === 'fullscreen') { - return 'fullscreen'; - } - - return 'sidebar'; -}; - -const getStoredFullscreenToolSettings = (): FullscreenToolStyleSettings => { - if (typeof window === 'undefined') { - return defaultFullscreenToolSettings; - } - - try { - const storedNew = window.localStorage.getItem(FULLSCREEN_TOOL_SETTINGS_STORAGE_KEY); - if (storedNew) { - return { ...defaultFullscreenToolSettings, ...JSON.parse(storedNew) }; - } - const storedLegacy = window.localStorage.getItem(LEGACY_TOOL_SETTINGS_STORAGE_KEY); - if (storedLegacy) { - return { ...defaultFullscreenToolSettings, ...JSON.parse(storedLegacy) }; - } - } catch (e) { - console.error('Failed to parse fullscreen tool settings:', e); - } - - return defaultFullscreenToolSettings; -}; - -const baseState: Omit = { - sidebarsVisible: true, - leftPanelView: 'toolPicker', - readerMode: false, - previewFile: null, - pageEditorFunctions: null, - searchQuery: '', -}; - -const createInitialState = (): ToolWorkflowState => ({ - ...baseState, - toolPanelMode: getStoredToolPanelMode(), - fullscreenToolSettings: getStoredFullscreenToolSettings(), -}); - -// Reducer -function toolWorkflowReducer(state: ToolWorkflowState, action: ToolWorkflowAction): ToolWorkflowState { - switch (action.type) { - case 'SET_SIDEBARS_VISIBLE': - return { ...state, sidebarsVisible: action.payload }; - case 'SET_LEFT_PANEL_VIEW': - return { ...state, leftPanelView: action.payload }; - case 'SET_READER_MODE': - return { ...state, readerMode: action.payload }; - case 'SET_TOOL_PANEL_MODE': - return { ...state, toolPanelMode: action.payload }; - case 'SET_FULLSCREEN_TOOL_SETTINGS': - return { ...state, fullscreenToolSettings: action.payload }; - case 'SET_PREVIEW_FILE': - return { ...state, previewFile: action.payload }; - case 'SET_PAGE_EDITOR_FUNCTIONS': - return { ...state, pageEditorFunctions: action.payload }; - case 'SET_SEARCH_QUERY': - return { ...state, searchQuery: action.payload }; - case 'RESET_UI_STATE': - return { - ...baseState, - toolPanelMode: state.toolPanelMode, - fullscreenToolSettings: state.fullscreenToolSettings, - searchQuery: state.searchQuery, - }; - default: - return state; - } -} +// Types and reducer/state moved to './toolWorkflow/state' // Context value interface interface ToolWorkflowContextValue extends ToolWorkflowState { @@ -266,7 +161,6 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) { const serialized = JSON.stringify(state.fullscreenToolSettings); window.localStorage.setItem(FULLSCREEN_TOOL_SETTINGS_STORAGE_KEY, serialized); - window.localStorage.setItem(LEGACY_TOOL_SETTINGS_STORAGE_KEY, serialized); }, [state.fullscreenToolSettings]); // Tool reset methods diff --git a/frontend/src/contexts/toolWorkflow/state.ts b/frontend/src/contexts/toolWorkflow/state.ts new file mode 100644 index 000000000..efc8d619a --- /dev/null +++ b/frontend/src/contexts/toolWorkflow/state.ts @@ -0,0 +1,114 @@ +import { FullscreenToolStyleSettings, defaultFullscreenToolSettings } from '../../components/tools/FullscreenToolSettings'; +import { PageEditorFunctions } from '../../types/pageEditor'; + +// State & Modes +export type ToolPanelMode = 'sidebar' | 'fullscreen'; + +export interface ToolWorkflowState { + // UI State + sidebarsVisible: boolean; + leftPanelView: 'toolPicker' | 'toolContent' | 'hidden'; + readerMode: boolean; + toolPanelMode: ToolPanelMode; + fullscreenToolSettings: FullscreenToolStyleSettings; + + // File/Preview State + previewFile: File | null; + pageEditorFunctions: PageEditorFunctions | null; + + // Search State + searchQuery: string; +} + +// Actions +export type ToolWorkflowAction = + | { type: 'SET_SIDEBARS_VISIBLE'; payload: boolean } + | { type: 'SET_LEFT_PANEL_VIEW'; payload: 'toolPicker' | 'toolContent' | 'hidden' } + | { type: 'SET_READER_MODE'; payload: boolean } + | { type: 'SET_TOOL_PANEL_MODE'; payload: ToolPanelMode } + | { type: 'SET_FULLSCREEN_TOOL_SETTINGS'; payload: FullscreenToolStyleSettings } + | { type: 'SET_PREVIEW_FILE'; payload: File | null } + | { type: 'SET_PAGE_EDITOR_FUNCTIONS'; payload: PageEditorFunctions | null } + | { type: 'SET_SEARCH_QUERY'; payload: string } + | { type: 'RESET_UI_STATE' }; + +// Storage keys +export const TOOL_PANEL_MODE_STORAGE_KEY = 'toolPanelModePreference'; +export const FULLSCREEN_TOOL_SETTINGS_STORAGE_KEY = 'fullscreenToolStyleSettings'; + +export const getStoredToolPanelMode = (): ToolPanelMode => { + if (typeof window === 'undefined') { + return 'sidebar'; + } + + const stored = window.localStorage.getItem(TOOL_PANEL_MODE_STORAGE_KEY); + if (stored === 'fullscreen') { + return 'fullscreen'; + } + + return 'sidebar'; +}; + +export const getStoredFullscreenToolSettings = (): FullscreenToolStyleSettings => { + if (typeof window === 'undefined') { + return defaultFullscreenToolSettings; + } + + try { + const storedNew = window.localStorage.getItem(FULLSCREEN_TOOL_SETTINGS_STORAGE_KEY); + if (storedNew) { + return { ...defaultFullscreenToolSettings, ...JSON.parse(storedNew) }; + } + } catch (e) { + console.error('Failed to parse fullscreen tool settings:', e); + } + + return defaultFullscreenToolSettings; +}; + +export const baseState: Omit = { + sidebarsVisible: true, + leftPanelView: 'toolPicker', + readerMode: false, + previewFile: null, + pageEditorFunctions: null, + searchQuery: '', +}; + +export const createInitialState = (): ToolWorkflowState => ({ + ...baseState, + toolPanelMode: getStoredToolPanelMode(), + fullscreenToolSettings: getStoredFullscreenToolSettings(), +}); + +export function toolWorkflowReducer(state: ToolWorkflowState, action: ToolWorkflowAction): ToolWorkflowState { + switch (action.type) { + case 'SET_SIDEBARS_VISIBLE': + return { ...state, sidebarsVisible: action.payload }; + case 'SET_LEFT_PANEL_VIEW': + return { ...state, leftPanelView: action.payload }; + case 'SET_READER_MODE': + return { ...state, readerMode: action.payload }; + case 'SET_TOOL_PANEL_MODE': + return { ...state, toolPanelMode: action.payload }; + case 'SET_FULLSCREEN_TOOL_SETTINGS': + return { ...state, fullscreenToolSettings: action.payload }; + case 'SET_PREVIEW_FILE': + return { ...state, previewFile: action.payload }; + case 'SET_PAGE_EDITOR_FUNCTIONS': + return { ...state, pageEditorFunctions: action.payload }; + case 'SET_SEARCH_QUERY': + return { ...state, searchQuery: action.payload }; + case 'RESET_UI_STATE': + return { + ...baseState, + toolPanelMode: state.toolPanelMode, + fullscreenToolSettings: state.fullscreenToolSettings, + searchQuery: state.searchQuery, + }; + default: + return state; + } +} + + diff --git a/frontend/src/data/useTranslatedToolRegistry.tsx b/frontend/src/data/useTranslatedToolRegistry.tsx index 745738566..603a928b7 100644 --- a/frontend/src/data/useTranslatedToolRegistry.tsx +++ b/frontend/src/data/useTranslatedToolRegistry.tsx @@ -109,85 +109,7 @@ import AddPageNumbersAutomationSettings from "../components/tools/addPageNumbers const showPlaceholderTools = true; // Show all tools; grey out unavailable ones in UI // Convert tool supported file formats -export const CONVERT_SUPPORTED_FORMATS = [ - // Microsoft Office - "doc", - "docx", - "dot", - "dotx", - "csv", - "xls", - "xlsx", - "xlt", - "xltx", - "slk", - "dif", - "ppt", - "pptx", - // OpenDocument - "odt", - "ott", - "ods", - "ots", - "odp", - "otp", - "odg", - "otg", - // Text formats - "txt", - "text", - "xml", - "rtf", - "html", - "lwp", - "md", - // Images - "bmp", - "gif", - "jpeg", - "jpg", - "png", - "tif", - "tiff", - "pbm", - "pgm", - "ppm", - "ras", - "xbm", - "xpm", - "svg", - "svm", - "wmf", - "webp", - // StarOffice - "sda", - "sdc", - "sdd", - "sdw", - "stc", - "std", - "sti", - "stw", - "sxd", - "sxg", - "sxi", - "sxw", - // Email formats - "eml", - // Archive formats - "zip", - // Other - "dbf", - "fods", - "vsd", - "vor", - "vor3", - "vor4", - "uop", - "pct", - "ps", - "pdf", -]; +import { CONVERT_SUPPORTED_FORMATS } from "../constants/convertSupportedFornats"; // Hook to get the translated tool registry export function useFlatToolRegistry(): ToolRegistry {