mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-26 14:19:24 +00:00
Translations and merges
This commit is contained in:
parent
018d1e57ff
commit
bd9c6f9a03
@ -85,6 +85,7 @@
|
||||
"warning": {
|
||||
"tooltipTitle": "Warning"
|
||||
},
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
@ -538,10 +539,6 @@
|
||||
"title": "Edit Table of Contents",
|
||||
"desc": "Add or edit bookmarks and table of contents in PDF documents"
|
||||
},
|
||||
"automate": {
|
||||
"title": "Automate",
|
||||
"desc": "Build multi-step workflows by chaining together PDF actions. Ideal for recurring tasks."
|
||||
},
|
||||
"manageCertificates": {
|
||||
"title": "Manage Certificates",
|
||||
"desc": "Import, export, or delete digital certificate files used for signing PDFs."
|
||||
@ -601,6 +598,10 @@
|
||||
"changePermissions": {
|
||||
"title": "Change Permissions",
|
||||
"desc": "Change document restrictions and permissions"
|
||||
},
|
||||
"automate": {
|
||||
"title": "Automate",
|
||||
"desc": "Build multi-step workflows by chaining together PDF actions. Ideal for recurring tasks."
|
||||
}
|
||||
},
|
||||
"viewPdf": {
|
||||
@ -2184,5 +2185,68 @@
|
||||
"results": {
|
||||
"title": "Decrypted PDFs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"automate": {
|
||||
"title": "Automate",
|
||||
"desc": "Build multi-step workflows by chaining together PDF actions. Ideal for recurring tasks.",
|
||||
"invalidStep": "Invalid step",
|
||||
"files": {
|
||||
"placeholder": "Select files to process with this automation"
|
||||
},
|
||||
"selection": {
|
||||
"title": "Automation Selection",
|
||||
"saved": {
|
||||
"title": "Saved"
|
||||
},
|
||||
"createNew": {
|
||||
"title": "Create New Automation"
|
||||
},
|
||||
"suggested": {
|
||||
"title": "Suggested"
|
||||
}
|
||||
},
|
||||
"creation": {
|
||||
"createTitle": "Create Automation",
|
||||
"editTitle": "Edit Automation",
|
||||
"description": "Automations run tools sequentially. To get started, add tools in the order you want them to run.",
|
||||
"name": {
|
||||
"placeholder": "Automation name"
|
||||
},
|
||||
"tools": {
|
||||
"selectTool": "Select a tool...",
|
||||
"selected": "Selected Tools",
|
||||
"remove": "Remove tool",
|
||||
"configure": "Configure tool",
|
||||
"notConfigured": "! Not Configured",
|
||||
"addTool": "Add Tool",
|
||||
"add": "Add a tool..."
|
||||
},
|
||||
"save": "Save Automation",
|
||||
"unsavedChanges": {
|
||||
"title": "Unsaved Changes",
|
||||
"message": "You have unsaved changes. Are you sure you want to go back? All changes will be lost.",
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Go Back"
|
||||
}
|
||||
},
|
||||
"run": {
|
||||
"title": "Run Automation"
|
||||
},
|
||||
"sequence": {
|
||||
"unnamed": "Unnamed Automation",
|
||||
"steps": "{{count}} steps",
|
||||
"running": "Running Automation...",
|
||||
"run": "Run Automation",
|
||||
"finish": "Finish"
|
||||
},
|
||||
"reviewTitle": "Automation Results",
|
||||
"config": {
|
||||
"loading": "Loading tool configuration...",
|
||||
"noSettings": "This tool does not have configurable settings.",
|
||||
"title": "Configure {{toolName}}",
|
||||
"description": "Configure the settings for this tool. These settings will be applied when the automation runs.",
|
||||
"cancel": "Cancel",
|
||||
"save": "Save Configuration"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import NumberInputWithUnit from "../shared/NumberInputWithUnit";
|
||||
|
||||
interface WatermarkFormattingProps {
|
||||
parameters: AddWatermarkParameters;
|
||||
onParameterChange: (key: keyof AddWatermarkParameters, value: any) => void;
|
||||
onParameterChange: <K extends keyof AddWatermarkParameters>(key: K, value: AddWatermarkParameters[K]) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ import FileUploadButton from "../../shared/FileUploadButton";
|
||||
|
||||
interface WatermarkImageFileProps {
|
||||
parameters: AddWatermarkParameters;
|
||||
onParameterChange: (key: keyof AddWatermarkParameters, value: any) => void;
|
||||
onParameterChange: <K extends keyof AddWatermarkParameters>(key: K, value: AddWatermarkParameters[K]) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ const WatermarkImageFile = ({ parameters, onParameterChange, disabled = false }:
|
||||
<Stack gap="sm">
|
||||
<FileUploadButton
|
||||
file={parameters.watermarkImage}
|
||||
onChange={(file) => onParameterChange('watermarkImage', file)}
|
||||
onChange={(file) => onParameterChange('watermarkImage', file || undefined)}
|
||||
accept="image/*"
|
||||
disabled={disabled}
|
||||
placeholder={t('watermark.settings.image.choose', 'Choose Image')}
|
||||
|
@ -5,7 +5,7 @@ import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAdd
|
||||
|
||||
interface WatermarkStyleSettingsProps {
|
||||
parameters: AddWatermarkParameters;
|
||||
onParameterChange: (key: keyof AddWatermarkParameters, value: any) => void;
|
||||
onParameterChange: <K extends keyof AddWatermarkParameters>(key: K, value: AddWatermarkParameters[K]) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ const WatermarkStyleSettings = ({ parameters, onParameterChange, disabled = fals
|
||||
<Text size="sm" fw={500}>{t('watermark.settings.rotation', 'Rotation (degrees)')}</Text>
|
||||
<NumberInput
|
||||
value={parameters.rotation}
|
||||
onChange={(value) => onParameterChange('rotation', value || 0)}
|
||||
onChange={(value) => onParameterChange('rotation', typeof value === 'number' ? value : (parseInt(value as string, 10) || 0))}
|
||||
min={-360}
|
||||
max={360}
|
||||
disabled={disabled}
|
||||
@ -28,7 +28,7 @@ const WatermarkStyleSettings = ({ parameters, onParameterChange, disabled = fals
|
||||
<Text size="sm" fw={500}>{t('watermark.settings.opacity', 'Opacity (%)')}</Text>
|
||||
<NumberInput
|
||||
value={parameters.opacity}
|
||||
onChange={(value) => onParameterChange('opacity', value || 50)}
|
||||
onChange={(value) => onParameterChange('opacity', typeof value === 'number' ? value : (parseInt(value as string, 10) || 50))}
|
||||
min={0}
|
||||
max={100}
|
||||
disabled={disabled}
|
||||
@ -40,7 +40,7 @@ const WatermarkStyleSettings = ({ parameters, onParameterChange, disabled = fals
|
||||
<Text size="sm" fw={500}>{t('watermark.settings.spacing.width', 'Width Spacing')}</Text>
|
||||
<NumberInput
|
||||
value={parameters.widthSpacer}
|
||||
onChange={(value) => onParameterChange('widthSpacer', value || 50)}
|
||||
onChange={(value) => onParameterChange('widthSpacer', typeof value === 'number' ? value : (parseInt(value as string, 10) || 50))}
|
||||
min={0}
|
||||
max={200}
|
||||
disabled={disabled}
|
||||
@ -49,7 +49,7 @@ const WatermarkStyleSettings = ({ parameters, onParameterChange, disabled = fals
|
||||
<Text size="sm" fw={500}>{t('watermark.settings.spacing.height', 'Height Spacing')}</Text>
|
||||
<NumberInput
|
||||
value={parameters.heightSpacer}
|
||||
onChange={(value) => onParameterChange('heightSpacer', value || 50)}
|
||||
onChange={(value) => onParameterChange('heightSpacer', typeof value === 'number' ? value : (parseInt(value as string, 10) || 50))}
|
||||
min={0}
|
||||
max={200}
|
||||
disabled={disabled}
|
||||
|
@ -6,7 +6,7 @@ import { alphabetOptions } from "../../../constants/addWatermarkConstants";
|
||||
|
||||
interface WatermarkTextStyleProps {
|
||||
parameters: AddWatermarkParameters;
|
||||
onParameterChange: (key: keyof AddWatermarkParameters, value: any) => void;
|
||||
onParameterChange: <K extends keyof AddWatermarkParameters>(key: K, value: AddWatermarkParameters[K]) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ import { removeEmojis } from "../../../utils/textUtils";
|
||||
|
||||
interface WatermarkWordingProps {
|
||||
parameters: AddWatermarkParameters;
|
||||
onParameterChange: (key: keyof AddWatermarkParameters, value: any) => void;
|
||||
onParameterChange: <K extends keyof AddWatermarkParameters>(key: K, value: AddWatermarkParameters[K]) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ export default function AutomationEntry({
|
||||
onEdit();
|
||||
}}
|
||||
>
|
||||
{t('common.edit', 'Edit')}
|
||||
{t('edit', 'Edit')}
|
||||
</Menu.Item>
|
||||
)}
|
||||
{onDelete && (
|
||||
@ -151,7 +151,7 @@ export default function AutomationEntry({
|
||||
onDelete();
|
||||
}}
|
||||
>
|
||||
{t('common.delete', 'Delete')}
|
||||
{t('delete', 'Delete')}
|
||||
</Menu.Item>
|
||||
)}
|
||||
</Menu.Dropdown>
|
||||
|
@ -39,7 +39,7 @@ export const AutomationExecutor: React.FC<AutomationExecutorProps> = ({
|
||||
const tool = toolRegistry[op.operation];
|
||||
if (tool?.component) {
|
||||
const toolComponent = tool.component as ToolComponent;
|
||||
if (toolComponent.tool) {
|
||||
if ('tool' in toolComponent) {
|
||||
// We still can't call the hook here dynamically
|
||||
// This approach also won't work
|
||||
}
|
||||
@ -79,7 +79,7 @@ export const AutomationExecutor: React.FC<AutomationExecutorProps> = ({
|
||||
}
|
||||
|
||||
const toolComponent = tool.component as ToolComponent;
|
||||
if (!toolComponent.tool) {
|
||||
if (!('tool' in toolComponent)) {
|
||||
throw new Error(`Tool ${operation.operation} does not support automation`);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ export default function AutomationSelection({
|
||||
key={automation.id}
|
||||
title={automation.name}
|
||||
badgeIcon={SettingsIcon}
|
||||
operations={automation.operations.map(op => typeof op === 'string' ? op : op.operation)}
|
||||
operations={automation.operations.map((op: any) => typeof op === 'string' ? op : op.operation)}
|
||||
onClick={() => onRun(automation)}
|
||||
showMenu={true}
|
||||
onEdit={() => onEdit(automation)}
|
||||
|
@ -229,14 +229,12 @@ export function useToolWorkflow(): ToolWorkflowContextValue {
|
||||
|
||||
// Return minimal safe fallback to prevent crashes
|
||||
return {
|
||||
state: {
|
||||
sidebarsVisible: true,
|
||||
leftPanelView: 'toolPicker',
|
||||
readerMode: false,
|
||||
previewFile: null,
|
||||
pageEditorFunctions: null,
|
||||
searchQuery: ''
|
||||
},
|
||||
sidebarsVisible: true,
|
||||
leftPanelView: 'toolPicker',
|
||||
readerMode: false,
|
||||
previewFile: null,
|
||||
pageEditorFunctions: null,
|
||||
searchQuery: '',
|
||||
selectedToolKey: null,
|
||||
selectedTool: null,
|
||||
toolRegistry: {},
|
||||
|
@ -46,3 +46,4 @@ export const useAddWatermarkParameters = (): AddWatermarkParametersHook => {
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -49,7 +49,7 @@ export const useAutomationExecution = () => {
|
||||
|
||||
// Initialize operation hooks for all tools in the automation
|
||||
const hooks: Record<string, any> = {};
|
||||
steps.forEach((step) => {
|
||||
steps.forEach((step: ExecutionStep) => {
|
||||
const tool = toolRegistry[step.operation];
|
||||
if (tool?.component) {
|
||||
const toolComponent = tool.component as ToolComponent;
|
||||
|
@ -4,8 +4,6 @@ import StarIcon from '@mui/icons-material/Star';
|
||||
|
||||
export interface SuggestedAutomation {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
operations: string[];
|
||||
icon: React.ComponentType<any>;
|
||||
}
|
||||
@ -16,22 +14,16 @@ export function useSuggestedAutomations(): SuggestedAutomation[] {
|
||||
const suggestedAutomations = useMemo<SuggestedAutomation[]>(() => [
|
||||
{
|
||||
id: "compress-and-merge",
|
||||
name: t("automate.suggested.compressAndMerge.name", "Compress & Merge"),
|
||||
description: t("automate.suggested.compressAndMerge.description", "Compress multiple PDFs then merge them into one"),
|
||||
operations: ["compress", "merge"],
|
||||
icon: StarIcon,
|
||||
},
|
||||
{
|
||||
id: "ocr-and-convert",
|
||||
name: t("automate.suggested.ocrAndConvert.name", "OCR & Convert"),
|
||||
description: t("automate.suggested.ocrAndConvert.description", "Apply OCR to PDFs then convert to different format"),
|
||||
operations: ["ocr", "convert"],
|
||||
icon: StarIcon,
|
||||
},
|
||||
{
|
||||
id: "secure-workflow",
|
||||
name: t("automate.suggested.secureWorkflow.name", "Secure Workflow"),
|
||||
description: t("automate.suggested.secureWorkflow.description", "Sanitize, add password, and set permissions"),
|
||||
operations: ["sanitize", "addPassword", "changePermissions"],
|
||||
icon: StarIcon,
|
||||
},
|
||||
|
@ -4,7 +4,7 @@ import { useFileContext } from "../contexts/FileContext";
|
||||
import { useToolFileSelection } from "../contexts/FileSelectionContext";
|
||||
|
||||
import { createToolFlow } from "../components/tools/shared/createToolFlow";
|
||||
import { createFilesToolStep } from "../components/tools/shared/filesToolStep";
|
||||
import { createFilesToolStep } from "../components/tools/shared/FilesToolStep";
|
||||
import AutomationSelection from "../components/tools/automate/AutomationSelection";
|
||||
import AutomationCreation, { AutomationMode } from "../components/tools/automate/AutomationCreation";
|
||||
import AutomationRun from "../components/tools/automate/AutomationRun";
|
||||
@ -133,7 +133,7 @@ const Automate = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => {
|
||||
},
|
||||
steps: automationSteps,
|
||||
review: {
|
||||
isVisible: true,
|
||||
isVisible: hasResults,
|
||||
operation: automateOperation,
|
||||
title: t('automate.reviewTitle', 'Automation Results')
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import React, { use, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useEndpointEnabled } from "../hooks/useEndpointConfig";
|
||||
import { useFileContext } from "../contexts/FileContext";
|
||||
@ -8,7 +8,7 @@ import { createToolFlow } from "../components/tools/shared/createToolFlow";
|
||||
|
||||
import CompressSettings from "../components/tools/compress/CompressSettings";
|
||||
|
||||
import { useCompressParameters, initialParameters } from "../hooks/tools/compress/useCompressParameters";
|
||||
import { useCompressParameters } from "../hooks/tools/compress/useCompressParameters";
|
||||
import { useCompressOperation } from "../hooks/tools/compress/useCompressOperation";
|
||||
import { BaseToolProps, ToolComponent } from "../types/tool";
|
||||
import { useCompressTips } from "../components/tooltips/useCompressTips";
|
||||
@ -99,8 +99,6 @@ const Compress = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => {
|
||||
Compress.tool = () => useCompressOperation;
|
||||
|
||||
// Static method to get default parameters for automation
|
||||
Compress.getDefaultParameters = () => {
|
||||
return initialParameters;
|
||||
};
|
||||
Compress.getDefaultParameters = () => useCompressParameters();
|
||||
|
||||
export default Compress as ToolComponent;
|
||||
|
Loading…
x
Reference in New Issue
Block a user