add synonyms/tags to search

This commit is contained in:
EthanHealy01 2025-09-23 23:51:28 +01:00
parent 4bdf1c93ae
commit cd94584278
5 changed files with 129 additions and 44 deletions

View File

@ -10,7 +10,7 @@ import { renderToolButtons } from "./shared/renderToolButtons";
interface ToolPickerProps { interface ToolPickerProps {
selectedToolKey: string | null; selectedToolKey: string | null;
onSelect: (id: string) => void; onSelect: (id: string) => void;
filteredTools: [string, ToolRegistryEntry][]; filteredTools: Array<{ item: [string, ToolRegistryEntry]; matchedText?: string }>;
isSearching?: boolean; isSearching?: boolean;
} }

View File

@ -58,8 +58,13 @@ export default function ToolSelector({
return registry; return registry;
}, [baseFilteredTools]); }, [baseFilteredTools]);
// Transform filteredTools to the expected format for useToolSections
const transformedFilteredTools = useMemo(() => {
return filteredTools.map(([id, tool]) => ({ item: [id, tool] as [string, ToolRegistryEntry] }));
}, [filteredTools]);
// Use the same tool sections logic as the main ToolPicker // Use the same tool sections logic as the main ToolPicker
const { sections, searchGroups } = useToolSections(filteredTools); const { sections, searchGroups } = useToolSections(transformedFilteredTools);
// Determine what to display: search results or organized sections // Determine what to display: search results or organized sections
const isSearching = searchTerm.trim().length > 0; const isSearching = searchTerm.trim().length > 0;

View File

@ -120,7 +120,7 @@ const ToolButton: React.FC<ToolButtonProps> = ({ id, tool, isSelected, onSelect,
justify="flex-start" justify="flex-start"
className="tool-button" className="tool-button"
aria-disabled={isUnavailable} aria-disabled={isUnavailable}
styles={{ root: { borderRadius: 0, color: "var(--tools-text-and-icon-color)", cursor: isUnavailable ? 'not-allowed' : undefined } }} styles={{ root: { borderRadius: 0, color: "var(--tools-text-and-icon-color)", cursor: isUnavailable ? 'not-allowed' : undefined, overflow: 'visible' }, label: { overflow: 'visible' } }}
> >
{buttonContent} {buttonContent}
</Button> </Button>

View File

@ -11,7 +11,7 @@ import { useNavigationActions, useNavigationState } from './NavigationContext';
import { ToolId, isValidToolId } from '../types/toolId'; import { ToolId, isValidToolId } from '../types/toolId';
import { useNavigationUrlSync } from '../hooks/useUrlSync'; import { useNavigationUrlSync } from '../hooks/useUrlSync';
import { getDefaultWorkbench } from '../types/workbench'; import { getDefaultWorkbench } from '../types/workbench';
import { rankByFuzzy, idToWords } from '../utils/fuzzySearch'; import { idToWords, scoreMatch, minScoreForQuery } from '../utils/fuzzySearch';
// State interface // State interface
interface ToolWorkflowState { interface ToolWorkflowState {
@ -227,17 +227,46 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) {
// Return in the new format even when not searching // Return in the new format even when not searching
return entries.map(([id, tool]) => ({ item: [id, tool] as [string, ToolRegistryEntry] })); return entries.map(([id, tool]) => ({ item: [id, tool] as [string, ToolRegistryEntry] }));
} }
const ranked = rankByFuzzy(entries, state.searchQuery, [
([key]) => idToWords(key), const threshold = minScoreForQuery(state.searchQuery);
([, v]) => v.name, const results: Array<{ item: [string, ToolRegistryEntry]; matchedText?: string; score: number }> = [];
([, v]) => v.description,
([, v]) => v.synonyms?.join(' ') || '', for (const [id, tool] of entries) {
]); let best = 0;
// Keep reasonable number in search view? Return all ranked to preserve grouping downstream let matchedText = '';
return ranked.map(r => ({
item: r.item as [string, ToolRegistryEntry], const candidates: string[] = [
matchedText: r.matchedText idToWords(id),
})); tool.name || '',
tool.description || ''
];
for (const value of candidates) {
if (!value) continue;
const s = scoreMatch(state.searchQuery, value);
if (s > best) {
best = s;
matchedText = value;
}
}
if (Array.isArray(tool.synonyms)) {
for (const synonym of tool.synonyms) {
if (!synonym) continue;
const s = scoreMatch(state.searchQuery, synonym);
if (s > best) {
best = s;
matchedText = synonym;
}
}
}
if (best >= threshold) {
results.push({ item: [id, tool] as [string, ToolRegistryEntry], matchedText, score: best });
}
}
results.sort((a, b) => b.score - a.score);
return results.map(({ item, matchedText }) => ({ item, matchedText }));
}, [toolRegistry, state.searchQuery]); }, [toolRegistry, state.searchQuery]);
const isPanelVisible = useMemo(() => const isPanelVisible = useMemo(() =>

View File

@ -146,6 +146,31 @@ export const CONVERT_SUPPORTED_FORMATS = [
"pdf", "pdf",
]; ];
// Helper function to get translated synonyms for a tool
const getTranslatedSynonyms = (t: any, toolId: string): string[] => {
try {
const tagsKey = `${toolId}.tags`;
const tags = t(tagsKey);
// If the translation key doesn't exist or returns the key itself, return empty array
if (!tags || tags === tagsKey) {
return [];
}
// Split by comma and clean up the tags
return tags.split(',').map((tag: string) => tag.trim()).filter((tag: string) => tag.length > 0);
} catch (error) {
console.warn(`Failed to get translated synonyms for tool ${toolId}:`, error);
return [];
}
};
// Helper function to merge translated synonyms with existing synonyms
const mergeSynonyms = (t: any, toolId: string, existingSynonyms: string[] = []): string[] => {
const translatedSynonyms = getTranslatedSynonyms(t, toolId);
return [...translatedSynonyms, ...existingSynonyms];
};
// Hook to get the translated tool registry // Hook to get the translated tool registry
export function useFlatToolRegistry(): ToolRegistry { export function useFlatToolRegistry(): ToolRegistry {
const { t } = useTranslation(); const { t } = useTranslation();
@ -161,6 +186,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.certSign.desc", "Signs a PDF with a Certificate/Key (PEM/P12)"), description: t("home.certSign.desc", "Signs a PDF with a Certificate/Key (PEM/P12)"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.SIGNING, subcategoryId: SubcategoryId.SIGNING,
synonyms: mergeSynonyms(t, "certSign"),
}, },
sign: { sign: {
icon: <LocalIcon icon="signature-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="signature-rounded" width="1.5rem" height="1.5rem" />,
@ -169,7 +195,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.sign.desc", "Adds signature to PDF by drawing, text or image"), description: t("home.sign.desc", "Adds signature to PDF by drawing, text or image"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.SIGNING, subcategoryId: SubcategoryId.SIGNING,
synonyms: ["signature", "autograph"] synonyms: mergeSynonyms(t, "sign", ["signature", "autograph"])
}, },
// Document Security // Document Security
@ -185,7 +211,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["add-password"], endpoints: ["add-password"],
operationConfig: addPasswordOperationConfig, operationConfig: addPasswordOperationConfig,
settingsComponent: AddPasswordSettings, settingsComponent: AddPasswordSettings,
synonyms: ["lock", "secure"] synonyms: mergeSynonyms(t, "addPassword", ["lock", "secure"])
}, },
watermark: { watermark: {
icon: <LocalIcon icon="branding-watermark-outline-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="branding-watermark-outline-rounded" width="1.5rem" height="1.5rem" />,
@ -198,7 +224,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["add-watermark"], endpoints: ["add-watermark"],
operationConfig: addWatermarkOperationConfig, operationConfig: addWatermarkOperationConfig,
settingsComponent: AddWatermarkSingleStepSettings, settingsComponent: AddWatermarkSingleStepSettings,
synonyms: ["brand", "logo", "stamp"] synonyms: mergeSynonyms(t, "watermark", ["brand", "logo", "stamp"])
}, },
addStamp: { addStamp: {
icon: <LocalIcon icon="approval-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="approval-rounded" width="1.5rem" height="1.5rem" />,
@ -207,6 +233,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.addStamp.desc", "Add text or add image stamps at set locations"), description: t("home.addStamp.desc", "Add text or add image stamps at set locations"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.DOCUMENT_SECURITY, subcategoryId: SubcategoryId.DOCUMENT_SECURITY,
synonyms: mergeSynonyms(t, "addStamp"),
}, },
sanitize: { sanitize: {
icon: <LocalIcon icon="cleaning-services-outline-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="cleaning-services-outline-rounded" width="1.5rem" height="1.5rem" />,
@ -219,7 +246,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["sanitize-pdf"], endpoints: ["sanitize-pdf"],
operationConfig: sanitizeOperationConfig, operationConfig: sanitizeOperationConfig,
settingsComponent: SanitizeSettings, settingsComponent: SanitizeSettings,
synonyms: ["clean", "purge", "remove"] synonyms: mergeSynonyms(t, "sanitize", ["clean", "purge", "remove"])
}, },
flatten: { flatten: {
icon: <LocalIcon icon="layers-clear-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="layers-clear-rounded" width="1.5rem" height="1.5rem" />,
@ -232,7 +259,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["flatten"], endpoints: ["flatten"],
operationConfig: flattenOperationConfig, operationConfig: flattenOperationConfig,
settingsComponent: FlattenSettings, settingsComponent: FlattenSettings,
synonyms: ["simplify", "flatten", "static"] synonyms: mergeSynonyms(t, "flatten", ["simplify", "flatten", "static"])
}, },
unlockPDFForms: { unlockPDFForms: {
icon: <LocalIcon icon="preview-off-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="preview-off-rounded" width="1.5rem" height="1.5rem" />,
@ -245,6 +272,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["unlock-pdf-forms"], endpoints: ["unlock-pdf-forms"],
operationConfig: unlockPdfFormsOperationConfig, operationConfig: unlockPdfFormsOperationConfig,
settingsComponent: UnlockPdfFormsSettings, settingsComponent: UnlockPdfFormsSettings,
synonyms: mergeSynonyms(t, "unlockPDFForms"),
}, },
manageCertificates: { manageCertificates: {
icon: <LocalIcon icon="license-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="license-rounded" width="1.5rem" height="1.5rem" />,
@ -256,6 +284,7 @@ export function useFlatToolRegistry(): ToolRegistry {
), ),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.DOCUMENT_SECURITY, subcategoryId: SubcategoryId.DOCUMENT_SECURITY,
synonyms: mergeSynonyms(t, "manageCertificates"),
}, },
changePermissions: { changePermissions: {
icon: <LocalIcon icon="lock-outline" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="lock-outline" width="1.5rem" height="1.5rem" />,
@ -268,6 +297,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["add-password"], endpoints: ["add-password"],
operationConfig: changePermissionsOperationConfig, operationConfig: changePermissionsOperationConfig,
settingsComponent: ChangePermissionsSettings, settingsComponent: ChangePermissionsSettings,
synonyms: mergeSynonyms(t, "changePermissions"),
}, },
// Verification // Verification
@ -278,6 +308,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.getPdfInfo.desc", "Grabs any and all information possible on PDFs"), description: t("home.getPdfInfo.desc", "Grabs any and all information possible on PDFs"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.VERIFICATION, subcategoryId: SubcategoryId.VERIFICATION,
synonyms: mergeSynonyms(t, "getPdfInfo"),
}, },
validateSignature: { validateSignature: {
icon: <LocalIcon icon="verified-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="verified-rounded" width="1.5rem" height="1.5rem" />,
@ -286,6 +317,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.validateSignature.desc", "Verify digital signatures and certificates in PDF documents"), description: t("home.validateSignature.desc", "Verify digital signatures and certificates in PDF documents"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.VERIFICATION, subcategoryId: SubcategoryId.VERIFICATION,
synonyms: mergeSynonyms(t, "validateSignature"),
}, },
// Document Review // Document Review
@ -301,7 +333,7 @@ export function useFlatToolRegistry(): ToolRegistry {
), ),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.DOCUMENT_REVIEW, subcategoryId: SubcategoryId.DOCUMENT_REVIEW,
synonyms: ["view", "open", "display"] synonyms: mergeSynonyms(t, "read", ["view", "open", "display"])
}, },
changeMetadata: { changeMetadata: {
icon: <LocalIcon icon="assignment-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="assignment-rounded" width="1.5rem" height="1.5rem" />,
@ -314,7 +346,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["update-metadata"], endpoints: ["update-metadata"],
operationConfig: changeMetadataOperationConfig, operationConfig: changeMetadataOperationConfig,
settingsComponent: ChangeMetadataSingleStep, settingsComponent: ChangeMetadataSingleStep,
synonyms: ["edit", "modify", "update"] synonyms: mergeSynonyms(t, "changeMetadata", ["edit", "modify", "update"])
}, },
// Page Formatting // Page Formatting
@ -325,7 +357,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.crop.desc", "Crop a PDF to reduce its size (maintains text!)"), description: t("home.crop.desc", "Crop a PDF to reduce its size (maintains text!)"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING, subcategoryId: SubcategoryId.PAGE_FORMATTING,
synonyms: ["trim", "cut", "resize"] synonyms: mergeSynonyms(t, "crop", ["trim", "cut", "resize"])
}, },
rotate: { rotate: {
icon: <LocalIcon icon="rotate-right-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="rotate-right-rounded" width="1.5rem" height="1.5rem" />,
@ -338,7 +370,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["rotate-pdf"], endpoints: ["rotate-pdf"],
operationConfig: rotateOperationConfig, operationConfig: rotateOperationConfig,
settingsComponent: RotateSettings, settingsComponent: RotateSettings,
synonyms: ["turn", "flip", "orient"] synonyms: mergeSynonyms(t, "rotate", ["turn", "flip", "orient"])
}, },
split: { split: {
icon: <LocalIcon icon="content-cut-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="content-cut-rounded" width="1.5rem" height="1.5rem" />,
@ -349,7 +381,7 @@ export function useFlatToolRegistry(): ToolRegistry {
subcategoryId: SubcategoryId.PAGE_FORMATTING, subcategoryId: SubcategoryId.PAGE_FORMATTING,
operationConfig: splitOperationConfig, operationConfig: splitOperationConfig,
settingsComponent: SplitSettings, settingsComponent: SplitSettings,
synonyms: ["divide", "separate", "cut"] synonyms: mergeSynonyms(t, "split", ["divide", "separate", "cut"])
}, },
reorganizePages: { reorganizePages: {
icon: <LocalIcon icon="move-down-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="move-down-rounded" width="1.5rem" height="1.5rem" />,
@ -362,7 +394,7 @@ export function useFlatToolRegistry(): ToolRegistry {
), ),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING, subcategoryId: SubcategoryId.PAGE_FORMATTING,
synonyms: ["rearrange", "reorder", "organize"] synonyms: mergeSynonyms(t, "reorganizePages", ["rearrange", "reorder", "organize"])
}, },
scalePages: { scalePages: {
icon: <LocalIcon icon="crop-free-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="crop-free-rounded" width="1.5rem" height="1.5rem" />,
@ -375,7 +407,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["scale-pages"], endpoints: ["scale-pages"],
operationConfig: adjustPageScaleOperationConfig, operationConfig: adjustPageScaleOperationConfig,
settingsComponent: AdjustPageScaleSettings, settingsComponent: AdjustPageScaleSettings,
synonyms: ["resize", "adjust", "scale"] synonyms: mergeSynonyms(t, "scalePages", ["resize", "adjust", "scale"])
}, },
addPageNumbers: { addPageNumbers: {
icon: <LocalIcon icon="123-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="123-rounded" width="1.5rem" height="1.5rem" />,
@ -385,7 +417,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.addPageNumbers.desc", "Add Page numbers throughout a document in a set location"), description: t("home.addPageNumbers.desc", "Add Page numbers throughout a document in a set location"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING, subcategoryId: SubcategoryId.PAGE_FORMATTING,
synonyms: ["number", "pagination", "count"] synonyms: mergeSynonyms(t, "addPageNumbers", ["number", "pagination", "count"])
}, },
pageLayout: { pageLayout: {
icon: <LocalIcon icon="dashboard-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="dashboard-rounded" width="1.5rem" height="1.5rem" />,
@ -395,7 +427,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.pageLayout.desc", "Merge multiple pages of a PDF document into a single page"), description: t("home.pageLayout.desc", "Merge multiple pages of a PDF document into a single page"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING, subcategoryId: SubcategoryId.PAGE_FORMATTING,
synonyms: ["layout", "arrange", "combine"] synonyms: mergeSynonyms(t, "pageLayout", ["layout", "arrange", "combine"])
}, },
pdfToSinglePage: { pdfToSinglePage: {
icon: <LocalIcon icon="looks-one-outline-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="looks-one-outline-rounded" width="1.5rem" height="1.5rem" />,
@ -409,7 +441,7 @@ export function useFlatToolRegistry(): ToolRegistry {
urlPath: '/pdf-to-single-page', urlPath: '/pdf-to-single-page',
endpoints: ["pdf-to-single-page"], endpoints: ["pdf-to-single-page"],
operationConfig: singleLargePageOperationConfig, operationConfig: singleLargePageOperationConfig,
synonyms: ["combine", "merge", "single"] synonyms: mergeSynonyms(t, "pdfToSinglePage", ["combine", "merge", "single"])
}, },
addAttachments: { addAttachments: {
icon: <LocalIcon icon="attachment-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="attachment-rounded" width="1.5rem" height="1.5rem" />,
@ -419,7 +451,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.addAttachments.desc", "Add or remove embedded files (attachments) to/from a PDF"), description: t("home.addAttachments.desc", "Add or remove embedded files (attachments) to/from a PDF"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING, subcategoryId: SubcategoryId.PAGE_FORMATTING,
synonyms: ["embed", "attach", "include"] synonyms: mergeSynonyms(t, "addAttachments", ["embed", "attach", "include"])
}, },
// Extraction // Extraction
@ -431,7 +463,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.extractPages.desc", "Extract specific pages from a PDF document"), description: t("home.extractPages.desc", "Extract specific pages from a PDF document"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.EXTRACTION, subcategoryId: SubcategoryId.EXTRACTION,
synonyms: ["pull", "select", "copy"] synonyms: mergeSynonyms(t, "extractPages", ["pull", "select", "copy"])
}, },
extractImages: { extractImages: {
icon: <LocalIcon icon="filter-alt" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="filter-alt" width="1.5rem" height="1.5rem" />,
@ -440,7 +472,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.extractImages.desc", "Extract images from PDF documents"), description: t("home.extractImages.desc", "Extract images from PDF documents"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.EXTRACTION, subcategoryId: SubcategoryId.EXTRACTION,
synonyms: ["pull", "save", "export"] synonyms: mergeSynonyms(t, "extractImages", ["pull", "save", "export"])
}, },
// Removal // Removal
@ -454,7 +486,7 @@ export function useFlatToolRegistry(): ToolRegistry {
subcategoryId: SubcategoryId.REMOVAL, subcategoryId: SubcategoryId.REMOVAL,
maxFiles: 1, maxFiles: 1,
endpoints: ["remove-pages"], endpoints: ["remove-pages"],
synonyms: ["delete", "extract", "exclude"] synonyms: mergeSynonyms(t, "removePages", ["delete", "extract", "exclude"])
}, },
removeBlanks: { removeBlanks: {
icon: <LocalIcon icon="scan-delete-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="scan-delete-rounded" width="1.5rem" height="1.5rem" />,
@ -465,7 +497,7 @@ export function useFlatToolRegistry(): ToolRegistry {
subcategoryId: SubcategoryId.REMOVAL, subcategoryId: SubcategoryId.REMOVAL,
maxFiles: 1, maxFiles: 1,
endpoints: ["remove-blanks"], endpoints: ["remove-blanks"],
synonyms: ["delete", "clean", "empty"] synonyms: mergeSynonyms(t, "removeBlanks", ["delete", "clean", "empty"])
}, },
removeAnnotations: { removeAnnotations: {
icon: <LocalIcon icon="thread-unread-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="thread-unread-rounded" width="1.5rem" height="1.5rem" />,
@ -474,7 +506,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.removeAnnotations.desc", "Remove annotations and comments from PDF documents"), description: t("home.removeAnnotations.desc", "Remove annotations and comments from PDF documents"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.REMOVAL, subcategoryId: SubcategoryId.REMOVAL,
synonyms: ["delete", "clean", "strip"] synonyms: mergeSynonyms(t, "removeAnnotations", ["delete", "clean", "strip"])
}, },
removeImage: { removeImage: {
icon: <LocalIcon icon="remove-selection-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="remove-selection-rounded" width="1.5rem" height="1.5rem" />,
@ -483,6 +515,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.removeImage.desc", "Remove images from PDF documents"), description: t("home.removeImage.desc", "Remove images from PDF documents"),
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.REMOVAL, subcategoryId: SubcategoryId.REMOVAL,
synonyms: mergeSynonyms(t, "removeImage"),
}, },
removePassword: { removePassword: {
icon: <LocalIcon icon="lock-open-right-outline-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="lock-open-right-outline-rounded" width="1.5rem" height="1.5rem" />,
@ -495,7 +528,7 @@ export function useFlatToolRegistry(): ToolRegistry {
maxFiles: -1, maxFiles: -1,
operationConfig: removePasswordOperationConfig, operationConfig: removePasswordOperationConfig,
settingsComponent: RemovePasswordSettings, settingsComponent: RemovePasswordSettings,
synonyms: ["unlock"] synonyms: mergeSynonyms(t, "removePassword", ["unlock"])
}, },
removeCertSign: { removeCertSign: {
icon: <LocalIcon icon="remove-moderator-outline-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="remove-moderator-outline-rounded" width="1.5rem" height="1.5rem" />,
@ -507,6 +540,7 @@ export function useFlatToolRegistry(): ToolRegistry {
maxFiles: -1, maxFiles: -1,
endpoints: ["remove-certificate-sign"], endpoints: ["remove-certificate-sign"],
operationConfig: removeCertificateSignOperationConfig, operationConfig: removeCertificateSignOperationConfig,
synonyms: mergeSynonyms(t, "removeCertSign"),
}, },
// Automation // Automation
@ -524,6 +558,7 @@ export function useFlatToolRegistry(): ToolRegistry {
maxFiles: -1, maxFiles: -1,
supportedFormats: CONVERT_SUPPORTED_FORMATS, supportedFormats: CONVERT_SUPPORTED_FORMATS,
endpoints: ["handleData"], endpoints: ["handleData"],
synonyms: mergeSynonyms(t, "automate"),
}, },
autoRename: { autoRename: {
icon: <LocalIcon icon="match-word-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="match-word-rounded" width="1.5rem" height="1.5rem" />,
@ -535,6 +570,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.autoRename.desc", "Automatically rename PDF files based on their content"), description: t("home.autoRename.desc", "Automatically rename PDF files based on their content"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.AUTOMATION, subcategoryId: SubcategoryId.AUTOMATION,
synonyms: mergeSynonyms(t, "autoRename"),
}, },
autoSplitPDF: { autoSplitPDF: {
icon: <LocalIcon icon="split-scene-right-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="split-scene-right-rounded" width="1.5rem" height="1.5rem" />,
@ -543,6 +579,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.autoSplitPDF.desc", "Automatically split PDF pages based on content detection"), description: t("home.autoSplitPDF.desc", "Automatically split PDF pages based on content detection"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.AUTOMATION, subcategoryId: SubcategoryId.AUTOMATION,
synonyms: mergeSynonyms(t, "autoSplitPDF"),
}, },
autoSizeSplitPDF: { autoSizeSplitPDF: {
icon: <LocalIcon icon="content-cut-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="content-cut-rounded" width="1.5rem" height="1.5rem" />,
@ -551,6 +588,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.autoSizeSplitPDF.desc", "Automatically split PDFs by file size or page count"), description: t("home.autoSizeSplitPDF.desc", "Automatically split PDFs by file size or page count"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.AUTOMATION, subcategoryId: SubcategoryId.AUTOMATION,
synonyms: mergeSynonyms(t, "autoSizeSplitPDF"),
}, },
// Advanced Formatting // Advanced Formatting
@ -562,6 +600,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.adjustContrast.desc", "Adjust colors and contrast of PDF documents"), description: t("home.adjustContrast.desc", "Adjust colors and contrast of PDF documents"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING, subcategoryId: SubcategoryId.ADVANCED_FORMATTING,
synonyms: mergeSynonyms(t, "adjustContrast"),
}, },
repair: { repair: {
icon: <LocalIcon icon="build-outline-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="build-outline-rounded" width="1.5rem" height="1.5rem" />,
@ -574,7 +613,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["repair"], endpoints: ["repair"],
operationConfig: repairOperationConfig, operationConfig: repairOperationConfig,
settingsComponent: RepairSettings, settingsComponent: RepairSettings,
synonyms: ["fix", "restore"] synonyms: mergeSynonyms(t, "repair", ["fix", "restore"])
}, },
scannerImageSplit: { scannerImageSplit: {
icon: <LocalIcon icon="scanner-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="scanner-rounded" width="1.5rem" height="1.5rem" />,
@ -583,6 +622,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.scannerImageSplit.desc", "Detect and split scanned photos into separate pages"), description: t("home.scannerImageSplit.desc", "Detect and split scanned photos into separate pages"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING, subcategoryId: SubcategoryId.ADVANCED_FORMATTING,
synonyms: mergeSynonyms(t, "ScannerImageSplit"),
}, },
overlayPdfs: { overlayPdfs: {
icon: <LocalIcon icon="layers-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="layers-rounded" width="1.5rem" height="1.5rem" />,
@ -591,6 +631,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.overlayPdfs.desc", "Overlay one PDF on top of another"), description: t("home.overlayPdfs.desc", "Overlay one PDF on top of another"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING, subcategoryId: SubcategoryId.ADVANCED_FORMATTING,
synonyms: mergeSynonyms(t, "overlayPdfs"),
}, },
replaceColorPdf: { replaceColorPdf: {
icon: <LocalIcon icon="format-color-fill-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="format-color-fill-rounded" width="1.5rem" height="1.5rem" />,
@ -599,6 +640,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.replaceColorPdf.desc", "Replace or invert colors in PDF documents"), description: t("home.replaceColorPdf.desc", "Replace or invert colors in PDF documents"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING, subcategoryId: SubcategoryId.ADVANCED_FORMATTING,
synonyms: mergeSynonyms(t, "replaceColorPdf"),
}, },
addImage: { addImage: {
icon: <LocalIcon icon="image-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="image-rounded" width="1.5rem" height="1.5rem" />,
@ -607,6 +649,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.addImage.desc", "Add images to PDF documents"), description: t("home.addImage.desc", "Add images to PDF documents"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING, subcategoryId: SubcategoryId.ADVANCED_FORMATTING,
synonyms: mergeSynonyms(t, "addImage"),
}, },
editTableOfContents: { editTableOfContents: {
icon: <LocalIcon icon="bookmark-add-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="bookmark-add-rounded" width="1.5rem" height="1.5rem" />,
@ -615,6 +658,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.editTableOfContents.desc", "Add or edit bookmarks and table of contents in PDF documents"), description: t("home.editTableOfContents.desc", "Add or edit bookmarks and table of contents in PDF documents"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING, subcategoryId: SubcategoryId.ADVANCED_FORMATTING,
synonyms: mergeSynonyms(t, "editTableOfContents"),
}, },
fakeScan: { fakeScan: {
icon: <LocalIcon icon="scanner-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="scanner-rounded" width="1.5rem" height="1.5rem" />,
@ -623,6 +667,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.fakeScan.desc", "Create a PDF that looks like it was scanned"), description: t("home.fakeScan.desc", "Create a PDF that looks like it was scanned"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING, subcategoryId: SubcategoryId.ADVANCED_FORMATTING,
synonyms: mergeSynonyms(t, "fakeScan"),
}, },
// Developer Tools // Developer Tools
@ -634,6 +679,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.showJS.desc", "Extract and display JavaScript code from PDF documents"), description: t("home.showJS.desc", "Extract and display JavaScript code from PDF documents"),
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.DEVELOPER_TOOLS, subcategoryId: SubcategoryId.DEVELOPER_TOOLS,
synonyms: mergeSynonyms(t, "showJS"),
}, },
devApi: { devApi: {
icon: <LocalIcon icon="open-in-new-rounded" width="1.5rem" height="1.5rem" style={{ color: "#2F7BF6" }} />, icon: <LocalIcon icon="open-in-new-rounded" width="1.5rem" height="1.5rem" style={{ color: "#2F7BF6" }} />,
@ -643,6 +689,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.DEVELOPER_TOOLS, subcategoryId: SubcategoryId.DEVELOPER_TOOLS,
link: "https://stirlingpdf.io/swagger-ui/5.21.0/index.html", link: "https://stirlingpdf.io/swagger-ui/5.21.0/index.html",
synonyms: mergeSynonyms(t, "devApi", ["api"]),
}, },
devFolderScanning: { devFolderScanning: {
icon: <LocalIcon icon="open-in-new-rounded" width="1.5rem" height="1.5rem" style={{ color: "#2F7BF6" }} />, icon: <LocalIcon icon="open-in-new-rounded" width="1.5rem" height="1.5rem" style={{ color: "#2F7BF6" }} />,
@ -652,6 +699,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.DEVELOPER_TOOLS, subcategoryId: SubcategoryId.DEVELOPER_TOOLS,
link: "https://docs.stirlingpdf.com/Advanced%20Configuration/Folder%20Scanning/", link: "https://docs.stirlingpdf.com/Advanced%20Configuration/Folder%20Scanning/",
synonyms: mergeSynonyms(t, "devFolderScanning"),
}, },
devSsoGuide: { devSsoGuide: {
icon: <LocalIcon icon="open-in-new-rounded" width="1.5rem" height="1.5rem" style={{ color: "#2F7BF6" }} />, icon: <LocalIcon icon="open-in-new-rounded" width="1.5rem" height="1.5rem" style={{ color: "#2F7BF6" }} />,
@ -661,6 +709,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.DEVELOPER_TOOLS, subcategoryId: SubcategoryId.DEVELOPER_TOOLS,
link: "https://docs.stirlingpdf.com/Advanced%20Configuration/Single%20Sign-On%20Configuration", link: "https://docs.stirlingpdf.com/Advanced%20Configuration/Single%20Sign-On%20Configuration",
synonyms: mergeSynonyms(t, "devSsoGuide"),
}, },
devAirgapped: { devAirgapped: {
icon: <LocalIcon icon="open-in-new-rounded" width="1.5rem" height="1.5rem" style={{ color: "#2F7BF6" }} />, icon: <LocalIcon icon="open-in-new-rounded" width="1.5rem" height="1.5rem" style={{ color: "#2F7BF6" }} />,
@ -670,6 +719,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.DEVELOPER_TOOLS, subcategoryId: SubcategoryId.DEVELOPER_TOOLS,
link: "https://docs.stirlingpdf.com/Pro/#activation", link: "https://docs.stirlingpdf.com/Pro/#activation",
synonyms: mergeSynonyms(t, "devAirgapped"),
}, },
// Recommended Tools // Recommended Tools
@ -680,7 +730,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.compare.desc", "Compare two PDF documents and highlight differences"), description: t("home.compare.desc", "Compare two PDF documents and highlight differences"),
categoryId: ToolCategoryId.RECOMMENDED_TOOLS, categoryId: ToolCategoryId.RECOMMENDED_TOOLS,
subcategoryId: SubcategoryId.GENERAL, subcategoryId: SubcategoryId.GENERAL,
synonyms: ["difference"] synonyms: mergeSynonyms(t, "compare", ["difference"])
}, },
compress: { compress: {
icon: <LocalIcon icon="zoom-in-map-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="zoom-in-map-rounded" width="1.5rem" height="1.5rem" />,
@ -692,7 +742,7 @@ export function useFlatToolRegistry(): ToolRegistry {
maxFiles: -1, maxFiles: -1,
operationConfig: compressOperationConfig, operationConfig: compressOperationConfig,
settingsComponent: CompressSettings, settingsComponent: CompressSettings,
synonyms: ["shrink", "reduce", "optimize"] synonyms: mergeSynonyms(t, "compress", ["shrink", "reduce", "optimize"])
}, },
convert: { convert: {
icon: <LocalIcon icon="sync-alt-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="sync-alt-rounded" width="1.5rem" height="1.5rem" />,
@ -722,7 +772,7 @@ export function useFlatToolRegistry(): ToolRegistry {
operationConfig: convertOperationConfig, operationConfig: convertOperationConfig,
settingsComponent: ConvertSettings, settingsComponent: ConvertSettings,
synonyms: ["transform", "change"] synonyms: mergeSynonyms(t, "convert", ["transform", "change"])
}, },
merge: { merge: {
icon: <LocalIcon icon="library-add-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="library-add-rounded" width="1.5rem" height="1.5rem" />,
@ -735,7 +785,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["merge-pdfs"], endpoints: ["merge-pdfs"],
operationConfig: mergeOperationConfig, operationConfig: mergeOperationConfig,
settingsComponent: MergeSettings, settingsComponent: MergeSettings,
synonyms: ["combine", "join", "unite"] synonyms: mergeSynonyms(t, "merge", ["combine", "join", "unite"])
}, },
multiTool: { multiTool: {
icon: <LocalIcon icon="dashboard-customize-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="dashboard-customize-rounded" width="1.5rem" height="1.5rem" />,
@ -746,6 +796,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.RECOMMENDED_TOOLS, categoryId: ToolCategoryId.RECOMMENDED_TOOLS,
subcategoryId: SubcategoryId.GENERAL, subcategoryId: SubcategoryId.GENERAL,
maxFiles: -1, maxFiles: -1,
synonyms: mergeSynonyms(t, "multiTool", ["multiple", "tools"]),
}, },
ocr: { ocr: {
icon: <LocalIcon icon="quick-reference-all-outline-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="quick-reference-all-outline-rounded" width="1.5rem" height="1.5rem" />,
@ -758,7 +809,7 @@ export function useFlatToolRegistry(): ToolRegistry {
urlPath: '/ocr-pdf', urlPath: '/ocr-pdf',
operationConfig: ocrOperationConfig, operationConfig: ocrOperationConfig,
settingsComponent: OCRSettings, settingsComponent: OCRSettings,
synonyms: ["extract", "scan"] synonyms: mergeSynonyms(t, "ocr", ["extract", "scan"])
}, },
redact: { redact: {
icon: <LocalIcon icon="visibility-off-rounded" width="1.5rem" height="1.5rem" />, icon: <LocalIcon icon="visibility-off-rounded" width="1.5rem" height="1.5rem" />,
@ -771,7 +822,7 @@ export function useFlatToolRegistry(): ToolRegistry {
endpoints: ["auto-redact"], endpoints: ["auto-redact"],
operationConfig: redactOperationConfig, operationConfig: redactOperationConfig,
settingsComponent: RedactSingleStepSettings, settingsComponent: RedactSingleStepSettings,
synonyms: ["censor", "blackout", "hide"] synonyms: mergeSynonyms(t, "redact", ["censor", "blackout", "hide"])
}, },
}; };