import { Group, Text, useMantineColorScheme } from "@mantine/core"; import { IconCategoryPlus, IconFileImport, IconLanguage, IconMailForward, IconMoon, IconPackage, IconPlug, IconSun, IconUserPlus, IconUsersGroup, } from "@tabler/icons-react"; import { useSession } from "@homarr/auth/client"; import { useModalAction } from "@homarr/modals"; import { AddBoardModal, AddGroupModal, ImportBoardModal, InviteCreateModal } from "@homarr/modals-collection"; import { useScopedI18n } from "@homarr/translation/client"; import type { TablerIcon } from "@homarr/ui"; import { createGroup } from "../../lib/group"; import type { inferSearchInteractionDefinition, SearchInteraction } from "../../lib/interaction"; import { interaction } from "../../lib/interaction"; import type { SearchMode } from "../../lib/mode"; import { languageChildrenOptions } from "./children/language"; import { newIntegrationChildrenOptions } from "./children/new-integration"; // This has to be type so it can be interpreted as Record. // eslint-disable-next-line @typescript-eslint/consistent-type-definitions type Command = { commandKey: string; icon: TablerIcon; name: string; useInteraction: ( _c: Command, query: string, ) => inferSearchInteractionDefinition; }; export const commandMode = { modeKey: "command", character: ">", groups: [ createGroup({ keyPath: "commandKey", title: "Global commands", useInteraction: (option, query) => option.useInteraction(option, query), Component: ({ icon: Icon, name }) => ( {name} ), filter(query, option) { return option.name.toLowerCase().includes(query.toLowerCase()); }, useOptions() { const tOption = useScopedI18n("search.mode.command.group.globalCommand.option"); const { colorScheme } = useMantineColorScheme(); const { data: session } = useSession(); const commands: (Command & { hidden?: boolean })[] = [ { commandKey: "colorScheme", icon: colorScheme === "dark" ? IconSun : IconMoon, name: tOption(`colorScheme.${colorScheme === "dark" ? "light" : "dark"}`), useInteraction: () => { const { toggleColorScheme } = useMantineColorScheme(); return { type: "javaScript", onSelect: toggleColorScheme, }; }, }, { commandKey: "language", icon: IconLanguage, name: tOption("language.label"), useInteraction: interaction.children(languageChildrenOptions), }, { commandKey: "newBoard", icon: IconCategoryPlus, name: tOption("newBoard.label"), useInteraction() { const { openModal } = useModalAction(AddBoardModal); return { type: "javaScript", onSelect() { openModal(undefined); }, }; }, hidden: !session?.user.permissions.includes("board-create"), }, { commandKey: "importBoard", icon: IconFileImport, name: tOption("importBoard.label"), useInteraction() { const { openModal } = useModalAction(ImportBoardModal); return { type: "javaScript", onSelect() { openModal(undefined); }, }; }, hidden: !session?.user.permissions.includes("board-create"), }, { commandKey: "newApp", icon: IconPackage, name: tOption("newApp.label"), useInteraction: interaction.link(() => ({ href: "/manage/apps/new" })), }, { commandKey: "newIntegration", icon: IconPlug, name: tOption("newIntegration.label"), useInteraction: interaction.children(newIntegrationChildrenOptions), hidden: !session?.user.permissions.includes("integration-create"), }, { commandKey: "newUser", icon: IconUserPlus, name: tOption("newUser.label"), useInteraction: interaction.link(() => ({ href: "/manage/users/new" })), hidden: !session?.user.permissions.includes("admin"), }, { commandKey: "newInvite", icon: IconMailForward, name: tOption("newInvite.label"), useInteraction() { const { openModal } = useModalAction(InviteCreateModal); return { type: "javaScript", onSelect() { openModal(undefined); }, }; }, hidden: !session?.user.permissions.includes("admin"), }, { commandKey: "newGroup", icon: IconUsersGroup, name: tOption("newGroup.label"), useInteraction() { const { openModal } = useModalAction(AddGroupModal); return { type: "javaScript", onSelect() { openModal(undefined); }, }; }, hidden: !session?.user.permissions.includes("admin"), }, ]; return commands.filter((command) => !command.hidden); }, }), ], } satisfies SearchMode;