mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-09-18 09:29:24 +00:00
automation
This commit is contained in:
parent
c8b911366c
commit
1c043b60fb
@ -2110,13 +2110,24 @@
|
|||||||
"automation": {
|
"automation": {
|
||||||
"suggested": {
|
"suggested": {
|
||||||
"securePdfIngestion": "Secure PDF Ingestion",
|
"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",
|
"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",
|
"secureWorkflow": "Security Workflow",
|
||||||
"secureWorkflowDesc": "Sanitize PDFs and add password protection",
|
"secureWorkflowDesc": "Secures PDF documents by removing potentially malicious content like JavaScript and embedded files, then adds password protection to prevent unauthorized access.",
|
||||||
"optimizationWorkflow": "Optimization Workflow",
|
"processImages": "Process Images",
|
||||||
"optimizationWorkflowDesc": "Repair and compress PDFs for better performance"
|
"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": {
|
"automate": {
|
||||||
|
@ -5,14 +5,17 @@ import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|||||||
import EditIcon from '@mui/icons-material/Edit';
|
import EditIcon from '@mui/icons-material/Edit';
|
||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||||
|
import { Tooltip } from '../../shared/Tooltip';
|
||||||
|
|
||||||
interface AutomationEntryProps {
|
interface AutomationEntryProps {
|
||||||
/** Optional title for the automation (usually for custom ones) */
|
/** Optional title for the automation (usually for custom ones) */
|
||||||
title?: string;
|
title?: string;
|
||||||
|
/** Optional description for tooltip */
|
||||||
|
description?: string;
|
||||||
/** MUI Icon component for the badge */
|
/** MUI Icon component for the badge */
|
||||||
badgeIcon?: React.ComponentType<any>;
|
badgeIcon?: React.ComponentType<any>;
|
||||||
/** Array of tool operation names in the workflow */
|
/** Array of tool operation names in the workflow OR full operation objects with display names */
|
||||||
operations: string[];
|
operations: string[] | Array<{operation: string; displayName?: string}>;
|
||||||
/** Click handler */
|
/** Click handler */
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
/** Whether to keep the icon at normal color (for special cases like "Add New") */
|
/** Whether to keep the icon at normal color (for special cases like "Add New") */
|
||||||
@ -29,6 +32,7 @@ interface AutomationEntryProps {
|
|||||||
|
|
||||||
export default function AutomationEntry({
|
export default function AutomationEntry({
|
||||||
title,
|
title,
|
||||||
|
description,
|
||||||
badgeIcon: BadgeIcon,
|
badgeIcon: BadgeIcon,
|
||||||
operations,
|
operations,
|
||||||
onClick,
|
onClick,
|
||||||
@ -45,6 +49,53 @@ export default function AutomationEntry({
|
|||||||
// Keep item in hovered state if menu is open
|
// Keep item in hovered state if menu is open
|
||||||
const shouldShowHovered = isHovered || isMenuOpen;
|
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 (
|
||||||
|
<React.Fragment key={`${operationName}-${index}`}>
|
||||||
|
<Text
|
||||||
|
component="span"
|
||||||
|
size="sm"
|
||||||
|
fw={600}
|
||||||
|
style={{
|
||||||
|
color: 'var(--mantine-primary-color-filled)',
|
||||||
|
background: 'var(--mantine-primary-color-light)',
|
||||||
|
padding: '2px 6px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
fontSize: '0.75rem',
|
||||||
|
whiteSpace: 'nowrap'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{displayName}
|
||||||
|
</Text>
|
||||||
|
{index < operations.length - 1 && (
|
||||||
|
<Text component="span" size="sm" mx={4}>
|
||||||
|
→
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ minWidth: '400px', width: 'auto' }}>
|
||||||
|
<Text size="sm" mb={8} style={{ whiteSpace: 'normal', wordWrap: 'break-word' }}>
|
||||||
|
{description}
|
||||||
|
</Text>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: '4px', whiteSpace: 'nowrap' }}>
|
||||||
|
{toolChain}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
if (title) {
|
if (title) {
|
||||||
// Custom automation with title
|
// Custom automation with title
|
||||||
@ -74,26 +125,32 @@ export default function AutomationEntry({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Group gap="xs" justify="flex-start" style={{ flex: 1 }}>
|
<Group gap="xs" justify="flex-start" style={{ flex: 1 }}>
|
||||||
{operations.map((op, index) => (
|
{operations.map((op, index) => {
|
||||||
<React.Fragment key={`${op}-${index}`}>
|
// Handle both string[] and operation object arrays
|
||||||
<Text size="xs" style={{ color: 'var(--mantine-color-text)' }}>
|
const operationName = typeof op === 'string' ? op : op.operation;
|
||||||
{t(`${op}.title`, op)}
|
const displayName = typeof op === 'object' && op.displayName ? op.displayName : t(`${operationName}.title`, operationName);
|
||||||
</Text>
|
|
||||||
|
return (
|
||||||
{index < operations.length - 1 && (
|
<React.Fragment key={`${operationName}-${index}`}>
|
||||||
<Text size="xs" c="dimmed" style={{ color: 'var(--mantine-color-text)' }}>
|
<Text size="xs" style={{ color: 'var(--mantine-color-text)' }}>
|
||||||
→
|
{displayName}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
|
||||||
</React.Fragment>
|
{index < operations.length - 1 && (
|
||||||
))}
|
<Text size="xs" c="dimmed" style={{ color: 'var(--mantine-color-text)' }}>
|
||||||
|
→
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
const boxContent = (
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: shouldShowHovered ? 'var(--mantine-color-gray-1)' : 'transparent',
|
backgroundColor: shouldShowHovered ? 'var(--mantine-color-gray-1)' : 'transparent',
|
||||||
@ -175,4 +232,18 @@ export default function AutomationEntry({
|
|||||||
</Group>
|
</Group>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Only show tooltip if description exists, otherwise return plain content
|
||||||
|
return description ? (
|
||||||
|
<Tooltip
|
||||||
|
content={createTooltipContent()}
|
||||||
|
position="right"
|
||||||
|
arrow={true}
|
||||||
|
delay={500}
|
||||||
|
>
|
||||||
|
{boxContent}
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
boxContent
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -66,8 +66,9 @@ export default function AutomationSelection({
|
|||||||
<AutomationEntry
|
<AutomationEntry
|
||||||
key={automation.id}
|
key={automation.id}
|
||||||
title={automation.name}
|
title={automation.name}
|
||||||
|
description={automation.description}
|
||||||
badgeIcon={automation.icon}
|
badgeIcon={automation.icon}
|
||||||
operations={automation.operations.map(op => op.operation)}
|
operations={automation.operations}
|
||||||
onClick={() => onRun(automation)}
|
onClick={() => onRun(automation)}
|
||||||
showMenu={true}
|
showMenu={true}
|
||||||
onCopy={() => onCopyFromSuggested(automation)}
|
onCopy={() => onCopyFromSuggested(automation)}
|
||||||
|
@ -19,10 +19,11 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
|||||||
{
|
{
|
||||||
id: "secure-pdf-ingestion",
|
id: "secure-pdf-ingestion",
|
||||||
name: t("automation.suggested.securePdfIngestion", "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: [
|
operations: [
|
||||||
{
|
{
|
||||||
operation: "sanitize",
|
operation: "sanitize",
|
||||||
|
displayName: t("automation.operation.sanitize", "Sanitize"),
|
||||||
parameters: {
|
parameters: {
|
||||||
removeJavaScript: true,
|
removeJavaScript: true,
|
||||||
removeEmbeddedFiles: true,
|
removeEmbeddedFiles: true,
|
||||||
@ -34,6 +35,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
operation: "ocr",
|
operation: "ocr",
|
||||||
|
displayName: t("automation.operation.ocrCleanup", "OCR & Cleanup"),
|
||||||
parameters: {
|
parameters: {
|
||||||
languages: ['eng'],
|
languages: ['eng'],
|
||||||
ocrType: 'skip-text',
|
ocrType: 'skip-text',
|
||||||
@ -43,6 +45,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
operation: "convert",
|
operation: "convert",
|
||||||
|
displayName: t("automation.operation.pdfaConversion", "PDF/A Conversion"),
|
||||||
parameters: {
|
parameters: {
|
||||||
fromExtension: 'pdf',
|
fromExtension: 'pdf',
|
||||||
toExtension: 'pdfa',
|
toExtension: 'pdfa',
|
||||||
@ -53,6 +56,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
operation: "compress",
|
operation: "compress",
|
||||||
|
displayName: t("automation.operation.compress", "Compress"),
|
||||||
parameters: {
|
parameters: {
|
||||||
compressionLevel: 5,
|
compressionLevel: 5,
|
||||||
grayscale: false,
|
grayscale: false,
|
||||||
@ -70,10 +74,11 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
|||||||
{
|
{
|
||||||
id: "email-preparation",
|
id: "email-preparation",
|
||||||
name: t("automation.suggested.emailPreparation", "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: [
|
operations: [
|
||||||
{
|
{
|
||||||
operation: "compress",
|
operation: "compress",
|
||||||
|
displayName: t("automation.operation.compress", "Compress"),
|
||||||
parameters: {
|
parameters: {
|
||||||
compressionLevel: 5,
|
compressionLevel: 5,
|
||||||
grayscale: false,
|
grayscale: false,
|
||||||
@ -85,6 +90,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
operation: "splitPdf",
|
operation: "splitPdf",
|
||||||
|
displayName: t("automation.operation.splitBySize", "Split by Size (20MB)"),
|
||||||
parameters: {
|
parameters: {
|
||||||
mode: 'bySizeOrCount',
|
mode: 'bySizeOrCount',
|
||||||
pages: '',
|
pages: '',
|
||||||
@ -100,6 +106,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
operation: "sanitize",
|
operation: "sanitize",
|
||||||
|
displayName: t("automation.operation.sanitizeMetadata", "Remove Metadata"),
|
||||||
parameters: {
|
parameters: {
|
||||||
removeJavaScript: false,
|
removeJavaScript: false,
|
||||||
removeEmbeddedFiles: false,
|
removeEmbeddedFiles: false,
|
||||||
@ -117,10 +124,11 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
|||||||
{
|
{
|
||||||
id: "secure-workflow",
|
id: "secure-workflow",
|
||||||
name: t("automation.suggested.secureWorkflow", "Security 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: [
|
operations: [
|
||||||
{
|
{
|
||||||
operation: "sanitize",
|
operation: "sanitize",
|
||||||
|
displayName: t("automation.operation.sanitize", "Sanitize"),
|
||||||
parameters: {
|
parameters: {
|
||||||
removeJavaScript: true,
|
removeJavaScript: true,
|
||||||
removeEmbeddedFiles: true,
|
removeEmbeddedFiles: true,
|
||||||
@ -132,6 +140,7 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
operation: "addPassword",
|
operation: "addPassword",
|
||||||
|
displayName: t("automation.operation.addPassword", "Add Password Protection"),
|
||||||
parameters: {
|
parameters: {
|
||||||
password: 'password',
|
password: 'password',
|
||||||
ownerPassword: '',
|
ownerPassword: '',
|
||||||
@ -154,23 +163,34 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
|||||||
icon: SecurityIcon,
|
icon: SecurityIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "optimization-workflow",
|
id: "process-images",
|
||||||
name: t("automation.suggested.optimizationWorkflow", "Optimization Workflow"),
|
name: t("automation.suggested.processImages", "Process Images"),
|
||||||
description: t("automation.suggested.optimizationWorkflowDesc", "Repair and compress PDFs for better performance"),
|
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: [
|
operations: [
|
||||||
{
|
{
|
||||||
operation: "repair",
|
operation: "convert",
|
||||||
parameters: {}
|
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: {
|
parameters: {
|
||||||
compressionLevel: 7,
|
languages: ['eng'],
|
||||||
grayscale: false,
|
ocrType: 'skip-text',
|
||||||
expectedSize: '',
|
ocrRenderType: 'hocr',
|
||||||
compressionMethod: 'quality',
|
additionalOptions: [],
|
||||||
fileSizeValue: '',
|
|
||||||
fileSizeUnit: 'MB',
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
export interface AutomationOperation {
|
export interface AutomationOperation {
|
||||||
operation: string;
|
operation: string;
|
||||||
parameters: Record<string, any>;
|
parameters: Record<string, any>;
|
||||||
|
displayName?: string; // Custom display name for tooltip
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AutomationConfig {
|
export interface AutomationConfig {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user