diff --git a/next-i18next.config.js b/next-i18next.config.js index 9c876f550..69be36201 100644 --- a/next-i18next.config.js +++ b/next-i18next.config.js @@ -1,6 +1,5 @@ module.exports = { // https://www.i18next.com/overview/configuration-options#logging - debug: process.env.NODE_ENV === 'development', i18n: { defaultLocale: 'en', locales: ['en', 'de', 'en', 'es', 'fr', 'it', 'ja', 'nl', 'pl', 'ru', 'sl', 'sv', 'zh'], diff --git a/public/locales/en/modules/docker.json b/public/locales/en/modules/docker.json index a4d738b61..f54db9bd9 100644 --- a/public/locales/en/modules/docker.json +++ b/public/locales/en/modules/docker.json @@ -37,12 +37,14 @@ "start": { "title": "Start" }, - "refreshData": "Refresh data", - "addToHomarr": { - "title": "Add to Homarr" + "refreshData": { + "title": "Refresh data" }, "remove": { "title": "Remove" + }, + "addToHomarr": { + "title": "Add to Homarr" } }, "messages": { diff --git a/src/components/AppShelf/AddAppShelfItem.tsx b/src/components/AppShelf/AddAppShelfItem.tsx index 8b5ef87c2..d6db7ac07 100644 --- a/src/components/AppShelf/AddAppShelfItem.tsx +++ b/src/components/AppShelf/AddAppShelfItem.tsx @@ -25,10 +25,11 @@ import { useTranslation } from 'next-i18next'; import { useEffect, useState } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { useConfig } from '../../tools/state'; -import { ServiceTypeList, StatusCodes, tryMatchPort } from '../../tools/types'; +import { tryMatchPort, ServiceTypeList, StatusCodes, Config } from '../../tools/types'; import Tip from '../layout/Tip'; export function AddItemShelfButton(props: any) { + const { config, setConfig } = useConfig(); const [opened, setOpened] = useState(false); const { t } = useTranslation('layout/add-service-app-shelf'); return ( @@ -40,7 +41,7 @@ export function AddItemShelfButton(props: any) { opened={props.opened || opened} onClose={() => setOpened(false)} > - + void } & any) { - const { setOpened } = props; - const { config, setConfig } = useConfig(); +interface AddAppShelfItemFormProps { + setOpened: (b: boolean) => void; + config: Config; + setConfig: (config: Config) => void; + // Any other props you want to pass to the form + [key: string]: any; +} + +export function AddAppShelfItemForm(props: AddAppShelfItemFormProps) { + const { setOpened, config, setConfig } = props; + // Only get config and setConfig from useCOnfig if they are not present in props const [isLoading, setLoading] = useState(false); const { t } = useTranslation('layout/add-service-app-shelf'); @@ -201,6 +210,7 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & }), }); } else { + console.log(newForm); setConfig({ ...config, services: [...config.services, newForm], @@ -401,8 +411,7 @@ export function AddAppShelfItemForm(props: { setOpened: (b: boolean) => void } & )} - - + ; function sendDockerCommand( action: string, @@ -22,8 +28,6 @@ function sendDockerCommand( containerName: string, reload: () => void ) { - const { t } = useTranslation('modules/docker'); - showNotification({ id: containerId, loading: true, @@ -63,24 +67,28 @@ export interface ContainerActionBarProps { } export default function ContainerActionBar({ selected, reload }: ContainerActionBarProps) { - const [opened, setOpened] = useState(false); - const { t } = useTranslation('modules/docker'); + t = useTranslation('modules/docker').t; + const [isLoading, setisLoading] = useState(false); + const { config, setConfig } = useConfig(); return ( - } + onClick={() => { + setisLoading(true); + setTimeout(() => { + reload(); + setisLoading(false); + }, 750); + }} + variant="light" + color="violet" + loading={isLoading} radius="md" - opened={opened} - onClose={() => setOpened(false)} - title={t('actionBar.addService.title')} > - - + {t('actionBar.refreshData.title')} + @@ -108,6 +117,7 @@ export default function ContainerActionBar({ selected, reload }: ContainerAction variant="light" color="red" radius="md" + disabled={selected.length === 0} > {t('actionBar.stop.title')} @@ -123,32 +133,10 @@ export default function ContainerActionBar({ selected, reload }: ContainerAction variant="light" color="green" radius="md" + disabled={selected.length === 0} > {t('actionBar.start.title')} - - + ); } diff --git a/src/modules/docker/DockerModule.tsx b/src/modules/docker/DockerModule.tsx index 3def68f2b..61101723e 100644 --- a/src/modules/docker/DockerModule.tsx +++ b/src/modules/docker/DockerModule.tsx @@ -42,7 +42,9 @@ export default function DockerMenuButton(props: any) { setContainers(res.data); setSelection([]); }) - .catch(() => + .catch(() => { + // Remove containers from the list + setContainers([]); // Send an Error notification showNotification({ autoClose: 1500, @@ -50,8 +52,8 @@ export default function DockerMenuButton(props: any) { color: 'red', icon: , message: t('errors.integrationFailed.message'), - }) - ); + }); + }); }, 300); } const exists = config.modules?.[DockerModule.id]?.enabled ?? false; diff --git a/src/modules/docker/DockerTable.tsx b/src/modules/docker/DockerTable.tsx index 2b06a1b0e..c8fbf9c19 100644 --- a/src/modules/docker/DockerTable.tsx +++ b/src/modules/docker/DockerTable.tsx @@ -1,9 +1,19 @@ -import { Table, Checkbox, Group, Badge, createStyles, ScrollArea, TextInput } from '@mantine/core'; +import { + Table, + Checkbox, + Group, + Badge, + createStyles, + ScrollArea, + TextInput, + Modal, +} from '@mantine/core'; import { IconSearch } from '@tabler/icons'; -import { useTranslation } from 'next-i18next'; - import Dockerode from 'dockerode'; +import { useTranslation } from 'next-i18next'; import { useEffect, useState } from 'react'; +import { AddAppShelfItemForm } from '../../components/AppShelf/AddAppShelfItem'; +import { tryMatchService } from '../../tools/addToHomarr'; import ContainerState from './ContainerState'; const useStyles = createStyles((theme) => ({ @@ -105,6 +115,7 @@ export default function DockerTable({ icon={} value={search} onChange={handleSearchChange} + disabled={usedContainers.length === 0} /> @@ -112,9 +123,10 @@ export default function DockerTable({ diff --git a/src/pages/api/docker/DockerSingleton.tsx b/src/pages/api/docker/DockerSingleton.ts similarity index 100% rename from src/pages/api/docker/DockerSingleton.tsx rename to src/pages/api/docker/DockerSingleton.ts
0} indeterminate={selection.length > 0 && selection.length !== usedContainers.length} transitionDuration={0} + disabled={usedContainers.length === 0} /> {t('table.header.name')}