V2 Auto rename (#4244)
# Description of Changes
This pull request introduces the new "Auto Rename PDF" tool to the
frontend, enabling users to automatically rename PDF files based on
their content. The implementation includes UI components, parameter
handling, operation logic, localization, and enhancements to the file
response utilities to support backend-provided filenames. Below are the
most important changes grouped by theme:
**Feature: Auto Rename PDF Tool**
- Added the main `AutoRename` tool component (`AutoRename.tsx`) and
registered it in the tool registry, enabling selection and execution of
the auto-rename operation in the UI.
[[1]](diffhunk://#diff-3647ca39d46d109d122d4cd6cbfe981beb4189d05b1b446e5c46824eb98a4a88R1-R80)
[[2]](diffhunk://#diff-0a3e636736c137356dd9354ff3cacbd302ebda40147545e13c62d073525d1969R17)
[[3]](diffhunk://#diff-0a3e636736c137356dd9354ff3cacbd302ebda40147545e13c62d073525d1969L359-R366)
[[4]](diffhunk://#diff-29427b8d06a23772c56645fc4b72af2980c813605abc162e3d47c2e39d026d06L25-R26)
- Implemented the settings panel (`AutoRenameSettings.tsx`) and
parameter management hook (`useAutoRenameParameters.ts`), allowing users
to configure options such as using the first text as a fallback for the
filename.
[[1]](diffhunk://#diff-b2f9474c8e5a7a42df00a12ffd2d31a785895fe1096e8ca515e6af5633a4d648R1-R27)
[[2]](diffhunk://#diff-8798a1ef451233bf3a1bf8825c12c5b434ad1a17a1beb1ca21fd972fdaceb50cR1-R19)
- Created the operation hook (`useAutoRenameOperation.ts`) to handle API
requests, error handling, and result processing for the auto-rename
feature.
**Localization**
- Added English (US and GB) translations for the new tool, including UI
labels, descriptions, error messages, and settings.
[[1]](diffhunk://#diff-e4d543afa388d9eb8a423e45dfebb91641e3558d00848d70b285ebb91c40b249R1048-R1066)
[[2]](diffhunk://#diff-14c707e28788a3a84ed5293ff6689be73d4bca00e155beaf090f9b37c978babbR1321-R1339)
**File Response Handling Enhancements**
- Updated the file response processor and related hooks to support
preserving backend-provided filenames via the `Content-Disposition`
header, ensuring files are renamed according to backend results.
[[1]](diffhunk://#diff-97ea1c842d4b269c566a3085d8555ded7f9b462d9ce8dc73706bec79fe3973e0R11)
[[2]](diffhunk://#diff-97ea1c842d4b269c566a3085d8555ded7f9b462d9ce8dc73706bec79fe3973e0L49-R51)
[[3]](diffhunk://#diff-d44da7f96721d9829f3c20bf9c7ac5b9e156b647d2c75d76e861c8c09abc5191R52-R58)
[[4]](diffhunk://#diff-d44da7f96721d9829f3c20bf9c7ac5b9e156b647d2c75d76e861c8c09abc5191L175-R183)
[[5]](diffhunk://#diff-fa8af80f4d87370d58e3a5b79df675d201f0c3aa753eda89cec03ff027c4213dL13-R21)
[[6]](diffhunk://#diff-efa525dbdeceaeb5701aa3d2303bf1d533541f65a92d985f94f33b8e87b036d1R2-R37)
These changes collectively deliver a new advanced tool for users to
automatically rename PDFs, with robust parameter handling, user
interface integration, and proper handling of filenames as determined by
backend logic.
---
## Checklist
### General
- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings
### Documentation
- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)
### UI Changes (if applicable)
- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)
### Testing (if applicable)
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
---------
Co-authored-by: Connor Yoh <connor@stirlingpdf.com>
Co-authored-by: ConnorYoh <40631091+ConnorYoh@users.noreply.github.com>
Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
2025-09-05 17:12:52 +01:00
|
|
|
import { useState, useMemo, useCallback, useRef, useEffect } from 'react';
|
2025-08-22 14:40:27 +01:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2025-08-26 09:44:30 +01:00
|
|
|
import { Stack, Text, ScrollArea } from '@mantine/core';
|
2025-08-22 14:40:27 +01:00
|
|
|
import { ToolRegistryEntry } from '../../../data/toolsTaxonomy';
|
|
|
|
import { useToolSections } from '../../../hooks/useToolSections';
|
|
|
|
import { renderToolButtons } from '../shared/renderToolButtons';
|
|
|
|
import ToolSearch from '../toolPicker/ToolSearch';
|
2025-08-26 09:44:30 +01:00
|
|
|
import ToolButton from '../toolPicker/ToolButton';
|
2025-08-22 14:40:27 +01:00
|
|
|
|
|
|
|
interface ToolSelectorProps {
|
|
|
|
onSelect: (toolKey: string) => void;
|
|
|
|
excludeTools?: string[];
|
|
|
|
toolRegistry: Record<string, ToolRegistryEntry>; // Pass registry as prop to break circular dependency
|
|
|
|
selectedValue?: string; // For showing current selection when editing existing tool
|
|
|
|
placeholder?: string; // Custom placeholder text
|
|
|
|
}
|
|
|
|
|
|
|
|
export default function ToolSelector({
|
|
|
|
onSelect,
|
|
|
|
excludeTools = [],
|
|
|
|
toolRegistry,
|
|
|
|
selectedValue,
|
|
|
|
placeholder
|
|
|
|
}: ToolSelectorProps) {
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const [opened, setOpened] = useState(false);
|
|
|
|
const [searchTerm, setSearchTerm] = useState('');
|
2025-08-26 09:44:30 +01:00
|
|
|
const [shouldAutoFocus, setShouldAutoFocus] = useState(false);
|
|
|
|
const containerRef = useRef<HTMLDivElement>(null);
|
2025-08-22 14:40:27 +01:00
|
|
|
|
|
|
|
// Filter out excluded tools (like 'automate' itself)
|
|
|
|
const baseFilteredTools = useMemo(() => {
|
|
|
|
return Object.entries(toolRegistry).filter(([key]) => !excludeTools.includes(key));
|
|
|
|
}, [toolRegistry, excludeTools]);
|
|
|
|
|
|
|
|
// Apply search filter
|
|
|
|
const filteredTools = useMemo(() => {
|
|
|
|
if (!searchTerm.trim()) {
|
|
|
|
return baseFilteredTools;
|
|
|
|
}
|
|
|
|
|
|
|
|
const lowercaseSearch = searchTerm.toLowerCase();
|
|
|
|
return baseFilteredTools.filter(([key, tool]) => {
|
|
|
|
return (
|
|
|
|
tool.name.toLowerCase().includes(lowercaseSearch) ||
|
|
|
|
tool.description?.toLowerCase().includes(lowercaseSearch) ||
|
|
|
|
key.toLowerCase().includes(lowercaseSearch)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}, [baseFilteredTools, searchTerm]);
|
|
|
|
|
|
|
|
// Create filtered tool registry for ToolSearch
|
|
|
|
const filteredToolRegistry = useMemo(() => {
|
|
|
|
const registry: Record<string, ToolRegistryEntry> = {};
|
|
|
|
baseFilteredTools.forEach(([key, tool]) => {
|
|
|
|
registry[key] = tool;
|
|
|
|
});
|
|
|
|
return registry;
|
|
|
|
}, [baseFilteredTools]);
|
|
|
|
|
|
|
|
// Use the same tool sections logic as the main ToolPicker
|
|
|
|
const { sections, searchGroups } = useToolSections(filteredTools);
|
|
|
|
|
|
|
|
// Determine what to display: search results or organized sections
|
|
|
|
const isSearching = searchTerm.trim().length > 0;
|
|
|
|
const displayGroups = useMemo(() => {
|
|
|
|
if (isSearching) {
|
|
|
|
return searchGroups || [];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sections || sections.length === 0) {
|
2025-08-26 09:44:30 +01:00
|
|
|
// If no sections, create a simple group from filtered tools
|
|
|
|
if (baseFilteredTools.length > 0) {
|
|
|
|
return [{
|
|
|
|
name: 'All Tools',
|
|
|
|
subcategoryId: 'all' as any,
|
|
|
|
tools: baseFilteredTools.map(([key, tool]) => ({ id: key, tool }))
|
|
|
|
}];
|
|
|
|
}
|
2025-08-22 14:40:27 +01:00
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find the "all" section which contains all tools without duplicates
|
|
|
|
const allSection = sections.find(s => (s as any).key === 'all');
|
|
|
|
return allSection?.subcategories || [];
|
2025-08-26 09:44:30 +01:00
|
|
|
}, [isSearching, searchGroups, sections, baseFilteredTools]);
|
2025-08-22 14:40:27 +01:00
|
|
|
|
|
|
|
const handleToolSelect = useCallback((toolKey: string) => {
|
|
|
|
onSelect(toolKey);
|
|
|
|
setOpened(false);
|
|
|
|
setSearchTerm(''); // Clear search to show the selected tool display
|
|
|
|
}, [onSelect]);
|
|
|
|
|
|
|
|
const renderedTools = useMemo(() =>
|
|
|
|
displayGroups.map((subcategory) =>
|
V2 Auto rename (#4244)
# Description of Changes
This pull request introduces the new "Auto Rename PDF" tool to the
frontend, enabling users to automatically rename PDF files based on
their content. The implementation includes UI components, parameter
handling, operation logic, localization, and enhancements to the file
response utilities to support backend-provided filenames. Below are the
most important changes grouped by theme:
**Feature: Auto Rename PDF Tool**
- Added the main `AutoRename` tool component (`AutoRename.tsx`) and
registered it in the tool registry, enabling selection and execution of
the auto-rename operation in the UI.
[[1]](diffhunk://#diff-3647ca39d46d109d122d4cd6cbfe981beb4189d05b1b446e5c46824eb98a4a88R1-R80)
[[2]](diffhunk://#diff-0a3e636736c137356dd9354ff3cacbd302ebda40147545e13c62d073525d1969R17)
[[3]](diffhunk://#diff-0a3e636736c137356dd9354ff3cacbd302ebda40147545e13c62d073525d1969L359-R366)
[[4]](diffhunk://#diff-29427b8d06a23772c56645fc4b72af2980c813605abc162e3d47c2e39d026d06L25-R26)
- Implemented the settings panel (`AutoRenameSettings.tsx`) and
parameter management hook (`useAutoRenameParameters.ts`), allowing users
to configure options such as using the first text as a fallback for the
filename.
[[1]](diffhunk://#diff-b2f9474c8e5a7a42df00a12ffd2d31a785895fe1096e8ca515e6af5633a4d648R1-R27)
[[2]](diffhunk://#diff-8798a1ef451233bf3a1bf8825c12c5b434ad1a17a1beb1ca21fd972fdaceb50cR1-R19)
- Created the operation hook (`useAutoRenameOperation.ts`) to handle API
requests, error handling, and result processing for the auto-rename
feature.
**Localization**
- Added English (US and GB) translations for the new tool, including UI
labels, descriptions, error messages, and settings.
[[1]](diffhunk://#diff-e4d543afa388d9eb8a423e45dfebb91641e3558d00848d70b285ebb91c40b249R1048-R1066)
[[2]](diffhunk://#diff-14c707e28788a3a84ed5293ff6689be73d4bca00e155beaf090f9b37c978babbR1321-R1339)
**File Response Handling Enhancements**
- Updated the file response processor and related hooks to support
preserving backend-provided filenames via the `Content-Disposition`
header, ensuring files are renamed according to backend results.
[[1]](diffhunk://#diff-97ea1c842d4b269c566a3085d8555ded7f9b462d9ce8dc73706bec79fe3973e0R11)
[[2]](diffhunk://#diff-97ea1c842d4b269c566a3085d8555ded7f9b462d9ce8dc73706bec79fe3973e0L49-R51)
[[3]](diffhunk://#diff-d44da7f96721d9829f3c20bf9c7ac5b9e156b647d2c75d76e861c8c09abc5191R52-R58)
[[4]](diffhunk://#diff-d44da7f96721d9829f3c20bf9c7ac5b9e156b647d2c75d76e861c8c09abc5191L175-R183)
[[5]](diffhunk://#diff-fa8af80f4d87370d58e3a5b79df675d201f0c3aa753eda89cec03ff027c4213dL13-R21)
[[6]](diffhunk://#diff-efa525dbdeceaeb5701aa3d2303bf1d533541f65a92d985f94f33b8e87b036d1R2-R37)
These changes collectively deliver a new advanced tool for users to
automatically rename PDFs, with robust parameter handling, user
interface integration, and proper handling of filenames as determined by
backend logic.
---
## Checklist
### General
- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings
### Documentation
- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)
### UI Changes (if applicable)
- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)
### Testing (if applicable)
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
---------
Co-authored-by: Connor Yoh <connor@stirlingpdf.com>
Co-authored-by: ConnorYoh <40631091+ConnorYoh@users.noreply.github.com>
Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
2025-09-05 17:12:52 +01:00
|
|
|
renderToolButtons(t, subcategory, null, handleToolSelect, !isSearching, true)
|
2025-08-22 14:40:27 +01:00
|
|
|
), [displayGroups, handleToolSelect, isSearching, t]
|
|
|
|
);
|
|
|
|
|
|
|
|
const handleSearchFocus = () => {
|
|
|
|
setOpened(true);
|
2025-08-26 09:44:30 +01:00
|
|
|
setShouldAutoFocus(true); // Request auto-focus for the input
|
2025-08-22 14:40:27 +01:00
|
|
|
};
|
|
|
|
|
2025-08-26 09:44:30 +01:00
|
|
|
// Handle click outside to close dropdown
|
|
|
|
useEffect(() => {
|
|
|
|
const handleClickOutside = (event: MouseEvent) => {
|
|
|
|
if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
|
|
|
|
setOpened(false);
|
|
|
|
setSearchTerm('');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if (opened) {
|
|
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
|
|
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
|
|
}
|
|
|
|
}, [opened]);
|
|
|
|
|
|
|
|
|
2025-08-22 14:40:27 +01:00
|
|
|
const handleSearchChange = (value: string) => {
|
|
|
|
setSearchTerm(value);
|
|
|
|
if (!opened) {
|
|
|
|
setOpened(true);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2025-08-26 09:44:30 +01:00
|
|
|
const handleInputFocus = () => {
|
|
|
|
if (!opened) {
|
|
|
|
setOpened(true);
|
|
|
|
}
|
|
|
|
// Clear auto-focus flag since input is now focused
|
|
|
|
setShouldAutoFocus(false);
|
|
|
|
};
|
|
|
|
|
2025-08-22 14:40:27 +01:00
|
|
|
// Get display value for selected tool
|
|
|
|
const getDisplayValue = () => {
|
|
|
|
if (selectedValue && toolRegistry[selectedValue]) {
|
|
|
|
return toolRegistry[selectedValue].name;
|
|
|
|
}
|
|
|
|
return placeholder || t('automate.creation.tools.add', 'Add a tool...');
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2025-08-26 09:44:30 +01:00
|
|
|
<div ref={containerRef} className='rounded-xl'>
|
|
|
|
{/* Always show the target - either selected tool or search input */}
|
|
|
|
|
|
|
|
{selectedValue && toolRegistry[selectedValue] && !opened ? (
|
|
|
|
// Show selected tool in AutomationEntry style when tool is selected and dropdown closed
|
|
|
|
<div onClick={handleSearchFocus} style={{ cursor: 'pointer',
|
|
|
|
borderRadius: "var(--mantine-radius-lg)" }}>
|
|
|
|
<ToolButton id='tool' tool={toolRegistry[selectedValue]} isSelected={false}
|
V2 Auto rename (#4244)
# Description of Changes
This pull request introduces the new "Auto Rename PDF" tool to the
frontend, enabling users to automatically rename PDF files based on
their content. The implementation includes UI components, parameter
handling, operation logic, localization, and enhancements to the file
response utilities to support backend-provided filenames. Below are the
most important changes grouped by theme:
**Feature: Auto Rename PDF Tool**
- Added the main `AutoRename` tool component (`AutoRename.tsx`) and
registered it in the tool registry, enabling selection and execution of
the auto-rename operation in the UI.
[[1]](diffhunk://#diff-3647ca39d46d109d122d4cd6cbfe981beb4189d05b1b446e5c46824eb98a4a88R1-R80)
[[2]](diffhunk://#diff-0a3e636736c137356dd9354ff3cacbd302ebda40147545e13c62d073525d1969R17)
[[3]](diffhunk://#diff-0a3e636736c137356dd9354ff3cacbd302ebda40147545e13c62d073525d1969L359-R366)
[[4]](diffhunk://#diff-29427b8d06a23772c56645fc4b72af2980c813605abc162e3d47c2e39d026d06L25-R26)
- Implemented the settings panel (`AutoRenameSettings.tsx`) and
parameter management hook (`useAutoRenameParameters.ts`), allowing users
to configure options such as using the first text as a fallback for the
filename.
[[1]](diffhunk://#diff-b2f9474c8e5a7a42df00a12ffd2d31a785895fe1096e8ca515e6af5633a4d648R1-R27)
[[2]](diffhunk://#diff-8798a1ef451233bf3a1bf8825c12c5b434ad1a17a1beb1ca21fd972fdaceb50cR1-R19)
- Created the operation hook (`useAutoRenameOperation.ts`) to handle API
requests, error handling, and result processing for the auto-rename
feature.
**Localization**
- Added English (US and GB) translations for the new tool, including UI
labels, descriptions, error messages, and settings.
[[1]](diffhunk://#diff-e4d543afa388d9eb8a423e45dfebb91641e3558d00848d70b285ebb91c40b249R1048-R1066)
[[2]](diffhunk://#diff-14c707e28788a3a84ed5293ff6689be73d4bca00e155beaf090f9b37c978babbR1321-R1339)
**File Response Handling Enhancements**
- Updated the file response processor and related hooks to support
preserving backend-provided filenames via the `Content-Disposition`
header, ensuring files are renamed according to backend results.
[[1]](diffhunk://#diff-97ea1c842d4b269c566a3085d8555ded7f9b462d9ce8dc73706bec79fe3973e0R11)
[[2]](diffhunk://#diff-97ea1c842d4b269c566a3085d8555ded7f9b462d9ce8dc73706bec79fe3973e0L49-R51)
[[3]](diffhunk://#diff-d44da7f96721d9829f3c20bf9c7ac5b9e156b647d2c75d76e861c8c09abc5191R52-R58)
[[4]](diffhunk://#diff-d44da7f96721d9829f3c20bf9c7ac5b9e156b647d2c75d76e861c8c09abc5191L175-R183)
[[5]](diffhunk://#diff-fa8af80f4d87370d58e3a5b79df675d201f0c3aa753eda89cec03ff027c4213dL13-R21)
[[6]](diffhunk://#diff-efa525dbdeceaeb5701aa3d2303bf1d533541f65a92d985f94f33b8e87b036d1R2-R37)
These changes collectively deliver a new advanced tool for users to
automatically rename PDFs, with robust parameter handling, user
interface integration, and proper handling of filenames as determined by
backend logic.
---
## Checklist
### General
- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings
### Documentation
- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)
### UI Changes (if applicable)
- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)
### Testing (if applicable)
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
---------
Co-authored-by: Connor Yoh <connor@stirlingpdf.com>
Co-authored-by: ConnorYoh <40631091+ConnorYoh@users.noreply.github.com>
Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
2025-09-05 17:12:52 +01:00
|
|
|
onSelect={()=>{}} rounded={true} disableNavigation={true}></ToolButton>
|
2025-08-22 14:40:27 +01:00
|
|
|
</div>
|
2025-08-26 09:44:30 +01:00
|
|
|
) : (
|
|
|
|
// Show search input when no tool selected OR when dropdown is opened
|
|
|
|
<ToolSearch
|
|
|
|
value={searchTerm}
|
|
|
|
onChange={handleSearchChange}
|
|
|
|
toolRegistry={filteredToolRegistry}
|
|
|
|
mode="unstyled"
|
|
|
|
placeholder={getDisplayValue()}
|
|
|
|
hideIcon={true}
|
|
|
|
onFocus={handleInputFocus}
|
|
|
|
autoFocus={shouldAutoFocus}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
|
|
|
|
{/* Custom dropdown */}
|
|
|
|
{opened && (
|
|
|
|
<div
|
|
|
|
style={{
|
|
|
|
position: 'absolute',
|
|
|
|
top: '100%',
|
|
|
|
left: 0,
|
|
|
|
right: 0,
|
|
|
|
zIndex: 1000,
|
|
|
|
backgroundColor: 'var(--mantine-color-body)',
|
|
|
|
border: '1px solid var(--mantine-color-gray-3)',
|
|
|
|
borderRadius: 'var(--mantine-radius-sm)',
|
|
|
|
boxShadow: 'var(--mantine-shadow-sm)',
|
|
|
|
marginTop: '4px',
|
|
|
|
minWidth: '16rem'
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<ScrollArea h={350}>
|
|
|
|
<Stack gap="sm" p="sm">
|
|
|
|
{displayGroups.length === 0 ? (
|
|
|
|
<Text size="sm" c="dimmed" ta="center" p="md">
|
|
|
|
{isSearching
|
|
|
|
? t('tools.noSearchResults', 'No tools found')
|
|
|
|
: t('tools.noTools', 'No tools available')
|
|
|
|
}
|
|
|
|
</Text>
|
|
|
|
) : (
|
|
|
|
renderedTools
|
|
|
|
)}
|
|
|
|
</Stack>
|
|
|
|
</ScrollArea>
|
|
|
|
</div>
|
|
|
|
)}
|
2025-08-22 14:40:27 +01:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|