mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-12-23 06:56:31 +01:00
Cambios realizados:
1. ai-status.service.ts:
- Importa 'of' desde 'rxjs' para retornar Observables correctamente
- Corrige catchError que retornaba array [] en lugar de Observable
- Ahora retorna of({...}) con valores por defecto cuando falla el endpoint
- Estadísticas ahora muestran 0 en lugar de valores mock cuando hay error
2. ai-suggestions-panel.component.ts:
- Importa 'of' y 'catchError' desde 'rxjs/operators'
- Agrega catchError a TODAS las llamadas de servicios (tags, correspondents, etc.)
- Cada llamada ahora maneja errores y retorna array vacío en caso de fallo
- Previene que errores de red rompan la funcionalidad del panel
- Agrega logging de errores para debugging
Estos cambios corrigen:
- ✓ Estadísticas mostrando 0 incorrectamente
- ✓ Errores no manejados en llamadas HTTP
- ✓ Fallos al cargar metadata de sugerencias
- ✓ Panel de sugerencias fallando silenciosamente
110 lines
2.7 KiB
TypeScript
110 lines
2.7 KiB
TypeScript
import { HttpClient } from '@angular/common/http'
|
|
import { Injectable, inject } from '@angular/core'
|
|
import { BehaviorSubject, Observable, interval, Subscription, of } from 'rxjs'
|
|
import { catchError, map, startWith, switchMap } from 'rxjs/operators'
|
|
import { AIStatus } from 'src/app/data/ai-status'
|
|
import { environment } from 'src/environments/environment'
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
export class AIStatusService {
|
|
private http = inject(HttpClient)
|
|
|
|
private baseUrl: string = environment.apiBaseUrl
|
|
private aiStatusSubject = new BehaviorSubject<AIStatus>({
|
|
active: false,
|
|
processing: false,
|
|
documents_scanned_today: 0,
|
|
suggestions_applied: 0,
|
|
pending_deletion_requests: 0,
|
|
})
|
|
|
|
public loading: boolean = false
|
|
private pollingSubscription?: Subscription
|
|
|
|
// Poll every 30 seconds for AI status updates
|
|
private readonly POLL_INTERVAL = 30000
|
|
|
|
constructor() {
|
|
// Polling is now controlled manually via startPolling()
|
|
}
|
|
|
|
/**
|
|
* Get the current AI status as an observable
|
|
*/
|
|
public getStatus(): Observable<AIStatus> {
|
|
return this.aiStatusSubject.asObservable()
|
|
}
|
|
|
|
/**
|
|
* Get the current AI status value
|
|
*/
|
|
public getCurrentStatus(): AIStatus {
|
|
return this.aiStatusSubject.value
|
|
}
|
|
|
|
/**
|
|
* Start polling for AI status updates
|
|
*/
|
|
public startPolling(): void {
|
|
if (this.pollingSubscription) {
|
|
return // Already running
|
|
}
|
|
this.pollingSubscription = interval(this.POLL_INTERVAL)
|
|
.pipe(
|
|
startWith(0), // Emit immediately on subscription
|
|
switchMap(() => this.fetchAIStatus())
|
|
)
|
|
.subscribe((status) => {
|
|
this.aiStatusSubject.next(status)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Stop polling for AI status updates
|
|
*/
|
|
public stopPolling(): void {
|
|
if (this.pollingSubscription) {
|
|
this.pollingSubscription.unsubscribe()
|
|
this.pollingSubscription = undefined
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch AI status from the backend
|
|
*/
|
|
private fetchAIStatus(): Observable<AIStatus> {
|
|
this.loading = true
|
|
|
|
return this.http
|
|
.get<AIStatus>(`${this.baseUrl}ai/status/`)
|
|
.pipe(
|
|
map((status) => {
|
|
this.loading = false
|
|
return status
|
|
}),
|
|
catchError((error) => {
|
|
this.loading = false
|
|
console.warn('Failed to fetch AI status:', error)
|
|
// Return default status if endpoint fails
|
|
return of({
|
|
active: false,
|
|
processing: false,
|
|
documents_scanned_today: 0,
|
|
suggestions_applied: 0,
|
|
pending_deletion_requests: 0,
|
|
})
|
|
})
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Manually refresh the AI status
|
|
*/
|
|
public refresh(): void {
|
|
this.fetchAIStatus().subscribe((status) => {
|
|
this.aiStatusSubject.next(status)
|
|
})
|
|
}
|
|
}
|