mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-26 14:19:24 +00:00
merge headache
This commit is contained in:
parent
14f6cf76e2
commit
b2822c1d43
@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { Button, Text, Stack, Group, Card, Progress } from "@mantine/core";
|
import { Button, Text, Stack, Group, Card, Progress } from "@mantine/core";
|
||||||
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
|
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
|
||||||
import CheckIcon from "@mui/icons-material/Check";
|
import CheckIcon from "@mui/icons-material/Check";
|
||||||
import { useFileSelection } from "../../../contexts/FileSelectionContext";
|
import { useFileSelection } from "../../../contexts/FileContext";
|
||||||
import { useFlatToolRegistry } from "../../../data/useTranslatedToolRegistry";
|
import { useFlatToolRegistry } from "../../../data/useTranslatedToolRegistry";
|
||||||
|
|
||||||
interface AutomationRunProps {
|
interface AutomationRunProps {
|
||||||
|
@ -1,15 +1,22 @@
|
|||||||
import React from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { Stack, Text, Divider, Card, Group } from '@mantine/core';
|
import { Stack, Text, Divider, Card, Group } from '@mantine/core';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useSuggestedTools } from '../../../hooks/useSuggestedTools';
|
import { useSuggestedTools } from '../../../hooks/useSuggestedTools';
|
||||||
import { useToolNavigation } from '../../../contexts/ToolNavigationContext';
|
import { useNavigationActions, useNavigationState, type ModeType } from '../../../contexts/NavigationContext';
|
||||||
|
|
||||||
export interface SuggestedToolsSectionProps {}
|
export interface SuggestedToolsSectionProps {}
|
||||||
|
|
||||||
export function SuggestedToolsSection(): React.ReactElement {
|
export function SuggestedToolsSection(): React.ReactElement {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { handleToolSelect, selectedToolKey } = useToolNavigation();
|
const { actions } = useNavigationActions();
|
||||||
const suggestedTools = useSuggestedTools(selectedToolKey, handleToolSelect);
|
const { currentMode } = useNavigationState();
|
||||||
|
|
||||||
|
// Create handleToolSelect function that navigates to the tool
|
||||||
|
const handleToolSelect = useCallback((toolId: string) => {
|
||||||
|
actions.setMode(toolId as ModeType);
|
||||||
|
}, [actions]);
|
||||||
|
|
||||||
|
const suggestedTools = useSuggestedTools(currentMode, handleToolSelect);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap="md">
|
<Stack gap="md">
|
||||||
|
@ -1,85 +1,85 @@
|
|||||||
/**
|
// /**
|
||||||
* ToolNavigationContext - Handles tool selection and navigation without tool registry
|
// * ToolNavigationContext - Handles tool selection and navigation without tool registry
|
||||||
* This breaks the circular dependency by not importing the tool registry
|
// * This breaks the circular dependency by not importing the tool registry
|
||||||
*/
|
// */
|
||||||
|
|
||||||
import React, { createContext, useContext, useState, useCallback } from 'react';
|
// import React, { createContext, useContext, useState, useCallback } from 'react';
|
||||||
import { useFileContext } from './FileContext';
|
// import { useFileContext } from './FileContext';
|
||||||
|
|
||||||
// Navigation state interface
|
// // Navigation state interface
|
||||||
interface ToolNavigationState {
|
// interface ToolNavigationState {
|
||||||
selectedToolKey: string | null;
|
// selectedToolKey: string | null;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Context value interface
|
// // Context value interface
|
||||||
interface ToolNavigationContextValue extends ToolNavigationState {
|
// interface ToolNavigationContextValue extends ToolNavigationState {
|
||||||
// Navigation Actions
|
// // Navigation Actions
|
||||||
selectTool: (toolKey: string) => void;
|
// selectTool: (toolKey: string) => void;
|
||||||
clearToolSelection: () => void;
|
// clearToolSelection: () => void;
|
||||||
handleToolSelect: (toolId: string) => void;
|
// handleToolSelect: (toolId: string) => void;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const ToolNavigationContext = createContext<ToolNavigationContextValue | undefined>(undefined);
|
// const ToolNavigationContext = createContext<ToolNavigationContextValue | undefined>(undefined);
|
||||||
|
|
||||||
// Provider component
|
// // Provider component
|
||||||
interface ToolNavigationProviderProps {
|
// interface ToolNavigationProviderProps {
|
||||||
children: React.ReactNode;
|
// children: React.ReactNode;
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function ToolNavigationProvider({ children }: ToolNavigationProviderProps) {
|
// export function ToolNavigationProvider({ children }: ToolNavigationProviderProps) {
|
||||||
const [selectedToolKey, setSelectedToolKey] = useState<string | null>(null);
|
// const [selectedToolKey, setSelectedToolKey] = useState<string | null>(null);
|
||||||
const { setCurrentView } = useFileContext();
|
// const { setCurrentView } = useFileContext();
|
||||||
|
|
||||||
const selectTool = useCallback((toolKey: string) => {
|
// const selectTool = useCallback((toolKey: string) => {
|
||||||
setSelectedToolKey(toolKey);
|
// setSelectedToolKey(toolKey);
|
||||||
}, []);
|
// }, []);
|
||||||
|
|
||||||
const clearToolSelection = useCallback(() => {
|
// const clearToolSelection = useCallback(() => {
|
||||||
setSelectedToolKey(null);
|
// setSelectedToolKey(null);
|
||||||
}, []);
|
// }, []);
|
||||||
|
|
||||||
const handleToolSelect = useCallback((toolId: string) => {
|
// const handleToolSelect = useCallback((toolId: string) => {
|
||||||
// Handle special cases
|
// // Handle special cases
|
||||||
if (toolId === 'allTools') {
|
// if (toolId === 'allTools') {
|
||||||
clearToolSelection();
|
// clearToolSelection();
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
selectTool(toolId);
|
// selectTool(toolId);
|
||||||
setCurrentView('fileEditor');
|
// setCurrentView('fileEditor');
|
||||||
}, [selectTool, setCurrentView, clearToolSelection]);
|
// }, [selectTool, setCurrentView, clearToolSelection]);
|
||||||
|
|
||||||
const contextValue: ToolNavigationContextValue = {
|
// const contextValue: ToolNavigationContextValue = {
|
||||||
selectedToolKey,
|
// selectedToolKey,
|
||||||
selectTool,
|
// selectTool,
|
||||||
clearToolSelection,
|
// clearToolSelection,
|
||||||
handleToolSelect
|
// handleToolSelect
|
||||||
};
|
// };
|
||||||
|
|
||||||
return (
|
// return (
|
||||||
<ToolNavigationContext.Provider value={contextValue}>
|
// <ToolNavigationContext.Provider value={contextValue}>
|
||||||
{children}
|
// {children}
|
||||||
</ToolNavigationContext.Provider>
|
// </ToolNavigationContext.Provider>
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Custom hook to use the context
|
// // Custom hook to use the context
|
||||||
export function useToolNavigation(): ToolNavigationContextValue {
|
// export function useToolNavigation(): ToolNavigationContextValue {
|
||||||
const context = useContext(ToolNavigationContext);
|
// const context = useContext(ToolNavigationContext);
|
||||||
if (!context) {
|
// if (!context) {
|
||||||
// During development hot reload, temporarily return a safe fallback
|
// // During development hot reload, temporarily return a safe fallback
|
||||||
if (process.env.NODE_ENV === 'development') {
|
// if (process.env.NODE_ENV === 'development') {
|
||||||
console.warn('ToolNavigationContext temporarily unavailable during hot reload, using fallback');
|
// console.warn('ToolNavigationContext temporarily unavailable during hot reload, using fallback');
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
selectedToolKey: null,
|
// selectedToolKey: null,
|
||||||
selectTool: () => {},
|
// selectTool: () => {},
|
||||||
clearToolSelection: () => {},
|
// clearToolSelection: () => {},
|
||||||
handleToolSelect: () => {}
|
// handleToolSelect: () => {}
|
||||||
} as ToolNavigationContextValue;
|
// } as ToolNavigationContextValue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
throw new Error('useToolNavigation must be used within a ToolNavigationProvider');
|
// throw new Error('useToolNavigation must be used within a ToolNavigationProvider');
|
||||||
}
|
// }
|
||||||
return context;
|
// return context;
|
||||||
}
|
// }
|
||||||
|
@ -26,7 +26,7 @@ import { ToolOperationConfig, ToolOperationHook, useToolOperation } from '../sha
|
|||||||
describe('useAddPasswordOperation', () => {
|
describe('useAddPasswordOperation', () => {
|
||||||
const mockUseToolOperation = vi.mocked(useToolOperation);
|
const mockUseToolOperation = vi.mocked(useToolOperation);
|
||||||
|
|
||||||
const getToolConfig = (): ToolOperationConfig<AddPasswordFullParameters> => mockUseToolOperation.mock.calls[0][0];
|
const getToolConfig = (): ToolOperationConfig<AddPasswordFullParameters> => mockUseToolOperation.mock.calls[0][0] as ToolOperationConfig<AddPasswordFullParameters>;
|
||||||
|
|
||||||
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
||||||
files: [],
|
files: [],
|
||||||
|
@ -25,7 +25,7 @@ import { ToolOperationConfig, ToolOperationHook, useToolOperation } from '../sha
|
|||||||
describe('useChangePermissionsOperation', () => {
|
describe('useChangePermissionsOperation', () => {
|
||||||
const mockUseToolOperation = vi.mocked(useToolOperation);
|
const mockUseToolOperation = vi.mocked(useToolOperation);
|
||||||
|
|
||||||
const getToolConfig = (): ToolOperationConfig<ChangePermissionsParameters> => mockUseToolOperation.mock.calls[0][0];
|
const getToolConfig = (): ToolOperationConfig<ChangePermissionsParameters> => mockUseToolOperation.mock.calls[0][0] as ToolOperationConfig<ChangePermissionsParameters>;
|
||||||
|
|
||||||
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
||||||
files: [],
|
files: [],
|
||||||
|
@ -53,7 +53,7 @@ export const buildOCRFormData = (parameters: OCRParameters, file: File): FormDat
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Static response handler for OCR - can be used by automation executor
|
// Static response handler for OCR - can be used by automation executor
|
||||||
export const ocrResponseHandler = async (blob: Blob, originalFiles: File[], extractZipFiles: (blob: Blob) => Promise<{ success: boolean; extractedFiles: File[]; errors: string[] }>): Promise<File[]> => {
|
export const ocrResponseHandler = async (blob: Blob, originalFiles: File[], extractZipFiles: (blob: Blob) => Promise<File[]>): Promise<File[]> => {
|
||||||
const headBuf = await blob.slice(0, 8).arrayBuffer();
|
const headBuf = await blob.slice(0, 8).arrayBuffer();
|
||||||
const head = new TextDecoder().decode(new Uint8Array(headBuf));
|
const head = new TextDecoder().decode(new Uint8Array(headBuf));
|
||||||
|
|
||||||
@ -61,8 +61,8 @@ export const ocrResponseHandler = async (blob: Blob, originalFiles: File[], extr
|
|||||||
if (head.startsWith('PK')) {
|
if (head.startsWith('PK')) {
|
||||||
const base = stripExt(originalFiles[0].name);
|
const base = stripExt(originalFiles[0].name);
|
||||||
try {
|
try {
|
||||||
const result = await extractZipFiles(blob);
|
const extractedFiles = await extractZipFiles(blob);
|
||||||
if (result.success && result.extractedFiles.length > 0) return result.extractedFiles;
|
if (extractedFiles.length > 0) return extractedFiles;
|
||||||
} catch { /* ignore and try local extractor */ }
|
} catch { /* ignore and try local extractor */ }
|
||||||
try {
|
try {
|
||||||
const local = await extractZipFile(blob); // local fallback
|
const local = await extractZipFile(blob); // local fallback
|
||||||
@ -108,7 +108,9 @@ export const useOCROperation = () => {
|
|||||||
|
|
||||||
// OCR-specific parsing: ZIP (sidecar) vs PDF vs HTML error
|
// OCR-specific parsing: ZIP (sidecar) vs PDF vs HTML error
|
||||||
const responseHandler = useCallback(async (blob: Blob, originalFiles: File[]): Promise<File[]> => {
|
const responseHandler = useCallback(async (blob: Blob, originalFiles: File[]): Promise<File[]> => {
|
||||||
return ocrResponseHandler(blob, originalFiles, extractZipFiles);
|
// extractZipFiles from useToolResources already returns File[] directly
|
||||||
|
const simpleExtractZipFiles = extractZipFiles;
|
||||||
|
return ocrResponseHandler(blob, originalFiles, simpleExtractZipFiles);
|
||||||
}, [extractZipFiles]);
|
}, [extractZipFiles]);
|
||||||
|
|
||||||
const ocrConfig: ToolOperationConfig<OCRParameters> = {
|
const ocrConfig: ToolOperationConfig<OCRParameters> = {
|
||||||
|
@ -25,7 +25,7 @@ import { ToolOperationConfig, ToolOperationHook, useToolOperation } from '../sha
|
|||||||
describe('useRemovePasswordOperation', () => {
|
describe('useRemovePasswordOperation', () => {
|
||||||
const mockUseToolOperation = vi.mocked(useToolOperation);
|
const mockUseToolOperation = vi.mocked(useToolOperation);
|
||||||
|
|
||||||
const getToolConfig = (): ToolOperationConfig<RemovePasswordParameters> => mockUseToolOperation.mock.calls[0][0];
|
const getToolConfig = (): ToolOperationConfig<RemovePasswordParameters> => mockUseToolOperation.mock.calls[0][0] as ToolOperationConfig<RemovePasswordParameters>;
|
||||||
|
|
||||||
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
const mockToolOperationReturn: ToolOperationHook<unknown> = {
|
||||||
files: [],
|
files: [],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useFileContext } from "../contexts/FileContext";
|
import { useFileContext } from "../contexts/FileContext";
|
||||||
import { useToolFileSelection } from "../contexts/FileSelectionContext";
|
import { useFileSelection } from "../contexts/FileContext";
|
||||||
|
|
||||||
import { createToolFlow } from "../components/tools/shared/createToolFlow";
|
import { createToolFlow } from "../components/tools/shared/createToolFlow";
|
||||||
import { createFilesToolStep } from "../components/tools/shared/FilesToolStep";
|
import { createFilesToolStep } from "../components/tools/shared/FilesToolStep";
|
||||||
@ -16,8 +16,7 @@ import { useSavedAutomations } from "../hooks/tools/automate/useSavedAutomations
|
|||||||
|
|
||||||
const Automate = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => {
|
const Automate = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { setCurrentMode } = useFileContext();
|
const { selectedFiles } = useFileSelection();
|
||||||
const { selectedFiles } = useToolFileSelection();
|
|
||||||
|
|
||||||
const [currentStep, setCurrentStep] = useState<'selection' | 'creation' | 'run'>('selection');
|
const [currentStep, setCurrentStep] = useState<'selection' | 'creation' | 'run'>('selection');
|
||||||
const [stepData, setStepData] = useState<any>({});
|
const [stepData, setStepData] = useState<any>({});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user