feat: NUT (Network UPS Tools) service provider + provider-agnostic UI
Add full NUT support as a polling-based service provider: - Async TCP client for upsd protocol (port 3493, configurable) - 8 event types: online, on_battery, low_battery, battery_restored, comms_lost, comms_restored, replace_battery, overload - 3 bot commands: /status, /devices, /battery - 38 Jinja2 templates (EN+RU notification + command templates) - Database: tracking config fields, migration, seeds - Frontend: provider form with host/port/credentials, grid items, i18n Provider-agnostic UI improvements: - Remove hardcoded 'immich' defaults from all config forms - Dynamic collection labels per provider type (Albums/Repos/Boards/UPS Devices) - Capability-driven test types instead of provider type checks - Template variable helpers for all providers (was Immich-only) - Guard Immich-only shared link check to Immich providers - Auto-clear stale global provider filter from localStorage - EntitySelect search placeholder shows current selection - Fix noneLabel in linked target config selectors New CLAUDE.md rule #8: no provider-specific hardcoding
This commit is contained in:
@@ -12,6 +12,7 @@ const PROVIDER_TYPE_ICONS: Record<string, string> = {
|
||||
gitea: 'mdiGit',
|
||||
planka: 'mdiViewDashboard',
|
||||
scheduler: 'mdiClockOutline',
|
||||
nut: 'mdiBatteryCharging80',
|
||||
};
|
||||
|
||||
/** Get the default icon for a provider, falling back by type then generic. */
|
||||
@@ -118,6 +119,7 @@ export const providerTypeFilterItems = (): GridItem[] => [
|
||||
{ value: 'gitea', icon: 'mdiGit', label: t('providers.typeGitea'), desc: t('gridDesc.providerGitea') },
|
||||
{ value: 'planka', icon: 'mdiViewDashboard', label: t('providers.typePlanka'), desc: t('gridDesc.providerPlanka') },
|
||||
{ value: 'scheduler', icon: 'mdiClockOutline', label: t('providers.typeScheduler'), desc: t('gridDesc.providerScheduler') },
|
||||
{ value: 'nut', icon: PROVIDER_TYPE_ICONS.nut, label: t('providers.typeNut'), desc: t('gridDesc.providerNut') },
|
||||
];
|
||||
|
||||
// --- Provider type ---
|
||||
@@ -127,4 +129,5 @@ export const providerTypeItems = (): GridItem[] => [
|
||||
{ value: 'gitea', icon: PROVIDER_TYPE_ICONS.gitea, label: t('providers.typeGitea'), desc: t('gridDesc.providerGitea') },
|
||||
{ value: 'planka', icon: PROVIDER_TYPE_ICONS.planka, label: t('providers.typePlanka'), desc: t('gridDesc.providerPlanka') },
|
||||
{ value: 'scheduler', icon: PROVIDER_TYPE_ICONS.scheduler, label: t('providers.typeScheduler'), desc: t('gridDesc.providerScheduler') },
|
||||
{ value: 'nut', icon: PROVIDER_TYPE_ICONS.nut, label: t('providers.typeNut'), desc: t('gridDesc.providerNut') },
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user