Build 2602262049: split magent settings and harden local login

This commit is contained in:
2026-02-26 20:50:38 +13:00
parent 0b73d9f4ee
commit 1c6b8255c1
7 changed files with 142 additions and 27 deletions

View File

@@ -20,6 +20,8 @@ type ServiceOptions = {
const SECTION_LABELS: Record<string, string> = {
magent: 'Magent',
general: 'General',
notifications: 'Notifications',
jellyseerr: 'Jellyseerr',
jellyfin: 'Jellyfin',
artwork: 'Artwork cache',
@@ -82,7 +84,11 @@ const BANNER_TONES = ['info', 'warning', 'error', 'maintenance']
const SECTION_DESCRIPTIONS: Record<string, string> = {
magent:
'Application-level Magent settings including proxy, binding, TLS, and notification channels.',
'Magent service settings. Runtime and notification controls are organized under General and Notifications.',
general:
'Application runtime, binding, reverse proxy, and manual SSL settings for the Magent UI/API.',
notifications:
'Notification providers and delivery channel settings used by Magent messaging features.',
jellyseerr: 'Connect the request system where users submit content.',
jellyfin: 'Control Jellyfin login and availability checks.',
artwork: 'Cache posters/backdrops and review artwork coverage.',
@@ -98,6 +104,8 @@ const SECTION_DESCRIPTIONS: Record<string, string> = {
const SETTINGS_SECTION_MAP: Record<string, string | null> = {
magent: 'magent',
general: 'magent',
notifications: 'magent',
jellyseerr: 'jellyseerr',
jellyfin: 'jellyfin',
artwork: null,
@@ -214,6 +222,17 @@ const MAGENT_SECTION_GROUPS: Array<{
},
]
const MAGENT_GROUPS_BY_SECTION: Record<string, Set<string>> = {
general: new Set(['magent-runtime', 'magent-proxy', 'magent-ssl']),
notifications: new Set([
'magent-notify-core',
'magent-notify-email',
'magent-notify-discord',
'magent-notify-telegram',
'magent-notify-push',
]),
}
const SETTING_LABEL_OVERRIDES: Record<string, string> = {
magent_application_url: 'Application URL',
magent_application_port: 'Application port',
@@ -474,6 +493,7 @@ export default function SettingsPage({ section }: SettingsPageProps) {
}, [settings])
const settingsSection = SETTINGS_SECTION_MAP[section] ?? null
const isMagentGroupedSection = section === 'magent' || section === 'general' || section === 'notifications'
const visibleSections = settingsSection ? [settingsSection] : []
const isCacheSection = section === 'cache'
const cacheSettingKeys = new Set(['requests_sync_ttl_minutes', 'requests_data_source'])
@@ -502,18 +522,20 @@ export default function SettingsPage({ section }: SettingsPageProps) {
{ key: 'cache', title: 'Cache control', items: cacheSettings },
{ key: 'artwork', title: 'Artwork cache', items: artworkSettings },
]
: section === 'magent'
: isMagentGroupedSection
? (() => {
if (section === 'magent') {
return []
}
const magentItems = groupedSettings.magent ?? []
const byKey = new Map(magentItems.map((item) => [item.key, item]))
const used = new Set<string>()
const groups: SettingsSectionGroup[] = MAGENT_SECTION_GROUPS.map((group) => {
const allowedGroupKeys = MAGENT_GROUPS_BY_SECTION[section] ?? new Set<string>()
const groups: SettingsSectionGroup[] = MAGENT_SECTION_GROUPS.filter((group) =>
allowedGroupKeys.has(group.key),
).map((group) => {
const items = group.keys
.map((key) => byKey.get(key))
.filter((item): item is AdminSetting => Boolean(item))
for (const item of items) {
used.add(item.key)
}
return {
key: group.key,
title: group.title,
@@ -521,15 +543,6 @@ export default function SettingsPage({ section }: SettingsPageProps) {
items,
}
})
const remaining = magentItems.filter((item) => !used.has(item.key))
if (remaining.length) {
groups.push({
key: 'magent-other',
title: 'Additional Magent settings',
description: 'Uncategorized Magent settings.',
items: remaining,
})
}
return groups
})()
: visibleSections.map((sectionKey) => ({
@@ -1320,12 +1333,12 @@ export default function SettingsPage({ section }: SettingsPageProps) {
)}
</div>
{(sectionGroup.description || SECTION_DESCRIPTIONS[sectionGroup.key]) &&
(!settingsSection || section === 'magent') && (
(!settingsSection || isMagentGroupedSection) && (
<p className="section-subtitle">
{sectionGroup.description || SECTION_DESCRIPTIONS[sectionGroup.key]}
</p>
)}
{section === 'magent' && sectionGroup.key === 'magent-runtime' && (
{section === 'general' && sectionGroup.key === 'magent-runtime' && (
<div className="status-banner">
Runtime host/port and SSL values are configuration settings. Container/process
restarts may still be required before bind/port changes take effect.
@@ -1845,7 +1858,9 @@ export default function SettingsPage({ section }: SettingsPageProps) {
</form>
) : (
<div className="status-banner">
No settings to show here yet. Try the Cache Control page for artwork and saved-request controls.
{section === 'magent'
? 'Magent runtime settings have moved to General. Notification provider settings have moved to Notifications.'
: 'No settings to show here yet. Try the Cache Control page for artwork and saved-request controls.'}
</div>
)}
{showLogs && (