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/package.json b/apps/nextjs/package.json index 0515c0ca7..9e1989e46 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -29,15 +29,16 @@ "@homarr/ui": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0", "@homarr/widgets": "workspace:^0.1.0", - "@mantine/colors-generator": "^7.9.1", - "@mantine/hooks": "^7.9.1", - "@mantine/modals": "^7.9.1", - "@mantine/tiptap": "^7.9.1", + "@mantine/colors-generator": "^7.9.2", + "@mantine/hooks": "^7.9.2", + "@mantine/modals": "^7.9.2", + "@mantine/tiptap": "^7.9.2", + "@homarr/server-settings": "workspace:^0.1.0", "@t3-oss/env-nextjs": "^0.10.1", - "@tanstack/react-query": "^5.36.2", - "@tanstack/react-query-devtools": "^5.36.2", - "@tanstack/react-query-next-experimental": "5.36.2", - "@trpc/client": "11.0.0-rc.373", + "@tanstack/react-query": "^5.37.1", + "@tanstack/react-query-devtools": "^5.37.1", + "@tanstack/react-query-next-experimental": "5.37.1", + "@trpc/client": "11.0.0-rc.374", "@trpc/next": "next", "@trpc/react-query": "next", "@trpc/server": "next", @@ -47,13 +48,14 @@ "chroma-js": "^2.4.2", "dayjs": "^1.11.11", "dotenv": "^16.4.5", + "flag-icons": "^7.2.1", "glob": "^10.3.15", "jotai": "^2.8.0", "next": "^14.2.3", "postcss-preset-mantine": "^1.15.0", "react": "18.3.1", "react-dom": "18.3.1", - "sass": "^1.77.1", + "sass": "^1.77.2", "superjson": "2.2.1", "use-deep-compare-effect": "^1.8.1" }, @@ -68,7 +70,7 @@ "concurrently": "^8.2.2", "eslint": "^8.57.0", "prettier": "^3.2.5", - "tsx": "4.10.3", + "tsx": "4.10.5", "typescript": "^5.4.5" }, "eslintConfig": { 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 091bcfa78..b1986f12c 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 @@ -4,11 +4,8 @@ import { useRouter } from "next/navigation"; import { Button, PasswordInput, Stack, TextInput } from "@mantine/core"; import { clientApi } from "@homarr/api/client"; -import { useForm, zodResolver } from "@homarr/form"; -import { - showErrorNotification, - showSuccessNotification, -} from "@homarr/notifications"; +import { useZodForm } from "@homarr/form"; +import { showErrorNotification, showSuccessNotification } from "@homarr/notifications"; import { useScopedI18n } from "@homarr/translation/client"; import type { z } from "@homarr/validation"; import { validation } from "@homarr/validation"; @@ -24,18 +21,15 @@ export const RegistrationForm = ({ invite }: RegistrationFormProps) => { const t = useScopedI18n("user"); const router = useRouter(); const { mutate, isPending } = clientApi.user.register.useMutation(); - const form = useForm({ - validate: zodResolver(validation.user.registration), + const form = useZodForm(validation.user.registration, { initialValues: { username: "", password: "", confirmPassword: "", }, - validateInputOnBlur: true, - validateInputOnChange: true, }); - const handleSubmit = (values: FormType) => { + const handleSubmit = (values: z.infer) => { mutate( { ...values, @@ -69,11 +63,7 @@ export const RegistrationForm = ({ invite }: RegistrationFormProps) => {
- + { ); }; - -type FormType = z.infer; diff --git a/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx b/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx index a7441022d..989406228 100644 --- a/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx +++ b/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx @@ -18,18 +18,12 @@ interface InviteUsagePageProps { }; } -export default async function InviteUsagePage({ - params, - searchParams, -}: InviteUsagePageProps) { +export default async function InviteUsagePage({ params, searchParams }: InviteUsagePageProps) { const session = await auth(); if (session) notFound(); const invite = await db.query.invites.findFirst({ - where: and( - eq(invites.id, params.id), - eq(invites.token, searchParams.token), - ), + where: and(eq(invites.id, params.id), eq(invites.token, searchParams.token)), columns: { id: true, token: true, diff --git a/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx b/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx index ec5edf3a5..d0345ec72 100644 --- a/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx +++ b/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx @@ -2,22 +2,12 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; -import { - Alert, - Button, - PasswordInput, - rem, - Stack, - TextInput, -} from "@mantine/core"; +import { Alert, Button, PasswordInput, rem, Stack, TextInput } from "@mantine/core"; import { IconAlertTriangle } from "@tabler/icons-react"; import { signIn } from "@homarr/auth/client"; -import { useForm, zodResolver } from "@homarr/form"; -import { - showErrorNotification, - showSuccessNotification, -} from "@homarr/notifications"; +import { useZodForm } from "@homarr/form"; +import { showErrorNotification, showSuccessNotification } from "@homarr/notifications"; import { useScopedI18n } from "@homarr/translation/client"; import type { z } from "@homarr/validation"; import { validation } from "@homarr/validation"; @@ -27,15 +17,14 @@ export const LoginForm = () => { const router = useRouter(); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(); - const form = useForm({ - validate: zodResolver(validation.user.signIn), + const form = useZodForm(validation.user.signIn, { initialValues: { name: "", password: "", }, }); - const handleSubmitAsync = async (values: FormType) => { + const handleSubmitAsync = async (values: z.infer) => { setIsLoading(true); setError(undefined); await signIn("credentials", { @@ -66,18 +55,10 @@ export const LoginForm = () => { return ( - void handleSubmitAsync(values))} - > + void handleSubmitAsync(values))}> - - + + @@ -92,5 +73,3 @@ export const LoginForm = () => { ); }; - -type FormType = z.infer; diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/(default)/_definition.ts b/apps/nextjs/src/app/[locale]/boards/(content)/(home)/_definition.ts similarity index 81% rename from apps/nextjs/src/app/[locale]/boards/(content)/(default)/_definition.ts rename to apps/nextjs/src/app/[locale]/boards/(content)/(home)/_definition.ts index 79a6a42c2..2357d7424 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/(default)/_definition.ts +++ b/apps/nextjs/src/app/[locale]/boards/(content)/(home)/_definition.ts @@ -4,6 +4,6 @@ import { createBoardContentPage } from "../_creator"; export default createBoardContentPage<{ locale: string }>({ async getInitialBoardAsync() { - return await api.board.getDefaultBoard(); + return await api.board.getHomeBoard(); }, }); diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/(default)/layout.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/(home)/layout.tsx similarity index 100% rename from apps/nextjs/src/app/[locale]/boards/(content)/(default)/layout.tsx rename to apps/nextjs/src/app/[locale]/boards/(content)/(home)/layout.tsx diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/(default)/page.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/(home)/page.tsx similarity index 100% rename from apps/nextjs/src/app/[locale]/boards/(content)/(default)/page.tsx rename to apps/nextjs/src/app/[locale]/boards/(content)/(home)/page.tsx diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx index 3faac9877..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"]["getDefaultBoard"], -) => RouterOutputs["board"]["getDefaultBoard"]; +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 5fbb6886d..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"; @@ -16,7 +10,7 @@ import { clientApi } from "@homarr/api/client"; import { updateBoardName } from "./_client"; const BoardContext = createContext<{ - board: RouterOutputs["board"]["getDefaultBoard"]; + board: RouterOutputs["board"]["getHomeBoard"]; isReady: boolean; markAsReady: (id: string) => void; } | null>(null); @@ -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 badc80a07..fe56c11ea 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx @@ -1,11 +1,12 @@ import type { Metadata } from "next"; import { TRPCError } from "@trpc/server"; -import { capitalize } from "@homarr/common"; - // Placed here because gridstack styles are used for board content import "~/styles/gridstack.scss"; +import { getI18n } from "@homarr/translation/server"; + +import { createMetaTitle } from "~/metadata"; import { createBoardLayout } from "../_layout-creator"; import type { Board } from "../_types"; import { ClientBoard } from "./_client"; @@ -17,9 +18,7 @@ interface Props { getInitialBoardAsync: (params: TParams) => Promise; } -export const createBoardContentPage = < - TParams extends Record, ->({ +export const createBoardContentPage = >({ getInitialBoardAsync: getInitialBoard, }: Props) => { return { @@ -31,16 +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 ?? `${capitalize(board.name)} board | Homarr`, + 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)/_custom-css.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_custom-css.tsx new file mode 100644 index 000000000..ab01aff39 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_custom-css.tsx @@ -0,0 +1,9 @@ +"use client"; + +import { useRequiredBoard } from "./_context"; + +export const CustomCss = () => { + const board = useRequiredBoard(); + + return ; +}; 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))}> + +