fix: FilesView merge logic and computed property
Bug: When regFiles API fails, all files get 'unregistered' status even if they are actually registered. Also, computed property was using reference to files.value instead of a copy, which could cause mutation issues. Fix: - Fetch scan results FIRST (source of truth for files on disk) - Use scan API's is_registered field as fallback status - Only override with regFiles data if file exists in scan results - Computed property now uses [...files.value] to create a copy - Skip files from regFiles that don't exist on disk (deleted)
This commit is contained in:
@@ -220,7 +220,8 @@ function getMediaType(fileName: string): 'video' | 'photo' {
|
||||
}
|
||||
|
||||
const displayFiles = computed(() => {
|
||||
let result = files.value
|
||||
// Start with a copy to avoid mutation issues
|
||||
let result = [...files.value]
|
||||
|
||||
// Filter by media type
|
||||
if (mediaType.value !== 'all') {
|
||||
@@ -263,7 +264,20 @@ async function fetchFiles() {
|
||||
try {
|
||||
const config = getCurrentConfig()
|
||||
|
||||
// Get registered files with real processing status FIRST
|
||||
// Get scan results FIRST (source of truth for files on disk)
|
||||
const scanResp = await httpFetch<any>(`${config.api_base_url}/api/v1/files/scan`)
|
||||
const scanFiles: any[] = (scanResp?.files || []).map((f: any) => {
|
||||
const mediaType = getMediaType(f.file_name)
|
||||
return {
|
||||
...f,
|
||||
media_type: mediaType,
|
||||
is_indexed: false,
|
||||
// Use scan API's is_registered field as default status
|
||||
status: f.is_registered ? 'pending' : 'unregistered'
|
||||
}
|
||||
})
|
||||
|
||||
// Get registered files with real processing status
|
||||
let regFiles: any[] = []
|
||||
try {
|
||||
const regResp = await httpFetch<any>(`${config.api_base_url}/api/v1/files?page=1&page_size=200`)
|
||||
@@ -277,38 +291,37 @@ async function fetchFiles() {
|
||||
}
|
||||
})
|
||||
} catch {
|
||||
// Registered files API may not be available
|
||||
// Registered files API may not be available; scan data will be used as fallback
|
||||
console.warn('Failed to fetch registered files, using scan data as fallback')
|
||||
}
|
||||
|
||||
// Get scan results
|
||||
const scanResp = await httpFetch<any>(`${config.api_base_url}/api/v1/files/scan`)
|
||||
const scanFiles: any[] = (scanResp?.files || []).map((f: any) => {
|
||||
const mediaType = getMediaType(f.file_name)
|
||||
return {
|
||||
...f,
|
||||
media_type: mediaType,
|
||||
is_indexed: false
|
||||
}
|
||||
})
|
||||
|
||||
// Build a set of registered file paths for quick lookup
|
||||
const registeredPaths = new Set(regFiles.map(f => f.file_path))
|
||||
// Build a map of registered files by file_path for quick lookup
|
||||
const regMap = new Map<string, any>()
|
||||
for (const f of regFiles) {
|
||||
regMap.set(f.file_path, f)
|
||||
}
|
||||
|
||||
// Merge: start with scan results, override with registered data where available
|
||||
const merged = new Map<string, any>()
|
||||
|
||||
// First pass: add all scan results
|
||||
for (const f of scanFiles) {
|
||||
const isRegistered = registeredPaths.has(f.file_path)
|
||||
merged.set(f.file_path, {
|
||||
...f,
|
||||
status: isRegistered ? 'pending' : 'unregistered'
|
||||
})
|
||||
merged.set(f.file_path, { ...f })
|
||||
}
|
||||
|
||||
// Second pass: override with real registered data
|
||||
// Second pass: override with real registered data (only for files that exist in scan)
|
||||
for (const f of regFiles) {
|
||||
merged.set(f.file_path, f)
|
||||
if (merged.has(f.file_path)) {
|
||||
// File exists on disk, update with real status
|
||||
const existing = merged.get(f.file_path)
|
||||
merged.set(f.file_path, {
|
||||
...existing,
|
||||
...f,
|
||||
media_type: f.media_type || existing.media_type,
|
||||
is_indexed: f.is_indexed || existing.is_indexed
|
||||
})
|
||||
}
|
||||
// If file not in scan, it might have been deleted from disk - skip it
|
||||
}
|
||||
|
||||
files.value = Array.from(merged.values())
|
||||
|
||||
Reference in New Issue
Block a user