diff --git a/.vscode/settings.json b/.vscode/settings.json index 5b8f77bbc..7c231b4ef 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -139,5 +139,8 @@ "app/core/src/main/java", "app/common/src/main/java", "app/proprietary/src/main/java" - ] + ], + "[typescript]": { + "editor.defaultFormatter": "vscode.typescript-language-features" + } } diff --git a/frontend/src/hooks/tools/autoRename/useAutoRenameOperation.ts b/frontend/src/hooks/tools/autoRename/useAutoRenameOperation.ts index a8910af84..e0d868a7d 100644 --- a/frontend/src/hooks/tools/autoRename/useAutoRenameOperation.ts +++ b/frontend/src/hooks/tools/autoRename/useAutoRenameOperation.ts @@ -1,25 +1,43 @@ import { useTranslation } from 'react-i18next'; -import { useToolOperation } from '../shared/useToolOperation'; +import { ToolType, useToolOperation } from '../shared/useToolOperation'; import { createStandardErrorHandler } from '../../../utils/toolErrorHandler'; -import { AutoRenameParameters } from './useAutoRenameParameters'; +import { AutoRenameParameters, defaultParameters } from './useAutoRenameParameters'; + +export const getFormData = ((parameters: AutoRenameParameters) => + Object.entries(parameters).map(([key, value]) => + [key, value.toString()] + ) as string[][] +); + +// Static function that can be used by both the hook and automation executor +export const buildAutoRenameFormData = (parameters: AutoRenameParameters, file: File): FormData => { + const formData = new FormData(); + formData.append("fileInput", file); + + // Add all permission parameters + getFormData(parameters).forEach(([key, value]) => { + formData.append(key, value); + }); + + return formData; +}; + +// Static configuration object +export const autoRenameOperationConfig = { + toolType: ToolType.singleFile, + buildFormData: buildAutoRenameFormData, + operationType: 'autoRename', + endpoint: '/api/v1/misc/auto-rename', + filePrefix: 'autoRename_', + preserveBackendFilename: true, // Use filename from backend response headers + defaultParameters, +} as const; export const useAutoRenameOperation = () => { const { t } = useTranslation(); - const buildFormData = (parameters: AutoRenameParameters, file: File): FormData => { - const formData = new FormData(); - formData.append("fileInput", file); - formData.append("useFirstTextAsFallback", parameters.useFirstTextAsFallback.toString()); - return formData; - }; - - return useToolOperation({ - operationType: 'autoRename', - endpoint: '/api/v1/misc/auto-rename', - buildFormData, - filePrefix: '', // Not used when preserveBackendFilename is true - multiFileEndpoint: false, - preserveBackendFilename: true, // Use filename from backend response headers + return useToolOperation({ + ...autoRenameOperationConfig, getErrorMessage: createStandardErrorHandler(t('auto-rename.error.failed', 'An error occurred while auto-renaming the PDF.')) }); -}; \ No newline at end of file +}; diff --git a/frontend/src/hooks/tools/shared/useToolOperation.ts b/frontend/src/hooks/tools/shared/useToolOperation.ts index 4558de07d..6d696b6ca 100644 --- a/frontend/src/hooks/tools/shared/useToolOperation.ts +++ b/frontend/src/hooks/tools/shared/useToolOperation.ts @@ -178,7 +178,8 @@ export const useToolOperation = ( endpoint: config.endpoint, buildFormData: config.buildFormData, filePrefix: config.filePrefix, - responseHandler: config.responseHandler + responseHandler: config.responseHandler, + preserveBackendFilename: config.preserveBackendFilename }; processedFiles = await processFiles( params, diff --git a/frontend/src/tools/AutoRename.tsx b/frontend/src/tools/AutoRename.tsx index 3a60e4d73..b8a46af2c 100644 --- a/frontend/src/tools/AutoRename.tsx +++ b/frontend/src/tools/AutoRename.tsx @@ -1,80 +1,43 @@ -import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; -import { useEndpointEnabled } from "../hooks/useEndpointConfig"; -import { useFileContext } from "../contexts/FileContext"; -import { useToolFileSelection } from "../contexts/FileSelectionContext"; - import { createToolFlow } from "../components/tools/shared/createToolFlow"; +import { useBaseTool } from "../hooks/tools/shared/useBaseTool"; +import { BaseToolProps, ToolComponent } from "../types/tool"; import { useAutoRenameParameters } from "../hooks/tools/autoRename/useAutoRenameParameters"; import { useAutoRenameOperation } from "../hooks/tools/autoRename/useAutoRenameOperation"; -import { BaseToolProps } from "../types/tool"; +import { useAutoRenameTips } from "../components/tooltips/useAutoRenameTips"; -const AutoRename = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => { +const AutoRename =(props: BaseToolProps) => { const { t } = useTranslation(); - const { setCurrentMode } = useFileContext(); - const { selectedFiles } = useToolFileSelection(); - const autoRenameParams = useAutoRenameParameters(); - const autoRenameOperation = useAutoRenameOperation(); + const base = useBaseTool( + '"auto-rename-pdf-file', + useAutoRenameParameters, + useAutoRenameOperation, + props + ); - // Endpoint validation - const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled(autoRenameParams.getEndpointName()); - - useEffect(() => { - autoRenameOperation.resetResults(); - onPreviewFile?.(null); - }, [autoRenameParams.parameters]); - - const handleAutoRename = async () => { - try { - await autoRenameOperation.executeOperation(autoRenameParams.parameters, selectedFiles); - if (autoRenameOperation.files && onComplete) { - onComplete(autoRenameOperation.files); - } - } catch (error) { - if (onError) { - onError(error instanceof Error ? error.message : t("auto-rename.error.failed", "Auto-rename operation failed")); - } - } - }; - - const handleThumbnailClick = (file: File) => { - onPreviewFile?.(file); - sessionStorage.setItem("previousMode", "auto-rename-pdf-file"); - setCurrentMode("viewer"); - }; - - const handleSettingsReset = () => { - autoRenameOperation.resetResults(); - onPreviewFile?.(null); - setCurrentMode("auto-rename-pdf-file"); - }; - - const hasFiles = selectedFiles.length > 0; - const hasResults = autoRenameOperation.files.length > 0 || autoRenameOperation.downloadUrl !== null; - - return createToolFlow({ +return createToolFlow({ + title: { title:t("auto-rename.title", "Auto Rename PDF"), tooltip: useAutoRenameTips()}, files: { - selectedFiles, - isCollapsed: hasFiles || hasResults, - placeholder: t("auto-rename.files.placeholder", "Select a PDF file in the main view to get started"), + selectedFiles: base.selectedFiles, + isCollapsed: base.hasResults, }, steps: [], executeButton: { text: t("auto-rename.submit", "Auto Rename"), - isVisible: !hasResults, + isVisible: !base.hasResults, loadingText: t("loading"), - onClick: handleAutoRename, - disabled: !autoRenameParams.validateParameters() || !hasFiles || !endpointEnabled, + onClick: base.handleExecute, + disabled: !base.params.validateParameters() || !base.hasFiles || !base.endpointEnabled, }, review: { - isVisible: hasResults, - operation: autoRenameOperation, + isVisible: base.hasResults, + operation: base.operation, title: t("auto-rename.results.title", "Auto-Rename Results"), - onFileClick: handleThumbnailClick, + onFileClick: base.handleThumbnailClick, }, }); }; -export default AutoRename; \ No newline at end of file +export default AutoRename;