Files
Stirling-PDF/frontend/src/hooks/tools/shared/useBaseTool.ts
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

142 lines
4.0 KiB
TypeScript
Raw Normal View History

2025-09-18 11:04:12 +01:00
import { useEffect, useCallback, useRef } from 'react';
2025-08-28 10:59:38 +01:00
import { useFileSelection } from '../../../contexts/FileContext';
import { useEndpointEnabled } from '../../useEndpointConfig';
import { BaseToolProps } from '../../../types/tool';
import { ToolOperationHook } from './useToolOperation';
import { BaseParametersHook } from './useBaseParameters';
import { StirlingFile } from '../../../types/fileContext';
2025-08-28 10:59:38 +01:00
2025-09-15 14:28:18 +01:00
interface BaseToolReturn<TParams, TParamsHook extends BaseParametersHook<TParams>> {
2025-08-28 10:59:38 +01:00
// File management
selectedFiles: StirlingFile[];
2025-08-28 10:59:38 +01:00
// Tool-specific hooks
2025-09-15 14:28:18 +01:00
params: TParamsHook;
2025-08-28 10:59:38 +01:00
operation: ToolOperationHook<TParams>;
// Endpoint validation
endpointEnabled: boolean | null;
endpointLoading: boolean;
// Standard handlers
handleExecute: () => Promise<void>;
handleThumbnailClick: (file: File) => void;
handleSettingsReset: () => void;
handleUndo: () => Promise<void>;
2025-08-28 10:59:38 +01:00
// Standard computed state
hasFiles: boolean;
hasResults: boolean;
settingsCollapsed: boolean;
}
/**
* Base tool hook for tool components. Manages standard behaviour for tools.
*/
2025-09-15 14:28:18 +01:00
export function useBaseTool<TParams, TParamsHook extends BaseParametersHook<TParams>>(
2025-08-28 10:59:38 +01:00
toolName: string,
2025-09-15 14:28:18 +01:00
useParams: () => TParamsHook,
2025-08-28 10:59:38 +01:00
useOperation: () => ToolOperationHook<TParams>,
props: BaseToolProps,
2025-09-10 14:06:23 +01:00
options?: { minFiles?: number }
2025-09-15 14:28:18 +01:00
): BaseToolReturn<TParams, TParamsHook> {
2025-09-10 14:06:23 +01:00
const minFiles = options?.minFiles ?? 1;
2025-08-28 10:59:38 +01:00
const { onPreviewFile, onComplete, onError } = props;
// File selection
const { selectedFiles } = useFileSelection();
2025-09-18 11:04:12 +01:00
const previousFileCount = useRef(selectedFiles.length);
2025-08-28 10:59:38 +01:00
// Tool-specific hooks
const params = useParams();
const operation = useOperation();
// Endpoint validation using parameters hook
const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled(params.getEndpointName());
// Reset results when parameters change
useEffect(() => {
operation.resetResults();
onPreviewFile?.(null);
}, [params.parameters]);
// Reset results when selected files change
useEffect(() => {
if (selectedFiles.length > 0) {
operation.resetResults();
onPreviewFile?.(null);
}
}, [selectedFiles.length]);
2025-09-18 11:04:12 +01:00
// Reset parameters when transitioning from 0 files to at least 1 file
useEffect(() => {
const currentFileCount = selectedFiles.length;
const prevFileCount = previousFileCount.current;
if (prevFileCount === 0 && currentFileCount > 0) {
params.resetParameters();
}
previousFileCount.current = currentFileCount;
}, [selectedFiles.length]);
2025-08-28 10:59:38 +01:00
// Standard handlers
const handleExecute = useCallback(async () => {
try {
await operation.executeOperation(params.parameters, selectedFiles);
if (operation.files && onComplete) {
onComplete(operation.files);
}
} catch (error) {
if (onError) {
const message = error instanceof Error ? error.message : `${toolName} operation failed`;
onError(message);
}
}
}, [operation, params.parameters, selectedFiles, onComplete, onError, toolName]);
const handleThumbnailClick = useCallback((file: File) => {
onPreviewFile?.(file);
sessionStorage.setItem('previousMode', toolName);
}, [onPreviewFile, toolName]);
const handleSettingsReset = useCallback(() => {
operation.resetResults();
onPreviewFile?.(null);
}, [operation, onPreviewFile]);
const handleUndo = useCallback(async () => {
await operation.undoOperation();
onPreviewFile?.(null);
}, [operation, onPreviewFile]);
2025-08-28 10:59:38 +01:00
// Standard computed state
2025-09-10 14:06:23 +01:00
const hasFiles = selectedFiles.length >= minFiles;
2025-08-28 10:59:38 +01:00
const hasResults = operation.files.length > 0 || operation.downloadUrl !== null;
const settingsCollapsed = !hasFiles || hasResults;
return {
// File management
selectedFiles,
// Tool-specific hooks
params,
operation,
// Endpoint validation
endpointEnabled,
endpointLoading,
// Handlers
handleExecute,
handleThumbnailClick,
handleSettingsReset,
handleUndo,
2025-08-28 10:59:38 +01:00
// State
hasFiles,
hasResults,
settingsCollapsed
};
}