Clarify request sync settings (build 271261159)
This commit is contained in:
@@ -1 +1 @@
|
|||||||
271261149
|
271261159
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const SECTION_LABELS: Record<string, string> = {
|
|||||||
prowlarr: 'Prowlarr',
|
prowlarr: 'Prowlarr',
|
||||||
qbittorrent: 'qBittorrent',
|
qbittorrent: 'qBittorrent',
|
||||||
log: 'Activity log',
|
log: 'Activity log',
|
||||||
requests: 'Request syncing',
|
requests: 'Request sync',
|
||||||
site: 'Site',
|
site: 'Site',
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ const SECTION_DESCRIPTIONS: Record<string, string> = {
|
|||||||
radarr: 'Movie automation settings.',
|
radarr: 'Movie automation settings.',
|
||||||
prowlarr: 'Indexer search settings.',
|
prowlarr: 'Indexer search settings.',
|
||||||
qbittorrent: 'Downloader connection settings.',
|
qbittorrent: 'Downloader connection settings.',
|
||||||
requests: 'Sync and refresh cadence for requests.',
|
requests: 'Control how often requests are refreshed and cleaned up.',
|
||||||
log: 'Activity log for troubleshooting.',
|
log: 'Activity log for troubleshooting.',
|
||||||
site: 'Sitewide banner, version, and changelog details.',
|
site: 'Sitewide banner, version, and changelog details.',
|
||||||
}
|
}
|
||||||
@@ -73,13 +73,13 @@ const labelFromKey = (key: string) =>
|
|||||||
.replace('quality profile id', 'Quality profile ID')
|
.replace('quality profile id', 'Quality profile ID')
|
||||||
.replace('root folder', 'Root folder')
|
.replace('root folder', 'Root folder')
|
||||||
.replace('qbittorrent', 'qBittorrent')
|
.replace('qbittorrent', 'qBittorrent')
|
||||||
.replace('requests sync ttl minutes', 'Refresh saved requests if older than (minutes)')
|
.replace('requests sync ttl minutes', 'Saved request refresh TTL (minutes)')
|
||||||
.replace('requests poll interval seconds', 'Background refresh check (seconds)')
|
.replace('requests poll interval seconds', 'Full refresh check interval (seconds)')
|
||||||
.replace('requests delta sync interval minutes', 'Check for new or updated requests every (minutes)')
|
.replace('requests delta sync interval minutes', 'Delta sync interval (minutes)')
|
||||||
.replace('requests full sync time', 'Full refresh time (24h)')
|
.replace('requests full sync time', 'Daily full refresh time (24h)')
|
||||||
.replace('requests cleanup time', 'Clean up old history time (24h)')
|
.replace('requests cleanup time', 'Daily history cleanup time (24h)')
|
||||||
.replace('requests cleanup days', 'Remove history older than (days)')
|
.replace('requests cleanup days', 'History retention window (days)')
|
||||||
.replace('requests data source', 'Where requests are loaded from')
|
.replace('requests data source', 'Request source (cache vs Jellyseerr)')
|
||||||
.replace('jellyfin public url', 'Jellyfin public URL')
|
.replace('jellyfin public url', 'Jellyfin public URL')
|
||||||
.replace('jellyfin sync to arr', 'Sync Jellyfin to Sonarr/Radarr')
|
.replace('jellyfin sync to arr', 'Sync Jellyfin to Sonarr/Radarr')
|
||||||
.replace('artwork cache mode', 'Artwork cache mode')
|
.replace('artwork cache mode', 'Artwork cache mode')
|
||||||
@@ -277,6 +277,22 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
|||||||
const cacheSettingKeys = new Set(['requests_sync_ttl_minutes', 'requests_data_source'])
|
const cacheSettingKeys = new Set(['requests_sync_ttl_minutes', 'requests_data_source'])
|
||||||
const artworkSettingKeys = new Set(['artwork_cache_mode'])
|
const artworkSettingKeys = new Set(['artwork_cache_mode'])
|
||||||
const hiddenSettingKeys = new Set([...cacheSettingKeys, ...artworkSettingKeys])
|
const hiddenSettingKeys = new Set([...cacheSettingKeys, ...artworkSettingKeys])
|
||||||
|
const requestSettingOrder = [
|
||||||
|
'requests_poll_interval_seconds',
|
||||||
|
'requests_delta_sync_interval_minutes',
|
||||||
|
'requests_full_sync_time',
|
||||||
|
'requests_cleanup_time',
|
||||||
|
'requests_cleanup_days',
|
||||||
|
]
|
||||||
|
const sortByOrder = (items: AdminSetting[], order: string[]) => {
|
||||||
|
const position = new Map(order.map((key, index) => [key, index]))
|
||||||
|
return [...items].sort((a, b) => {
|
||||||
|
const aIndex = position.get(a.key) ?? Number.POSITIVE_INFINITY
|
||||||
|
const bIndex = position.get(b.key) ?? Number.POSITIVE_INFINITY
|
||||||
|
if (aIndex !== bIndex) return aIndex - bIndex
|
||||||
|
return a.key.localeCompare(b.key)
|
||||||
|
})
|
||||||
|
}
|
||||||
const cacheSettings = settings.filter((setting) => cacheSettingKeys.has(setting.key))
|
const cacheSettings = settings.filter((setting) => cacheSettingKeys.has(setting.key))
|
||||||
const artworkSettings = settings.filter((setting) => artworkSettingKeys.has(setting.key))
|
const artworkSettings = settings.filter((setting) => artworkSettingKeys.has(setting.key))
|
||||||
const settingsSections = isCacheSection
|
const settingsSections = isCacheSection
|
||||||
@@ -287,12 +303,17 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
|||||||
: visibleSections.map((sectionKey) => ({
|
: visibleSections.map((sectionKey) => ({
|
||||||
key: sectionKey,
|
key: sectionKey,
|
||||||
title: SECTION_LABELS[sectionKey] ?? sectionKey,
|
title: SECTION_LABELS[sectionKey] ?? sectionKey,
|
||||||
items:
|
items: (() => {
|
||||||
|
const sectionItems = groupedSettings[sectionKey] ?? []
|
||||||
|
const filtered =
|
||||||
sectionKey === 'requests' || sectionKey === 'artwork'
|
sectionKey === 'requests' || sectionKey === 'artwork'
|
||||||
? (groupedSettings[sectionKey] ?? []).filter(
|
? sectionItems.filter((setting) => !hiddenSettingKeys.has(setting.key))
|
||||||
(setting) => !hiddenSettingKeys.has(setting.key)
|
: sectionItems
|
||||||
)
|
if (sectionKey === 'requests') {
|
||||||
: groupedSettings[sectionKey] ?? [],
|
return sortByOrder(filtered, requestSettingOrder)
|
||||||
|
}
|
||||||
|
return filtered
|
||||||
|
})(),
|
||||||
}))
|
}))
|
||||||
const showLogs = section === 'logs'
|
const showLogs = section === 'logs'
|
||||||
const showMaintenance = section === 'maintenance'
|
const showMaintenance = section === 'maintenance'
|
||||||
@@ -332,11 +353,11 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
|||||||
qbittorrent_password: 'qBittorrent login password.',
|
qbittorrent_password: 'qBittorrent login password.',
|
||||||
requests_sync_ttl_minutes: 'How long saved requests stay fresh before a refresh is needed.',
|
requests_sync_ttl_minutes: 'How long saved requests stay fresh before a refresh is needed.',
|
||||||
requests_poll_interval_seconds:
|
requests_poll_interval_seconds:
|
||||||
'How often Magent wakes up to check if the cache is stale and needs a full refresh.',
|
'How often Magent checks if a full refresh should run.',
|
||||||
requests_delta_sync_interval_minutes:
|
requests_delta_sync_interval_minutes:
|
||||||
'How often we actively poll for new or updated requests (delta sync).',
|
'How often we poll for new or updated requests.',
|
||||||
requests_full_sync_time: 'Daily time to refresh the full request list.',
|
requests_full_sync_time: 'Daily time to rebuild the full request cache.',
|
||||||
requests_cleanup_time: 'Daily time to trim old history.',
|
requests_cleanup_time: 'Daily time to trim old request history.',
|
||||||
requests_cleanup_days: 'History older than this is removed during cleanup.',
|
requests_cleanup_days: 'History older than this is removed during cleanup.',
|
||||||
requests_data_source:
|
requests_data_source:
|
||||||
'Pick where Magent should read requests from. Cache-only avoids Jellyseerr lookups on reads.',
|
'Pick where Magent should read requests from. Cache-only avoids Jellyseerr lookups on reads.',
|
||||||
@@ -782,7 +803,9 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
|||||||
.map((sectionGroup) => (
|
.map((sectionGroup) => (
|
||||||
<section key={sectionGroup.key} className="admin-section">
|
<section key={sectionGroup.key} className="admin-section">
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
<h2>{sectionGroup.key === 'requests' ? 'Sync controls' : sectionGroup.title}</h2>
|
<h2>
|
||||||
|
{sectionGroup.key === 'requests' ? 'Request sync controls' : sectionGroup.title}
|
||||||
|
</h2>
|
||||||
{sectionGroup.key === 'sonarr' && (
|
{sectionGroup.key === 'sonarr' && (
|
||||||
<button type="button" onClick={() => loadOptions('sonarr')}>
|
<button type="button" onClick={() => loadOptions('sonarr')}>
|
||||||
Refresh Sonarr options
|
Refresh Sonarr options
|
||||||
@@ -816,14 +839,15 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
|||||||
<div className="sync-actions-block">
|
<div className="sync-actions-block">
|
||||||
<div className="sync-actions">
|
<div className="sync-actions">
|
||||||
<button type="button" onClick={syncRequests}>
|
<button type="button" onClick={syncRequests}>
|
||||||
Full refresh (all requests)
|
Run full refresh (rebuild cache)
|
||||||
</button>
|
</button>
|
||||||
<button type="button" className="ghost-button" onClick={syncRequestsDelta}>
|
<button type="button" className="ghost-button" onClick={syncRequestsDelta}>
|
||||||
Quick refresh (delta changes)
|
Run delta sync (recent changes)
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="meta sync-note">
|
<div className="meta sync-note">
|
||||||
Full refresh reloads the entire list. Quick refresh only checks recent changes.
|
Full refresh rebuilds the entire cache. Delta sync only checks new or updated
|
||||||
|
requests.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -877,8 +901,8 @@ export default function SettingsPage({ section }: SettingsPageProps) {
|
|||||||
)}
|
)}
|
||||||
{showRequestsExtras && sectionGroup.key === 'requests' && (
|
{showRequestsExtras && sectionGroup.key === 'requests' && (
|
||||||
<div className="status-banner">
|
<div className="status-banner">
|
||||||
Background refresh checks only decide when to run a full refresh. The delta sync
|
Full refresh checks only decide when to run a full refresh. The delta sync interval
|
||||||
interval actively polls for new or updated requests.
|
polls for new or updated requests.
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{showArtworkExtras && sectionGroup.key === 'artwork' && artworkPrefetch && (
|
{showArtworkExtras && sectionGroup.key === 'artwork' && artworkPrefetch && (
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const NAV_GROUPS = [
|
|||||||
{
|
{
|
||||||
title: 'Requests',
|
title: 'Requests',
|
||||||
items: [
|
items: [
|
||||||
{ href: '/admin/requests', label: 'Request syncing' },
|
{ href: '/admin/requests', label: 'Request sync' },
|
||||||
{ href: '/admin/cache', label: 'Cache Control' },
|
{ href: '/admin/cache', label: 'Cache Control' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user