V2 reduce tool boilerplate (#4313)

# Description of Changes
Reduce boilerplate in tool frontends by creating a base frontend hook
for the simple tools to use.

I've done all the simple tools here. It'd be nice to add in some of the
more complex tools as well in the future if we can figure out how.
This commit is contained in:
James Brunton
2025-08-28 09:59:38 +00:00
committed by GitHub
parent e142af2863
commit 442b373ff4
10 changed files with 291 additions and 534 deletions
+17 -56
View File
@@ -1,78 +1,39 @@
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { useEndpointEnabled } from "../hooks/useEndpointConfig";
import { useFileContext } from "../contexts/FileContext";
import { useNavigationActions } from "../contexts/NavigationContext";
import { useFileSelection } from "../contexts/file/fileHooks";
import { createToolFlow } from "../components/tools/shared/createToolFlow";
import { useUnlockPdfFormsParameters } from "../hooks/tools/unlockPdfForms/useUnlockPdfFormsParameters";
import { useUnlockPdfFormsOperation } from "../hooks/tools/unlockPdfForms/useUnlockPdfFormsOperation";
import { useBaseTool } from "../hooks/tools/shared/useBaseTool";
import { BaseToolProps, ToolComponent } from "../types/tool";
const UnlockPdfForms = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => {
const UnlockPdfForms = (props: BaseToolProps) => {
const { t } = useTranslation();
const { actions } = useNavigationActions();
const { selectedFiles } = useFileSelection();
const unlockPdfFormsParams = useUnlockPdfFormsParameters();
const unlockPdfFormsOperation = useUnlockPdfFormsOperation();
// Endpoint validation
const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled(unlockPdfFormsParams.getEndpointName());
useEffect(() => {
unlockPdfFormsOperation.resetResults();
onPreviewFile?.(null);
}, [unlockPdfFormsParams.parameters]);
const handleUnlock = async () => {
try {
await unlockPdfFormsOperation.executeOperation(unlockPdfFormsParams.parameters, selectedFiles);
if (unlockPdfFormsOperation.files && onComplete) {
onComplete(unlockPdfFormsOperation.files);
}
} catch (error) {
if (onError) {
onError(error instanceof Error ? error.message : t("unlockPDFForms.error.failed", "Unlock PDF forms operation failed"));
}
}
};
const handleThumbnailClick = (file: File) => {
onPreviewFile?.(file);
sessionStorage.setItem("previousMode", "unlockPdfForms");
actions.setMode("viewer");
};
const handleSettingsReset = () => {
unlockPdfFormsOperation.resetResults();
onPreviewFile?.(null);
};
const hasFiles = selectedFiles.length > 0;
const hasResults = unlockPdfFormsOperation.files.length > 0 || unlockPdfFormsOperation.downloadUrl !== null;
const base = useBaseTool(
'unlockPdfForms',
useUnlockPdfFormsParameters,
useUnlockPdfFormsOperation,
props
);
return createToolFlow({
files: {
selectedFiles,
isCollapsed: hasFiles || hasResults,
selectedFiles: base.selectedFiles,
isCollapsed: base.hasFiles || base.hasResults,
placeholder: t("unlockPDFForms.files.placeholder", "Select a PDF file in the main view to get started"),
},
steps: [],
executeButton: {
text: t("unlockPDFForms.submit", "Unlock Forms"),
isVisible: !hasResults,
isVisible: !base.hasResults,
loadingText: t("loading"),
onClick: handleUnlock,
disabled: !unlockPdfFormsParams.validateParameters() || !hasFiles || !endpointEnabled,
onClick: base.handleExecute,
disabled: !base.params.validateParameters() || !base.hasFiles || !base.endpointEnabled,
},
review: {
isVisible: hasResults,
operation: unlockPdfFormsOperation,
isVisible: base.hasResults,
operation: base.operation,
title: t("unlockPDFForms.results.title", "Unlocked Forms Results"),
onFileClick: handleThumbnailClick,
onFileClick: base.handleThumbnailClick,
},
});
};
@@ -80,4 +41,4 @@ const UnlockPdfForms = ({ onPreviewFile, onComplete, onError }: BaseToolProps) =
// Static method to get the operation hook for automation
UnlockPdfForms.tool = () => useUnlockPdfFormsOperation;
export default UnlockPdfForms as ToolComponent;
export default UnlockPdfForms as ToolComponent;