diff --git a/.gitignore b/.gitignore index 6b4c33b50..8327c8b84 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,7 @@ yarn-error.log* db.sqlite # logs -*.log \ No newline at end of file +*.log + +apps/tasks/tasks.cjs +apps/websocket/wssServer.cjs \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index b59ae4f97..53c760db0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,9 +6,10 @@ ], "typescript.tsdk": "node_modules\\typescript\\lib", "js/ts.implicitProjectConfig.experimentalDecorators": true, + "prettier.configPath": "./tooling/prettier/index.mjs", "cSpell.words": [ "superjson", "homarr", "trpc" ] -} +} \ No newline at end of file diff --git a/apps/nextjs/next.config.mjs b/apps/nextjs/next.config.mjs index 26bb9d9c1..fcf1321a4 100644 --- a/apps/nextjs/next.config.mjs +++ b/apps/nextjs/next.config.mjs @@ -10,19 +10,9 @@ const config = { eslint: { ignoreDuringBuilds: true }, typescript: { ignoreBuildErrors: true }, experimental: { - optimizePackageImports: [ - "@mantine/core", - "@mantine/hooks", - "@tabler/icons-react", - ], + optimizePackageImports: ["@mantine/core", "@mantine/hooks", "@tabler/icons-react"], }, - transpilePackages: [ - "@homarr/ui", - "@homarr/notifications", - "@homarr/modals", - "@homarr/spotlight", - "@homarr/widgets", - ], + transpilePackages: ["@homarr/ui", "@homarr/notifications", "@homarr/modals", "@homarr/spotlight", "@homarr/widgets"], images: { domains: ["cdn.jsdelivr.net"], }, diff --git a/apps/nextjs/src/app/[locale]/_client-providers/next-international.tsx b/apps/nextjs/src/app/[locale]/_client-providers/next-international.tsx index 626296d69..8297a73bb 100644 --- a/apps/nextjs/src/app/[locale]/_client-providers/next-international.tsx +++ b/apps/nextjs/src/app/[locale]/_client-providers/next-international.tsx @@ -3,10 +3,7 @@ import type { PropsWithChildren } from "react"; import { defaultLocale } from "@homarr/translation"; import { I18nProviderClient } from "@homarr/translation/client"; -export const NextInternationalProvider = ({ - children, - locale, -}: PropsWithChildren<{ locale: string }>) => { +export const NextInternationalProvider = ({ children, locale }: PropsWithChildren<{ locale: string }>) => { return ( {children} diff --git a/apps/nextjs/src/app/[locale]/_client-providers/session.tsx b/apps/nextjs/src/app/[locale]/_client-providers/session.tsx index 5ed469e1c..d4e0538db 100644 --- a/apps/nextjs/src/app/[locale]/_client-providers/session.tsx +++ b/apps/nextjs/src/app/[locale]/_client-providers/session.tsx @@ -9,9 +9,6 @@ interface AuthProviderProps { session: Session | null; } -export const AuthProvider = ({ - children, - session, -}: PropsWithChildren) => { +export const AuthProvider = ({ children, session }: PropsWithChildren) => { return {children}; }; diff --git a/apps/nextjs/src/app/[locale]/_client-providers/trpc.tsx b/apps/nextjs/src/app/[locale]/_client-providers/trpc.tsx index 00a923407..db34ced95 100644 --- a/apps/nextjs/src/app/[locale]/_client-providers/trpc.tsx +++ b/apps/nextjs/src/app/[locale]/_client-providers/trpc.tsx @@ -5,12 +5,7 @@ import { useState } from "react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { ReactQueryStreamedHydration } from "@tanstack/react-query-next-experimental"; -import { - createWSClient, - loggerLink, - unstable_httpBatchStreamLink, - wsLink, -} from "@trpc/client"; +import { createWSClient, loggerLink, unstable_httpBatchStreamLink, wsLink } from "@trpc/client"; import superjson from "superjson"; import type { AppRouter } from "@homarr/api"; @@ -37,8 +32,7 @@ export function TRPCReactProvider(props: PropsWithChildren) { links: [ loggerLink({ enabled: (opts) => - process.env.NODE_ENV === "development" || - (opts.direction === "down" && opts.result instanceof Error), + process.env.NODE_ENV === "development" || (opts.direction === "down" && opts.result instanceof Error), }), (args) => { return ({ op, next }) => { @@ -69,9 +63,7 @@ export function TRPCReactProvider(props: PropsWithChildren) { return ( - - {props.children} - + {props.children} diff --git a/apps/nextjs/src/app/[locale]/auth/invite/[id]/_registration-form.tsx b/apps/nextjs/src/app/[locale]/auth/invite/[id]/_registration-form.tsx index 9baf60958..e91e78de0 100644 --- a/apps/nextjs/src/app/[locale]/auth/invite/[id]/_registration-form.tsx +++ b/apps/nextjs/src/app/[locale]/auth/invite/[id]/_registration-form.tsx @@ -5,10 +5,7 @@ import { Button, PasswordInput, Stack, TextInput } from "@mantine/core"; import { clientApi } from "@homarr/api/client"; import { useZodForm } from "@homarr/form"; -import { - showErrorNotification, - showSuccessNotification, -} from "@homarr/notifications"; +import { showErrorNotification, showSuccessNotification } from "@homarr/notifications"; import { useScopedI18n } from "@homarr/translation/client"; import type { z } from "@homarr/validation"; import { validation } from "@homarr/validation"; @@ -32,9 +29,7 @@ export const RegistrationForm = ({ invite }: RegistrationFormProps) => { }, }); - const handleSubmit = ( - values: z.infer, - ) => { + const handleSubmit = (values: z.infer) => { mutate( { ...values, @@ -63,11 +58,7 @@ export const RegistrationForm = ({ invite }: RegistrationFormProps) => {
- + { }, }); - const handleSubmitAsync = async ( - values: z.infer, - ) => { + const handleSubmitAsync = async (values: z.infer) => { setIsLoading(true); setError(undefined); await signIn("credentials", { @@ -67,18 +55,10 @@ export const LoginForm = () => { return ( - void handleSubmitAsync(values))} - > + void handleSubmitAsync(values))}> - - + + diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx index 1a7fe0cc1..ea80dc68b 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx @@ -18,9 +18,7 @@ export const updateBoardName = (name: string | null) => { boardName = name; }; -type UpdateCallback = ( - prev: RouterOutputs["board"]["getHomeBoard"], -) => RouterOutputs["board"]["getHomeBoard"]; +type UpdateCallback = (prev: RouterOutputs["board"]["getHomeBoard"]) => RouterOutputs["board"]["getHomeBoard"]; export const useUpdateBoard = () => { const utils = clientApi.useUtils(); @@ -46,9 +44,7 @@ export const ClientBoard = () => { const board = useRequiredBoard(); const isReady = useIsBoardReady(); - const sortedSections = board.sections.sort( - (sectionA, sectionB) => sectionA.position - sectionB.position, - ); + const sortedSections = board.sections.sort((sectionA, sectionB) => sectionA.position - sectionB.position); const ref = useRef(null); @@ -61,24 +57,12 @@ export const ClientBoard = () => { loaderProps={{ size: "lg" }} h={fullHeightWithoutHeaderAndFooter} /> - + {sortedSections.map((section) => section.kind === "empty" ? ( - + ) : ( - + ), )} diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_context.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_context.tsx index ae12b472f..a5ab76c03 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_context.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_context.tsx @@ -1,13 +1,7 @@ "use client"; import type { PropsWithChildren } from "react"; -import { - createContext, - useCallback, - useContext, - useEffect, - useState, -} from "react"; +import { createContext, useCallback, useContext, useEffect, useState } from "react"; import { usePathname } from "next/navigation"; import type { RouterOutputs } from "@homarr/api"; @@ -52,18 +46,12 @@ export const BoardProvider = ({ }, [pathname, utils, initialBoard.name]); useEffect(() => { - setReadySections((previous) => - previous.filter((id) => - data.sections.some((section) => section.id === id), - ), - ); + setReadySections((previous) => previous.filter((id) => data.sections.some((section) => section.id === id))); // eslint-disable-next-line react-hooks/exhaustive-deps }, [data.sections.length, setReadySections]); const markAsReady = useCallback((id: string) => { - setReadySections((previous) => - previous.includes(id) ? previous : [...previous, id], - ); + setReadySections((previous) => (previous.includes(id) ? previous : [...previous, id])); }, []); return ( diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx index 55eada4b2..fe56c11ea 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx @@ -18,9 +18,7 @@ interface Props { getInitialBoardAsync: (params: TParams) => Promise; } -export const createBoardContentPage = < - TParams extends Record, ->({ +export const createBoardContentPage = >({ getInitialBoardAsync: getInitialBoard, }: Props) => { return { @@ -32,21 +30,13 @@ export const createBoardContentPage = < page: () => { return ; }, - generateMetadataAsync: async ({ - params, - }: { - params: TParams; - }): Promise => { + generateMetadataAsync: async ({ params }: { params: TParams }): Promise => { try { const board = await getInitialBoard(params); const t = await getI18n(); return { - title: - board.metaTitle ?? - createMetaTitle( - t("board.content.metaTitle", { boardName: board.name }), - ), + title: board.metaTitle ?? createMetaTitle(t("board.content.metaTitle", { boardName: board.name })), icons: { icon: board.faviconImageUrl ? board.faviconImageUrl : undefined, }, diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx index 33abb0661..79c019dad 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx @@ -16,10 +16,7 @@ import { useAtom, useAtomValue } from "jotai"; import { clientApi } from "@homarr/api/client"; import { useModalAction } from "@homarr/modals"; -import { - showErrorNotification, - showSuccessNotification, -} from "@homarr/notifications"; +import { showErrorNotification, showSuccessNotification } from "@homarr/notifications"; import { useI18n, useScopedI18n } from "@homarr/translation/client"; import { revalidatePathActionAsync } from "~/app/revalidatePathAction"; @@ -54,8 +51,7 @@ export const BoardContentHeaderActions = () => { }; const AddMenu = () => { - const { openModal: openCategoryEditModal } = - useModalAction(CategoryEditModal); + const { openModal: openCategoryEditModal } = useModalAction(CategoryEditModal); const { openModal: openItemSelectModal } = useModalAction(ItemSelectModal); const { addCategoryToEnd } = useCategoryActions(); const t = useI18n(); @@ -95,22 +91,14 @@ const AddMenu = () => { - } - onClick={handleSelectItem} - > + } onClick={handleSelectItem}> {t("item.action.create")} - }> - {t("item.action.import")} - + }>{t("item.action.import")} - } - onClick={handleAddCategory} - > + } onClick={handleAddCategory}> {t("section.category.action.create")} @@ -123,24 +111,23 @@ const EditModeMenu = () => { const board = useRequiredBoard(); const utils = clientApi.useUtils(); const t = useScopedI18n("board.action.edit"); - const { mutate: saveBoard, isPending } = - clientApi.board.saveBoard.useMutation({ - onSuccess() { - showSuccessNotification({ - title: t("notification.success.title"), - message: t("notification.success.message"), - }); - void utils.board.getBoardByName.invalidate({ name: board.name }); - void revalidatePathActionAsync(`/boards/${board.name}`); - setEditMode(false); - }, - onError() { - showErrorNotification({ - title: t("notification.error.title"), - message: t("notification.error.message"), - }); - }, - }); + const { mutate: saveBoard, isPending } = clientApi.board.saveBoard.useMutation({ + onSuccess() { + showSuccessNotification({ + title: t("notification.success.title"), + message: t("notification.success.message"), + }); + void utils.board.getBoardByName.invalidate({ name: board.name }); + void revalidatePathActionAsync(`/boards/${board.name}`); + setEditMode(false); + }, + onError() { + showErrorNotification({ + title: t("notification.error.title"), + message: t("notification.error.message"), + }); + }, + }); const toggle = useCallback(() => { if (isEditMode) return saveBoard(board); @@ -149,11 +136,7 @@ const EditModeMenu = () => { return ( - {isEditMode ? ( - - ) : ( - - )} + {isEditMode ? : } ); }; diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_theme.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_theme.tsx index 48c8a829d..bf68bb902 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_theme.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_theme.tsx @@ -22,9 +22,7 @@ export const BoardMantineProvider = ({ children }: PropsWithChildren) => { }; export const generateColors = (hex: string) => { - const lightnessForColors = [ - -0.25, -0.2, -0.15, -0.1, -0.05, 0, 0.05, 0.1, 0.15, 0.2, - ] as const; + const lightnessForColors = [-0.25, -0.2, -0.15, -0.1, -0.05, 0, 0.05, 0.1, 0.15, 0.2] as const; const rgbaColors = lightnessForColors.map((lightness) => { if (lightness < 0) { return lighten(hex, -lightness); diff --git a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access.tsx b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access.tsx index c90192bfa..5739e98b6 100644 --- a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access.tsx +++ b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access.tsx @@ -44,11 +44,7 @@ export const AccessSettingsContent = ({ board, initialPermissions }: Props) => { - + diff --git a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access/board-access-table-rows.tsx b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access/board-access-table-rows.tsx index 392e5a36d..4a370051a 100644 --- a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access/board-access-table-rows.tsx +++ b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access/board-access-table-rows.tsx @@ -1,21 +1,8 @@ import { useCallback } from "react"; import type { ReactNode } from "react"; import type { SelectProps } from "@mantine/core"; -import { - Button, - Flex, - Group, - Select, - TableTd, - TableTr, - Text, -} from "@mantine/core"; -import { - IconCheck, - IconEye, - IconPencil, - IconSettings, -} from "@tabler/icons-react"; +import { Button, Flex, Group, Select, TableTd, TableTr, Text } from "@mantine/core"; +import { IconCheck, IconEye, IconPencil, IconSettings } from "@tabler/icons-react"; import type { BoardPermission } from "@homarr/definitions"; import { boardPermissions } from "@homarr/definitions"; @@ -38,12 +25,7 @@ interface BoardAccessSelectRowProps { onCountChange: OnCountChange; } -export const BoardAccessSelectRow = ({ - itemContent, - permission, - index, - onCountChange, -}: BoardAccessSelectRowProps) => { +export const BoardAccessSelectRow = ({ itemContent, permission, index, onCountChange }: BoardAccessSelectRowProps) => { const tRoot = useI18n(); const tPermissions = useScopedI18n("board.setting.section.access.permission"); const form = useFormContext(); @@ -61,11 +43,7 @@ export const BoardAccessSelectRow = ({ {itemContent} - + : undefined} - nothingFoundMessage={t("group.action.select.notFound")} - limit={5} - data={groups - ?.filter( - (group) => !innerProps.presentGroupIds.includes(group.id), - ) - .map((group) => ({ value: group.id, label: group.name }))} - /> - - - - - - - ); - }, -).withOptions({ - defaultTitle: (t) => - t("board.setting.section.access.permission.groupSelect.title"), + return ( +
void handleSubmitAsync(values))}> + + - ) : currentUser ? ( - - ) : undefined - } - nothingFoundMessage={t("user.action.select.notFound")} - renderOption={createRenderOption(users ?? [])} - limit={5} - data={users - ?.filter((user) => !innerProps.presentUserIds.includes(user.id)) - .map((user) => ({ value: user.id, label: user.name ?? "" }))} - /> - - - - - -
- ); - }, -).withOptions({ - defaultTitle: (t) => - t("board.setting.section.access.permission.userSelect.title"), + return ( +
void handleSubmitAsync(values))}> + +