import type { Action } from "kbar";
import {
KBarAnimator,
KBarPortal,
KBarPositioner,
KBarProvider,
KBarResults,
KBarSearch,
useKBar,
useMatches,
useRegisterActions,
} from "kbar";
import { useRouter } from "next/navigation";
import type { ReactNode } from "react";
import { useMemo } from "react";
import { appStoreMetadata } from "@calcom/app-store/appStoreMetaData";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { isMac } from "@calcom/lib/isMac";
import { trpc } from "@calcom/trpc/react";
import { Icon } from "@calcom/ui/components/icon";
import { Tooltip } from "@calcom/ui/components/tooltip";
type ShortcutArrayType = {
shortcuts?: string[];
};
type ActionConfig = {
id: string;
name: string;
section?: string;
shortcut?: string[];
keywords: string;
href: string;
};
type AppAction = {
id: string;
name: string;
section: string;
keywords: string;
};
const getApps: AppAction[] = Object.values(appStoreMetadata).map(({ name, slug }) => ({
id: slug,
name,
section: "Installable Apps",
keywords: `app ${name}`,
}));
const KBAR_ACTION_CONFIGS: ActionConfig[] = [
{ id: "workflows", name: "workflows", section: "workflows", shortcut: ["w", "f"], keywords: "workflows automation", href: "/workflows" },
{ id: "event-types", name: "event_types_page_title", section: "event_types_page_title", shortcut: ["e", "t"], keywords: "event types", href: "/event-types" },
{ id: "app-store", name: "app_store", section: "apps", shortcut: ["a", "s"], keywords: "app store", href: "/apps" },
{ id: "upcoming-bookings", name: "upcoming", section: "bookings", shortcut: ["u", "b"], keywords: "upcoming bookings", href: "/bookings/upcoming" },
{ id: "recurring-bookings", name: "recurring", section: "bookings", shortcut: ["r", "b"], keywords: "recurring bookings", href: "/bookings/recurring" },
{ id: "past-bookings", name: "past", section: "bookings", shortcut: ["p", "b"], keywords: "past bookings", href: "/bookings/past" },
{ id: "cancelled-bookings", name: "cancelled", section: "bookings", shortcut: ["c", "b"], keywords: "cancelled bookings", href: "/bookings/cancelled" },
{ id: "schedule", name: "availability", section: "availability", shortcut: ["s", "a"], keywords: "schedule availability", href: "/availability" },
{ id: "profile", name: "profile", section: "profile", shortcut: ["p", "s"], keywords: "setting profile", href: "/settings/my-account/profile" },
{ id: "avatar", name: "change_avatar", section: "profile", shortcut: ["c", "a"], keywords: "remove change modify avatar", href: "/settings/my-account/profile" },
{ id: "timezone", name: "timezone", section: "profile", shortcut: ["c", "t"], keywords: "change modify timezone", href: "/settings/my-account/general" },
{ id: "brand-color", name: "brand_color", section: "profile", shortcut: ["b", "c"], keywords: "change modify brand color", href: "/settings/my-account/appearance" },
{ id: "teams", name: "teams", shortcut: ["t", "s"], keywords: "add manage modify team", href: "/settings/teams" },
{ id: "password", name: "change_password", section: "security", shortcut: ["c", "p"], keywords: "change modify password", href: "/settings/security/password" },
{ id: "two-factor", name: "two_factor_auth", section: "security", shortcut: ["t", "f", "a"], keywords: "two factor authentication", href: "/settings/security/two-factor-auth" },
{ id: "impersonation", name: "user_impersonation_heading", section: "security", shortcut: ["u", "i"], keywords: "user impersonation", href: "/settings/security/impersonation" },
{ id: "license", name: "choose_a_license", section: "admin", shortcut: ["u", "l"], keywords: "license", href: "/auth/setup?step=1" },
{ id: "webhooks", name: "Webhooks", section: "developer", shortcut: ["w", "h"], keywords: "webhook automation", href: "/settings/developer/webhooks" },
{ id: "api-keys", name: "api_keys", section: "developer", shortcut: ["a", "p", "i"], keywords: "api keys", href: "/settings/developer/api-keys" },
{ id: "billing", name: "manage_billing", section: "billing", shortcut: ["m", "b"], keywords: "billing view manage", href: "/settings/billing" },
];
function buildKbarActions(push: (href: string) => void): Action[] {
const staticActions: Action[] = KBAR_ACTION_CONFIGS.map((config) => ({
id: config.id,
name: config.name,
section: config.section,
shortcut: config.shortcut,
keywords: config.keywords,
perform: () => push(config.href),
}));
const appStoreActions: Action[] = getApps.map((item) => ({
...item,
perform: () => push(`/apps/${item.id}`),
}));
return [...staticActions, ...appStoreActions];
}
function useEventTypesAction(): void {
const router = useRouter();
const { data } = trpc.viewer.eventTypes.getEventTypesFromGroup.useInfiniteQuery(
{
limit: 10,
group: { teamId: null, parentId: null },
},
{
refetchOnWindowFocus: false,
staleTime: 1 * 60 * 60 * 1000,
getNextPageParam: (lastPage: { nextCursor?: number | null }) => lastPage.nextCursor,
}
);
const eventTypeActions: Action[] =
data?.pages?.flatMap((page) => {
return (
page?.eventTypes?.map((item) => ({
id: `event-type-${item.id}`,
name: item.title,
section: "event_types_page_title",
keywords: "event types",
perform: () => router.push(`/event-types/${item.id}`),
})) ?? []
);
}) ?? [];
let actions: Action[] = [];
if (eventTypeActions.length > 0) {
actions = eventTypeActions;
}
useRegisterActions(actions);
}
const KBarRoot = ({ children }: { children: ReactNode }): JSX.Element => {
const router = useRouter();
const actions = useMemo(() => buildKbarActions(router.push), [router.push]);
return