feat: filter metadata refresh to ongoing series & improve job action buttons
- Metadata refresh now skips series with ended/cancelled status - Add xs size to Button component - Unify view/cancel button sizes (h-7) with icons (eye & cross) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -110,9 +110,16 @@ pub async fn start_refresh(
|
|||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check there are approved links to refresh
|
// Check there are approved links to refresh (only ongoing series)
|
||||||
let link_count: i64 = sqlx::query_scalar(
|
let link_count: i64 = sqlx::query_scalar(
|
||||||
"SELECT COUNT(*) FROM external_metadata_links WHERE library_id = $1 AND status = 'approved'",
|
r#"
|
||||||
|
SELECT COUNT(*) FROM external_metadata_links eml
|
||||||
|
LEFT JOIN series_metadata sm
|
||||||
|
ON sm.library_id = eml.library_id AND sm.name = eml.series_name
|
||||||
|
WHERE eml.library_id = $1
|
||||||
|
AND eml.status = 'approved'
|
||||||
|
AND COALESCE(sm.status, 'ongoing') NOT IN ('ended', 'cancelled')
|
||||||
|
"#,
|
||||||
)
|
)
|
||||||
.bind(library_id)
|
.bind(library_id)
|
||||||
.fetch_one(&state.pool)
|
.fetch_one(&state.pool)
|
||||||
@@ -234,13 +241,17 @@ pub(crate) async fn process_metadata_refresh(
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// Get all approved links for this library
|
// Get approved links for this library, only for ongoing series (not ended/cancelled)
|
||||||
let links: Vec<(Uuid, String, String, String)> = sqlx::query_as(
|
let links: Vec<(Uuid, String, String, String)> = sqlx::query_as(
|
||||||
r#"
|
r#"
|
||||||
SELECT id, series_name, provider, external_id
|
SELECT eml.id, eml.series_name, eml.provider, eml.external_id
|
||||||
FROM external_metadata_links
|
FROM external_metadata_links eml
|
||||||
WHERE library_id = $1 AND status = 'approved'
|
LEFT JOIN series_metadata sm
|
||||||
ORDER BY series_name
|
ON sm.library_id = eml.library_id AND sm.name = eml.series_name
|
||||||
|
WHERE eml.library_id = $1
|
||||||
|
AND eml.status = 'approved'
|
||||||
|
AND COALESCE(sm.status, 'ongoing') NOT IN ('ended', 'cancelled')
|
||||||
|
ORDER BY eml.series_name
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(library_id)
|
.bind(library_id)
|
||||||
|
|||||||
@@ -205,16 +205,23 @@ export function JobRow({ job, libraryName, highlighted, onCancel, formatDate, fo
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Link
|
<Link
|
||||||
href={`/jobs/${job.id}`}
|
href={`/jobs/${job.id}`}
|
||||||
className="inline-flex items-center px-3 py-1.5 text-xs font-medium rounded-lg bg-primary text-white hover:bg-primary/90 transition-colors"
|
className="inline-flex items-center justify-center gap-1.5 h-7 px-2.5 text-xs font-medium rounded-md bg-primary text-white hover:bg-primary/90 transition-colors"
|
||||||
>
|
>
|
||||||
|
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
||||||
|
</svg>
|
||||||
{t("jobRow.view")}
|
{t("jobRow.view")}
|
||||||
</Link>
|
</Link>
|
||||||
{(job.status === "pending" || job.status === "running" || job.status === "extracting_pages" || job.status === "generating_thumbnails") && (
|
{(job.status === "pending" || job.status === "running" || job.status === "extracting_pages" || job.status === "generating_thumbnails") && (
|
||||||
<Button
|
<Button
|
||||||
variant="danger"
|
variant="danger"
|
||||||
size="sm"
|
size="xs"
|
||||||
onClick={() => onCancel(job.id)}
|
onClick={() => onCancel(job.id)}
|
||||||
>
|
>
|
||||||
|
<svg className="w-3.5 h-3.5 mr-1.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
{t("common.cancel")}
|
{t("common.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type ButtonVariant =
|
|||||||
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
variant?: ButtonVariant;
|
variant?: ButtonVariant;
|
||||||
size?: "sm" | "md" | "lg";
|
size?: "xs" | "sm" | "md" | "lg";
|
||||||
}
|
}
|
||||||
|
|
||||||
const variantStyles: Record<ButtonVariant, string> = {
|
const variantStyles: Record<ButtonVariant, string> = {
|
||||||
@@ -33,6 +33,7 @@ const variantStyles: Record<ButtonVariant, string> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const sizeStyles: Record<string, string> = {
|
const sizeStyles: Record<string, string> = {
|
||||||
|
xs: "h-7 px-2.5 text-xs rounded-md",
|
||||||
sm: "h-9 px-3 text-xs rounded-md",
|
sm: "h-9 px-3 text-xs rounded-md",
|
||||||
md: "h-10 px-4 py-2 text-sm rounded-md",
|
md: "h-10 px-4 py-2 text-sm rounded-md",
|
||||||
lg: "h-11 px-8 text-base rounded-md",
|
lg: "h-11 px-8 text-base rounded-md",
|
||||||
|
|||||||
Reference in New Issue
Block a user