import { createDocumentationLink } from "./docs"; import type { IntegrationKind } from "./integration"; import { getIntegrationKindsByCategory } from "./integration"; import type { WidgetKind } from "./widget"; /** * Static mapping of widget kinds to the integration kinds they support. * Mirrors the supportedIntegrations declared in each widget definition * but lives in @homarr/definitions so server-side code (API layer) * can use it without importing @homarr/widgets. */ export const widgetIntegrationSupport: Partial> = { dnsHoleSummary: getIntegrationKindsByCategory("dnsHole"), dnsHoleControls: getIntegrationKindsByCategory("dnsHole"), "smartHome-entityState": getIntegrationKindsByCategory("smartHomeServer"), "smartHome-executeAutomation": getIntegrationKindsByCategory("smartHomeServer"), mediaServer: getIntegrationKindsByCategory("mediaService"), calendar: getIntegrationKindsByCategory("calendar"), downloads: getIntegrationKindsByCategory("downloadClient"), "mediaRequests-requestList": getIntegrationKindsByCategory("mediaRequest"), "mediaRequests-requestStats": getIntegrationKindsByCategory("mediaRequest"), mediaTranscoding: getIntegrationKindsByCategory("mediaTranscoding"), mediaMissing: getIntegrationKindsByCategory("mediaOrganizer"), networkControllerSummary: getIntegrationKindsByCategory("networkController"), networkControllerStatus: getIntegrationKindsByCategory("networkController"), indexerManager: getIntegrationKindsByCategory("indexerManager"), healthMonitoring: getIntegrationKindsByCategory("healthMonitoring").filter( (kind) => kind !== "patchmon" && kind !== "wud", ), firewall: getIntegrationKindsByCategory("firewall"), notifications: getIntegrationKindsByCategory("notifications"), mediaReleases: ["mock", "emby", "jellyfin", "plex"], systemResources: ["dashDot", "openmediavault", "truenas", "unraid", "glances", "synology"], systemDisks: ["dashDot", "openmediavault", "truenas", "unraid", "synology"], beszelAlerts: ["beszel", "mock"], beszelSystemGrid: ["beszel", "mock"], beszelSystemStats: ["beszel", "mock"], beszelSystemTable: ["beszel", "mock"], coolify: ["coolify"], "immich-serverStats": ["immich"], "immich-albumCarousel": ["immich"], paperlessNgx: ["paperlessNgx"], patchmon: ["patchmon"], bazarr: ["bazarr"], tracearr: ["tracearr"], speedtestTracker: ["speedtestTracker"], uptimeKuma: ["uptimeKuma"], audioStats: ["navidrome", "audiobookshelf"], umami: ["umami"], vpn: getIntegrationKindsByCategory("vpn"), ups: getIntegrationKindsByCategory("ups"), archiveTeamWarrior: ["archiveTeamWarrior"], anchorNote: ["anchor"], traefik: ["traefik"], wud: ["wud"], }; /** Widgets that remain useful without a configured integration. */ export const widgetKindsWithOptionalIntegrations = new Set(["calendar"]); /** Widgets that support fewer integrations than the default unlimited selection. */ export const widgetIntegrationLimits: Partial> = { audioStats: 1, }; export const getWidgetKindsForIntegration = (integrationKind: IntegrationKind): WidgetKind[] => { const result: WidgetKind[] = []; for (const [widgetKind, supportedIntegrations] of Object.entries(widgetIntegrationSupport)) { if (supportedIntegrations.includes(integrationKind)) { result.push(widgetKind as WidgetKind); } } return result; }; export interface DefaultWidgetConfig { kind: WidgetKind; width: number; height: number; options?: Record; skip?: boolean; } export const defaultWidgetConfigs: DefaultWidgetConfig[] = [ { kind: "clock", width: 2, height: 1 }, { kind: "weather", width: 2, height: 1, options: { showCity: true, hasForecast: true, forecastDayCount: 3 } }, { kind: "bookmarks", width: 2, height: 2, options: { title: "Useful Links", layout: "grid", openNewTab: true } }, ]; export const generalWidgets: WidgetKind[] = defaultWidgetConfigs .filter((config) => !config.skip) .map((config) => config.kind); export const featuredIntegrations: readonly IntegrationKind[] = [ "sonarr", "radarr", "prowlarr", "sabNzbd", "qBittorrent", "seerr", "jellyfin", ]; export const hiddenFromOnboarding = new Set(["mock"]); export const defaultBookmarkApps = [ { name: "Homarr Docs", href: createDocumentationLink("/docs/getting-started"), iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/homarr.svg", }, { name: "Homarr GitHub", href: "https://github.com/homarr-labs/homarr", iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/svg/github.svg", }, { name: "Help Translate", href: createDocumentationLink("/docs/community/translations"), iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/homarr.svg", }, { name: "Support Homarr", href: "https://opencollective.com/homarr", iconUrl: "https://cdn.jsdelivr.net/gh/loganmarchione/homelab-svg-assets@latest/assets/opencollective.svg", }, ];