Revert change to add ToolId

This commit is contained in:
James Brunton 2025-08-22 12:20:34 +01:00
parent c2feebc6a5
commit f1757f8b31
11 changed files with 113 additions and 174 deletions

View File

@ -14,7 +14,6 @@ import PageEditorControls from '../pageEditor/PageEditorControls';
import Viewer from '../viewer/Viewer'; import Viewer from '../viewer/Viewer';
import ToolRenderer from '../tools/ToolRenderer'; import ToolRenderer from '../tools/ToolRenderer';
import LandingPage from '../shared/LandingPage'; import LandingPage from '../shared/LandingPage';
import { ToolId } from '../../data/toolsTaxonomy';
// No props needed - component uses contexts directly // No props needed - component uses contexts directly
export default function Workbench() { export default function Workbench() {
@ -43,15 +42,15 @@ export default function Workbench() {
const handlePreviewClose = () => { const handlePreviewClose = () => {
setPreviewFile(null); setPreviewFile(null);
const previousMode = sessionStorage.getItem('previousMode'); const previousMode = sessionStorage.getItem('previousMode');
if (previousMode === ToolId.SPLIT_PDF) { if (previousMode === 'split') {
// Use context's handleToolSelect which coordinates tool selection and view changes // Use context's handleToolSelect which coordinates tool selection and view changes
handleToolSelect(ToolId.SPLIT_PDF); handleToolSelect('split');
sessionStorage.removeItem('previousMode'); sessionStorage.removeItem('previousMode');
} else if (previousMode === ToolId.COMPRESS) { } else if (previousMode === 'compress') {
handleToolSelect(ToolId.COMPRESS); handleToolSelect('compress');
sessionStorage.removeItem('previousMode'); sessionStorage.removeItem('previousMode');
} else if (previousMode === ToolId.CONVERT) { } else if (previousMode === 'convert') {
handleToolSelect(ToolId.CONVERT); handleToolSelect('convert');
sessionStorage.removeItem('previousMode'); sessionStorage.removeItem('previousMode');
} else { } else {
setCurrentView('fileEditor'); setCurrentView('fileEditor');

View File

@ -18,7 +18,6 @@ import {
getNavButtonStyle, getNavButtonStyle,
getActiveNavButton, getActiveNavButton,
} from './quickAccessBar/QuickAccessBar'; } from './quickAccessBar/QuickAccessBar';
import { ToolId } from "../../data/toolsTaxonomy";
const QuickAccessBar = forwardRef<HTMLDivElement>(({ const QuickAccessBar = forwardRef<HTMLDivElement>(({
}, ref) => { }, ref) => {
@ -43,20 +42,20 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
const buttonConfigs: ButtonConfig[] = [ const buttonConfigs: ButtonConfig[] = [
{ {
id: ToolId.READ, id: 'read',
name: t("quickAccess.read", "Read"), name: t("quickAccess.read", "Read"),
icon: <MenuBookIcon sx={{ fontSize: "1.5rem" }} />, icon: <MenuBookIcon sx={{ fontSize: "1.5rem" }} />,
size: 'lg', size: 'lg',
isRound: false, isRound: false,
type: 'navigation', type: 'navigation',
onClick: () => { onClick: () => {
setActiveButton(ToolId.READ); setActiveButton('read');
handleBackToTools(); handleBackToTools();
handleReaderToggle(); handleReaderToggle();
} }
}, },
{ {
id: ToolId.SIGN, id: 'sign',
name: t("quickAccess.sign", "Sign"), name: t("quickAccess.sign", "Sign"),
icon: icon:
<span className="material-symbols-rounded font-size-20"> <span className="material-symbols-rounded font-size-20">
@ -67,11 +66,11 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
type: 'navigation', type: 'navigation',
onClick: () => { onClick: () => {
setActiveButton('sign'); setActiveButton('sign');
handleToolSelect(ToolId.SIGN); handleToolSelect('sign');
} }
}, },
{ {
id: ToolId.AUTOMATE, id: 'automate',
name: t("quickAccess.automate", "Automate"), name: t("quickAccess.automate", "Automate"),
icon: icon:
<span className="material-symbols-rounded font-size-20"> <span className="material-symbols-rounded font-size-20">
@ -81,8 +80,8 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
isRound: false, isRound: false,
type: 'navigation', type: 'navigation',
onClick: () => { onClick: () => {
setActiveButton(ToolId.AUTOMATE); setActiveButton('automate');
handleToolSelect(ToolId.AUTOMATE); handleToolSelect('automate');
} }
}, },
{ {

View File

@ -1,6 +1,6 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Box, Stack, Text } from '@mantine/core'; import { Box, Stack, Text } from '@mantine/core';
import { getSubcategoryLabel, ToolId, ToolRegistryEntry } from '../../data/toolsTaxonomy'; import { getSubcategoryLabel, ToolRegistryEntry } from '../../data/toolsTaxonomy';
import ToolButton from './toolPicker/ToolButton'; import ToolButton from './toolPicker/ToolButton';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useToolSections } from '../../hooks/useToolSections'; import { useToolSections } from '../../hooks/useToolSections';
@ -8,8 +8,8 @@ import SubcategoryHeader from './shared/SubcategoryHeader';
import NoToolsFound from './shared/NoToolsFound'; import NoToolsFound from './shared/NoToolsFound';
interface SearchResultsProps { interface SearchResultsProps {
filteredTools: [ToolId, ToolRegistryEntry][]; filteredTools: [string, ToolRegistryEntry][];
onSelect: (id: ToolId) => void; onSelect: (id: string) => void;
} }
const SearchResults: React.FC<SearchResultsProps> = ({ filteredTools, onSelect }) => { const SearchResults: React.FC<SearchResultsProps> = ({ filteredTools, onSelect }) => {

View File

@ -1,7 +1,7 @@
import React, { useMemo, useRef, useLayoutEffect, useState } from "react"; import React, { useMemo, useRef, useLayoutEffect, useState } from "react";
import { Box, Text, Stack } from "@mantine/core"; import { Box, Text, Stack } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { getSubcategoryLabel, ToolId, ToolRegistryEntry } from "../../data/toolsTaxonomy"; import { getSubcategoryLabel, ToolRegistryEntry } from "../../data/toolsTaxonomy";
import ToolButton from "./toolPicker/ToolButton"; import ToolButton from "./toolPicker/ToolButton";
import "./toolPicker/ToolPicker.css"; import "./toolPicker/ToolPicker.css";
import { SubcategoryGroup, useToolSections } from "../../hooks/useToolSections"; import { SubcategoryGroup, useToolSections } from "../../hooks/useToolSections";
@ -10,9 +10,9 @@ import NoToolsFound from "./shared/NoToolsFound";
import { TFunction } from "i18next"; import { TFunction } from "i18next";
interface ToolPickerProps { interface ToolPickerProps {
selectedToolKey: ToolId | null; selectedToolKey: string | null;
onSelect: (id: ToolId) => void; onSelect: (id: string) => void;
filteredTools: [ToolId, ToolRegistryEntry][]; filteredTools: [string, ToolRegistryEntry][];
isSearching?: boolean; isSearching?: boolean;
} }
@ -20,8 +20,8 @@ interface ToolPickerProps {
const renderToolButtons = ( const renderToolButtons = (
t: TFunction, t: TFunction,
subcategory: SubcategoryGroup, subcategory: SubcategoryGroup,
selectedToolKey: ToolId | null, selectedToolKey: string | null,
onSelect: (id: ToolId) => void, onSelect: (id: string) => void,
showSubcategoryHeader: boolean = true showSubcategoryHeader: boolean = true
) => ( ) => (
<Box key={subcategory.subcategoryId} w="100%"> <Box key={subcategory.subcategoryId} w="100%">
@ -29,7 +29,7 @@ const renderToolButtons = (
<SubcategoryHeader label={getSubcategoryLabel(t, subcategory.subcategoryId)} /> <SubcategoryHeader label={getSubcategoryLabel(t, subcategory.subcategoryId)} />
)} )}
<Stack gap="xs"> <Stack gap="xs">
{subcategory.tools.map(({ id, tool }) => ( {subcategory.tools.map(({ id, tool }: { id: string; tool: any }) => (
<ToolButton <ToolButton
key={id} key={id}
id={id} id={id}

View File

@ -1,18 +1,18 @@
import React from "react"; import React from "react";
import { Button } from "@mantine/core"; import { Button } from "@mantine/core";
import { Tooltip } from "../../shared/Tooltip"; import { Tooltip } from "../../shared/Tooltip";
import { ToolId, ToolRegistryEntry } from "../../../data/toolsTaxonomy"; import { ToolRegistryEntry } from "../../../data/toolsTaxonomy";
import FitText from "../../shared/FitText"; import FitText from "../../shared/FitText";
interface ToolButtonProps { interface ToolButtonProps {
id: ToolId; id: string;
tool: ToolRegistryEntry; tool: ToolRegistryEntry;
isSelected: boolean; isSelected: boolean;
onSelect: (id: ToolId) => void; onSelect: (id: string) => void;
} }
const ToolButton: React.FC<ToolButtonProps> = ({ id, tool, isSelected, onSelect }) => { const ToolButton: React.FC<ToolButtonProps> = ({ id, tool, isSelected, onSelect }) => {
const handleClick = (id: ToolId) => { const handleClick = (id: string) => {
if (tool.link) { if (tool.link) {
// Open external link in new tab // Open external link in new tab
window.open(tool.link, '_blank', 'noopener,noreferrer'); window.open(tool.link, '_blank', 'noopener,noreferrer');

View File

@ -6,7 +6,7 @@
import React, { createContext, useContext, useReducer, useCallback, useMemo } from 'react'; import React, { createContext, useContext, useReducer, useCallback, useMemo } from 'react';
import { useToolManagement } from '../hooks/useToolManagement'; import { useToolManagement } from '../hooks/useToolManagement';
import { PageEditorFunctions } from '../types/pageEditor'; import { PageEditorFunctions } from '../types/pageEditor';
import { ToolId, ToolRegistryEntry } from '../data/toolsTaxonomy'; import { ToolRegistryEntry } from '../data/toolsTaxonomy';
import { useToolWorkflowUrlSync } from '../hooks/useUrlSync'; import { useToolWorkflowUrlSync } from '../hooks/useUrlSync';
// State interface // State interface
@ -69,7 +69,7 @@ function toolWorkflowReducer(state: ToolWorkflowState, action: ToolWorkflowActio
// Context value interface // Context value interface
interface ToolWorkflowContextValue extends ToolWorkflowState { interface ToolWorkflowContextValue extends ToolWorkflowState {
// Tool management (from hook) // Tool management (from hook)
selectedToolKey: ToolId | null; selectedToolKey: string | null;
selectedTool: ToolRegistryEntry | null; selectedTool: ToolRegistryEntry | null;
toolRegistry: any; // From useToolManagement toolRegistry: any; // From useToolManagement
@ -82,16 +82,16 @@ interface ToolWorkflowContextValue extends ToolWorkflowState {
setSearchQuery: (query: string) => void; setSearchQuery: (query: string) => void;
// Tool Actions // Tool Actions
selectTool: (toolId: ToolId) => void; selectTool: (toolId: string) => void;
clearToolSelection: () => void; clearToolSelection: () => void;
// Workflow Actions (compound actions) // Workflow Actions (compound actions)
handleToolSelect: (toolId: ToolId) => void; handleToolSelect: (toolId: string) => void;
handleBackToTools: () => void; handleBackToTools: () => void;
handleReaderToggle: () => void; handleReaderToggle: () => void;
// Computed values // Computed values
filteredTools: [ToolId, ToolRegistryEntry][]; // Filtered by search filteredTools: [string, ToolRegistryEntry][]; // Filtered by search
isPanelVisible: boolean; isPanelVisible: boolean;
} }
@ -144,9 +144,9 @@ export function ToolWorkflowProvider({ children, onViewChange, enableUrlSync = t
}, []); }, []);
// Workflow actions (compound actions that coordinate multiple state changes) // Workflow actions (compound actions that coordinate multiple state changes)
const handleToolSelect = useCallback((toolId: ToolId) => { const handleToolSelect = useCallback((toolId: string) => {
// Special-case: if tool is a dedicated reader tool, enter reader mode and do not go to toolContent // Special-case: if tool is a dedicated reader tool, enter reader mode and do not go to toolContent
if (toolId === ToolId.READ) { if (toolId === 'read' || toolId === 'view-pdf') {
setReaderMode(true); setReaderMode(true);
setLeftPanelView('toolPicker'); setLeftPanelView('toolPicker');
clearToolSelection(); clearToolSelection();
@ -175,7 +175,7 @@ export function ToolWorkflowProvider({ children, onViewChange, enableUrlSync = t
// Filter tools based on search query // Filter tools based on search query
const filteredTools = useMemo(() => { const filteredTools = useMemo(() => {
if (!toolRegistry) return []; if (!toolRegistry) return [];
return (Object.entries(toolRegistry) as [ToolId, ToolRegistryEntry][]).filter(([_, { name }]) => return Object.entries(toolRegistry).filter(([_, { name }]) =>
name.toLowerCase().includes(state.searchQuery.toLowerCase()) name.toLowerCase().includes(state.searchQuery.toLowerCase())
); );
}, [toolRegistry, state.searchQuery]); }, [toolRegistry, state.searchQuery]);

View File

@ -2,64 +2,6 @@ import { type TFunction } from 'i18next';
import React from 'react'; import React from 'react';
import { BaseToolProps } from '../types/tool'; import { BaseToolProps } from '../types/tool';
export enum ToolId {
CERT_SIGN = 'certSign',
SIGN = 'sign',
ADD_PASSWORD = 'addPassword',
WATERMARK = 'watermark',
ADD_STAMP = 'add-stamp',
SANITIZE = 'sanitize',
FLATTEN = 'flatten',
UNLOCK_PDF_FORMS = 'unlock-pdf-forms',
MANAGE_CERTIFICATES = 'manage-certificates',
CHANGE_PERMISSIONS = 'change-permissions',
GET_ALL_INFO_ON_PDF = 'get-all-info-on-pdf',
VALIDATE_PDF_SIGNATURE = 'validate-pdf-signature',
READ = 'read',
CHANGE_METADATA = 'change-metadata',
CROP_PDF = 'cropPdf',
ROTATE = 'rotate',
SPLIT_PDF = 'splitPdf',
REORGANIZE_PAGES = 'reorganize-pages',
ADJUST_PAGE_SIZE_SCALE = 'adjust-page-size-scale',
ADD_PAGE_NUMBERS = 'addPageNumbers',
MULTI_PAGE_LAYOUT = 'multi-page-layout',
SINGLE_LARGE_PAGE = 'single-large-page',
ADD_ATTACHMENTS = 'add-attachments',
EXTRACT_PAGES = 'extractPages',
EXTRACT_IMAGES = 'extract-images',
REMOVE_PAGES = 'removePages',
REMOVE_BLANK_PAGES = 'remove-blank-pages',
REMOVE_ANNOTATIONS = 'remove-annotations',
REMOVE_IMAGE = 'remove-image',
REMOVE_PASSWORD = 'remove-password',
REMOVE_CERTIFICATE_SIGN = 'remove-certificate-sign',
AUTOMATE = 'automate',
AUTO_RENAME_PDF_FILE = 'auto-rename-pdf-file',
AUTO_SPLIT_PAGES = 'auto-split-pages',
AUTO_SPLIT_BY_SIZE_COUNT = 'auto-split-by-size-count',
ADJUST_CONTRAST = 'adjustContrast',
REPAIR = 'repair',
DETECT_SPLIT_SCANNED_PHOTOS = 'detect-split-scanned-photos',
OVERLAY_PDFS = 'overlay-pdfs',
REPLACE_AND_INVERT_COLOR = 'replace-and-invert-color',
ADD_IMAGE = 'add-image',
EDIT_TABLE_OF_CONTENTS = 'edit-table-of-contents',
SCANNER_EFFECT = 'scanner-effect',
SHOW_JAVASCRIPT = 'show-javascript',
DEV_API = 'dev-api',
DEV_FOLDER_SCANNING = 'dev-folder-scanning',
DEV_SSO_GUIDE = 'dev-sso-guide',
DEV_AIRGAPPED = 'dev-airgapped',
COMPARE = 'compare',
COMPRESS = 'compress',
CONVERT = 'convert',
MERGE_PDFS = 'mergePdfs',
MULTI_TOOL = 'multi-tool',
OCR = 'ocr',
REDACT = 'redact'
};
export enum SubcategoryId { export enum SubcategoryId {
SIGNING = 'signing', SIGNING = 'signing',
DOCUMENT_SECURITY = 'documentSecurity', DOCUMENT_SECURITY = 'documentSecurity',
@ -95,7 +37,7 @@ export type ToolRegistryEntry = {
type?: string; type?: string;
} }
export type ToolRegistry = Record<ToolId, ToolRegistryEntry>; export type ToolRegistry = Record<string /* FIX ME: Should be ToolId */, ToolRegistryEntry>;
export const SUBCATEGORY_ORDER: SubcategoryId[] = [ export const SUBCATEGORY_ORDER: SubcategoryId[] = [
SubcategoryId.SIGNING, SubcategoryId.SIGNING,

View File

@ -7,7 +7,7 @@ import Sanitize from '../tools/Sanitize';
import AddPassword from '../tools/AddPassword'; import AddPassword from '../tools/AddPassword';
import ChangePermissions from '../tools/ChangePermissions'; import ChangePermissions from '../tools/ChangePermissions';
import RemovePassword from '../tools/RemovePassword'; import RemovePassword from '../tools/RemovePassword';
import { SubcategoryId, ToolCategoryId, ToolId, ToolRegistry } from './toolsTaxonomy'; import { SubcategoryId, ToolCategoryId, ToolRegistry } from './toolsTaxonomy';
import AddWatermark from '../tools/AddWatermark'; import AddWatermark from '../tools/AddWatermark';
import Repair from '../tools/Repair'; import Repair from '../tools/Repair';
import SingleLargePage from '../tools/SingleLargePage'; import SingleLargePage from '../tools/SingleLargePage';
@ -23,7 +23,7 @@ export function useFlatToolRegistry(): ToolRegistry {
const allTools: ToolRegistry = { const allTools: ToolRegistry = {
// Signing // Signing
[ToolId.CERT_SIGN]: { "certSign": {
icon: <span className="material-symbols-rounded">workspace_premium</span>, icon: <span className="material-symbols-rounded">workspace_premium</span>,
name: t("home.certSign.title", "Sign with Certificate"), name: t("home.certSign.title", "Sign with Certificate"),
component: null, component: null,
@ -32,7 +32,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.SIGNING subcategoryId: SubcategoryId.SIGNING
}, },
[ToolId.SIGN]: { "sign": {
icon: <span className="material-symbols-rounded">signature</span>, icon: <span className="material-symbols-rounded">signature</span>,
name: t("home.sign.title", "Sign"), name: t("home.sign.title", "Sign"),
component: null, component: null,
@ -45,7 +45,7 @@ export function useFlatToolRegistry(): ToolRegistry {
// Document Security // Document Security
[ToolId.ADD_PASSWORD]: { "addPassword": {
icon: <span className="material-symbols-rounded">password</span>, icon: <span className="material-symbols-rounded">password</span>,
name: t("home.addPassword.title", "Add Password"), name: t("home.addPassword.title", "Add Password"),
component: AddPassword, component: AddPassword,
@ -56,7 +56,7 @@ export function useFlatToolRegistry(): ToolRegistry {
maxFiles: -1, maxFiles: -1,
endpoints: ["add-password"] endpoints: ["add-password"]
}, },
[ToolId.WATERMARK]: { "watermark": {
icon: <span className="material-symbols-rounded">branding_watermark</span>, icon: <span className="material-symbols-rounded">branding_watermark</span>,
name: t("home.watermark.title", "Add Watermark"), name: t("home.watermark.title", "Add Watermark"),
component: AddWatermark, component: AddWatermark,
@ -67,7 +67,7 @@ export function useFlatToolRegistry(): ToolRegistry {
subcategoryId: SubcategoryId.DOCUMENT_SECURITY, subcategoryId: SubcategoryId.DOCUMENT_SECURITY,
endpoints: ["add-watermark"] endpoints: ["add-watermark"]
}, },
[ToolId.ADD_STAMP]: { "add-stamp": {
icon: <span className="material-symbols-rounded">approval</span>, icon: <span className="material-symbols-rounded">approval</span>,
name: t("home.AddStampRequest.title", "Add Stamp to PDF"), name: t("home.AddStampRequest.title", "Add Stamp to PDF"),
component: null, component: null,
@ -76,7 +76,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.DOCUMENT_SECURITY subcategoryId: SubcategoryId.DOCUMENT_SECURITY
}, },
[ToolId.SANITIZE]: { "sanitize": {
icon: <span className="material-symbols-rounded">cleaning_services</span>, icon: <span className="material-symbols-rounded">cleaning_services</span>,
name: t("home.sanitize.title", "Sanitize"), name: t("home.sanitize.title", "Sanitize"),
component: Sanitize, component: Sanitize,
@ -87,7 +87,7 @@ export function useFlatToolRegistry(): ToolRegistry {
description: t("home.sanitize.desc", "Remove potentially harmful elements from PDF files"), description: t("home.sanitize.desc", "Remove potentially harmful elements from PDF files"),
endpoints: ["sanitize-pdf"] endpoints: ["sanitize-pdf"]
}, },
[ToolId.FLATTEN]: { "flatten": {
icon: <span className="material-symbols-rounded">layers_clear</span>, icon: <span className="material-symbols-rounded">layers_clear</span>,
name: t("home.flatten.title", "Flatten"), name: t("home.flatten.title", "Flatten"),
component: null, component: null,
@ -96,7 +96,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.DOCUMENT_SECURITY subcategoryId: SubcategoryId.DOCUMENT_SECURITY
}, },
[ToolId.UNLOCK_PDF_FORMS]: { "unlock-pdf-forms": {
icon: <span className="material-symbols-rounded">preview_off</span>, icon: <span className="material-symbols-rounded">preview_off</span>,
name: t("home.unlockPDFForms.title", "Unlock PDF Forms"), name: t("home.unlockPDFForms.title", "Unlock PDF Forms"),
component: UnlockPdfForms, component: UnlockPdfForms,
@ -107,7 +107,7 @@ export function useFlatToolRegistry(): ToolRegistry {
maxFiles: -1, maxFiles: -1,
endpoints: ["unlock-pdf-forms"] endpoints: ["unlock-pdf-forms"]
}, },
[ToolId.MANAGE_CERTIFICATES]: { "manage-certificates": {
icon: <span className="material-symbols-rounded">license</span>, icon: <span className="material-symbols-rounded">license</span>,
name: t("home.manageCertificates.title", "Manage Certificates"), name: t("home.manageCertificates.title", "Manage Certificates"),
component: null, component: null,
@ -116,7 +116,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.DOCUMENT_SECURITY subcategoryId: SubcategoryId.DOCUMENT_SECURITY
}, },
[ToolId.CHANGE_PERMISSIONS]: { "change-permissions": {
icon: <span className="material-symbols-rounded">lock</span>, icon: <span className="material-symbols-rounded">lock</span>,
name: t("home.changePermissions.title", "Change Permissions"), name: t("home.changePermissions.title", "Change Permissions"),
component: ChangePermissions, component: ChangePermissions,
@ -129,7 +129,7 @@ export function useFlatToolRegistry(): ToolRegistry {
}, },
// Verification // Verification
[ToolId.GET_ALL_INFO_ON_PDF]: { "get-all-info-on-pdf": {
icon: <span className="material-symbols-rounded">fact_check</span>, icon: <span className="material-symbols-rounded">fact_check</span>,
name: t("home.getPdfInfo.title", "Get ALL Info on PDF"), name: t("home.getPdfInfo.title", "Get ALL Info on PDF"),
component: null, component: null,
@ -138,7 +138,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.VERIFICATION subcategoryId: SubcategoryId.VERIFICATION
}, },
[ToolId.VALIDATE_PDF_SIGNATURE]: { "validate-pdf-signature": {
icon: <span className="material-symbols-rounded">verified</span>, icon: <span className="material-symbols-rounded">verified</span>,
name: t("home.validateSignature.title", "Validate PDF Signature"), name: t("home.validateSignature.title", "Validate PDF Signature"),
component: null, component: null,
@ -151,7 +151,7 @@ export function useFlatToolRegistry(): ToolRegistry {
// Document Review // Document Review
[ToolId.READ]: { "read": {
icon: <span className="material-symbols-rounded">article</span>, icon: <span className="material-symbols-rounded">article</span>,
name: t("home.read.title", "Read"), name: t("home.read.title", "Read"),
component: null, component: null,
@ -160,7 +160,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.DOCUMENT_REVIEW subcategoryId: SubcategoryId.DOCUMENT_REVIEW
}, },
[ToolId.CHANGE_METADATA]: { "change-metadata": {
icon: <span className="material-symbols-rounded">assignment</span>, icon: <span className="material-symbols-rounded">assignment</span>,
name: t("home.changeMetadata.title", "Change Metadata"), name: t("home.changeMetadata.title", "Change Metadata"),
component: null, component: null,
@ -171,7 +171,7 @@ export function useFlatToolRegistry(): ToolRegistry {
}, },
// Page Formatting // Page Formatting
[ToolId.CROP_PDF]: { "cropPdf": {
icon: <span className="material-symbols-rounded">crop</span>, icon: <span className="material-symbols-rounded">crop</span>,
name: t("home.crop.title", "Crop PDF"), name: t("home.crop.title", "Crop PDF"),
component: null, component: null,
@ -180,7 +180,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING subcategoryId: SubcategoryId.PAGE_FORMATTING
}, },
[ToolId.ROTATE]: { "rotate": {
icon: <span className="material-symbols-rounded">rotate_right</span>, icon: <span className="material-symbols-rounded">rotate_right</span>,
name: t("home.rotate.title", "Rotate"), name: t("home.rotate.title", "Rotate"),
component: null, component: null,
@ -189,7 +189,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING subcategoryId: SubcategoryId.PAGE_FORMATTING
}, },
[ToolId.SPLIT_PDF]: { "splitPdf": {
icon: <span className="material-symbols-rounded">content_cut</span>, icon: <span className="material-symbols-rounded">content_cut</span>,
name: t("home.split.title", "Split"), name: t("home.split.title", "Split"),
component: SplitPdfPanel, component: SplitPdfPanel,
@ -198,7 +198,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING subcategoryId: SubcategoryId.PAGE_FORMATTING
}, },
[ToolId.REORGANIZE_PAGES]: { "reorganize-pages": {
icon: <span className="material-symbols-rounded">move_down</span>, icon: <span className="material-symbols-rounded">move_down</span>,
name: t("home.reorganizePages.title", "Reorganize Pages"), name: t("home.reorganizePages.title", "Reorganize Pages"),
component: null, component: null,
@ -207,7 +207,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING subcategoryId: SubcategoryId.PAGE_FORMATTING
}, },
[ToolId.ADJUST_PAGE_SIZE_SCALE]: { "adjust-page-size-scale": {
icon: <span className="material-symbols-rounded">crop_free</span>, icon: <span className="material-symbols-rounded">crop_free</span>,
name: t("home.scalePages.title", "Adjust page size/scale"), name: t("home.scalePages.title", "Adjust page size/scale"),
component: null, component: null,
@ -216,7 +216,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING subcategoryId: SubcategoryId.PAGE_FORMATTING
}, },
[ToolId.ADD_PAGE_NUMBERS]: { "addPageNumbers": {
icon: <span className="material-symbols-rounded">123</span>, icon: <span className="material-symbols-rounded">123</span>,
name: t("home.addPageNumbers.title", "Add Page Numbers"), name: t("home.addPageNumbers.title", "Add Page Numbers"),
component: null, component: null,
@ -225,7 +225,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING subcategoryId: SubcategoryId.PAGE_FORMATTING
}, },
[ToolId.MULTI_PAGE_LAYOUT]: { "multi-page-layout": {
icon: <span className="material-symbols-rounded">dashboard</span>, icon: <span className="material-symbols-rounded">dashboard</span>,
name: t("home.pageLayout.title", "Multi-Page Layout"), name: t("home.pageLayout.title", "Multi-Page Layout"),
component: null, component: null,
@ -234,7 +234,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.PAGE_FORMATTING subcategoryId: SubcategoryId.PAGE_FORMATTING
}, },
[ToolId.SINGLE_LARGE_PAGE]: { "single-large-page": {
icon: <span className="material-symbols-rounded">looks_one</span>, icon: <span className="material-symbols-rounded">looks_one</span>,
name: t("home.pdfToSinglePage.title", "PDF to Single Large Page"), name: t("home.pdfToSinglePage.title", "PDF to Single Large Page"),
component: SingleLargePage, component: SingleLargePage,
@ -245,7 +245,7 @@ export function useFlatToolRegistry(): ToolRegistry {
maxFiles: -1, maxFiles: -1,
endpoints: ["pdf-to-single-page"] endpoints: ["pdf-to-single-page"]
}, },
[ToolId.ADD_ATTACHMENTS]: { "add-attachments": {
icon: <span className="material-symbols-rounded">attachment</span>, icon: <span className="material-symbols-rounded">attachment</span>,
name: t("home.attachments.title", "Add Attachments"), name: t("home.attachments.title", "Add Attachments"),
component: null, component: null,
@ -258,7 +258,7 @@ export function useFlatToolRegistry(): ToolRegistry {
// Extraction // Extraction
[ToolId.EXTRACT_PAGES]: { "extractPages": {
icon: <span className="material-symbols-rounded">upload</span>, icon: <span className="material-symbols-rounded">upload</span>,
name: t("home.extractPages.title", "Extract Pages"), name: t("home.extractPages.title", "Extract Pages"),
component: null, component: null,
@ -267,7 +267,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.EXTRACTION subcategoryId: SubcategoryId.EXTRACTION
}, },
[ToolId.EXTRACT_IMAGES]: { "extract-images": {
icon: <span className="material-symbols-rounded">filter</span>, icon: <span className="material-symbols-rounded">filter</span>,
name: t("home.extractImages.title", "Extract Images"), name: t("home.extractImages.title", "Extract Images"),
component: null, component: null,
@ -280,7 +280,7 @@ export function useFlatToolRegistry(): ToolRegistry {
// Removal // Removal
[ToolId.REMOVE_PAGES]: { "removePages": {
icon: <span className="material-symbols-rounded">delete</span>, icon: <span className="material-symbols-rounded">delete</span>,
name: t("home.removePages.title", "Remove Pages"), name: t("home.removePages.title", "Remove Pages"),
component: null, component: null,
@ -289,7 +289,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.REMOVAL subcategoryId: SubcategoryId.REMOVAL
}, },
[ToolId.REMOVE_BLANK_PAGES]: { "remove-blank-pages": {
icon: <span className="material-symbols-rounded">scan_delete</span>, icon: <span className="material-symbols-rounded">scan_delete</span>,
name: t("home.removeBlanks.title", "Remove Blank Pages"), name: t("home.removeBlanks.title", "Remove Blank Pages"),
component: null, component: null,
@ -298,7 +298,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.REMOVAL subcategoryId: SubcategoryId.REMOVAL
}, },
[ToolId.REMOVE_ANNOTATIONS]: { "remove-annotations": {
icon: <span className="material-symbols-rounded">thread_unread</span>, icon: <span className="material-symbols-rounded">thread_unread</span>,
name: t("home.removeAnnotations.title", "Remove Annotations"), name: t("home.removeAnnotations.title", "Remove Annotations"),
component: null, component: null,
@ -307,7 +307,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.REMOVAL subcategoryId: SubcategoryId.REMOVAL
}, },
[ToolId.REMOVE_IMAGE]: { "remove-image": {
icon: <span className="material-symbols-rounded">remove_selection</span>, icon: <span className="material-symbols-rounded">remove_selection</span>,
name: t("home.removeImagePdf.title", "Remove Image"), name: t("home.removeImagePdf.title", "Remove Image"),
component: null, component: null,
@ -316,7 +316,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.STANDARD_TOOLS, categoryId: ToolCategoryId.STANDARD_TOOLS,
subcategoryId: SubcategoryId.REMOVAL subcategoryId: SubcategoryId.REMOVAL
}, },
[ToolId.REMOVE_PASSWORD]: { "remove-password": {
icon: <span className="material-symbols-rounded">lock_open_right</span>, icon: <span className="material-symbols-rounded">lock_open_right</span>,
name: t("home.removePassword.title", "Remove Password"), name: t("home.removePassword.title", "Remove Password"),
component: RemovePassword, component: RemovePassword,
@ -328,7 +328,7 @@ export function useFlatToolRegistry(): ToolRegistry {
maxFiles: -1, maxFiles: -1,
}, },
[ToolId.REMOVE_CERTIFICATE_SIGN]: { "remove-certificate-sign": {
icon: <span className="material-symbols-rounded">remove_moderator</span>, icon: <span className="material-symbols-rounded">remove_moderator</span>,
name: t("home.removeCertSign.title", "Remove Certificate Sign"), name: t("home.removeCertSign.title", "Remove Certificate Sign"),
component: RemoveCertificateSign, component: RemoveCertificateSign,
@ -343,7 +343,7 @@ export function useFlatToolRegistry(): ToolRegistry {
// Automation // Automation
[ToolId.AUTOMATE]: { "automate": {
icon: <span className="material-symbols-rounded">automation</span>, icon: <span className="material-symbols-rounded">automation</span>,
name: t("home.automate.title", "Automate"), name: t("home.automate.title", "Automate"),
component: null, component: null,
@ -352,7 +352,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.AUTOMATION subcategoryId: SubcategoryId.AUTOMATION
}, },
[ToolId.AUTO_RENAME_PDF_FILE]: { "auto-rename-pdf-file": {
icon: <span className="material-symbols-rounded">match_word</span>, icon: <span className="material-symbols-rounded">match_word</span>,
name: t("home.auto-rename.title", "Auto Rename PDF File"), name: t("home.auto-rename.title", "Auto Rename PDF File"),
component: null, component: null,
@ -361,7 +361,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.AUTOMATION subcategoryId: SubcategoryId.AUTOMATION
}, },
[ToolId.AUTO_SPLIT_PAGES]: { "auto-split-pages": {
icon: <span className="material-symbols-rounded">split_scene_right</span>, icon: <span className="material-symbols-rounded">split_scene_right</span>,
name: t("home.autoSplitPDF.title", "Auto Split Pages"), name: t("home.autoSplitPDF.title", "Auto Split Pages"),
component: null, component: null,
@ -370,7 +370,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.AUTOMATION subcategoryId: SubcategoryId.AUTOMATION
}, },
[ToolId.AUTO_SPLIT_BY_SIZE_COUNT]: { "auto-split-by-size-count": {
icon: <span className="material-symbols-rounded">content_cut</span>, icon: <span className="material-symbols-rounded">content_cut</span>,
name: t("home.autoSizeSplitPDF.title", "Auto Split by Size/Count"), name: t("home.autoSizeSplitPDF.title", "Auto Split by Size/Count"),
component: null, component: null,
@ -383,7 +383,7 @@ export function useFlatToolRegistry(): ToolRegistry {
// Advanced Formatting // Advanced Formatting
[ToolId.ADJUST_CONTRAST]: { "adjustContrast": {
icon: <span className="material-symbols-rounded">palette</span>, icon: <span className="material-symbols-rounded">palette</span>,
name: t("home.adjustContrast.title", "Adjust Colors/Contrast"), name: t("home.adjustContrast.title", "Adjust Colors/Contrast"),
component: null, component: null,
@ -392,7 +392,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING subcategoryId: SubcategoryId.ADVANCED_FORMATTING
}, },
[ToolId.REPAIR]: { "repair": {
icon: <span className="material-symbols-rounded">build</span>, icon: <span className="material-symbols-rounded">build</span>,
name: t("home.repair.title", "Repair"), name: t("home.repair.title", "Repair"),
component: Repair, component: Repair,
@ -403,7 +403,7 @@ export function useFlatToolRegistry(): ToolRegistry {
maxFiles: -1, maxFiles: -1,
endpoints: ["repair"] endpoints: ["repair"]
}, },
[ToolId.DETECT_SPLIT_SCANNED_PHOTOS]: { "detect-split-scanned-photos": {
icon: <span className="material-symbols-rounded">scanner</span>, icon: <span className="material-symbols-rounded">scanner</span>,
name: t("home.ScannerImageSplit.title", "Detect & Split Scanned Photos"), name: t("home.ScannerImageSplit.title", "Detect & Split Scanned Photos"),
component: null, component: null,
@ -412,7 +412,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING subcategoryId: SubcategoryId.ADVANCED_FORMATTING
}, },
[ToolId.OVERLAY_PDFS]: { "overlay-pdfs": {
icon: <span className="material-symbols-rounded">layers</span>, icon: <span className="material-symbols-rounded">layers</span>,
name: t("home.overlay-pdfs.title", "Overlay PDFs"), name: t("home.overlay-pdfs.title", "Overlay PDFs"),
component: null, component: null,
@ -421,7 +421,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING subcategoryId: SubcategoryId.ADVANCED_FORMATTING
}, },
[ToolId.REPLACE_AND_INVERT_COLOR]: { "replace-and-invert-color": {
icon: <span className="material-symbols-rounded">format_color_fill</span>, icon: <span className="material-symbols-rounded">format_color_fill</span>,
name: t("home.replaceColorPdf.title", "Replace & Invert Color"), name: t("home.replaceColorPdf.title", "Replace & Invert Color"),
component: null, component: null,
@ -430,7 +430,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING subcategoryId: SubcategoryId.ADVANCED_FORMATTING
}, },
[ToolId.ADD_IMAGE]: { "add-image": {
icon: <span className="material-symbols-rounded">image</span>, icon: <span className="material-symbols-rounded">image</span>,
name: t("home.addImage.title", "Add Image"), name: t("home.addImage.title", "Add Image"),
component: null, component: null,
@ -439,7 +439,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING subcategoryId: SubcategoryId.ADVANCED_FORMATTING
}, },
[ToolId.EDIT_TABLE_OF_CONTENTS]: { "edit-table-of-contents": {
icon: <span className="material-symbols-rounded">bookmark_add</span>, icon: <span className="material-symbols-rounded">bookmark_add</span>,
name: t("home.editTableOfContents.title", "Edit Table of Contents"), name: t("home.editTableOfContents.title", "Edit Table of Contents"),
component: null, component: null,
@ -448,7 +448,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.ADVANCED_FORMATTING subcategoryId: SubcategoryId.ADVANCED_FORMATTING
}, },
[ToolId.SCANNER_EFFECT]: { "scanner-effect": {
icon: <span className="material-symbols-rounded">scanner</span>, icon: <span className="material-symbols-rounded">scanner</span>,
name: t("home.fakeScan.title", "Scanner Effect"), name: t("home.fakeScan.title", "Scanner Effect"),
component: null, component: null,
@ -461,7 +461,7 @@ export function useFlatToolRegistry(): ToolRegistry {
// Developer Tools // Developer Tools
[ToolId.SHOW_JAVASCRIPT]: { "show-javascript": {
icon: <span className="material-symbols-rounded">javascript</span>, icon: <span className="material-symbols-rounded">javascript</span>,
name: t("home.showJS.title", "Show JavaScript"), name: t("home.showJS.title", "Show JavaScript"),
component: null, component: null,
@ -470,7 +470,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.ADVANCED_TOOLS, categoryId: ToolCategoryId.ADVANCED_TOOLS,
subcategoryId: SubcategoryId.DEVELOPER_TOOLS subcategoryId: SubcategoryId.DEVELOPER_TOOLS
}, },
[ToolId.DEV_API]: { "dev-api": {
icon: <span className="material-symbols-rounded" style={{ color: '#2F7BF6' }}>open_in_new</span>, icon: <span className="material-symbols-rounded" style={{ color: '#2F7BF6' }}>open_in_new</span>,
name: t("home.devApi.title", "API"), name: t("home.devApi.title", "API"),
component: null, component: null,
@ -480,7 +480,7 @@ export function useFlatToolRegistry(): ToolRegistry {
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"
}, },
[ToolId.DEV_FOLDER_SCANNING]: { "dev-folder-scanning": {
icon: <span className="material-symbols-rounded" style={{ color: '#2F7BF6' }}>open_in_new</span>, icon: <span className="material-symbols-rounded" style={{ color: '#2F7BF6' }}>open_in_new</span>,
name: t("home.devFolderScanning.title", "Automated Folder Scanning"), name: t("home.devFolderScanning.title", "Automated Folder Scanning"),
component: null, component: null,
@ -490,7 +490,7 @@ export function useFlatToolRegistry(): ToolRegistry {
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/"
}, },
[ToolId.DEV_SSO_GUIDE]: { "dev-sso-guide": {
icon: <span className="material-symbols-rounded" style={{ color: '#2F7BF6' }}>open_in_new</span>, icon: <span className="material-symbols-rounded" style={{ color: '#2F7BF6' }}>open_in_new</span>,
name: t("home.devSsoGuide.title", "SSO Guide"), name: t("home.devSsoGuide.title", "SSO Guide"),
component: null, component: null,
@ -500,7 +500,7 @@ export function useFlatToolRegistry(): ToolRegistry {
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",
}, },
[ToolId.DEV_AIRGAPPED]: { "dev-airgapped": {
icon: <span className="material-symbols-rounded" style={{ color: '#2F7BF6' }}>open_in_new</span>, icon: <span className="material-symbols-rounded" style={{ color: '#2F7BF6' }}>open_in_new</span>,
name: t("home.devAirgapped.title", "Air-gapped Setup"), name: t("home.devAirgapped.title", "Air-gapped Setup"),
component: null, component: null,
@ -513,7 +513,7 @@ export function useFlatToolRegistry(): ToolRegistry {
// Recommended Tools // Recommended Tools
[ToolId.COMPARE]: { "compare": {
icon: <span className="material-symbols-rounded">compare</span>, icon: <span className="material-symbols-rounded">compare</span>,
name: t("home.compare.title", "Compare"), name: t("home.compare.title", "Compare"),
component: null, component: null,
@ -522,7 +522,7 @@ export function useFlatToolRegistry(): ToolRegistry {
categoryId: ToolCategoryId.RECOMMENDED_TOOLS, categoryId: ToolCategoryId.RECOMMENDED_TOOLS,
subcategoryId: SubcategoryId.GENERAL subcategoryId: SubcategoryId.GENERAL
}, },
[ToolId.COMPRESS]: { "compress": {
icon: <span className="material-symbols-rounded">zoom_in_map</span>, icon: <span className="material-symbols-rounded">zoom_in_map</span>,
name: t("home.compress.title", "Compress"), name: t("home.compress.title", "Compress"),
component: CompressPdfPanel, component: CompressPdfPanel,
@ -532,7 +532,7 @@ export function useFlatToolRegistry(): ToolRegistry {
subcategoryId: SubcategoryId.GENERAL, subcategoryId: SubcategoryId.GENERAL,
maxFiles: -1 maxFiles: -1
}, },
[ToolId.CONVERT]: { "convert": {
icon: <span className="material-symbols-rounded">sync_alt</span>, icon: <span className="material-symbols-rounded">sync_alt</span>,
name: t("home.convert.title", "Convert"), name: t("home.convert.title", "Convert"),
component: ConvertPanel, component: ConvertPanel,
@ -576,7 +576,7 @@ export function useFlatToolRegistry(): ToolRegistry {
"dbf", "fods", "vsd", "vor", "vor3", "vor4", "uop", "pct", "ps", "pdf" "dbf", "fods", "vsd", "vor", "vor3", "vor4", "uop", "pct", "ps", "pdf"
] ]
}, },
[ToolId.MERGE_PDFS]: { "mergePdfs": {
icon: <span className="material-symbols-rounded">library_add</span>, icon: <span className="material-symbols-rounded">library_add</span>,
name: t("home.merge.title", "Merge"), name: t("home.merge.title", "Merge"),
component: null, component: null,
@ -586,7 +586,7 @@ export function useFlatToolRegistry(): ToolRegistry {
subcategoryId: SubcategoryId.GENERAL, subcategoryId: SubcategoryId.GENERAL,
maxFiles: -1 maxFiles: -1
}, },
[ToolId.MULTI_TOOL]: { "multi-tool": {
icon: <span className="material-symbols-rounded">dashboard_customize</span>, icon: <span className="material-symbols-rounded">dashboard_customize</span>,
name: t("home.multiTool.title", "Multi-Tool"), name: t("home.multiTool.title", "Multi-Tool"),
component: null, component: null,
@ -596,7 +596,7 @@ export function useFlatToolRegistry(): ToolRegistry {
subcategoryId: SubcategoryId.GENERAL, subcategoryId: SubcategoryId.GENERAL,
maxFiles: -1 maxFiles: -1
}, },
[ToolId.OCR]: { "ocr": {
icon: <span className="material-symbols-rounded">quick_reference_all</span>, icon: <span className="material-symbols-rounded">quick_reference_all</span>,
name: t("home.ocr.title", "OCR"), name: t("home.ocr.title", "OCR"),
component: OCRPanel, component: OCRPanel,
@ -606,7 +606,7 @@ export function useFlatToolRegistry(): ToolRegistry {
subcategoryId: SubcategoryId.GENERAL, subcategoryId: SubcategoryId.GENERAL,
maxFiles: -1 maxFiles: -1
}, },
[ToolId.REDACT]: { "redact": {
icon: <span className="material-symbols-rounded">visibility_off</span>, icon: <span className="material-symbols-rounded">visibility_off</span>,
name: t("home.redact.title", "Redact"), name: t("home.redact.title", "Redact"),
component: null, component: null,
@ -620,7 +620,7 @@ export function useFlatToolRegistry(): ToolRegistry {
if (showPlaceholderTools) { if (showPlaceholderTools) {
return allTools; return allTools;
} else { } else {
const filteredTools = (Object.keys(allTools) as ToolId[]) const filteredTools = Object.keys(allTools)
.filter(key => allTools[key].component !== null || allTools[key].link) .filter(key => allTools[key].component !== null || allTools[key].link)
.reduce((obj, key) => { .reduce((obj, key) => {
obj[key] = allTools[key]; obj[key] = allTools[key];

View File

@ -7,10 +7,9 @@ import SwapHorizIcon from '@mui/icons-material/SwapHoriz';
import CleaningServicesIcon from '@mui/icons-material/CleaningServices'; import CleaningServicesIcon from '@mui/icons-material/CleaningServices';
import CropIcon from '@mui/icons-material/Crop'; import CropIcon from '@mui/icons-material/Crop';
import TextFieldsIcon from '@mui/icons-material/TextFields'; import TextFieldsIcon from '@mui/icons-material/TextFields';
import { ToolId } from '../data/toolsTaxonomy';
export interface SuggestedTool { export interface SuggestedTool {
id: ToolId; id: string /* FIX ME: Should be ToolId */;
title: string; title: string;
icon: React.ComponentType<any>; icon: React.ComponentType<any>;
navigate: () => void; navigate: () => void;
@ -18,27 +17,27 @@ export interface SuggestedTool {
const ALL_SUGGESTED_TOOLS: Omit<SuggestedTool, 'navigate'>[] = [ const ALL_SUGGESTED_TOOLS: Omit<SuggestedTool, 'navigate'>[] = [
{ {
id: ToolId.COMPRESS, id: 'compress',
title: 'Compress', title: 'Compress',
icon: CompressIcon icon: CompressIcon
}, },
{ {
id: ToolId.CONVERT, id: 'convert',
title: 'Convert', title: 'Convert',
icon: SwapHorizIcon icon: SwapHorizIcon
}, },
{ {
id: ToolId.SANITIZE, id: 'sanitize',
title: 'Sanitize', title: 'Sanitize',
icon: CleaningServicesIcon icon: CleaningServicesIcon
}, },
{ {
id: ToolId.SPLIT_PDF, id: 'split',
title: 'Split', title: 'Split',
icon: CropIcon icon: CropIcon
}, },
{ {
id: ToolId.OCR, id: 'ocr',
title: 'OCR', title: 'OCR',
icon: TextFieldsIcon icon: TextFieldsIcon
} }

View File

@ -1,15 +1,15 @@
import React, { useState, useCallback, useMemo, useEffect } from 'react'; import React, { useState, useCallback, useMemo, useEffect } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useFlatToolRegistry } from "../data/useTranslatedToolRegistry"; import { useFlatToolRegistry } from "../data/useTranslatedToolRegistry";
import { getAllEndpoints, ToolId, type ToolRegistryEntry } from "../data/toolsTaxonomy"; import { getAllEndpoints, type ToolRegistryEntry } from "../data/toolsTaxonomy";
import { useMultipleEndpointsEnabled } from "./useEndpointConfig"; import { useMultipleEndpointsEnabled } from "./useEndpointConfig";
interface ToolManagementResult { interface ToolManagementResult {
selectedToolKey: ToolId | null; selectedToolKey: string | null;
selectedTool: ToolRegistryEntry | null; selectedTool: ToolRegistryEntry | null;
toolSelectedFileIds: string[]; toolSelectedFileIds: string[];
toolRegistry: Record<string, ToolRegistryEntry>; toolRegistry: Record<string, ToolRegistryEntry>;
selectTool: (toolKey: ToolId) => void; selectTool: (toolKey: string) => void;
clearToolSelection: () => void; clearToolSelection: () => void;
setToolSelectedFileIds: (fileIds: string[]) => void; setToolSelectedFileIds: (fileIds: string[]) => void;
} }
@ -17,7 +17,7 @@ interface ToolManagementResult {
export const useToolManagement = (): ToolManagementResult => { export const useToolManagement = (): ToolManagementResult => {
const { t } = useTranslation(); const { t } = useTranslation();
const [selectedToolKey, setSelectedToolKey] = useState<ToolId | null>(null); const [selectedToolKey, setSelectedToolKey] = useState<string /* FIX ME: Should be ToolId */ | null>(null);
const [toolSelectedFileIds, setToolSelectedFileIds] = useState<string[]>([]); const [toolSelectedFileIds, setToolSelectedFileIds] = useState<string[]>([]);
// Build endpoints list from registry entries with fallback to legacy mapping // Build endpoints list from registry entries with fallback to legacy mapping
@ -35,7 +35,7 @@ export const useToolManagement = (): ToolManagementResult => {
const allEndpoints = useMemo(() => getAllEndpoints(baseRegistry), [baseRegistry]); const allEndpoints = useMemo(() => getAllEndpoints(baseRegistry), [baseRegistry]);
const { endpointStatus, loading: endpointsLoading } = useMultipleEndpointsEnabled(allEndpoints); const { endpointStatus, loading: endpointsLoading } = useMultipleEndpointsEnabled(allEndpoints);
const isToolAvailable = useCallback((toolKey: ToolId): boolean => { const isToolAvailable = useCallback((toolKey: string): boolean => {
if (endpointsLoading) return true; if (endpointsLoading) return true;
const endpoints = baseRegistry[toolKey]?.endpoints || []; const endpoints = baseRegistry[toolKey]?.endpoints || [];
return endpoints.length === 0 || endpoints.some((endpoint: string) => endpointStatus[endpoint] === true); return endpoints.length === 0 || endpoints.some((endpoint: string) => endpointStatus[endpoint] === true);
@ -43,7 +43,7 @@ export const useToolManagement = (): ToolManagementResult => {
const toolRegistry: Record<string, ToolRegistryEntry> = useMemo(() => { const toolRegistry: Record<string, ToolRegistryEntry> = useMemo(() => {
const availableToolRegistry: Record<string, ToolRegistryEntry> = {}; const availableToolRegistry: Record<string, ToolRegistryEntry> = {};
(Object.keys(baseRegistry) as ToolId[]).forEach(toolKey => { Object.keys(baseRegistry).forEach(toolKey => {
if (isToolAvailable(toolKey)) { if (isToolAvailable(toolKey)) {
const baseTool = baseRegistry[toolKey as keyof typeof baseRegistry]; const baseTool = baseRegistry[toolKey as keyof typeof baseRegistry];
availableToolRegistry[toolKey] = { availableToolRegistry[toolKey] = {
@ -58,7 +58,7 @@ export const useToolManagement = (): ToolManagementResult => {
useEffect(() => { useEffect(() => {
if (!endpointsLoading && selectedToolKey && !toolRegistry[selectedToolKey]) { if (!endpointsLoading && selectedToolKey && !toolRegistry[selectedToolKey]) {
const firstAvailableTool = (Object.keys(toolRegistry) as ToolId[])[0]; const firstAvailableTool = Object.keys(toolRegistry)[0];
if (firstAvailableTool) { if (firstAvailableTool) {
setSelectedToolKey(firstAvailableTool); setSelectedToolKey(firstAvailableTool);
} else { } else {
@ -67,7 +67,7 @@ export const useToolManagement = (): ToolManagementResult => {
} }
}, [endpointsLoading, selectedToolKey, toolRegistry]); }, [endpointsLoading, selectedToolKey, toolRegistry]);
const selectTool = useCallback((toolKey: ToolId) => { const selectTool = useCallback((toolKey: string) => {
setSelectedToolKey(toolKey); setSelectedToolKey(toolKey);
}, []); }, []);

View File

@ -1,10 +1,10 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import { SUBCATEGORY_ORDER, SubcategoryId, ToolCategoryId, ToolId, ToolRegistryEntry } from '../data/toolsTaxonomy'; import { SUBCATEGORY_ORDER, SubcategoryId, ToolCategoryId, ToolRegistryEntry } from '../data/toolsTaxonomy';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
type SubcategoryIdMap = { type SubcategoryIdMap = {
[subcategoryId in SubcategoryId]: Array<{ id: ToolId; tool: ToolRegistryEntry }>; [subcategoryId in SubcategoryId]: Array<{ id: string /* FIX ME: Should be ToolId */; tool: ToolRegistryEntry }>;
} }
type GroupedTools = { type GroupedTools = {
@ -14,7 +14,7 @@ type GroupedTools = {
export interface SubcategoryGroup { export interface SubcategoryGroup {
subcategoryId: SubcategoryId; subcategoryId: SubcategoryId;
tools: { tools: {
id: ToolId; id: string /* FIX ME: Should be ToolId */;
tool: ToolRegistryEntry; tool: ToolRegistryEntry;
}[]; }[];
}; };
@ -27,7 +27,7 @@ export interface ToolSection {
subcategories: SubcategoryGroup[]; subcategories: SubcategoryGroup[];
}; };
export function useToolSections(filteredTools: [ToolId, ToolRegistryEntry][]) { export function useToolSections(filteredTools: [string /* FIX ME: Should be ToolId */, ToolRegistryEntry][]) {
const { t } = useTranslation(); const { t } = useTranslation();
const groupedTools = useMemo(() => { const groupedTools = useMemo(() => {
@ -91,9 +91,9 @@ export function useToolSections(filteredTools: [ToolId, ToolRegistryEntry][]) {
const searchGroups: SubcategoryGroup[] = useMemo(() => { const searchGroups: SubcategoryGroup[] = useMemo(() => {
const subMap = {} as SubcategoryIdMap; const subMap = {} as SubcategoryIdMap;
const seen = new Set<ToolId>(); const seen = new Set<string /* FIX ME: Should be ToolId */>();
filteredTools.forEach(([id, tool]) => { filteredTools.forEach(([id, tool]) => {
const toolId = id as ToolId; const toolId = id as string /* FIX ME: Should be ToolId */;
if (seen.has(toolId)) return; if (seen.has(toolId)) return;
seen.add(toolId); seen.add(toolId);
const sub = tool.subcategoryId; const sub = tool.subcategoryId;