feat: add scheduled metadata refresh for libraries
Add metadata_refresh_mode (manual/hourly/daily/weekly) to libraries, with automatic scheduling via the indexer. Includes API support, backoffice UI controls, i18n translations, and DB migration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ interface LibraryActionsProps {
|
||||
watcherEnabled: boolean;
|
||||
metadataProvider: string | null;
|
||||
fallbackMetadataProvider: string | null;
|
||||
metadataRefreshMode: string;
|
||||
onUpdate?: () => void;
|
||||
}
|
||||
|
||||
@@ -22,6 +23,7 @@ export function LibraryActions({
|
||||
watcherEnabled,
|
||||
metadataProvider,
|
||||
fallbackMetadataProvider,
|
||||
metadataRefreshMode,
|
||||
onUpdate
|
||||
}: LibraryActionsProps) {
|
||||
const { t } = useTranslation();
|
||||
@@ -48,6 +50,7 @@ export function LibraryActions({
|
||||
const scanMode = formData.get("scan_mode") as string;
|
||||
const newMetadataProvider = (formData.get("metadata_provider") as string) || null;
|
||||
const newFallbackProvider = (formData.get("fallback_metadata_provider") as string) || null;
|
||||
const newMetadataRefreshMode = formData.get("metadata_refresh_mode") as string;
|
||||
|
||||
try {
|
||||
const [response] = await Promise.all([
|
||||
@@ -58,6 +61,7 @@ export function LibraryActions({
|
||||
monitor_enabled: monitorEnabled,
|
||||
scan_mode: scanMode,
|
||||
watcher_enabled: watcherEnabled,
|
||||
metadata_refresh_mode: newMetadataRefreshMode,
|
||||
}),
|
||||
}),
|
||||
fetch(`/api/libraries/${libraryId}/metadata-provider`, {
|
||||
@@ -181,6 +185,20 @@ export function LibraryActions({
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<label className="text-sm font-medium text-foreground">{t("libraryActions.metadataRefreshSchedule")}</label>
|
||||
<select
|
||||
name="metadata_refresh_mode"
|
||||
defaultValue={metadataRefreshMode}
|
||||
className="text-sm border border-border rounded-lg px-2 py-1 bg-background"
|
||||
>
|
||||
<option value="manual">{t("monitoring.manual")}</option>
|
||||
<option value="hourly">{t("monitoring.hourly")}</option>
|
||||
<option value="daily">{t("monitoring.daily")}</option>
|
||||
<option value="weekly">{t("monitoring.weekly")}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{saveError && (
|
||||
<p className="text-xs text-destructive bg-destructive/10 px-2 py-1.5 rounded-lg break-all">
|
||||
{saveError}
|
||||
|
||||
@@ -131,6 +131,7 @@ export default async function LibrariesPage() {
|
||||
watcherEnabled={lib.watcher_enabled}
|
||||
metadataProvider={lib.metadata_provider}
|
||||
fallbackMetadataProvider={lib.fallback_metadata_provider}
|
||||
metadataRefreshMode={lib.metadata_refresh_mode}
|
||||
/>
|
||||
</div>
|
||||
</CardHeader>
|
||||
@@ -169,6 +170,11 @@ export default async function LibrariesPage() {
|
||||
{t("libraries.nextScan", { time: formatNextScan(lib.next_scan_at, t("libraries.imminent")) })}
|
||||
</span>
|
||||
)}
|
||||
{lib.metadata_refresh_mode !== "manual" && lib.next_metadata_refresh_at && (
|
||||
<span className="text-xs text-muted-foreground ml-auto" title={t("libraries.nextMetadataRefresh", { time: formatNextScan(lib.next_metadata_refresh_at, t("libraries.imminent")) })}>
|
||||
{t("libraries.nextMetadataRefreshShort", { time: formatNextScan(lib.next_metadata_refresh_at, t("libraries.imminent")) })}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Actions */}
|
||||
|
||||
Reference in New Issue
Block a user