Items that couldn't be processed in this library
Errors
-{ stats.ErrorCount }
-Warnings
-{ stats.WarningCount }
-Info
-{ stats.InfoCount }
-diff --git a/internal/router/frontend.go b/internal/router/frontend.go index 05dc77d4..8546d78a 100644 --- a/internal/router/frontend.go +++ b/internal/router/frontend.go @@ -1413,6 +1413,67 @@ func registerFrontendRoutes(cfg *Config) { return c.HTML(http.StatusOK, buf.String()) })) + // Content partial for the retry queue: after the client drains its + // sequential retry queue it swaps this in over #issues-content so + // resolved issues drop off server-side (unlinked_books matches + // partial precedent). Same family-lens gate as the page. + frontendProtected.GET("/admin/libraries/:id/issues/content", handlers.AdminMiddleware(func(c *echo.Context) error { + libraryID := c.Param("id") + libUUID, err := uuid.Parse(libraryID) + if err != nil { + return renderErrorPage(c, "Invalid library ID", "invalid_id") + } + visibleSet, _, visErr := visibleLibraryIDsFor(c, cfg) + if visErr != nil { + return renderErrorPage(c, "Error checking library access", "visibility_error") + } + if !visibleSet[libraryID] { + return renderErrorPage(c, "Library not accessible", "library_not_accessible") + } + stats, err := cfg.Queries.GetProcessingIssueStats(c.Request().Context(), uuidToPGType(libUUID)) + if err != nil { + return renderErrorPage(c, "Error loading stats", "stats_load_error") + } + dbIssues, err := cfg.Queries.ListProcessingIssuesByLibrary(c.Request().Context(), uuidToPGType(libUUID)) + if err != nil { + return renderErrorPage(c, "Error loading issues", "issues_load_error") + } + issues := make([]templates.ProcessingIssueData, len(dbIssues)) + for i, issue := range dbIssues { + issueUUID, _ := uuid.FromBytes(issue.ID.Bytes[0:16]) + itemID := "" + if issue.MediaItemID.Valid { + itemID = uuid.UUID(issue.MediaItemID.Bytes).String() + } + title := issue.Title + if title == "" { + title = issue.FilePath + } + issues[i] = templates.ProcessingIssueData{ + ID: issueUUID.String(), + MediaItemID: itemID, + Title: title, + FilePath: issue.FilePath, + FormatGroup: issue.FormatGroup, + LibraryTypeName: issue.LibraryTypeName, + IssueType: issue.IssueType, + IssueDescription: issue.IssueDescription, + Severity: issue.Severity, + CreatedAt: issue.CreatedAt.Time, + } + } + statsData := templates.IssueStats{ + ErrorCount: stats.ErrorCount, + WarningCount: stats.WarningCount, + InfoCount: stats.InfoCount, + } + var buf bytes.Buffer + if err := templates.ProcessingIssuesContent(libraryID, issues, statsData).Render(c.Request().Context(), &buf); err != nil { + return err + } + return c.HTML(http.StatusOK, buf.String()) + })) + // Admin hash conflicts page: content-duplicate groups flagged during hash // backfill or rescan, resolved by keeping all copies or merging into one. frontendProtected.GET("/admin/hash-conflicts", handlers.AdminMiddleware(func(c *echo.Context) error { diff --git a/templates/admin_processing_issues.templ b/templates/admin_processing_issues.templ index e4e29c16..f7ab5846 100644 --- a/templates/admin_processing_issues.templ +++ b/templates/admin_processing_issues.templ @@ -12,7 +12,13 @@ templ AdminProcessingIssues(user User, libraryID string, issues []ProcessingIssu
@Header(user, "/admin/library") -Items that couldn't be processed in this library
{ stats.ErrorCount }
-{ stats.WarningCount }
-{ stats.InfoCount }
-