Stirling-PDF/frontend/src/data/toolsTaxonomy.ts
Anthony Stirling e542f4bc61
legacy UI (#4612)
# Description of Changes

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: EthanHealy01 <ethan.healy.21@gmail.com>
Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
2025-10-10 15:36:35 +01:00

190 lines
7.0 KiB
TypeScript

import { type TFunction } from 'i18next';
import React from 'react';
import { ToolOperationConfig } from '../hooks/tools/shared/useToolOperation';
import { BaseToolProps } from '../types/tool';
import { WorkbenchType } from '../types/workbench';
import { ToolId } from '../types/toolId';
import DrawRoundedIcon from '@mui/icons-material/DrawRounded';
import SecurityRoundedIcon from '@mui/icons-material/SecurityRounded';
import VerifiedUserRoundedIcon from '@mui/icons-material/VerifiedUserRounded';
import RateReviewRoundedIcon from '@mui/icons-material/RateReviewRounded';
import ViewAgendaRoundedIcon from '@mui/icons-material/ViewAgendaRounded';
import FileDownloadRoundedIcon from '@mui/icons-material/FileDownloadRounded';
import DeleteSweepRoundedIcon from '@mui/icons-material/DeleteSweepRounded';
import SmartToyRoundedIcon from '@mui/icons-material/SmartToyRounded';
import BuildRoundedIcon from '@mui/icons-material/BuildRounded';
import TuneRoundedIcon from '@mui/icons-material/TuneRounded';
import CodeRoundedIcon from '@mui/icons-material/CodeRounded';
export enum SubcategoryId {
SIGNING = 'signing',
DOCUMENT_SECURITY = 'documentSecurity',
VERIFICATION = 'verification',
DOCUMENT_REVIEW = 'documentReview',
PAGE_FORMATTING = 'pageFormatting',
EXTRACTION = 'extraction',
REMOVAL = 'removal',
AUTOMATION = 'automation',
GENERAL = 'general',
ADVANCED_FORMATTING = 'advancedFormatting',
DEVELOPER_TOOLS = 'developerTools'
}
export enum ToolCategoryId {
STANDARD_TOOLS = 'standardTools',
ADVANCED_TOOLS = 'advancedTools',
RECOMMENDED_TOOLS = 'recommendedTools'
}
export type ToolRegistryEntry = {
icon: React.ReactNode;
name: string;
component: React.ComponentType<BaseToolProps> | null;
description: string;
categoryId: ToolCategoryId;
subcategoryId: SubcategoryId;
maxFiles?: number;
supportedFormats?: string[];
endpoints?: string[];
link?: string;
type?: string;
// Workbench type for navigation
workbench?: WorkbenchType;
// Operation configuration for automation
operationConfig?: ToolOperationConfig<any>;
// Settings component for automation configuration
automationSettings: React.ComponentType<any> | null;
// Whether this tool supports automation (defaults to true)
supportsAutomate?: boolean;
// Synonyms for search (optional)
synonyms?: string[];
}
export type ToolRegistry = Record<ToolId, ToolRegistryEntry>;
export const SUBCATEGORY_ORDER: SubcategoryId[] = [
SubcategoryId.SIGNING,
SubcategoryId.DOCUMENT_SECURITY,
SubcategoryId.VERIFICATION,
SubcategoryId.DOCUMENT_REVIEW,
SubcategoryId.PAGE_FORMATTING,
SubcategoryId.EXTRACTION,
SubcategoryId.REMOVAL,
SubcategoryId.AUTOMATION,
SubcategoryId.GENERAL,
SubcategoryId.ADVANCED_FORMATTING,
SubcategoryId.DEVELOPER_TOOLS,
];
export const SUBCATEGORY_COLOR_MAP: Record<SubcategoryId, string> = {
[SubcategoryId.SIGNING]: 'var(--category-color-signing)', // Green
[SubcategoryId.DOCUMENT_SECURITY]: 'var(--category-color-security)', // Orange
[SubcategoryId.VERIFICATION]: 'var(--category-color-verification)', // Orange
[SubcategoryId.DOCUMENT_REVIEW]: 'var(--category-color-general)', // Blue
[SubcategoryId.PAGE_FORMATTING]: 'var(--category-color-formatting)', // Purple
[SubcategoryId.EXTRACTION]: 'var(--category-color-extraction)', // Cyan
[SubcategoryId.REMOVAL]: 'var(--category-color-removal)', // Red
[SubcategoryId.AUTOMATION]: 'var(--category-color-automation)', // Pink
[SubcategoryId.GENERAL]: 'var(--category-color-general)', // Blue
[SubcategoryId.ADVANCED_FORMATTING]: 'var(--category-color-formatting)', // Purple
[SubcategoryId.DEVELOPER_TOOLS]: 'var(--category-color-developer)', // Gray
};
export const getSubcategoryIcon = (subcategory: SubcategoryId): React.ReactNode => {
switch (subcategory) {
case SubcategoryId.SIGNING:
return React.createElement(DrawRoundedIcon);
case SubcategoryId.DOCUMENT_SECURITY:
return React.createElement(SecurityRoundedIcon);
case SubcategoryId.VERIFICATION:
return React.createElement(VerifiedUserRoundedIcon);
case SubcategoryId.DOCUMENT_REVIEW:
return React.createElement(RateReviewRoundedIcon);
case SubcategoryId.PAGE_FORMATTING:
return React.createElement(ViewAgendaRoundedIcon);
case SubcategoryId.EXTRACTION:
return React.createElement(FileDownloadRoundedIcon);
case SubcategoryId.REMOVAL:
return React.createElement(DeleteSweepRoundedIcon);
case SubcategoryId.AUTOMATION:
return React.createElement(SmartToyRoundedIcon);
case SubcategoryId.GENERAL:
return React.createElement(BuildRoundedIcon);
case SubcategoryId.ADVANCED_FORMATTING:
return React.createElement(TuneRoundedIcon);
case SubcategoryId.DEVELOPER_TOOLS:
return React.createElement(CodeRoundedIcon);
default:
return React.createElement(BuildRoundedIcon);
}
};
export const getCategoryLabel = (t: TFunction, id: ToolCategoryId): string => t(`toolPicker.categories.${id}`, id);
export const getSubcategoryLabel = (t: TFunction, id: SubcategoryId): string => t(`toolPicker.subcategories.${id}`, id);
export const getSubcategoryColor = (subcategory: SubcategoryId): string => SUBCATEGORY_COLOR_MAP[subcategory] || '#7882FF';
export const getAllEndpoints = (registry: ToolRegistry): string[] => {
const lists: string[][] = [];
Object.values(registry).forEach(entry => {
if (entry.endpoints && entry.endpoints.length > 0) {
lists.push(entry.endpoints);
}
});
return Array.from(new Set(lists.flat()));
};
export const getConversionEndpoints = (extensionToEndpoint: Record<string, Record<string, string>>): string[] => {
const endpoints = new Set<string>();
Object.values(extensionToEndpoint).forEach(toEndpoints => {
Object.values(toEndpoints).forEach(endpoint => {
endpoints.add(endpoint);
});
});
return Array.from(endpoints);
};
export const getAllApplicationEndpoints = (
registry: ToolRegistry,
extensionToEndpoint?: Record<string, Record<string, string>>
): string[] => {
const toolEp = getAllEndpoints(registry);
const convEp = extensionToEndpoint ? getConversionEndpoints(extensionToEndpoint) : [];
return Array.from(new Set([...toolEp, ...convEp]));
};
/**
* Default workbench for tools that don't specify one
* Returns null to trigger the default case in Workbench component (ToolRenderer)
*/
export const getDefaultToolWorkbench = (): WorkbenchType => 'fileEditor';
/**
* Get workbench type for a tool
*/
export const getToolWorkbench = (tool: ToolRegistryEntry): WorkbenchType => {
return tool.workbench || getDefaultToolWorkbench();
};
/**
* Get URL path for a tool
*/
export const getToolUrlPath = (toolId: string): string => {
return `/${toolId.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
};
/**
* Check if a tool ID exists in the registry
*/
export const isValidToolId = (toolId: string, registry: ToolRegistry): boolean => {
return toolId in registry;
};
/**
* Check if a tool supports automation (defaults to true)
*/
export const getToolSupportsAutomate = (tool: ToolRegistryEntry): boolean => {
return tool.supportsAutomate !== false;
};