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(() => {
|
const displayFiles = computed(() => {
|
||||||
let result = files.value
|
// Start with a copy to avoid mutation issues
|
||||||
|
let result = [...files.value]
|
||||||
|
|
||||||
// Filter by media type
|
// Filter by media type
|
||||||
if (mediaType.value !== 'all') {
|
if (mediaType.value !== 'all') {
|
||||||
@@ -263,7 +264,20 @@ async function fetchFiles() {
|
|||||||
try {
|
try {
|
||||||
const config = getCurrentConfig()
|
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[] = []
|
let regFiles: any[] = []
|
||||||
try {
|
try {
|
||||||
const regResp = await httpFetch<any>(`${config.api_base_url}/api/v1/files?page=1&page_size=200`)
|
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 {
|
} 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
|
// Build a map of registered files by file_path for quick lookup
|
||||||
const scanResp = await httpFetch<any>(`${config.api_base_url}/api/v1/files/scan`)
|
const regMap = new Map<string, any>()
|
||||||
const scanFiles: any[] = (scanResp?.files || []).map((f: any) => {
|
for (const f of regFiles) {
|
||||||
const mediaType = getMediaType(f.file_name)
|
regMap.set(f.file_path, f)
|
||||||
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))
|
|
||||||
|
|
||||||
// Merge: start with scan results, override with registered data where available
|
// Merge: start with scan results, override with registered data where available
|
||||||
const merged = new Map<string, any>()
|
const merged = new Map<string, any>()
|
||||||
|
|
||||||
// First pass: add all scan results
|
// First pass: add all scan results
|
||||||
for (const f of scanFiles) {
|
for (const f of scanFiles) {
|
||||||
const isRegistered = registeredPaths.has(f.file_path)
|
merged.set(f.file_path, { ...f })
|
||||||
merged.set(f.file_path, {
|
|
||||||
...f,
|
|
||||||
status: isRegistered ? 'pending' : 'unregistered'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) {
|
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())
|
files.value = Array.from(merged.values())
|
||||||
|
|||||||
Reference in New Issue
Block a user