Move docker page to manage pages

This commit is contained in:
Manuel
2023-08-11 22:13:14 +02:00
parent 9ae2dc3037
commit caf74f9962
4 changed files with 76 additions and 16 deletions

View File

@@ -21,6 +21,12 @@
"discord": "Community Discord", "discord": "Community Discord",
"contribute": "Contribute" "contribute": "Contribute"
} }
},
"tools": {
"title": "Tools",
"items": {
"docker": "Docker"
}
} }
} }
} }

View File

@@ -0,0 +1,8 @@
{
"title": "Docker",
"alerts": {
"notConfigured": {
"text": "Your Homarr instance does not have Docker configured. Please check the documentation on how to set up the integration."
}
}
}

View File

@@ -16,12 +16,14 @@ import { useDisclosure } from '@mantine/hooks';
import { import {
IconBook2, IconBook2,
IconBrandDiscord, IconBrandDiscord,
IconBrandDocker,
IconBrandGithub, IconBrandGithub,
IconGitFork, IconGitFork,
IconHome, IconHome,
IconLayoutDashboard, IconLayoutDashboard,
IconMailForward, IconMailForward,
IconQuestionMark, IconQuestionMark,
IconTool,
IconUser, IconUser,
IconUsers, IconUsers,
TablerIconsProps, TablerIconsProps,
@@ -173,7 +175,7 @@ const CustomNavigationLink = forwardRef<
return ( return (
<NavLink {...commonProps} defaultOpened={isAnyActive} ref={ref as RefObject<HTMLButtonElement>}> <NavLink {...commonProps} defaultOpened={isAnyActive} ref={ref as RefObject<HTMLButtonElement>}>
{Object.entries(navigationLink.items).map(([itemName, item]) => { {Object.entries(navigationLink.items).map(([itemName, item], index) => {
const commonItemProps = { const commonItemProps = {
label: t(`navigation.${name}.items.${itemName}`), label: t(`navigation.${name}.items.${itemName}`),
icon: <item.icon size={16} />, icon: <item.icon size={16} />,
@@ -183,10 +185,18 @@ const CustomNavigationLink = forwardRef<
const matchesActive = router.pathname.endsWith(item.href); const matchesActive = router.pathname.endsWith(item.href);
if (item.href.startsWith('http')) { if (item.href.startsWith('http')) {
return <NavLink {...commonItemProps} active={matchesActive} target={item.target} component="a" />; return (
<NavLink
{...commonItemProps}
active={matchesActive}
target={item.target}
key={index}
component="a"
/>
);
} }
return <NavLink {...commonItemProps} active={matchesActive} component={Link} />; return <NavLink {...commonItemProps} active={matchesActive} component={Link} key={index} />;
})} })}
</NavLink> </NavLink>
); );
@@ -223,28 +233,38 @@ const navigationLinks: NavigationLinks = {
}, },
}, },
}, },
tools: {
icon: IconTool,
onlyAdmin: true,
items: {
docker: {
icon: IconBrandDocker,
href: '/manage/tools/docker',
},
},
},
help: { help: {
icon: IconQuestionMark, icon: IconQuestionMark,
items: { items: {
documentation: { documentation: {
icon: IconBook2, icon: IconBook2,
href: 'https://homarr.dev/docs/about', href: 'https://homarr.dev/docs/about',
target: '_blank' target: '_blank',
}, },
report: { report: {
icon: IconBrandGithub, icon: IconBrandGithub,
href: 'https://github.com/ajnart/homarr/issues/new/choose', href: 'https://github.com/ajnart/homarr/issues/new/choose',
target: '_blank' target: '_blank',
}, },
discord: { discord: {
icon: IconBrandDiscord, icon: IconBrandDiscord,
href: 'https://discord.com/invite/aCsmEV5RgA', href: 'https://discord.com/invite/aCsmEV5RgA',
target: '_blank' target: '_blank',
}, },
contribute: { contribute: {
icon: IconGitFork, icon: IconGitFork,
href: 'https://github.com/ajnart/homarr', href: 'https://github.com/ajnart/homarr',
target: '_blank' target: '_blank',
}, },
}, },
}, },

View File

@@ -1,8 +1,10 @@
import { Stack } from '@mantine/core'; import { Alert, Stack, Title } from '@mantine/core';
import { IconInfoCircle } from '@tabler/icons-react';
import { ContainerInfo } from 'dockerode'; import { ContainerInfo } from 'dockerode';
import { GetServerSideProps } from 'next'; import { GetServerSideProps, InferGetServerSidePropsType } from 'next';
import { useState } from 'react'; import { useState } from 'react';
import { MainLayout } from '~/components/layout/Templates/MainLayout'; import { useTranslation } from 'next-i18next';
import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
import { env } from '~/env'; import { env } from '~/env';
import ContainerActionBar from '~/modules/Docker/ContainerActionBar'; import ContainerActionBar from '~/modules/Docker/ContainerActionBar';
import DockerTable from '~/modules/Docker/DockerTable'; import DockerTable from '~/modules/Docker/DockerTable';
@@ -11,27 +13,45 @@ import { getServerSideTranslations } from '~/tools/server/getServerSideTranslati
import { boardNamespaces } from '~/tools/server/translation-namespaces'; import { boardNamespaces } from '~/tools/server/translation-namespaces';
import { api } from '~/utils/api'; import { api } from '~/utils/api';
export default function DockerPage() { export default function DockerPage({
dockerIsConfigured,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
const [selection, setSelection] = useState<ContainerInfo[]>([]); const [selection, setSelection] = useState<ContainerInfo[]>([]);
const { data, refetch, isRefetching } = api.docker.containers.useQuery(); const { data, refetch, isRefetching } = api.docker.containers.useQuery(undefined, {
enabled: dockerIsConfigured,
});
const { t } = useTranslation('tools/docker');
const reload = () => { const reload = () => {
refetch(); refetch();
setSelection([]); setSelection([]);
}; };
if (!dockerIsConfigured) {
return ( return (
<MainLayout> <ManageLayout>
<Title mb="lg">{t('title')}</Title>
<Alert icon={<IconInfoCircle size="1rem" />} color="blue">
{t('alerts.notConfigured.text')}
</Alert>
</ManageLayout>
);
}
return (
<ManageLayout>
<Stack> <Stack>
<ContainerActionBar selected={selection} reload={reload} isLoading={isRefetching} /> <ContainerActionBar selected={selection} reload={reload} isLoading={isRefetching} />
<DockerTable containers={data ?? []} selection={selection} setSelection={setSelection} /> <DockerTable containers={data ?? []} selection={selection} setSelection={setSelection} />
</Stack> </Stack>
</MainLayout> </ManageLayout>
); );
} }
export const getServerSideProps: GetServerSideProps = async ({ locale, req, res }) => { export const getServerSideProps: GetServerSideProps = async ({ locale, req, res }) => {
if (!env.DOCKER_HOST || !env.DOCKER_PORT) return { notFound: true }; const dockerIsConfigured = env.DOCKER_HOST !== undefined;
const session = await getServerAuthSession({ req, res }); const session = await getServerAuthSession({ req, res });
if (!session?.user.isAdmin) { if (!session?.user.isAdmin) {
return { return {
@@ -39,9 +59,15 @@ export const getServerSideProps: GetServerSideProps = async ({ locale, req, res
}; };
} }
const translations = await getServerSideTranslations(boardNamespaces, locale, req, res); const translations = await getServerSideTranslations(
[...boardNamespaces, 'layout/manage', 'tools/docker'],
locale,
req,
res
);
return { return {
props: { props: {
dockerIsConfigured: dockerIsConfigured,
...translations, ...translations,
}, },
}; };