diff --git a/src/components/About/AboutModal.tsx b/src/components/About/AboutModal.tsx index ea197383c..68e12db13 100644 --- a/src/components/About/AboutModal.tsx +++ b/src/components/About/AboutModal.tsx @@ -50,8 +50,8 @@ export const AboutModal = ({ opened, closeModal }: AboutModalProps) => { > Homarr is a simple and modern homepage for your server that helps you access all of your - apps in one place. It integrates with the apps you use to display useful information - or control them. It's easy to install and supports many different devices. + apps in one place. It integrates with the apps you use to display useful information or + control them. It's easy to install and supports many different devices. diff --git a/src/components/AppShelf/AppShelf.tsx b/src/components/AppShelf/AppShelf.tsx index fea2a044c..798d81cf2 100644 --- a/src/components/AppShelf/AppShelf.tsx +++ b/src/components/AppShelf/AppShelf.tsx @@ -12,7 +12,6 @@ import { import { arrayMove, SortableContext } from '@dnd-kit/sortable'; import { useLocalStorage } from '@mantine/hooks'; -import { useTranslation } from 'next-i18next'; import * as Modules from '../../modules'; import { useConfig } from '../../tools/state'; diff --git a/src/components/Config/ConfigChanger.tsx b/src/components/Config/ConfigChanger.tsx index 9a0947d9b..9df1773f5 100644 --- a/src/components/Config/ConfigChanger.tsx +++ b/src/components/Config/ConfigChanger.tsx @@ -47,11 +47,9 @@ export default function ConfigChanger() { ); } -const useConfigsQuery = () => { - return useQuery({ +const useConfigsQuery = () => useQuery({ queryKey: ['config/get-all'], queryFn: fetchConfigs, }); -}; const fetchConfigs = async () => (await (await fetch('/api/configs')).json()) as string[]; diff --git a/src/components/Dashboard/Dashboard.tsx b/src/components/Dashboard/Dashboard.tsx index 7ec984c36..35acd4d39 100644 --- a/src/components/Dashboard/Dashboard.tsx +++ b/src/components/Dashboard/Dashboard.tsx @@ -3,8 +3,6 @@ import { DashboardDetailView } from './Views/DetailView'; import { DashboardEditView } from './Views/EditView'; import { useEditModeStore } from './Views/useEditModeStore'; -interface DashboardProps {} - export const Dashboard = () => { const isEditMode = useEditModeStore((x) => x.enabled); diff --git a/src/components/Dashboard/Mobile/Ribbon/MobileRibbonSidebarDrawer.tsx b/src/components/Dashboard/Mobile/Ribbon/MobileRibbonSidebarDrawer.tsx index ccf8e8e7b..9a9002291 100644 --- a/src/components/Dashboard/Mobile/Ribbon/MobileRibbonSidebarDrawer.tsx +++ b/src/components/Dashboard/Mobile/Ribbon/MobileRibbonSidebarDrawer.tsx @@ -10,8 +10,7 @@ interface MobileRibbonSidebarDrawerProps { export const MobileRibbonSidebarDrawer = ({ location, ...props -}: MobileRibbonSidebarDrawerProps) => { - return ( +}: MobileRibbonSidebarDrawerProps) => ( <Drawer position={location} title={<Title order={4}>{location} sidebar} @@ -24,4 +23,3 @@ export const MobileRibbonSidebarDrawer = ({ ); -}; diff --git a/src/components/Dashboard/Modals/ChangePosition/ChangeWidgetPositionModal.tsx b/src/components/Dashboard/Modals/ChangePosition/ChangeWidgetPositionModal.tsx index 2e5325634..6e1d92f95 100644 --- a/src/components/Dashboard/Modals/ChangePosition/ChangeWidgetPositionModal.tsx +++ b/src/components/Dashboard/Modals/ChangePosition/ChangeWidgetPositionModal.tsx @@ -22,7 +22,7 @@ export const ChangeWidgetPositionModal = ({ updateConfig( configName, (prev) => { - let currentWidget = prev.widgets.find((x) => x.id === innerProps.widgetId); + const currentWidget = prev.widgets.find((x) => x.id === innerProps.widgetId); currentWidget!.shape = { location: { x, diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector/IconSelector.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector/IconSelector.tsx index 7ecc48366..48250ebb6 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector/IconSelector.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector/IconSelector.tsx @@ -29,11 +29,7 @@ interface IconSelectorProps { allowAppNamePropagation: boolean; } -export const IconSelector = ({ - onChange, - allowAppNamePropagation, - form, -}: IconSelectorProps) => { +export const IconSelector = ({ onChange, allowAppNamePropagation, form }: IconSelectorProps) => { const { data, isLoading } = useRepositoryIconsQuery({ url: 'https://api.github.com/repos/walkxcode/Dashboard-Icons/contents/png', converter: (item) => ({ diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/BehaviourTab/BehaviourTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/BehaviourTab/BehaviourTab.tsx index ee1d4d2c1..2f942927c 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/BehaviourTab/BehaviourTab.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/BehaviourTab/BehaviourTab.tsx @@ -1,6 +1,5 @@ -import { Tabs, TextInput, Switch, Text } from '@mantine/core'; +import { Tabs, Switch } from '@mantine/core'; import { UseFormReturnType } from '@mantine/form'; -import { IconClick } from '@tabler/icons'; import { useTranslation } from 'next-i18next'; import { AppType } from '../../../../../../types/app'; diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/IntegrationOptionsRenderer/IntegrationOptionsRenderer.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/IntegrationOptionsRenderer/IntegrationOptionsRenderer.tsx index 859e2a954..182539796 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/IntegrationOptionsRenderer/IntegrationOptionsRenderer.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/IntegrationOptionsRenderer/IntegrationOptionsRenderer.tsx @@ -31,9 +31,9 @@ export const IntegrationOptionsRenderer = ({ form }: IntegrationOptionsRendererP let indexInFormValue = form.values.integration?.properties.findIndex((p) => p.field === property) ?? -1; if (indexInFormValue === -1) { - const type = Object.entries(integrationFieldDefinitions).find( + const { type } = Object.entries(integrationFieldDefinitions).find( ([k, v]) => k === property - )![1].type; + )![1]; const newProperty: AppIntegrationPropertyType = { type, field: property as IntegrationField, diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/IntegrationTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/IntegrationTab.tsx index d4c196d58..0c031541e 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/IntegrationTab.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/IntegrationTab.tsx @@ -20,12 +20,7 @@ export const IntegrationTab = ({ form }: IntegrationTabProps) => { {hasIntegrationSelected && ( <> - + {t('integration.secrets.description')} diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/type.ts b/src/components/Dashboard/Modals/EditAppModal/Tabs/type.ts index 124864669..a67947134 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/type.ts +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/type.ts @@ -1,6 +1 @@ -export type EditAppModalTab = - | 'general' - | 'behaviour' - | 'network' - | 'appereance' - | 'integration'; +export type EditAppModalTab = 'general' | 'behaviour' | 'network' | 'appereance' | 'integration'; diff --git a/src/components/Dashboard/Modals/SelectElement/Components/WidgetsTab/WidgetElementType.tsx b/src/components/Dashboard/Modals/SelectElement/Components/WidgetsTab/WidgetElementType.tsx index 209f5d1d8..a2262164f 100644 --- a/src/components/Dashboard/Modals/SelectElement/Components/WidgetsTab/WidgetElementType.tsx +++ b/src/components/Dashboard/Modals/SelectElement/Components/WidgetsTab/WidgetElementType.tsx @@ -21,9 +21,7 @@ export const WidgetElementType = ({ id, image, disabled, widget }: WidgetElement if (!configName) return null; - const getLowestWrapper = () => { - return config?.wrappers.sort((a, b) => a.position - b.position)[0]; - }; + const getLowestWrapper = () => config?.wrappers.sort((a, b) => a.position - b.position)[0]; const handleAddition = async () => { updateConfig( diff --git a/src/components/Dashboard/Tiles/Apps/AppTile.tsx b/src/components/Dashboard/Tiles/Apps/AppTile.tsx index 84baba625..9c5a8c5e3 100644 --- a/src/components/Dashboard/Tiles/Apps/AppTile.tsx +++ b/src/components/Dashboard/Tiles/Apps/AppTile.tsx @@ -1,4 +1,4 @@ -import { Card, Center, Text, UnstyledButton } from '@mantine/core'; +import { Center, Text, UnstyledButton } from '@mantine/core'; import { NextLink } from '@mantine/next'; import { createStyles } from '@mantine/styles'; import { AppType } from '../../../../types/app'; diff --git a/src/components/Dashboard/Tiles/EmptyTile.tsx b/src/components/Dashboard/Tiles/EmptyTile.tsx index 0db967288..9fdb26db7 100644 --- a/src/components/Dashboard/Tiles/EmptyTile.tsx +++ b/src/components/Dashboard/Tiles/EmptyTile.tsx @@ -1,6 +1,6 @@ import { HomarrCardWrapper } from './HomarrCardWrapper'; import { BaseTileProps } from './type'; -export const EmptyTile = ({ className }: BaseTileProps) => { - return Empty; -}; +export const EmptyTile = ({ className }: BaseTileProps) => ( + Empty +); diff --git a/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx b/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx index 77d958060..62b8ac476 100644 --- a/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx +++ b/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx @@ -1,8 +1,8 @@ -import Widgets from '../../../../widgets'; import { Button, Group, MultiSelect, Stack, Switch, TextInput } from '@mantine/core'; import { ContextModalProps } from '@mantine/modals'; import { useTranslation } from 'next-i18next'; import { useState } from 'react'; +import Widgets from '../../../../widgets'; import { useConfigContext } from '../../../../config/provider'; import { useConfigStore } from '../../../../config/store'; import { IWidget } from '../../../../widgets/widgets'; @@ -48,7 +48,7 @@ export const WidgetsEditModal = ({ updateConfig( configName, (prev) => { - let currentWidget = prev.widgets.find((x) => x.id === innerProps.widgetId); + const currentWidget = prev.widgets.find((x) => x.id === innerProps.widgetId); currentWidget!.properties = moduleProperties; return { diff --git a/src/components/Dashboard/Tiles/Widgets/WidgetsMenu.tsx b/src/components/Dashboard/Tiles/Widgets/WidgetsMenu.tsx index f0bf00a7d..402826090 100644 --- a/src/components/Dashboard/Tiles/Widgets/WidgetsMenu.tsx +++ b/src/components/Dashboard/Tiles/Widgets/WidgetsMenu.tsx @@ -38,7 +38,7 @@ export const WidgetsMenu = ({ integration, widget }: WidgetsMenuProps) => { title: null, innerProps: { widgetId: integration, - widget: widget, + widget, }, }); }; diff --git a/src/components/Dashboard/Views/DetailView.tsx b/src/components/Dashboard/Views/DetailView.tsx index e367dd9df..e73c664bc 100644 --- a/src/components/Dashboard/Views/DetailView.tsx +++ b/src/components/Dashboard/Views/DetailView.tsx @@ -1,5 +1,3 @@ import { DashboardView } from './DashboardView'; -export const DashboardDetailView = () => { - return ; -}; +export const DashboardDetailView = () => ; diff --git a/src/components/Dashboard/Wrappers/Category/Category.tsx b/src/components/Dashboard/Wrappers/Category/Category.tsx index 638f72b20..e0f905524 100644 --- a/src/components/Dashboard/Wrappers/Category/Category.tsx +++ b/src/components/Dashboard/Wrappers/Category/Category.tsx @@ -1,10 +1,6 @@ -import { Card, Group, Title } from '@mantine/core'; +import { Group, Title } from '@mantine/core'; import { CategoryType } from '../../../../types/category'; -import { IWidgetDefinition } from '../../../../widgets/widgets'; import { HomarrCardWrapper } from '../../Tiles/HomarrCardWrapper'; -import { Tiles } from '../../Tiles/tilesDefinitions'; -import Widgets from '../../../../widgets'; -import { GridstackTileWrapper } from '../../Tiles/TileWrapper'; import { useEditModeStore } from '../../Views/useEditModeStore'; import { useGridstack } from '../gridstack/use-gridstack'; import { CategoryEditMenu } from './CategoryEditMenu'; diff --git a/src/components/Dashboard/Wrappers/Sidebar/Sidebar.tsx b/src/components/Dashboard/Wrappers/Sidebar/Sidebar.tsx index bfa37a628..c90ef9999 100644 --- a/src/components/Dashboard/Wrappers/Sidebar/Sidebar.tsx +++ b/src/components/Dashboard/Wrappers/Sidebar/Sidebar.tsx @@ -1,9 +1,5 @@ import { Card } from '@mantine/core'; import { RefObject } from 'react'; -import { IWidgetDefinition } from '../../../../widgets/widgets'; -import { Tiles } from '../../Tiles/tilesDefinitions'; -import Widgets from '../../../../widgets'; -import { GridstackTileWrapper } from '../../Tiles/TileWrapper'; import { useGridstack } from '../gridstack/use-gridstack'; import { WrapperContent } from '../WrapperContent'; @@ -38,6 +34,5 @@ export const DashboardSidebar = ({ location }: DashboardSidebarProps) => { ); }; -const useMinRowForFullHeight = (wrapperRef: RefObject) => { - return wrapperRef.current ? Math.floor(wrapperRef.current!.offsetHeight / 64) : 2; -}; +const useMinRowForFullHeight = (wrapperRef: RefObject) => + wrapperRef.current ? Math.floor(wrapperRef.current!.offsetHeight / 64) : 2; diff --git a/src/components/Dashboard/Wrappers/WrapperContent.tsx b/src/components/Dashboard/Wrappers/WrapperContent.tsx index 7ccf22746..bfc813f57 100644 --- a/src/components/Dashboard/Wrappers/WrapperContent.tsx +++ b/src/components/Dashboard/Wrappers/WrapperContent.tsx @@ -19,44 +19,44 @@ interface WrapperContentProps { } export const WrapperContent = ({ apps, refs, widgets }: WrapperContentProps) => ( - <> - {apps?.map((app) => { - const { component: TileComponent, ...tile } = Tiles.app; - return ( - - - - ); - })} - {widgets.map((widget) => { - const definition = Widgets[widget.id as keyof typeof Widgets] as - | IWidgetDefinition - | undefined; - if (!definition) return null; + <> + {apps?.map((app) => { + const { component: TileComponent, ...tile } = Tiles.app; + return ( + + + + ); + })} + {widgets.map((widget) => { + const definition = Widgets[widget.id as keyof typeof Widgets] as + | IWidgetDefinition + | undefined; + if (!definition) return null; - return ( - - - - - - ); - })} - - ); + return ( + + + + + + ); + })} + +); diff --git a/src/components/Settings/Common/CommonSettings.tsx b/src/components/Settings/Common/CommonSettings.tsx index 8923c3498..d61d1aecc 100644 --- a/src/components/Settings/Common/CommonSettings.tsx +++ b/src/components/Settings/Common/CommonSettings.tsx @@ -4,7 +4,6 @@ import ConfigChanger from '../../Config/ConfigChanger'; import ConfigActions from './Config/ConfigActions'; import LanguageSelect from './Language/LanguageSelect'; import { SearchEngineSelector } from './SearchEngine/SearchEngineSelector'; -import { SearchNewTabSwitch } from './SearchNewTabSwitch'; export default function CommonSettings() { const { config } = useConfigContext(); diff --git a/src/components/Settings/Customization/Layout/LayoutSelector.tsx b/src/components/Settings/Customization/Layout/LayoutSelector.tsx index 3ca3ed4df..94e380827 100644 --- a/src/components/Settings/Customization/Layout/LayoutSelector.tsx +++ b/src/components/Settings/Customization/Layout/LayoutSelector.tsx @@ -1,6 +1,5 @@ import { ActionIcon, - Center, Checkbox, createStyles, Flex, diff --git a/src/components/Settings/SettingsDrawer.tsx b/src/components/Settings/SettingsDrawer.tsx index 3fef9e2ef..8e1d3b51e 100644 --- a/src/components/Settings/SettingsDrawer.tsx +++ b/src/components/Settings/SettingsDrawer.tsx @@ -1,7 +1,4 @@ -import { ActionIcon, Title, Tooltip, Drawer, Tabs, ScrollArea } from '@mantine/core'; -import { useHotkeys } from '@mantine/hooks'; -import { useState } from 'react'; -import { IconSettings } from '@tabler/icons'; +import { Title, Drawer, Tabs, ScrollArea } from '@mantine/core'; import { useTranslation } from 'next-i18next'; import CustomizationSettings from './Customization/CustomizationSettings'; diff --git a/src/components/layout/header/Search.tsx b/src/components/layout/header/Search.tsx index 49ea9a201..bbc46d865 100644 --- a/src/components/layout/header/Search.tsx +++ b/src/components/layout/header/Search.tsx @@ -60,8 +60,7 @@ export function Search() { // Overseerr is not use anywhere else, so it makes no sense to add a standalone toggle for displaying results const isOverseerrEnabled = false; //config?.settings.common.enabledModules.overseerr; const overseerrApp = config?.apps.find( - (app) => - app.integration?.type === 'overseerr' || app.integration?.type === 'jellyseerr' + (app) => app.integration?.type === 'overseerr' || app.integration?.type === 'jellyseerr' ); const searchEngineSettings = config?.settings.common.searchEngine; const searchEngineUrl = !searchEngineSettings diff --git a/src/components/layout/header/SettingsMenu/ColorSchemeSwitch.tsx b/src/components/layout/header/SettingsMenu/ColorSchemeSwitch.tsx index be027cdf4..434cb5a0a 100644 --- a/src/components/layout/header/SettingsMenu/ColorSchemeSwitch.tsx +++ b/src/components/layout/header/SettingsMenu/ColorSchemeSwitch.tsx @@ -1,4 +1,4 @@ -import { Menu, useMantineColorScheme, useMantineTheme } from '@mantine/core'; +import { Menu, useMantineColorScheme } from '@mantine/core'; import { IconMoonStars, IconSun } from '@tabler/icons'; import { useTranslation } from 'next-i18next'; diff --git a/src/pages/api/modules/calendar.ts b/src/pages/api/modules/calendar.ts index 499c088e6..bcd1121ad 100644 --- a/src/pages/api/modules/calendar.ts +++ b/src/pages/api/modules/calendar.ts @@ -41,8 +41,7 @@ async function Get(req: NextApiRequest, res: NextApiResponse) { 'lidarr', ]; const mediaApps = config.apps.filter( - (app) => - app.integration && mediaAppIntegrationTypes.includes(app.integration.type) + (app) => app.integration && mediaAppIntegrationTypes.includes(app.integration.type) ); const medias = await Promise.all( diff --git a/src/pages/api/modules/overseerr/[id].tsx b/src/pages/api/modules/overseerr/[id].tsx index 20bee0e90..3b0240271 100644 --- a/src/pages/api/modules/overseerr/[id].tsx +++ b/src/pages/api/modules/overseerr/[id].tsx @@ -3,7 +3,6 @@ import { getCookie } from 'cookies-next'; import axios from 'axios'; import Consola from 'consola'; import { getConfig } from '../../../../tools/config/getConfig'; -import { Config } from '../../../../tools/types'; import { MediaType } from '../../../../modules/overseerr/SearchResult'; async function Get(req: NextApiRequest, res: NextApiResponse) { diff --git a/src/pages/api/modules/overseerr/index.ts b/src/pages/api/modules/overseerr/index.ts index d79a80686..321cf9afa 100644 --- a/src/pages/api/modules/overseerr/index.ts +++ b/src/pages/api/modules/overseerr/index.ts @@ -2,7 +2,6 @@ import axios from 'axios'; import { getCookie } from 'cookies-next'; import { NextApiRequest, NextApiResponse } from 'next'; import { getConfig } from '../../../../tools/config/getConfig'; -import { Config } from '../../../../tools/types'; async function Get(req: NextApiRequest, res: NextApiResponse) { const configName = getCookie('config-name', { req }); diff --git a/src/pages/api/modules/usenet/index.ts b/src/pages/api/modules/usenet/index.ts index 2aa8e3864..cd99c8ac9 100644 --- a/src/pages/api/modules/usenet/index.ts +++ b/src/pages/api/modules/usenet/index.ts @@ -39,10 +39,8 @@ async function Get(req: NextApiRequest, res: NextApiResponse) { const options = { host: url.hostname, port: url.port, - login: - app.integration.properties.find((x) => x.field === 'username')?.value ?? undefined, - hash: - app.integration.properties.find((x) => x.field === 'password')?.value ?? undefined, + login: app.integration.properties.find((x) => x.field === 'username')?.value ?? undefined, + hash: app.integration.properties.find((x) => x.field === 'password')?.value ?? undefined, }; const nzbGet = NzbgetClient(options); diff --git a/src/pages/api/modules/usenet/pause.ts b/src/pages/api/modules/usenet/pause.ts index cad0d372c..534c71055 100644 --- a/src/pages/api/modules/usenet/pause.ts +++ b/src/pages/api/modules/usenet/pause.ts @@ -31,10 +31,8 @@ async function Post(req: NextApiRequest, res: NextApiResponse) { const options = { host: url.hostname, port: url.port, - login: - app.integration.properties.find((x) => x.field === 'username')?.value ?? undefined, - hash: - app.integration.properties.find((x) => x.field === 'password')?.value ?? undefined, + login: app.integration.properties.find((x) => x.field === 'username')?.value ?? undefined, + hash: app.integration.properties.find((x) => x.field === 'password')?.value ?? undefined, }; const nzbGet = NzbgetClient(options); diff --git a/src/pages/api/modules/usenet/resume.ts b/src/pages/api/modules/usenet/resume.ts index 33d3cdd39..90675d2ed 100644 --- a/src/pages/api/modules/usenet/resume.ts +++ b/src/pages/api/modules/usenet/resume.ts @@ -32,10 +32,8 @@ async function Post(req: NextApiRequest, res: NextApiResponse) { const options = { host: url.hostname, port: url.port, - login: - app.integration.properties.find((x) => x.field === 'username')?.value ?? undefined, - hash: - app.integration.properties.find((x) => x.field === 'password')?.value ?? undefined, + login: app.integration.properties.find((x) => x.field === 'username')?.value ?? undefined, + hash: app.integration.properties.find((x) => x.field === 'password')?.value ?? undefined, }; const nzbGet = NzbgetClient(options); diff --git a/src/tools/hooks/useGetServiceByType.ts b/src/tools/hooks/useGetServiceByType.ts index 6a98e4c80..bd86c09bd 100644 --- a/src/tools/hooks/useGetServiceByType.ts +++ b/src/tools/hooks/useGetServiceByType.ts @@ -10,5 +10,4 @@ export const useGetServiceByType = (...serviceTypes: ServiceType[]) => { export const getServiceByType = (config: Config, ...serviceTypes: ServiceType[]) => config.apps.filter((s) => serviceTypes.includes(s.type)); -export const getServiceById = (config: Config, id: string) => - config.apps.find((s) => s.id === id); +export const getServiceById = (config: Config, id: string) => config.apps.find((s) => s.id === id);