mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-15 09:46:19 +01:00
🔧 add configuration to docker module
This commit is contained in:
@@ -1,20 +1,35 @@
|
|||||||
{
|
{
|
||||||
"name": "default",
|
"name": "default",
|
||||||
"services": [
|
"services": [],
|
||||||
{
|
|
||||||
"name": "example",
|
|
||||||
"id": "09c45847-8afc-4c1a-9697-f03192de948a",
|
|
||||||
"type": "Other",
|
|
||||||
"icon": "https://c.tenor.com/o656qFKDzeUAAAAC/rick-astley-never-gonna-give-you-up.gif",
|
|
||||||
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"searchUrl": "https://google.com/search?q="
|
"searchUrl": "https://google.com/search?q=",
|
||||||
|
"appCardWidth": 0.8
|
||||||
},
|
},
|
||||||
"modules": {
|
"modules": {
|
||||||
"Search Bar": {
|
"Search Bar": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
|
},
|
||||||
|
"Docker": {
|
||||||
|
"enabled": true,
|
||||||
|
"options": {
|
||||||
|
"endpoint": {
|
||||||
|
"value": "http://192.168.1.56:2376"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Weather": {
|
||||||
|
"enabled": true,
|
||||||
|
"options": {
|
||||||
|
"location": {
|
||||||
|
"value": "Perros-Guirec"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Download Speed": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"Ping Services": {
|
||||||
|
"enabled": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ import {
|
|||||||
} from '@tabler/icons';
|
} from '@tabler/icons';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import Dockerode from 'dockerode';
|
import Dockerode from 'dockerode';
|
||||||
|
import { useState } from 'react';
|
||||||
import { tryMatchService } from '../../tools/addToHomarr';
|
import { tryMatchService } from '../../tools/addToHomarr';
|
||||||
import { AddAppShelfItemForm } from '../../components/AppShelf/AddAppShelfItem';
|
import { AddAppShelfItemForm } from '../../components/AppShelf/AddAppShelfItem';
|
||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
function sendDockerCommand(
|
function sendDockerCommand(
|
||||||
action: string,
|
action: string,
|
||||||
@@ -30,7 +30,7 @@ function sendDockerCommand(
|
|||||||
disallowClose: true,
|
disallowClose: true,
|
||||||
});
|
});
|
||||||
axios
|
axios
|
||||||
.get(`/api/docker/container/${containerId}?action=${action}`)
|
.get(`localhost:2375/containers/${containerId}/${action}`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
updateNotification({
|
updateNotification({
|
||||||
id: containerId,
|
id: containerId,
|
||||||
@@ -88,6 +88,7 @@ export default function ContainerActionBar({ selected, reload }: ContainerAction
|
|||||||
variant="light"
|
variant="light"
|
||||||
color="orange"
|
color="orange"
|
||||||
radius="md"
|
radius="md"
|
||||||
|
disabled={selected.length === 0}
|
||||||
>
|
>
|
||||||
Restart
|
Restart
|
||||||
</Button>
|
</Button>
|
||||||
@@ -103,6 +104,7 @@ export default function ContainerActionBar({ selected, reload }: ContainerAction
|
|||||||
variant="light"
|
variant="light"
|
||||||
color="red"
|
color="red"
|
||||||
radius="md"
|
radius="md"
|
||||||
|
disabled={selected.length === 0}
|
||||||
>
|
>
|
||||||
Stop
|
Stop
|
||||||
</Button>
|
</Button>
|
||||||
@@ -118,10 +120,11 @@ export default function ContainerActionBar({ selected, reload }: ContainerAction
|
|||||||
variant="light"
|
variant="light"
|
||||||
color="green"
|
color="green"
|
||||||
radius="md"
|
radius="md"
|
||||||
|
disabled={selected.length === 0}
|
||||||
>
|
>
|
||||||
Start
|
Start
|
||||||
</Button>
|
</Button>
|
||||||
<Button leftIcon={<IconRefresh />} onClick={() => reload()} variant="light" radius="md">
|
<Button leftIcon={<IconRefresh />} onClick={() => reload()} variant="light" color="violet" radius="md">
|
||||||
Refresh data
|
Refresh data
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
@@ -141,6 +144,7 @@ export default function ContainerActionBar({ selected, reload }: ContainerAction
|
|||||||
setOpened(true);
|
setOpened(true);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
disabled={selected.length === 0}
|
||||||
>
|
>
|
||||||
Add to Homarr
|
Add to Homarr
|
||||||
</Button>
|
</Button>
|
||||||
@@ -156,6 +160,7 @@ export default function ContainerActionBar({ selected, reload }: ContainerAction
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
disabled={selected.length === 0}
|
||||||
>
|
>
|
||||||
Remove
|
Remove
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ActionIcon, Drawer, Group, LoadingOverlay, Text, Tooltip } from '@mantine/core';
|
import { ActionIcon, Drawer, Text, Tooltip } from '@mantine/core';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import Docker from 'dockerode';
|
import Docker from 'dockerode';
|
||||||
@@ -14,6 +14,12 @@ export const DockerModule: IModule = {
|
|||||||
description: 'Allows you to easily manage your torrents',
|
description: 'Allows you to easily manage your torrents',
|
||||||
icon: IconBrandDocker,
|
icon: IconBrandDocker,
|
||||||
component: DockerMenuButton,
|
component: DockerMenuButton,
|
||||||
|
options: {
|
||||||
|
endpoint: {
|
||||||
|
name: 'Docker Api endpoint entry',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function DockerMenuButton(props: any) {
|
export default function DockerMenuButton(props: any) {
|
||||||
@@ -21,6 +27,7 @@ export default function DockerMenuButton(props: any) {
|
|||||||
const [containers, setContainers] = useState<Docker.ContainerInfo[]>([]);
|
const [containers, setContainers] = useState<Docker.ContainerInfo[]>([]);
|
||||||
const [selection, setSelection] = useState<Docker.ContainerInfo[]>([]);
|
const [selection, setSelection] = useState<Docker.ContainerInfo[]>([]);
|
||||||
const { config } = useConfig();
|
const { config } = useConfig();
|
||||||
|
const dockerApi = (config?.modules?.[DockerModule.title]?.options?.endpoint?.value as string) ?? ''; // http://192.168.1.56:2376
|
||||||
const moduleEnabled = config.modules?.[DockerModule.title]?.enabled ?? false;
|
const moduleEnabled = config.modules?.[DockerModule.title]?.enabled ?? false;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -33,7 +40,7 @@ export default function DockerMenuButton(props: any) {
|
|||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
axios
|
axios
|
||||||
.get('/api/docker/containers')
|
.get(`${dockerApi}/v1.41/containers/json`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setContainers(res.data);
|
setContainers(res.data);
|
||||||
setSelection([]);
|
setSelection([]);
|
||||||
@@ -54,8 +61,7 @@ export default function DockerMenuButton(props: any) {
|
|||||||
if (!exists) {
|
if (!exists) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Check if the user has at least one container
|
// Always allow user to see DockerTable component through ActionIcon in order to set Docker's settings
|
||||||
if (containers.length < 1) return null;
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Drawer
|
<Drawer
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ export default function DockerTable({
|
|||||||
icon={<IconSearch size={14} />}
|
icon={<IconSearch size={14} />}
|
||||||
value={search}
|
value={search}
|
||||||
onChange={handleSearchChange}
|
onChange={handleSearchChange}
|
||||||
|
disabled={usedContainers.length === 0}
|
||||||
/>
|
/>
|
||||||
<Table captionSide="bottom" highlightOnHover sx={{ minWidth: 800 }} verticalSpacing="sm">
|
<Table captionSide="bottom" highlightOnHover sx={{ minWidth: 800 }} verticalSpacing="sm">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -106,9 +107,10 @@ export default function DockerTable({
|
|||||||
<th style={{ width: 40 }}>
|
<th style={{ width: 40 }}>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
onChange={toggleAll}
|
onChange={toggleAll}
|
||||||
checked={selection.length === usedContainers.length}
|
checked={selection.length === usedContainers.length && usedContainers.length > 0}
|
||||||
indeterminate={selection.length > 0 && selection.length !== usedContainers.length}
|
indeterminate={selection.length > 0 && selection.length !== usedContainers.length}
|
||||||
transitionDuration={0}
|
transitionDuration={0}
|
||||||
|
disabled={usedContainers.length === 0}
|
||||||
/>
|
/>
|
||||||
</th>
|
</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
|
|||||||
Reference in New Issue
Block a user