feat: Add open folder functionality for photos in file manager

This commit introduces a new feature that allows users to open the folder containing a selected photo in their system's file manager. The API has been updated with a new endpoint to handle folder opening requests, supporting various operating systems. The frontend has been enhanced to include a button for this action, providing user feedback and error handling. Documentation and tests have been updated to reflect these changes, ensuring reliability and usability.
This commit is contained in:
tanyar09
2025-11-03 14:50:10 -05:00
parent c0f9d19368
commit bb42478c8f
3 changed files with 215 additions and 11 deletions
+7
View File
@@ -88,6 +88,13 @@ export const photosApi = {
})
return data
},
openFolder: async (photoId: number): Promise<{ message: string; folder: string }> => {
const { data } = await apiClient.post<{ message: string; folder: string }>(
`/api/v1/photos/${photoId}/open-folder`
)
return data
},
}
export interface PhotoSearchResult {
+30 -11
View File
@@ -63,12 +63,12 @@ export default function Search() {
loadTags()
}, [])
const performSearch = async (pageNum: number = page) => {
const performSearch = async (pageNum: number = page, folderPathOverride?: string) => {
setLoading(true)
try {
const params: any = {
search_type: searchType,
folder_path: folderPath || undefined,
folder_path: folderPathOverride || folderPath || undefined,
page: pageNum,
page_size: pageSize,
}
@@ -105,7 +105,8 @@ export default function Search() {
// Auto-run search for no_faces and no_tags
if (searchType === 'no_faces' || searchType === 'no_tags') {
if (res.items.length === 0) {
const folderMsg = folderPath ? ` in folder '${folderPath}'` : ''
const actualFolderPath = folderPathOverride || folderPath
const folderMsg = actualFolderPath ? ` in folder '${actualFolderPath}'` : ''
alert(`No photos found${folderMsg}.`)
}
}
@@ -232,10 +233,17 @@ export default function Search() {
window.open(photoUrl, '_blank')
}
const openFolder = (path: string) => {
// Extract folder path from file path
const folder = path.substring(0, path.lastIndexOf('/'))
alert(`Open folder: ${folder}\n\nNote: Folder opening not implemented in web version.`)
const openFolder = async (photoId: number) => {
try {
const result = await photosApi.openFolder(photoId)
// Success - folder opened in file manager
// Optionally show a brief message
console.log('Folder opened:', result.folder)
} catch (error: any) {
console.error('Error opening folder:', error)
const errorMessage = error?.response?.data?.detail || error?.message || 'Failed to open folder'
alert(`Error opening folder: ${errorMessage}`)
}
}
return (
@@ -272,7 +280,14 @@ export default function Search() {
{filtersExpanded && (
<div className="mt-4 space-y-3">
<div>
<label className="block text-sm text-gray-700 mb-1">Folder location:</label>
<label className="block text-sm font-medium text-gray-700 mb-1">
Folder location:
{folderPath && (
<span className="ml-2 text-xs text-blue-600 font-normal">
(filtering by: {folderPath})
</span>
)}
</label>
<div className="flex gap-2">
<input
type="text"
@@ -502,9 +517,13 @@ export default function Search() {
)}
<td className="p-2">
<button
onClick={() => openFolder(photo.path)}
className="cursor-pointer hover:text-blue-600"
title="Open file location"
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
openFolder(photo.id)
}}
className="cursor-pointer hover:text-blue-600 text-lg"
title="Open folder in file manager"
>
📁
</button>