diff --git a/frontend/public/locales/en-US/translation.json b/frontend/public/locales/en-US/translation.json index c15def8cc..5ff617c9e 100644 --- a/frontend/public/locales/en-US/translation.json +++ b/frontend/public/locales/en-US/translation.json @@ -2110,13 +2110,24 @@ "automation": { "suggested": { "securePdfIngestion": "Secure PDF Ingestion", - "securePdfIngestionDesc": "Sanitise → OCR/Cleanup → PDF/A → Compress", + "securePdfIngestionDesc": "Comprehensive PDF processing workflow that sanitizes documents, applies OCR with cleanup, converts to PDF/A format for long-term archival, and optimizes file size.", "emailPreparation": "Email Preparation", - "emailPreparationDesc": "Compress → Split by Size 20MB → Sanitize metadata", + "emailPreparationDesc": "Optimizes PDFs for email distribution by compressing files, splitting large documents into 20MB chunks for email compatibility, and removing metadata for privacy.", "secureWorkflow": "Security Workflow", - "secureWorkflowDesc": "Sanitize PDFs and add password protection", - "optimizationWorkflow": "Optimization Workflow", - "optimizationWorkflowDesc": "Repair and compress PDFs for better performance" + "secureWorkflowDesc": "Secures PDF documents by removing potentially malicious content like JavaScript and embedded files, then adds password protection to prevent unauthorized access.", + "processImages": "Process Images", + "processImagesDesc": "Converts multiple image files into a single PDF document, then applies OCR technology to extract searchable text from the images." + }, + "operation": { + "sanitize": "Sanitize", + "ocrCleanup": "OCR & Cleanup", + "pdfaConversion": "PDF/A Conversion", + "compress": "Compress", + "splitBySize": "Split by Size (20MB)", + "sanitizeMetadata": "Remove Metadata", + "addPassword": "Add Password Protection", + "imageToPdf": "Image to PDF", + "ocr": "OCR Text Extraction" } }, "automate": { diff --git a/frontend/src/components/tools/automate/AutomationEntry.tsx b/frontend/src/components/tools/automate/AutomationEntry.tsx index 54295c0c6..5e050db1a 100644 --- a/frontend/src/components/tools/automate/AutomationEntry.tsx +++ b/frontend/src/components/tools/automate/AutomationEntry.tsx @@ -5,14 +5,17 @@ import MoreVertIcon from '@mui/icons-material/MoreVert'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import ContentCopyIcon from '@mui/icons-material/ContentCopy'; +import { Tooltip } from '../../shared/Tooltip'; interface AutomationEntryProps { /** Optional title for the automation (usually for custom ones) */ title?: string; + /** Optional description for tooltip */ + description?: string; /** MUI Icon component for the badge */ badgeIcon?: React.ComponentType; - /** Array of tool operation names in the workflow */ - operations: string[]; + /** Array of tool operation names in the workflow OR full operation objects with display names */ + operations: string[] | Array<{operation: string; displayName?: string}>; /** Click handler */ onClick: () => void; /** Whether to keep the icon at normal color (for special cases like "Add New") */ @@ -29,6 +32,7 @@ interface AutomationEntryProps { export default function AutomationEntry({ title, + description, badgeIcon: BadgeIcon, operations, onClick, @@ -45,6 +49,53 @@ export default function AutomationEntry({ // Keep item in hovered state if menu is open const shouldShowHovered = isHovered || isMenuOpen; + // Create tooltip content with description and tool chain + const createTooltipContent = () => { + if (!description) return null; + + const toolChain = operations.map((op, index) => { + // Handle both string[] and operation object arrays + const operationName = typeof op === 'string' ? op : op.operation; + const displayName = typeof op === 'object' && op.displayName ? op.displayName : t(`${operationName}.title`, operationName); + + return ( + + + {displayName} + + {index < operations.length - 1 && ( + + → + + )} + + ); + }); + + return ( +
+ + {description} + +
+ {toolChain} +
+
+ ); + }; + const renderContent = () => { if (title) { // Custom automation with title @@ -74,26 +125,32 @@ export default function AutomationEntry({ /> )} - {operations.map((op, index) => ( - - - {t(`${op}.title`, op)} - - - {index < operations.length - 1 && ( - - → + {operations.map((op, index) => { + // Handle both string[] and operation object arrays + const operationName = typeof op === 'string' ? op : op.operation; + const displayName = typeof op === 'object' && op.displayName ? op.displayName : t(`${operationName}.title`, operationName); + + return ( + + + {displayName} - )} - - ))} + + {index < operations.length - 1 && ( + + → + + )} + + ); + })} ); } }; - return ( + const boxContent = ( ); + + // Only show tooltip if description exists, otherwise return plain content + return description ? ( + + {boxContent} + + ) : ( + boxContent + ); } diff --git a/frontend/src/components/tools/automate/AutomationSelection.tsx b/frontend/src/components/tools/automate/AutomationSelection.tsx index 326ac3fe1..4c535be6d 100644 --- a/frontend/src/components/tools/automate/AutomationSelection.tsx +++ b/frontend/src/components/tools/automate/AutomationSelection.tsx @@ -66,8 +66,9 @@ export default function AutomationSelection({ op.operation)} + operations={automation.operations} onClick={() => onRun(automation)} showMenu={true} onCopy={() => onCopyFromSuggested(automation)} diff --git a/frontend/src/hooks/tools/automate/useSuggestedAutomations.ts b/frontend/src/hooks/tools/automate/useSuggestedAutomations.ts index fd9b7eaec..09caea51c 100644 --- a/frontend/src/hooks/tools/automate/useSuggestedAutomations.ts +++ b/frontend/src/hooks/tools/automate/useSuggestedAutomations.ts @@ -19,10 +19,11 @@ export function useSuggestedAutomations(): SuggestedAutomation[] { { id: "secure-pdf-ingestion", name: t("automation.suggested.securePdfIngestion", "Secure PDF Ingestion"), - description: t("automation.suggested.securePdfIngestionDesc", "Sanitise → OCR/Cleanup → PDF/A → Compress"), + description: t("automation.suggested.securePdfIngestionDesc", "Comprehensive PDF processing workflow that sanitizes documents, applies OCR with cleanup, converts to PDF/A format for long-term archival, and optimizes file size."), operations: [ { operation: "sanitize", + displayName: t("automation.operation.sanitize", "Sanitize"), parameters: { removeJavaScript: true, removeEmbeddedFiles: true, @@ -34,6 +35,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] { }, { operation: "ocr", + displayName: t("automation.operation.ocrCleanup", "OCR & Cleanup"), parameters: { languages: ['eng'], ocrType: 'skip-text', @@ -43,6 +45,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] { }, { operation: "convert", + displayName: t("automation.operation.pdfaConversion", "PDF/A Conversion"), parameters: { fromExtension: 'pdf', toExtension: 'pdfa', @@ -53,6 +56,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] { }, { operation: "compress", + displayName: t("automation.operation.compress", "Compress"), parameters: { compressionLevel: 5, grayscale: false, @@ -70,10 +74,11 @@ export function useSuggestedAutomations(): SuggestedAutomation[] { { id: "email-preparation", name: t("automation.suggested.emailPreparation", "Email Preparation"), - description: t("automation.suggested.emailPreparationDesc", "Compress → Split by Size 20MB → Sanitize metadata"), + description: t("automation.suggested.emailPreparationDesc", "Optimizes PDFs for email distribution by compressing files, splitting large documents into 20MB chunks for email compatibility, and removing metadata for privacy."), operations: [ { operation: "compress", + displayName: t("automation.operation.compress", "Compress"), parameters: { compressionLevel: 5, grayscale: false, @@ -85,6 +90,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] { }, { operation: "splitPdf", + displayName: t("automation.operation.splitBySize", "Split by Size (20MB)"), parameters: { mode: 'bySizeOrCount', pages: '', @@ -100,6 +106,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] { }, { operation: "sanitize", + displayName: t("automation.operation.sanitizeMetadata", "Remove Metadata"), parameters: { removeJavaScript: false, removeEmbeddedFiles: false, @@ -117,10 +124,11 @@ export function useSuggestedAutomations(): SuggestedAutomation[] { { id: "secure-workflow", name: t("automation.suggested.secureWorkflow", "Security Workflow"), - description: t("automation.suggested.secureWorkflowDesc", "Sanitize PDFs and add password protection"), + description: t("automation.suggested.secureWorkflowDesc", "Secures PDF documents by removing potentially malicious content like JavaScript and embedded files, then adds password protection to prevent unauthorized access."), operations: [ { operation: "sanitize", + displayName: t("automation.operation.sanitize", "Sanitize"), parameters: { removeJavaScript: true, removeEmbeddedFiles: true, @@ -132,6 +140,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] { }, { operation: "addPassword", + displayName: t("automation.operation.addPassword", "Add Password Protection"), parameters: { password: 'password', ownerPassword: '', @@ -154,23 +163,34 @@ export function useSuggestedAutomations(): SuggestedAutomation[] { icon: SecurityIcon, }, { - id: "optimization-workflow", - name: t("automation.suggested.optimizationWorkflow", "Optimization Workflow"), - description: t("automation.suggested.optimizationWorkflowDesc", "Repair and compress PDFs for better performance"), + id: "process-images", + name: t("automation.suggested.processImages", "Process Images"), + description: t("automation.suggested.processImagesDesc", "Converts multiple image files into a single PDF document, then applies OCR technology to extract searchable text from the images."), operations: [ { - operation: "repair", - parameters: {} + operation: "convert", + displayName: t("automation.operation.imageToPdf", "Image to PDF"), + parameters: { + fromExtension: 'image', + toExtension: 'pdf', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true, + } + } }, { - operation: "compress", + operation: "ocr", + displayName: t("automation.operation.ocr", "OCR Text Extraction"), parameters: { - compressionLevel: 7, - grayscale: false, - expectedSize: '', - compressionMethod: 'quality', - fileSizeValue: '', - fileSizeUnit: 'MB', + languages: ['eng'], + ocrType: 'skip-text', + ocrRenderType: 'hocr', + additionalOptions: [], } } ], diff --git a/frontend/src/types/automation.ts b/frontend/src/types/automation.ts index 8d2cb5ae8..0e05016dc 100644 --- a/frontend/src/types/automation.ts +++ b/frontend/src/types/automation.ts @@ -5,6 +5,7 @@ export interface AutomationOperation { operation: string; parameters: Record; + displayName?: string; // Custom display name for tooltip } export interface AutomationConfig {