Changes to make type ready to remove
This commit is contained in:
parent
c6ca411b54
commit
21ece8d9f6
|
@ -4,7 +4,7 @@ import { OptionProps } from "react-select";
|
|||
|
||||
import { InstallAppButton } from "@calcom/app-store/components";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
import { Button } from "@calcom/ui";
|
||||
|
||||
import { QueryCell } from "@lib/QueryCell";
|
||||
|
@ -14,11 +14,11 @@ interface AdditionalCalendarSelectorProps {
|
|||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const ImageOption = (optionProps: OptionProps<{ [key: string]: string; type: App["type"] }>) => {
|
||||
const ImageOption = (optionProps: OptionProps<{ [key: string]: string; appId: string }>) => {
|
||||
const { data } = optionProps;
|
||||
return (
|
||||
<InstallAppButton
|
||||
type={data.type}
|
||||
slug={data.appId}
|
||||
render={(installProps) => {
|
||||
return (
|
||||
<Button {...installProps} className="w-full" color="minimal">
|
||||
|
@ -46,7 +46,7 @@ const AdditionalCalendarSelector = ({ isLoading }: AdditionalCalendarSelectorPro
|
|||
label: item.name,
|
||||
slug: item.slug,
|
||||
image: item.imageSrc,
|
||||
type: item.type,
|
||||
appId: item.appId,
|
||||
}));
|
||||
return (
|
||||
<Select
|
||||
|
|
|
@ -14,7 +14,7 @@ import React, { useEffect, useState } from "react";
|
|||
|
||||
import { InstallAppButton } from "@calcom/app-store/components";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { App as AppType } from "@calcom/types/App";
|
||||
import { AppMeta as AppType } from "@calcom/types/App";
|
||||
import { Button, SkeletonButton } from "@calcom/ui";
|
||||
|
||||
import Shell from "@components/Shell";
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import AppCard from "./AppCard";
|
||||
|
||||
export default function AllApps({ apps }: { apps: App[] }) {
|
||||
export default function AllApps({ apps }: { apps: AppMeta[] }) {
|
||||
const { t } = useLocale();
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import AppCard from "./AppCard";
|
||||
import Slider from "./Slider";
|
||||
|
||||
const TrendingAppsSlider = <T extends App>({ items }: { items: T[] }) => {
|
||||
const TrendingAppsSlider = <T extends AppMeta>({ items }: { items: T[] }) => {
|
||||
const { t } = useLocale();
|
||||
|
||||
return (
|
||||
|
|
|
@ -131,7 +131,7 @@ function ConnectedCalendarsList(props: Props) {
|
|||
key={cal.externalId}
|
||||
externalId={cal.externalId}
|
||||
title={cal.name || "Nameless calendar"}
|
||||
type={item.integration.type}
|
||||
type={item.integration.appId}
|
||||
defaultSelected={cal.isSelected}
|
||||
/>
|
||||
))}
|
||||
|
|
|
@ -54,7 +54,11 @@ async function handlePaymentSuccess(event: Stripe.Event) {
|
|||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
credentials: true,
|
||||
credentials: {
|
||||
include: {
|
||||
app: true,
|
||||
},
|
||||
},
|
||||
timeZone: true,
|
||||
email: true,
|
||||
name: true,
|
||||
|
|
|
@ -8,8 +8,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
req.session = await getSession({ req });
|
||||
if (req.method === "GET" && req.session && req.session.user.id && req.query) {
|
||||
const { "app-slug": appSlug } = req.query;
|
||||
|
||||
if (!appSlug && Array.isArray(appSlug)) {
|
||||
if (!appSlug || typeof appSlug !== "string") {
|
||||
return res.status(400);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
select: {
|
||||
id: true,
|
||||
credentials: {
|
||||
include: {
|
||||
app: true,
|
||||
},
|
||||
orderBy: { id: "desc" as Prisma.SortOrder },
|
||||
},
|
||||
timeZone: true,
|
||||
|
|
|
@ -113,7 +113,11 @@ const userSelect = Prisma.validator<Prisma.UserArgs>()({
|
|||
name: true,
|
||||
username: true,
|
||||
timeZone: true,
|
||||
credentials: true,
|
||||
credentials: {
|
||||
include: {
|
||||
app: true,
|
||||
},
|
||||
},
|
||||
bufferTime: true,
|
||||
destinationCalendar: true,
|
||||
locale: true,
|
||||
|
|
|
@ -7,7 +7,7 @@ import Image from "next/image";
|
|||
import Link from "next/link";
|
||||
import path from "path";
|
||||
|
||||
import { getAppWithMetadata } from "@calcom/app-store/_appRegistry";
|
||||
import { getAppRegistry, getAppWithMetadata } from "@calcom/app-store/_appRegistry";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import useMediaQuery from "@lib/hooks/useMediaQuery";
|
||||
|
@ -88,8 +88,14 @@ export const getStaticProps = async (ctx: GetStaticPropsContext) => {
|
|||
|
||||
if (!app) return { notFound: true };
|
||||
|
||||
const singleApp = await getAppWithMetadata(app);
|
||||
|
||||
let singleApp = await getAppWithMetadata(app);
|
||||
const appStoreFromDb = await getAppRegistry();
|
||||
appStoreFromDb.forEach((appFromDb) => {
|
||||
singleApp = {
|
||||
...singleApp,
|
||||
...appFromDb,
|
||||
};
|
||||
});
|
||||
if (!singleApp) return { notFound: true };
|
||||
|
||||
const appDirname = app.dirName;
|
||||
|
|
|
@ -6,7 +6,7 @@ import { JSONObject } from "superjson/dist/types";
|
|||
import { InstallAppButton } from "@calcom/app-store/components";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import showToast from "@calcom/lib/notification";
|
||||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
import { Alert } from "@calcom/ui/Alert";
|
||||
import Button from "@calcom/ui/Button";
|
||||
import EmptyScreen from "@calcom/ui/EmptyScreen";
|
||||
|
@ -28,13 +28,13 @@ import SubHeadingTitleWithConnections from "@components/integrations/SubHeadingT
|
|||
|
||||
function ConnectOrDisconnectIntegrationButton(props: {
|
||||
credentialIds: number[];
|
||||
type: App["type"];
|
||||
slug: AppMeta["slug"];
|
||||
isGlobal?: boolean;
|
||||
installed?: boolean;
|
||||
}) {
|
||||
const { t } = useLocale();
|
||||
const [credentialId] = props.credentialIds;
|
||||
const type = props.type;
|
||||
const slug = props.slug;
|
||||
const utils = trpc.useContext();
|
||||
const handleOpenChange = () => {
|
||||
utils.invalidateQueries(["viewer.integrations"]);
|
||||
|
@ -83,7 +83,7 @@ function ConnectOrDisconnectIntegrationButton(props: {
|
|||
}
|
||||
return (
|
||||
<InstallAppButton
|
||||
type={props.type}
|
||||
slug={props.slug}
|
||||
render={(buttonProps) => (
|
||||
<Button color="secondary" {...buttonProps} data-testid="integration-connection-button">
|
||||
{t("connect")}
|
||||
|
@ -95,7 +95,7 @@ function ConnectOrDisconnectIntegrationButton(props: {
|
|||
}
|
||||
|
||||
interface IntegrationsContainerProps {
|
||||
variant: App["variant"];
|
||||
variant: AppMeta["variant"];
|
||||
className?: string;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ const IntegrationsContainer = ({ variant, className = "" }: IntegrationsContaine
|
|||
actions={
|
||||
<ConnectOrDisconnectIntegrationButton
|
||||
credentialIds={item.credentialIds}
|
||||
type={item.type}
|
||||
slug={item.appId}
|
||||
isGlobal={item.isGlobal}
|
||||
installed
|
||||
/>
|
||||
|
|
|
@ -708,7 +708,7 @@ export async function getServerSideProps(context: NextPageContext) {
|
|||
});
|
||||
|
||||
const integrations = getApps(credentials)
|
||||
.filter((item) => item.type.endsWith("_calendar"))
|
||||
.filter((item) => item.category.includes("calendar"))
|
||||
.map((item) => omit(item, "key"));
|
||||
|
||||
// get user's credentials + their connected integrations
|
||||
|
|
|
@ -58,6 +58,9 @@ async function getUserFromSession({
|
|||
userId: true,
|
||||
appId: true,
|
||||
},
|
||||
include: {
|
||||
app: true,
|
||||
},
|
||||
orderBy: {
|
||||
id: "asc",
|
||||
},
|
||||
|
|
|
@ -619,6 +619,7 @@ const loggedInViewerRouter = createProtectedRouter()
|
|||
const { variant, onlyInstalled } = input;
|
||||
const { credentials } = user;
|
||||
|
||||
// TODO: This fn doesn't seem to be used. Verify and remove it.
|
||||
function countActive(items: { credentialIds: unknown[] }[]) {
|
||||
return items.reduce((acc, item) => acc + item.credentialIds.length, 0);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import prisma from "@calcom/prisma";
|
||||
import { App } from "@calcom/types/App";
|
||||
import { App, AppMeta } from "@calcom/types/App";
|
||||
|
||||
export async function getAppWithMetadata(app: { dirName: string }) {
|
||||
let appMetadata: App | null = null;
|
||||
let appMetadata: AppMeta | null = null;
|
||||
try {
|
||||
appMetadata = (await import(`./${app.dirName}/_metadata`)).default as App;
|
||||
appMetadata = (await import(`./${app.dirName}/_metadata`)).default as AppMeta;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`No metadata found for: "${app.dirName}". Message:`, error.message);
|
||||
|
@ -20,7 +20,8 @@ export async function getAppWithMetadata(app: { dirName: string }) {
|
|||
/** Mainly to use in listings for the frontend, use in getStaticProps or getServerSideProps */
|
||||
export async function getAppRegistry() {
|
||||
const dbApps = await prisma.app.findMany({ select: { dirName: true, slug: true, categories: true } });
|
||||
const apps = [] as Omit<App, "key">[];
|
||||
const apps = [] as App[];
|
||||
const a: App = null;
|
||||
for await (const dbapp of dbApps) {
|
||||
const app = await getAppWithMetadata(dbapp);
|
||||
if (!app) continue;
|
||||
|
@ -29,6 +30,7 @@ export async function getAppRegistry() {
|
|||
// if (!app.installed) return apps;
|
||||
apps.push({
|
||||
...app,
|
||||
...dbapp,
|
||||
installed:
|
||||
true /* All apps from DB are considered installed by default. @TODO: Add and filter our by `enabled` property */,
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import config from "./config.json";
|
||||
import _package from "./package.json";
|
||||
|
@ -15,6 +15,6 @@ export const metadata = {
|
|||
trending: true,
|
||||
verified: true,
|
||||
...config,
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -21,6 +21,6 @@ export const metadata = {
|
|||
variant: "conferencing",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -2,9 +2,9 @@ import { useMutation } from "react-query";
|
|||
|
||||
import type { IntegrationOAuthCallbackState } from "@calcom/app-store/types";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { App } from "@calcom/types/App";
|
||||
import { AppMeta } from "@calcom/types/App";
|
||||
|
||||
function useAddAppMutation(type: App["type"], options?: Parameters<typeof useMutation>[2]) {
|
||||
function useAddAppMutation(type: AppMeta["type"], options?: Parameters<typeof useMutation>[2]) {
|
||||
// FIXME: Ensure that existing apps keep on working
|
||||
// const appName = type.replace(/_/g, "");
|
||||
const appName = type;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -20,6 +20,6 @@ export const metadata = {
|
|||
url: "https://cal.com/",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -20,6 +20,6 @@ export const metadata = {
|
|||
url: "https://cal.com/",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -20,7 +20,7 @@ export const metadata = {
|
|||
url: "https://cal.com/",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export * as api from "./api";
|
||||
export * as components from "./components";
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useSession } from "next-auth/react";
|
|||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { deriveAppKeyFromSlugOrType } from "@calcom/lib/deriveAppKeyFromSlugOrType";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
import Button from "@calcom/ui/Button";
|
||||
|
||||
import { InstallAppButtonMap } from "./apps.components.generated";
|
||||
|
@ -11,7 +11,7 @@ import { InstallAppButtonProps } from "./types";
|
|||
|
||||
export const InstallAppButton = (
|
||||
props: {
|
||||
slug: App["slug"];
|
||||
slug: AppMeta["slug"];
|
||||
} & InstallAppButtonProps
|
||||
) => {
|
||||
const { status } = useSession();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import { LocationType } from "../locations";
|
||||
import _package from "./package.json";
|
||||
|
@ -27,6 +27,6 @@ export const metadata = {
|
|||
locationType: LocationType.Daily,
|
||||
locationLabel: "Cal Video",
|
||||
key: { apikey: process.env.DAILY_API_KEY },
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -21,6 +21,6 @@ export const metadata = {
|
|||
variant: "other",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { validJson } from "@calcom/lib/jsonUtils";
|
||||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import { LocationType } from "../locations";
|
||||
import _package from "./package.json";
|
||||
|
@ -25,6 +25,6 @@ export const metadata = {
|
|||
email: "help@cal.com",
|
||||
locationType: LocationType.GoogleMeet,
|
||||
locationLabel: "Google Meet",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { validJson } from "@calcom/lib/jsonUtils";
|
||||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import { LocationType } from "../locations";
|
||||
import _package from "./package.json";
|
||||
|
@ -25,6 +25,6 @@ export const metadata = {
|
|||
email: "help@cal.com",
|
||||
locationType: LocationType.GoogleMeet,
|
||||
locationLabel: "Google Meet",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -21,6 +21,6 @@ export const metadata = {
|
|||
title: "HubSpot CRM",
|
||||
trending: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { randomString } from "@calcom/lib/random";
|
||||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import { LocationType } from "../locations";
|
||||
import _package from "./package.json";
|
||||
|
@ -26,6 +26,6 @@ export const metadata = {
|
|||
locationType: LocationType.Huddle01,
|
||||
locationLabel: "Huddle01 Video",
|
||||
key: { apikey: randomString(12) },
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import { LocationType } from "../locations";
|
||||
import _package from "./package.json";
|
||||
|
@ -24,6 +24,6 @@ export const metadata = {
|
|||
email: "help@cal.com",
|
||||
locationType: LocationType.Jitsi,
|
||||
locationLabel: "Jitsi Video",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -21,6 +21,6 @@ export const metadata = {
|
|||
variant: "other",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -19,6 +19,6 @@ export const metadata = {
|
|||
url: "https://cal.com/",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import { LocationType } from "../locations";
|
||||
import _package from "./package.json";
|
||||
|
@ -22,6 +22,6 @@ export const metadata = {
|
|||
email: "help@cal.com",
|
||||
locationType: LocationType.Teams,
|
||||
locationLabel: "MS Teams",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -14,11 +14,10 @@ export const metadata = {
|
|||
slug: "slack",
|
||||
title: "Slack App",
|
||||
trending: true,
|
||||
type: "slack_app" as App["type"],
|
||||
url: "https://slack.com/",
|
||||
variant: "conferencing",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -21,6 +21,6 @@ export const metadata = {
|
|||
variant: "other",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -25,6 +25,6 @@ export const metadata = {
|
|||
variant: "payment",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import { LocationType } from "../locations";
|
||||
import _package from "./package.json";
|
||||
|
@ -23,6 +23,6 @@ export const metadata = {
|
|||
email: "help@cal.com",
|
||||
locationType: LocationType.Tandem,
|
||||
locationLabel: "Tandem Video",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { Prisma } from "@prisma/client";
|
||||
import { TFunction } from "next-i18next";
|
||||
|
||||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import { getAppRegistry } from "./_appRegistry";
|
||||
// If you import this file on any app it should produce circular dependency
|
||||
// import appStore from "./index";
|
||||
import { appStoreMetadata } from "./apps.generated";
|
||||
|
@ -11,13 +12,13 @@ import { LocationType } from "./locations";
|
|||
const ALL_APPS_MAP = Object.keys(appStoreMetadata).reduce((store, key) => {
|
||||
store[key] = appStoreMetadata[key as keyof typeof appStoreMetadata];
|
||||
return store;
|
||||
}, {} as Record<string, App>);
|
||||
}, {} as Record<string, AppMeta>);
|
||||
|
||||
const credentialData = Prisma.validator<Prisma.CredentialArgs>()({
|
||||
select: { id: true, type: true, key: true, userId: true, appId: true },
|
||||
});
|
||||
|
||||
type CredentialData = Prisma.CredentialGetPayload<typeof credentialData>;
|
||||
type CredentialData = Omit<Prisma.CredentialGetPayload<typeof credentialData>, "type">;
|
||||
|
||||
export const ALL_APPS = Object.values(ALL_APPS_MAP);
|
||||
|
||||
|
@ -55,34 +56,35 @@ export function getLocationOptions(integrations: AppMeta, t: TFunction) {
|
|||
* This should get all available apps to the user based on his saved
|
||||
* credentials, this should also get globally available apps.
|
||||
*/
|
||||
function getApps(userCredentials: CredentialData[]) {
|
||||
const apps = ALL_APPS.map((appMeta) => {
|
||||
const credentials = userCredentials.filter((credential) => credential.type === appMeta.type);
|
||||
async function getApps(userCredentials: CredentialData[]) {
|
||||
const appsWithMeta = await getAppRegistry();
|
||||
const apps = appsWithMeta.map((app) => {
|
||||
const credentials = userCredentials.filter((credential) => credential.appId === app.slug);
|
||||
let locationOption: OptionTypeBase | null = null;
|
||||
|
||||
/** If the app is a globally installed one, let's inject it's key */
|
||||
if (appMeta.isGlobal) {
|
||||
if (app.isGlobal) {
|
||||
credentials.push({
|
||||
id: +new Date().getTime(),
|
||||
type: appMeta.type,
|
||||
key: appMeta.key!,
|
||||
key: app.key!,
|
||||
userId: +new Date().getTime(),
|
||||
appId: appMeta.slug,
|
||||
appId: app.slug,
|
||||
});
|
||||
}
|
||||
|
||||
/** Check if app has location option AND add it if user has credentials for it */
|
||||
if (credentials.length > 0 && appMeta?.locationType) {
|
||||
if (credentials.length > 0 && app?.locationType) {
|
||||
locationOption = {
|
||||
value: appMeta.locationType,
|
||||
label: appMeta.locationLabel || "No label set",
|
||||
value: app.locationType,
|
||||
label: app.locationLabel || "No label set",
|
||||
disabled: false,
|
||||
};
|
||||
}
|
||||
|
||||
const credential: typeof credentials[number] | null = credentials[0] || null;
|
||||
return {
|
||||
...appMeta,
|
||||
...app,
|
||||
appId: app.slug,
|
||||
/**
|
||||
* @deprecated use `credentials`
|
||||
*/
|
||||
|
@ -96,12 +98,6 @@ function getApps(userCredentials: CredentialData[]) {
|
|||
return apps;
|
||||
}
|
||||
|
||||
export type AppMeta = ReturnType<typeof getApps>;
|
||||
|
||||
export function hasIntegrationInstalled(type: App["type"]): boolean {
|
||||
return ALL_APPS.some((app) => app.type === type && !!app.installed);
|
||||
}
|
||||
|
||||
export function getLocationTypes(): string[] {
|
||||
return ALL_APPS.reduce((locations, app) => {
|
||||
if (typeof app.locationType === "string") {
|
||||
|
@ -113,13 +109,13 @@ export function getLocationTypes(): string[] {
|
|||
|
||||
export function getLocationLabels(t: TFunction) {
|
||||
const defaultLocationLabels = defaultLocations.reduce((locations, location) => {
|
||||
if(location.label === "attendee_phone_number") {
|
||||
locations[location.value] = t("your_number")
|
||||
return locations
|
||||
if (location.label === "attendee_phone_number") {
|
||||
locations[location.value] = t("your_number");
|
||||
return locations;
|
||||
}
|
||||
if(location.label === "host_phone_number") {
|
||||
locations[location.value] = `${t("phone_call")} (${t("number_provided")})`
|
||||
return locations
|
||||
if (location.label === "host_phone_number") {
|
||||
locations[location.value] = `${t("phone_call")} (${t("number_provided")})`;
|
||||
return locations;
|
||||
}
|
||||
locations[location.value] = t(location.label);
|
||||
return locations;
|
||||
|
@ -137,16 +133,4 @@ export function getAppName(name: string): string | null {
|
|||
return ALL_APPS_MAP[name as keyof typeof ALL_APPS_MAP]?.name ?? null;
|
||||
}
|
||||
|
||||
export function getAppType(name: string): string {
|
||||
const type = ALL_APPS_MAP[name as keyof typeof ALL_APPS_MAP].type;
|
||||
|
||||
if (type.endsWith("_calendar")) {
|
||||
return "Calendar";
|
||||
}
|
||||
if (type.endsWith("_payment")) {
|
||||
return "Payment";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
export default getApps;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -22,6 +22,6 @@ export const metadata = {
|
|||
variant: "other",
|
||||
verified: true,
|
||||
email: "support@tryvital.io",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -21,6 +21,6 @@ export const metadata = {
|
|||
variant: "other",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import _package from "./package.json";
|
||||
|
||||
|
@ -20,6 +20,6 @@ export const metadata = {
|
|||
variant: "other",
|
||||
verified: true,
|
||||
email: "help@cal.com",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -6,6 +6,7 @@ import { Toaster } from "react-hot-toast";
|
|||
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import showToast from "@calcom/lib/notification";
|
||||
import { App } from "@calcom/prisma/client";
|
||||
import { Button, Loader, Tooltip } from "@calcom/ui";
|
||||
|
||||
/** TODO: Maybe extract this into a package to prevent circular dependencies */
|
||||
|
@ -29,7 +30,7 @@ export default function ZapierSetup(props: IZapierSetupProps) {
|
|||
|
||||
const deleteApiKey = trpc.useMutation("viewer.apiKeys.delete");
|
||||
const zapierCredentials: { credentialIds: number[] } | undefined = integrations.data?.items.find(
|
||||
(item: { type: string }) => item.type === "zapier_other"
|
||||
(item: { appId: App["slug"] }) => item.appId === ZAPIER
|
||||
);
|
||||
const [credentialId] = zapierCredentials?.credentialIds || [false];
|
||||
const showContent = integrations.data && integrations.isSuccess && credentialId;
|
||||
|
@ -49,7 +50,7 @@ export default function ZapierSetup(props: IZapierSetupProps) {
|
|||
|
||||
if (integrations.isLoading) {
|
||||
return (
|
||||
<div className="flex absolute z-50 h-screen w-full items-center bg-gray-200">
|
||||
<div className="absolute z-50 flex h-screen w-full items-center bg-gray-200">
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
|
@ -75,7 +76,7 @@ export default function ZapierSetup(props: IZapierSetupProps) {
|
|||
) : (
|
||||
<>
|
||||
<div className="mt-1 text-xl">{t("your_unique_api_key")}</div>
|
||||
<div className="flex my-2 mt-3">
|
||||
<div className="my-2 mt-3 flex">
|
||||
<div className="mr-1 w-full rounded bg-gray-100 p-3 pr-5">{newApiKey}</div>
|
||||
<Tooltip content="copy to clipboard">
|
||||
<Button
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { App } from "@calcom/types/App";
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import { LocationType } from "../locations";
|
||||
import _package from "./package.json";
|
||||
|
@ -22,6 +22,6 @@ export const metadata = {
|
|||
email: "help@cal.com",
|
||||
locationType: LocationType.Zoom,
|
||||
locationLabel: "Zoom Video",
|
||||
} as App;
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -18,7 +18,7 @@ export { getCalendar };
|
|||
export const getCalendarCredentials = (credentials: Array<Credential>, userId: number) => {
|
||||
const calendarCredentials = getApps(credentials)
|
||||
.filter((app) => {
|
||||
return app.type.endsWith("_calendar");
|
||||
return app.category.includes("calendar");
|
||||
})
|
||||
.flatMap((app) => {
|
||||
const credentials = app.credentials.flatMap((credential) => {
|
||||
|
|
|
@ -110,8 +110,8 @@ export default class EventManager {
|
|||
*/
|
||||
constructor(user: EventManagerUser) {
|
||||
const appCredentials = getApps(user.credentials).flatMap((app) => app.credentials);
|
||||
this.calendarCredentials = appCredentials.filter((cred) => cred.type.endsWith("_calendar"));
|
||||
this.videoCredentials = appCredentials.filter((cred) => cred.type.endsWith("_video"));
|
||||
this.calendarCredentials = appCredentials.filter((cred) => cred.app.category.includes("calendar"));
|
||||
this.videoCredentials = appCredentials.filter((cred) => cred.app.category.includes("video"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -81,6 +81,7 @@ model EventType {
|
|||
|
||||
model Credential {
|
||||
id Int @id @default(autoincrement())
|
||||
// To be dropped, it is not being used.
|
||||
type String
|
||||
key Json
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Prisma } from "@prisma/client";
|
||||
import type { App as AppFromPrisma, Prisma } from "@prisma/client";
|
||||
|
||||
import type { LocationType } from "@calcom/app-store/locations";
|
||||
|
||||
|
@ -6,7 +6,7 @@ import type { LocationType } from "@calcom/app-store/locations";
|
|||
* This is the definition for an app store's app metadata.
|
||||
* This is used to display App info, categorize or hide certain apps in the app store.
|
||||
*/
|
||||
export interface App {
|
||||
export interface AppMeta {
|
||||
/**
|
||||
* @deprecated
|
||||
* Wheter if the app is installed or not. Usually we check for api keys in env
|
||||
|
@ -56,8 +56,6 @@ export interface App {
|
|||
locationLabel?: string;
|
||||
/** Needed API Keys (usually for global apps) */
|
||||
key?: Prisma.JsonValue;
|
||||
/** Needed API Keys (usually for global apps) */
|
||||
key?: Prisma.JsonValue;
|
||||
/** If not free, what kind of fees does the app have */
|
||||
feeType?: "monthly" | "usage-based" | "one-time" | "free";
|
||||
/** 0 = free. if type="usage-based" it's the price per booking */
|
||||
|
@ -65,3 +63,5 @@ export interface App {
|
|||
/** only required for "usage-based" billing. % of commission for paid bookings */
|
||||
commission?: number;
|
||||
}
|
||||
|
||||
export type App = AppMeta | AppFromPrisma;
|
||||
|
|
Loading…
Reference in New Issue
Block a user