diff --git a/data/configs/default.json b/data/configs/default.json
index ba6a91144..d159270a2 100644
--- a/data/configs/default.json
+++ b/data/configs/default.json
@@ -18,6 +18,9 @@
},
"Date": {
"enabled": false
+ },
+ "Docker": {
+ "enabled": true
}
}
}
\ No newline at end of file
diff --git a/data/constants.ts b/data/constants.ts
index 8054f1409..ee97a57f4 100644
--- a/data/constants.ts
+++ b/data/constants.ts
@@ -1,2 +1,2 @@
export const REPO_URL = 'ajnart/homarr';
-export const CURRENT_VERSION = 'v0.8.0';
+export const CURRENT_VERSION = 'v0.8.1';
diff --git a/package.json b/package.json
index 6ef4d50e4..d795ee97d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homarr",
- "version": "0.8.0",
+ "version": "0.8.1",
"description": "Homarr - A homepage for your server.",
"repository": {
"type": "git",
diff --git a/src/components/AppShelf/AddAppShelfItem.tsx b/src/components/AppShelf/AddAppShelfItem.tsx
index c9024d47c..20d759005 100644
--- a/src/components/AppShelf/AddAppShelfItem.tsx
+++ b/src/components/AppShelf/AddAppShelfItem.tsx
@@ -12,7 +12,6 @@ import {
Select,
Switch,
Tabs,
- Text,
TextInput,
Title,
Tooltip,
diff --git a/src/components/AppShelf/AppShelf.tsx b/src/components/AppShelf/AppShelf.tsx
index abfed55cc..a47346830 100644
--- a/src/components/AppShelf/AppShelf.tsx
+++ b/src/components/AppShelf/AppShelf.tsx
@@ -178,21 +178,21 @@ const AppShelf = (props: any) => {
) : null}
{downloadEnabled ? (
-
-
+
-
-
-
-
+ }}
+ >
+
+
+
+
) : null}
diff --git a/src/components/Docker/DockerMenu.tsx b/src/components/Docker/DockerMenu.tsx
deleted file mode 100644
index 6b9bdc8fe..000000000
--- a/src/components/Docker/DockerMenu.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import { Menu, Text, useMantineTheme } from '@mantine/core';
-import { showNotification, updateNotification } from '@mantine/notifications';
-import {
- IconCheck,
- IconCodePlus,
- IconPlayerPlay,
- IconPlayerStop,
- IconRotateClockwise,
- IconX,
-} from '@tabler/icons';
-import axios from 'axios';
-import Dockerode from 'dockerode';
-
-function sendNotification(action: string, containerId: string, containerName: string) {
- showNotification({
- id: 'load-data',
- loading: true,
- title: `${action}ing container ${containerName}`,
- message: 'Your password is being checked...',
- autoClose: false,
- disallowClose: true,
- });
- axios.get(`/api/docker/container/${containerId}?action=${action}`).then((res) => {
- setTimeout(() => {
- if (res.data.success === true) {
- updateNotification({
- id: 'load-data',
- title: 'Container restarted',
- message: 'Your container was successfully restarted',
- icon: ,
- autoClose: 2000,
- });
- }
- if (res.data.success === false) {
- updateNotification({
- id: 'load-data',
- color: 'red',
- title: 'There was an error restarting your container.',
- message: 'Your container has encountered issues while restarting.',
- icon: ,
- autoClose: 2000,
- });
- }
- }, 500);
- });
-}
-
-function restart(container: Dockerode.ContainerInfo) {
- sendNotification('restart', container.Id, container.Names[0]);
-}
-function stop(container: Dockerode.ContainerInfo) {
- console.log('stoping container', container.Id);
-}
-function start(container: Dockerode.ContainerInfo) {
- console.log('starting container', container.Id);
-}
-
-export default function DockerMenu(props: any) {
- const { container }: { container: Dockerode.ContainerInfo } = props;
- const theme = useMantineTheme();
- if (container === undefined) {
- return null;
- }
- return (
-
- );
-}
diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx
index 3964e7a83..27fadf06e 100644
--- a/src/components/layout/Header.tsx
+++ b/src/components/layout/Header.tsx
@@ -19,8 +19,8 @@ import {
WeatherModule,
DashdotModule,
} from '../modules';
+import DockerMenuButton from '../modules/docker/DockerModule';
import { ModuleWrapper } from '../modules/moduleWrapper';
-import DockerDrawer from '../Docker/DockerDrawer';
import SearchBar from '../modules/search/SearchModule';
import { SettingsMenuButton } from '../Settings/SettingsMenu';
import { Logo } from './Logo';
@@ -53,7 +53,7 @@ export function Header(props: any) {
-
+
diff --git a/src/components/modules/dash./DashdotModule.tsx b/src/components/modules/dash./DashdotModule.tsx
index 537b2a1d4..8afb5ec62 100644
--- a/src/components/modules/dash./DashdotModule.tsx
+++ b/src/components/modules/dash./DashdotModule.tsx
@@ -181,7 +181,7 @@ export function DashdotComponent() {
Storage:
- {(100 * totalUsed / (totalSize || 1)).toFixed(1)}%{'\n'}
+ {((100 * totalUsed) / (totalSize || 1)).toFixed(1)}%{'\n'}
{bytePrettyPrint(totalUsed)} / {bytePrettyPrint(totalSize)}
diff --git a/src/components/Docker/ContainerActionBar.tsx b/src/components/modules/docker/ContainerActionBar.tsx
similarity index 96%
rename from src/components/Docker/ContainerActionBar.tsx
rename to src/components/modules/docker/ContainerActionBar.tsx
index b4c17dd47..8fb1ae343 100644
--- a/src/components/Docker/ContainerActionBar.tsx
+++ b/src/components/modules/docker/ContainerActionBar.tsx
@@ -13,9 +13,9 @@ import {
} from '@tabler/icons';
import axios from 'axios';
import Dockerode from 'dockerode';
-import { tryMatchService } from '../../tools/addToHomarr';
-import { useConfig } from '../../tools/state';
-import { AddAppShelfItemForm } from '../AppShelf/AddAppShelfItem';
+import { tryMatchService } from '../../../tools/addToHomarr';
+import { useConfig } from '../../../tools/state';
+import { AddAppShelfItemForm } from '../../AppShelf/AddAppShelfItem';
function sendDockerCommand(action: string, containerId: string, containerName: string) {
showNotification({
diff --git a/src/components/Docker/ContainerState.tsx b/src/components/modules/docker/ContainerState.tsx
similarity index 100%
rename from src/components/Docker/ContainerState.tsx
rename to src/components/modules/docker/ContainerState.tsx
diff --git a/src/components/Docker/DockerDrawer.tsx b/src/components/modules/docker/DockerModule.tsx
similarity index 54%
rename from src/components/Docker/DockerDrawer.tsx
rename to src/components/modules/docker/DockerModule.tsx
index 678990cbc..993182398 100644
--- a/src/components/Docker/DockerDrawer.tsx
+++ b/src/components/modules/docker/DockerModule.tsx
@@ -1,31 +1,58 @@
-import { ActionIcon, Drawer, Group, LoadingOverlay } from '@mantine/core';
-import { IconBrandDocker } from '@tabler/icons';
+import { ActionIcon, Drawer, Group, LoadingOverlay, Text } from '@mantine/core';
import axios from 'axios';
import { useEffect, useState } from 'react';
import Docker from 'dockerode';
+import { IconBrandDocker, IconX } from '@tabler/icons';
+import { showNotification } from '@mantine/notifications';
import ContainerActionBar from './ContainerActionBar';
import DockerTable from './DockerTable';
+import { useConfig } from '../../../tools/state';
+import { IModule } from '../modules';
-export default function DockerDrawer(props: any) {
+export const DockerModule: IModule = {
+ title: 'Docker',
+ description: 'Allows you to easily manage your torrents',
+ icon: IconBrandDocker,
+ component: DockerMenuButton,
+};
+
+export default function DockerMenuButton(props: any) {
const [opened, setOpened] = useState(false);
const [containers, setContainers] = useState([]);
const [selection, setSelection] = useState([]);
const [visible, setVisible] = useState(false);
-
- function reload() {
- setVisible(true);
- setTimeout(() => {
- axios.get('/api/docker/containers').then((res) => {
- setContainers(res.data);
- setSelection([]);
- setVisible(false);
- });
- }, 300);
- }
+ const { config } = useConfig();
useEffect(() => {
reload();
}, []);
+
+ function reload() {
+ setVisible(true);
+ setTimeout(() => {
+ axios
+ .get('/api/docker/containers')
+ .then((res) => {
+ setContainers(res.data);
+ setSelection([]);
+ setVisible(false);
+ })
+ .catch(() =>
+ // Send an Error notification
+ showNotification({
+ autoClose: 1500,
+ title: Docker integration failed,
+ color: 'red',
+ icon: ,
+ message: 'Did you forget to mount the docker socket ?',
+ })
+ );
+ }, 300);
+ }
+ const exists = config.modules?.[DockerModule.title]?.enabled ?? false;
+ if (!exists) {
+ return null;
+ }
// Check if the user has at least one container
if (containers.length < 1) return null;
return (
diff --git a/src/components/Docker/DockerTable.tsx b/src/components/modules/docker/DockerTable.tsx
similarity index 100%
rename from src/components/Docker/DockerTable.tsx
rename to src/components/modules/docker/DockerTable.tsx
diff --git a/src/components/modules/docker/index.ts b/src/components/modules/docker/index.ts
new file mode 100644
index 000000000..8e0a617dc
--- /dev/null
+++ b/src/components/modules/docker/index.ts
@@ -0,0 +1 @@
+export { DockerModule } from './DockerModule';
diff --git a/src/components/modules/index.ts b/src/components/modules/index.ts
index 85b4b765b..d0b89acad 100644
--- a/src/components/modules/index.ts
+++ b/src/components/modules/index.ts
@@ -5,3 +5,4 @@ export * from './downloads';
export * from './ping';
export * from './search';
export * from './weather';
+export * from './docker';
diff --git a/src/components/modules/search/SearchModule.tsx b/src/components/modules/search/SearchModule.tsx
index eae9b52ca..75a206097 100644
--- a/src/components/modules/search/SearchModule.tsx
+++ b/src/components/modules/search/SearchModule.tsx
@@ -1,4 +1,4 @@
-import { Kbd, createStyles, Text, Popover, Autocomplete, Tooltip } from '@mantine/core';
+import { Kbd, createStyles, Autocomplete } from '@mantine/core';
import { useDebouncedValue, useForm, useHotkeys } from '@mantine/hooks';
import { useEffect, useRef, useState } from 'react';
import {
diff --git a/src/components/modules/weather/WeatherModule.tsx b/src/components/modules/weather/WeatherModule.tsx
index 36393c677..913ae9f8a 100644
--- a/src/components/modules/weather/WeatherModule.tsx
+++ b/src/components/modules/weather/WeatherModule.tsx
@@ -157,7 +157,7 @@ export default function WeatherComponent(props: any) {
});
}, [cityInput]);
if (!weather.current_weather) {
- return (
+ return (
<>
diff --git a/src/pages/api/docker/containers.tsx b/src/pages/api/docker/containers.tsx
index c4d6bf95d..e2b41cdb1 100644
--- a/src/pages/api/docker/containers.tsx
+++ b/src/pages/api/docker/containers.tsx
@@ -2,11 +2,14 @@ import { NextApiRequest, NextApiResponse } from 'next';
import Docker from 'dockerode';
-const docker = new Docker();
-
async function Get(req: NextApiRequest, res: NextApiResponse) {
- const containers = await docker.listContainers({ all: true });
- return res.status(200).json(containers);
+ try {
+ const docker = new Docker();
+ const containers = await docker.listContainers();
+ res.status(200).json(containers);
+ } catch (err) {
+ res.status(500).json({ err });
+ }
}
export default async (req: NextApiRequest, res: NextApiResponse) => {