mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-09-26 17:52:59 +02:00
offload to files
This commit is contained in:
parent
cd94584278
commit
0f74dcda6c
@ -11,7 +11,7 @@ import { useNavigationActions, useNavigationState } from './NavigationContext';
|
||||
import { ToolId, isValidToolId } from '../types/toolId';
|
||||
import { useNavigationUrlSync } from '../hooks/useUrlSync';
|
||||
import { getDefaultWorkbench } from '../types/workbench';
|
||||
import { idToWords, scoreMatch, minScoreForQuery } from '../utils/fuzzySearch';
|
||||
import { filterToolRegistryByQuery } from '../utils/toolSearch';
|
||||
|
||||
// State interface
|
||||
interface ToolWorkflowState {
|
||||
@ -219,54 +219,10 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) {
|
||||
setReaderMode(true);
|
||||
}, [setReaderMode]);
|
||||
|
||||
// Filter tools based on search query with fuzzy matching (name and description)
|
||||
// Filter tools based on search query with fuzzy matching (name, description, id, synonyms)
|
||||
const filteredTools = useMemo(() => {
|
||||
if (!toolRegistry) return [];
|
||||
const entries = Object.entries(toolRegistry);
|
||||
if (!state.searchQuery.trim()) {
|
||||
// Return in the new format even when not searching
|
||||
return entries.map(([id, tool]) => ({ item: [id, tool] as [string, ToolRegistryEntry] }));
|
||||
}
|
||||
|
||||
const threshold = minScoreForQuery(state.searchQuery);
|
||||
const results: Array<{ item: [string, ToolRegistryEntry]; matchedText?: string; score: number }> = [];
|
||||
|
||||
for (const [id, tool] of entries) {
|
||||
let best = 0;
|
||||
let matchedText = '';
|
||||
|
||||
const candidates: string[] = [
|
||||
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 }));
|
||||
return filterToolRegistryByQuery(toolRegistry as Record<string, ToolRegistryEntry>, state.searchQuery);
|
||||
}, [toolRegistry, state.searchQuery]);
|
||||
|
||||
const isPanelVisible = useMemo(() =>
|
||||
|
@ -12,6 +12,7 @@ import RemoveBlanks from "../tools/RemoveBlanks";
|
||||
import RemovePages from "../tools/RemovePages";
|
||||
import RemovePassword from "../tools/RemovePassword";
|
||||
import { SubcategoryId, ToolCategoryId, ToolRegistry } from "./toolsTaxonomy";
|
||||
import { mergeSynonyms } from "../utils/toolSynonyms";
|
||||
import AddWatermark from "../tools/AddWatermark";
|
||||
import Merge from '../tools/Merge';
|
||||
import Repair from "../tools/Repair";
|
||||
@ -146,31 +147,6 @@ export const CONVERT_SUPPORTED_FORMATS = [
|
||||
"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
|
||||
export function useFlatToolRegistry(): ToolRegistry {
|
||||
const { t } = useTranslation();
|
||||
|
@ -96,6 +96,9 @@ export function rankByFuzzy<T>(items: T[], query: string, getters: Array<(item:
|
||||
best = s;
|
||||
matchedText = value;
|
||||
}
|
||||
if (best >= 95) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (best >= threshold) results.push({ item, score: best, matchedText });
|
||||
}
|
||||
|
61
frontend/src/utils/toolSearch.ts
Normal file
61
frontend/src/utils/toolSearch.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { ToolRegistryEntry } from "../data/toolsTaxonomy";
|
||||
import { idToWords, scoreMatch, minScoreForQuery } from "./fuzzySearch";
|
||||
|
||||
export interface RankedToolItem {
|
||||
item: [string, ToolRegistryEntry];
|
||||
matchedText?: string;
|
||||
}
|
||||
|
||||
export function filterToolRegistryByQuery(
|
||||
toolRegistry: Record<string, ToolRegistryEntry>,
|
||||
query: string
|
||||
): RankedToolItem[] {
|
||||
const entries = Object.entries(toolRegistry);
|
||||
if (!query.trim()) {
|
||||
return entries.map(([id, tool]) => ({ item: [id, tool] as [string, ToolRegistryEntry] }));
|
||||
}
|
||||
|
||||
const threshold = minScoreForQuery(query);
|
||||
const results: Array<{ item: [string, ToolRegistryEntry]; matchedText?: string; score: number }> = [];
|
||||
|
||||
for (const [id, tool] of entries) {
|
||||
let best = 0;
|
||||
let matchedText = '';
|
||||
|
||||
const candidates: string[] = [
|
||||
idToWords(id),
|
||||
tool.name || '',
|
||||
tool.description || ''
|
||||
];
|
||||
for (const value of candidates) {
|
||||
if (!value) continue;
|
||||
const s = scoreMatch(query, value);
|
||||
if (s > best) {
|
||||
best = s;
|
||||
matchedText = value;
|
||||
}
|
||||
if (best >= 95) break;
|
||||
}
|
||||
|
||||
if (Array.isArray(tool.synonyms)) {
|
||||
for (const synonym of tool.synonyms) {
|
||||
if (!synonym) continue;
|
||||
const s = scoreMatch(query, synonym);
|
||||
if (s > best) {
|
||||
best = s;
|
||||
matchedText = synonym;
|
||||
}
|
||||
if (best >= 95) break;
|
||||
}
|
||||
}
|
||||
|
||||
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 }));
|
||||
}
|
||||
|
||||
|
36
frontend/src/utils/toolSynonyms.ts
Normal file
36
frontend/src/utils/toolSynonyms.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { TFunction } from 'i18next';
|
||||
|
||||
// Helper function to get translated synonyms for a tool
|
||||
export const getTranslatedSynonyms = (t: TFunction, toolId: string): string[] => {
|
||||
try {
|
||||
const tagsKey = `${toolId}.tags`;
|
||||
const tags = t(tagsKey) as unknown as string;
|
||||
|
||||
// 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) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`Failed to get translated synonyms for tool ${toolId}:`, error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
// Helper function to merge translated synonyms with existing synonyms
|
||||
export const mergeSynonyms = (
|
||||
t: TFunction,
|
||||
toolId: string,
|
||||
existingSynonyms: string[] = []
|
||||
): string[] => {
|
||||
const translatedSynonyms = getTranslatedSynonyms(t, toolId);
|
||||
return [...translatedSynonyms, ...existingSynonyms];
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user