Add "Add to homarr" feature and move code

This commit is contained in:
Thomas Camlong
2022-07-06 18:08:39 +02:00
parent be770d282a
commit 4b92c52ea8
8 changed files with 232 additions and 159 deletions

View File

@@ -1,118 +1,41 @@
import {
ActionIcon,
Badge,
Checkbox,
createStyles,
Drawer,
Group,
List,
Menu,
ScrollArea,
Table,
Text,
} from '@mantine/core';
import { ActionIcon, Drawer, Group, LoadingOverlay, ScrollArea } from '@mantine/core';
import { IconBrandDocker } from '@tabler/icons';
import axios from 'axios';
import { useEffect, useState } from 'react';
import Docker from 'dockerode';
import DockerMenu from './DockerMenu';
import ContainerState from './ContainerState';
import ContainerActionBar from './ContainerActionBar';
const useStyles = createStyles((theme) => ({
rowSelected: {
backgroundColor:
theme.colorScheme === 'dark'
? theme.fn.rgba(theme.colors[theme.primaryColor][7], 0.2)
: theme.colors[theme.primaryColor][0],
},
}));
import DockerTable from './DockerTable';
export default function DockerDrawer(props: any) {
const [opened, setOpened] = useState(false);
const [containers, setContainers] = useState<Docker.ContainerInfo[]>([]);
const { classes, cx } = useStyles();
const [selection, setSelection] = useState<Docker.ContainerInfo[]>([]);
function reload() {
axios.get('/api/docker/containers').then((res) => {
setContainers(res.data);
});
}
const [visible, setVisible] = useState(false);
const toggleRow = (container: Docker.ContainerInfo) =>
setSelection((current) =>
current.includes(container) ? current.filter((c) => c !== container) : [...current, container]
);
const toggleAll = () =>
setSelection((current) =>
current.length === containers.length ? [] : containers.map((c) => c)
);
function reload() {
setVisible(true);
setTimeout(() => {
axios.get('/api/docker/containers').then((res) => {
setContainers(res.data);
setSelection([]);
setVisible(false);
});
}, 300);
}
useEffect(() => {
reload();
}, []);
const rows = containers.map((element) => {
const selected = selection.includes(element);
return (
<tr key={element.Id} className={cx({ [classes.rowSelected]: selected })}>
<td>
<Checkbox
checked={selection.includes(element)}
onChange={() => toggleRow(element)}
transitionDuration={0}
/>
</td>
<td>{element.Names[0].replace('/', '')}</td>
<td>{element.Image}</td>
<td>
<Group>
{element.Ports.sort((a, b) => a.PrivatePort - b.PrivatePort)
.slice(-3)
.map((port) => (
<Badge variant="outline">
{port.PrivatePort}:{port.PublicPort}
</Badge>
))}
{element.Ports.length > 3 && (
<Badge variant="filled">{element.Ports.length - 3} more</Badge>
)}
</Group>
</td>
<td>
<ContainerState state={element.State} />
</td>
</tr>
);
});
return (
<>
<Drawer opened={opened} onClose={() => setOpened(false)} padding="xl" size="full">
<ScrollArea>
<ContainerActionBar selected={selection} reload={reload} />
<Table captionSide="bottom" highlightOnHover sx={{ minWidth: 800 }} verticalSpacing="sm">
<caption>your docker containers</caption>
<thead>
<tr>
<th style={{ width: 40 }}>
<Checkbox
onChange={toggleAll}
checked={selection.length === containers.length}
indeterminate={selection.length > 0 && selection.length !== containers.length}
transitionDuration={0}
/>
</th>
<th>Name</th>
<th>Image</th>
<th>Ports</th>
<th>State</th>
</tr>
</thead>
<tbody>{rows}</tbody>
</Table>
</ScrollArea>
<ContainerActionBar selected={selection} reload={reload} />
<div style={{ position: 'relative' }}>
<LoadingOverlay visible={visible} />
<DockerTable containers={containers} selection={selection} setSelection={setSelection} />
</div>
</Drawer>
<DockerMenu container={containers?.at(0)} />
<Group position="center">
<ActionIcon
variant="default"