mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-09-18 01:19:24 +00:00

# Description of Changes This pull request introduces the new "Auto Rename PDF" tool to the frontend, enabling users to automatically rename PDF files based on their content. The implementation includes UI components, parameter handling, operation logic, localization, and enhancements to the file response utilities to support backend-provided filenames. Below are the most important changes grouped by theme: **Feature: Auto Rename PDF Tool** - Added the main `AutoRename` tool component (`AutoRename.tsx`) and registered it in the tool registry, enabling selection and execution of the auto-rename operation in the UI. [[1]](diffhunk://#diff-3647ca39d46d109d122d4cd6cbfe981beb4189d05b1b446e5c46824eb98a4a88R1-R80) [[2]](diffhunk://#diff-0a3e636736c137356dd9354ff3cacbd302ebda40147545e13c62d073525d1969R17) [[3]](diffhunk://#diff-0a3e636736c137356dd9354ff3cacbd302ebda40147545e13c62d073525d1969L359-R366) [[4]](diffhunk://#diff-29427b8d06a23772c56645fc4b72af2980c813605abc162e3d47c2e39d026d06L25-R26) - Implemented the settings panel (`AutoRenameSettings.tsx`) and parameter management hook (`useAutoRenameParameters.ts`), allowing users to configure options such as using the first text as a fallback for the filename. [[1]](diffhunk://#diff-b2f9474c8e5a7a42df00a12ffd2d31a785895fe1096e8ca515e6af5633a4d648R1-R27) [[2]](diffhunk://#diff-8798a1ef451233bf3a1bf8825c12c5b434ad1a17a1beb1ca21fd972fdaceb50cR1-R19) - Created the operation hook (`useAutoRenameOperation.ts`) to handle API requests, error handling, and result processing for the auto-rename feature. **Localization** - Added English (US and GB) translations for the new tool, including UI labels, descriptions, error messages, and settings. [[1]](diffhunk://#diff-e4d543afa388d9eb8a423e45dfebb91641e3558d00848d70b285ebb91c40b249R1048-R1066) [[2]](diffhunk://#diff-14c707e28788a3a84ed5293ff6689be73d4bca00e155beaf090f9b37c978babbR1321-R1339) **File Response Handling Enhancements** - Updated the file response processor and related hooks to support preserving backend-provided filenames via the `Content-Disposition` header, ensuring files are renamed according to backend results. [[1]](diffhunk://#diff-97ea1c842d4b269c566a3085d8555ded7f9b462d9ce8dc73706bec79fe3973e0R11) [[2]](diffhunk://#diff-97ea1c842d4b269c566a3085d8555ded7f9b462d9ce8dc73706bec79fe3973e0L49-R51) [[3]](diffhunk://#diff-d44da7f96721d9829f3c20bf9c7ac5b9e156b647d2c75d76e861c8c09abc5191R52-R58) [[4]](diffhunk://#diff-d44da7f96721d9829f3c20bf9c7ac5b9e156b647d2c75d76e861c8c09abc5191L175-R183) [[5]](diffhunk://#diff-fa8af80f4d87370d58e3a5b79df675d201f0c3aa753eda89cec03ff027c4213dL13-R21) [[6]](diffhunk://#diff-efa525dbdeceaeb5701aa3d2303bf1d533541f65a92d985f94f33b8e87b036d1R2-R37) These changes collectively deliver a new advanced tool for users to automatically rename PDFs, with robust parameter handling, user interface integration, and proper handling of filenames as determined by backend logic. --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: Connor Yoh <connor@stirlingpdf.com> Co-authored-by: ConnorYoh <40631091+ConnorYoh@users.noreply.github.com> Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
116 lines
3.6 KiB
TypeScript
116 lines
3.6 KiB
TypeScript
import React from "react";
|
|
import { Button } from "@mantine/core";
|
|
import { Tooltip } from "../../shared/Tooltip";
|
|
import { ToolRegistryEntry } from "../../../data/toolsTaxonomy";
|
|
import { useToolNavigation } from "../../../hooks/useToolNavigation";
|
|
import { handleUnlessSpecialClick } from "../../../utils/clickHandlers";
|
|
import FitText from "../../shared/FitText";
|
|
|
|
interface ToolButtonProps {
|
|
id: string;
|
|
tool: ToolRegistryEntry;
|
|
isSelected: boolean;
|
|
onSelect: (id: string) => void;
|
|
rounded?: boolean;
|
|
disableNavigation?: boolean;
|
|
}
|
|
|
|
const ToolButton: React.FC<ToolButtonProps> = ({ id, tool, isSelected, onSelect, disableNavigation = false }) => {
|
|
const isUnavailable = !tool.component && !tool.link;
|
|
const { getToolNavigation } = useToolNavigation();
|
|
|
|
const handleClick = (id: string) => {
|
|
if (isUnavailable) return;
|
|
if (tool.link) {
|
|
// Open external link in new tab
|
|
window.open(tool.link, '_blank', 'noopener,noreferrer');
|
|
return;
|
|
}
|
|
// Normal tool selection
|
|
onSelect(id);
|
|
};
|
|
|
|
// Get navigation props for URL support (only if navigation is not disabled)
|
|
const navProps = !isUnavailable && !tool.link && !disableNavigation ? getToolNavigation(id, tool) : null;
|
|
|
|
const tooltipContent = isUnavailable
|
|
? (<span><strong>Coming soon:</strong> {tool.description}</span>)
|
|
: tool.description;
|
|
|
|
const buttonContent = (
|
|
<>
|
|
<div className="tool-button-icon" style={{ color: "var(--tools-text-and-icon-color)", marginRight: "0.5rem", transform: "scale(0.8)", transformOrigin: "center", opacity: isUnavailable ? 0.25 : 1 }}>{tool.icon}</div>
|
|
<FitText
|
|
text={tool.name}
|
|
lines={1}
|
|
minimumFontScale={0.8}
|
|
as="span"
|
|
style={{ display: 'inline-block', maxWidth: '100%', opacity: isUnavailable ? 0.25 : 1 }}
|
|
/>
|
|
</>
|
|
);
|
|
|
|
const handleExternalClick = (e: React.MouseEvent) => {
|
|
handleUnlessSpecialClick(e, () => handleClick(id));
|
|
};
|
|
|
|
const buttonElement = navProps ? (
|
|
// For internal tools with URLs, render Button as an anchor for proper link behavior
|
|
<Button
|
|
component="a"
|
|
href={navProps.href}
|
|
onClick={navProps.onClick}
|
|
variant={isSelected ? "filled" : "subtle"}
|
|
size="sm"
|
|
radius="md"
|
|
fullWidth
|
|
justify="flex-start"
|
|
className="tool-button"
|
|
styles={{ root: { borderRadius: 0, color: "var(--tools-text-and-icon-color)" } }}
|
|
>
|
|
{buttonContent}
|
|
</Button>
|
|
) : tool.link && !isUnavailable ? (
|
|
// For external links, render Button as an anchor with proper href
|
|
<Button
|
|
component="a"
|
|
href={tool.link}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
onClick={handleExternalClick}
|
|
variant={isSelected ? "filled" : "subtle"}
|
|
size="sm"
|
|
radius="md"
|
|
fullWidth
|
|
justify="flex-start"
|
|
className="tool-button"
|
|
styles={{ root: { borderRadius: 0, color: "var(--tools-text-and-icon-color)" } }}
|
|
>
|
|
{buttonContent}
|
|
</Button>
|
|
) : (
|
|
// For unavailable tools, use regular button
|
|
<Button
|
|
variant={isSelected ? "filled" : "subtle"}
|
|
onClick={() => handleClick(id)}
|
|
size="sm"
|
|
radius="md"
|
|
fullWidth
|
|
justify="flex-start"
|
|
className="tool-button"
|
|
aria-disabled={isUnavailable}
|
|
styles={{ root: { borderRadius: 0, color: "var(--tools-text-and-icon-color)", cursor: isUnavailable ? 'not-allowed' : undefined } }}
|
|
>
|
|
{buttonContent}
|
|
</Button>
|
|
);
|
|
|
|
return (
|
|
<Tooltip content={tooltipContent} position="right" arrow={true} delay={500}>
|
|
{buttonElement}
|
|
</Tooltip>
|
|
);
|
|
};
|
|
|
|
export default ToolButton;
|