🚧 Work in progress for Mantine v5

This commit is contained in:
ajnart
2022-07-26 00:51:55 +02:00
parent 7fcdb17d84
commit d4d9e5cfcb
25 changed files with 423 additions and 389 deletions

View File

@@ -1,4 +1,4 @@
import { Group, Text, Title } from '@mantine/core';
import { Group, Stack, Text, Title } from '@mantine/core';
import dayjs from 'dayjs';
import { useEffect, useState } from 'react';
import { IconClock as Clock } from '@tabler/icons';
@@ -34,7 +34,7 @@ export default function DateComponent(props: any) {
}, []);
return (
<Group p="sm" spacing="xs" direction="column">
<Group p="sm" spacing="xs">
<Title>{dayjs(date).format(formatString)}</Title>
<Text size="xl">{dayjs(date).format('dddd, MMMM D')}</Text>
</Group>

View File

@@ -1,5 +1,4 @@
import { Button, Group, Modal, Title } from '@mantine/core';
import { useBooleanToggle } from '@mantine/hooks';
import { showNotification, updateNotification } from '@mantine/notifications';
import {
IconCheck,
@@ -14,6 +13,7 @@ import axios from 'axios';
import Dockerode from 'dockerode';
import { tryMatchService } from '../../tools/addToHomarr';
import { AddAppShelfItemForm } from '../../components/AppShelf/AddAppShelfItem';
import { useState } from 'react';
function sendDockerCommand(
action: string,
@@ -60,7 +60,7 @@ export interface ContainerActionBarProps {
}
export default function ContainerActionBar({ selected, reload }: ContainerActionBarProps) {
const [opened, setOpened] = useBooleanToggle(false);
const [opened, setOpened] = useState<boolean>(false);
return (
<Group>
<Modal

View File

@@ -20,7 +20,6 @@ export default function DockerMenuButton(props: any) {
const [opened, setOpened] = useState(false);
const [containers, setContainers] = useState<Docker.ContainerInfo[]>([]);
const [selection, setSelection] = useState<Docker.ContainerInfo[]>([]);
const [visible, setVisible] = useState(false);
const { config } = useConfig();
const moduleEnabled = config.modules?.[DockerModule.title]?.enabled ?? false;
@@ -32,14 +31,12 @@ export default function DockerMenuButton(props: any) {
if (!moduleEnabled) {
return;
}
setVisible(true);
setTimeout(() => {
axios
.get('/api/docker/containers')
.then((res) => {
setContainers(res.data);
setSelection([]);
setVisible(false);
})
.catch(() =>
// Send an Error notification
@@ -61,12 +58,14 @@ export default function DockerMenuButton(props: any) {
if (containers.length < 1) return null;
return (
<>
<Drawer opened={opened} onClose={() => setOpened(false)} padding="xl" size="full">
<ContainerActionBar selected={selection} reload={reload} />
<div style={{ position: 'relative' }}>
<LoadingOverlay transitionDuration={500} visible={visible} />
<DockerTable containers={containers} selection={selection} setSelection={setSelection} />
</div>
<Drawer
opened={opened}
onClose={() => setOpened(false)}
padding="xl"
size="full"
title={<ContainerActionBar selected={selection} reload={reload} />}
>
<DockerTable containers={containers} selection={selection} setSelection={setSelection} />
</Drawer>
<Group position="center">
<ActionIcon

View File

@@ -101,7 +101,6 @@ export default function DockerTable({
onChange={handleSearchChange}
/>
<Table captionSide="bottom" highlightOnHover sx={{ minWidth: 800 }} verticalSpacing="sm">
<caption>your docker containers</caption>
<thead>
<tr>
<th style={{ width: 40 }}>

View File

@@ -9,6 +9,7 @@ import {
ScrollArea,
Center,
Image,
Stack,
} from '@mantine/core';
import { IconDownload as Download } from '@tabler/icons';
import { useEffect, useState } from 'react';
@@ -187,13 +188,8 @@ export default function DownloadComponent() {
);
});
const easteregg = (
<Center style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<Image fit="cover" height={300} src="https://danjohnvelasco.github.io/images/empty.png" />
</Center>
);
return (
<Group noWrap grow direction="column" mt="xl">
<Stack mt="xl">
<ScrollArea sx={{ height: 300 }}>
{rows.length > 0 ? (
<Table highlightOnHover>
@@ -201,9 +197,15 @@ export default function DownloadComponent() {
<tbody>{rows}</tbody>
</Table>
) : (
easteregg
<Center style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<Image
fit="cover"
height={300}
src="https://danjohnvelasco.github.io/images/empty.png"
/>
</Center>
)}
</ScrollArea>
</Group>
</Stack>
);
}

View File

@@ -1,4 +1,4 @@
import { Text, Title, Group, useMantineTheme, Box, Card, ColorSwatch } from '@mantine/core';
import { Text, Title, Group, useMantineTheme, Box, Card, ColorSwatch, Stack } from '@mantine/core';
import { IconDownload as Download } from '@tabler/icons';
import { useEffect, useState } from 'react';
import axios from 'axios';
@@ -78,13 +78,13 @@ export default function TotalDownloadsComponent() {
if (downloadServices.length === 0) {
return (
<Group direction="column">
<Stack>
<Title order={4}>No supported download clients found!</Title>
<Group noWrap>
<Text>Add a download service to view your current downloads...</Text>
<AddItemShelfButton />
</Group>
</Group>
</Stack>
);
}
@@ -101,9 +101,9 @@ export default function TotalDownloadsComponent() {
})) as Datum[];
return (
<Group noWrap direction="column" grow>
<Stack>
<Title order={4}>Current download speed</Title>
<Group direction="column">
<Stack>
<Group>
<ColorSwatch size={12} color={theme.colors.green[5]} />
<Text>Download: {humanFileSize(totalDownloadSpeed)}/s</Text>
@@ -112,7 +112,7 @@ export default function TotalDownloadsComponent() {
<ColorSwatch size={12} color={theme.colors.blue[5]} />
<Text>Upload: {humanFileSize(totalUploadSpeed)}/s</Text>
</Group>
</Group>
</Stack>
<Box
style={{
height: 200,
@@ -133,7 +133,7 @@ export default function TotalDownloadsComponent() {
<Card p="sm" radius="md" withBorder>
<Text size="md">{roundedSeconds} seconds ago</Text>
<Card.Section p="sm">
<Group direction="column">
<Stack>
<Group>
<ColorSwatch size={10} color={theme.colors.green[5]} />
<Text size="md">Download: {humanFileSize(Download)}</Text>
@@ -142,7 +142,7 @@ export default function TotalDownloadsComponent() {
<ColorSwatch size={10} color={theme.colors.blue[5]} />
<Text size="md">Upload: {humanFileSize(Upload)}</Text>
</Group>
</Group>
</Stack>
</Card.Section>
</Card>
);
@@ -181,6 +181,6 @@ export default function TotalDownloadsComponent() {
]}
/>
</Box>
</Group>
</Stack>
);
}

View File

@@ -1,4 +1,6 @@
import {
ActionIcon,
Box,
Button,
Card,
Group,
@@ -8,6 +10,9 @@ import {
TextInput,
useMantineColorScheme,
} from '@mantine/core';
import { useHover } from '@mantine/hooks';
import { IconAdjustments } from '@tabler/icons';
import { motion } from 'framer-motion';
import { useConfig } from '../tools/state';
import { IModule } from './ModuleTypes';
@@ -142,6 +147,8 @@ export function ModuleWrapper(props: any) {
const enabledModules = config.modules ?? {};
// Remove 'Module' from enabled modules titles
const isShown = enabledModules[module.title]?.enabled ?? false;
//TODO: fix the hover problem
const { hovered, ref } = useHover();
if (!isShown) {
return null;
@@ -150,6 +157,8 @@ export function ModuleWrapper(props: any) {
return (
<Card
{...props}
key={module.title}
ref={ref}
hidden={!isShown}
withBorder
radius="lg"
@@ -161,47 +170,61 @@ export function ModuleWrapper(props: any) {
${(config.settings.appOpacity || 100) / 100}`,
}}
>
<ModuleMenu
module={module}
styles={{
root: {
position: 'absolute',
top: 12,
right: 12,
},
}}
/>
<module.component />
<Group position="apart">
<ModuleMenu module={module} hovered={hovered} />
<module.component />
</Group>
</Card>
);
}
export function ModuleMenu(props: any) {
const { module, styles } = props;
const { module, styles, hovered } = props;
const items: JSX.Element[] = getItems(module);
return (
<>
{module.options && (
<Menu
size="lg"
withinPortal
width="lg"
shadow="xl"
withArrow
closeOnItemClick={false}
radius="md"
position="left"
styles={{
root: {
...props?.styles?.root,
},
body: {
dropdown: {
// Add shadow and elevation to the body
boxShadow: '0 0 14px 14px rgba(0, 0, 0, 0.05)',
},
}}
>
<Menu.Label>Settings</Menu.Label>
{items.map((item) => (
<Menu.Item key={item.key}>{item}</Menu.Item>
))}
<Menu.Target>
<Box
style={{
position: 'absolute',
top: 12,
right: 12,
}}
>
<motion.div
animate={{
//TODO: fix the hover problem
opacity: hovered ? 1 : 1,
}}
>
<ActionIcon>
<IconAdjustments />
</ActionIcon>
</motion.div>
</Box>
</Menu.Target>
<Menu.Dropdown>
<Menu.Label>Settings</Menu.Label>
{items.map((item) => (
<Menu.Item key={item.key}>{item}</Menu.Item>
))}
</Menu.Dropdown>
</Menu>
)}
</>

View File

@@ -1,5 +1,6 @@
import { Kbd, createStyles, Autocomplete } from '@mantine/core';
import { useDebouncedValue, useForm, useHotkeys } from '@mantine/hooks';
import { useDebouncedValue, useHotkeys } from '@mantine/hooks';
import { useForm } from '@mantine/form';
import { useEffect, useRef, useState } from 'react';
import {
IconSearch as Search,