first commit
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import Link from "next/link";
|
||||
|
||||
import type { TDependencyData } from "@calcom/app-store/_appRegistry";
|
||||
import { InstallAppButtonWithoutPlanCheck } from "@calcom/app-store/components";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import type { App } from "@calcom/types/App";
|
||||
import { Badge, Button, Icon } from "@calcom/ui";
|
||||
|
||||
interface IAppConnectionItem {
|
||||
title: string;
|
||||
description?: string;
|
||||
logo: string;
|
||||
type: App["type"];
|
||||
installed?: boolean;
|
||||
isDefault?: boolean;
|
||||
defaultInstall?: boolean;
|
||||
slug?: string;
|
||||
dependencyData?: TDependencyData;
|
||||
}
|
||||
|
||||
const AppConnectionItem = (props: IAppConnectionItem) => {
|
||||
const { title, logo, type, installed, isDefault, defaultInstall, slug } = props;
|
||||
const { t } = useLocale();
|
||||
const setDefaultConferencingApp = trpc.viewer.appsRouter.setDefaultConferencingApp.useMutation();
|
||||
const dependency = props.dependencyData?.find((data) => !data.installed);
|
||||
return (
|
||||
<div className="flex flex-row items-center justify-between p-5">
|
||||
<div className="flex items-center space-x-3">
|
||||
<img src={logo} alt={title} className="h-8 w-8" />
|
||||
<p className="text-sm font-bold">{title}</p>
|
||||
{isDefault && <Badge variant="green">{t("default")}</Badge>}
|
||||
</div>
|
||||
<InstallAppButtonWithoutPlanCheck
|
||||
type={type}
|
||||
options={{
|
||||
onSuccess: () => {
|
||||
if (defaultInstall && slug) {
|
||||
setDefaultConferencingApp.mutate({ slug });
|
||||
}
|
||||
},
|
||||
}}
|
||||
render={(buttonProps) => (
|
||||
<Button
|
||||
{...buttonProps}
|
||||
color="secondary"
|
||||
disabled={installed || !!dependency}
|
||||
type="button"
|
||||
loading={buttonProps?.isPending}
|
||||
tooltip={
|
||||
dependency ? (
|
||||
<div className="items-start space-x-2.5">
|
||||
<div className="flex items-start">
|
||||
<div>
|
||||
<Icon name="circle-alert" className="mr-2 mt-1 font-semibold" />
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-xs font-semibold">
|
||||
{t("this_app_requires_connected_account", {
|
||||
appName: title,
|
||||
dependencyName: dependency.name,
|
||||
})}
|
||||
</span>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<>
|
||||
<Link
|
||||
href={`${WEBAPP_URL}/getting-started/connected-calendar`}
|
||||
className="flex items-center text-xs underline">
|
||||
<span className="mr-1">
|
||||
{t("connect_app", { dependencyName: dependency.name })}
|
||||
</span>
|
||||
<Icon name="arrow-right" className="inline-block h-3 w-3" />
|
||||
</Link>
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : undefined
|
||||
}
|
||||
onClick={(event) => {
|
||||
// Save cookie key to return url step
|
||||
document.cookie = `return-to=${window.location.href};path=/;max-age=3600;SameSite=Lax`;
|
||||
buttonProps && buttonProps.onClick && buttonProps?.onClick(event);
|
||||
}}>
|
||||
{installed ? t("installed") : t("connect")}
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { AppConnectionItem };
|
||||
@@ -0,0 +1,72 @@
|
||||
import { CalendarSwitch } from "@calcom/features/calendars/CalendarSwitch";
|
||||
|
||||
interface IConnectedCalendarItem {
|
||||
name: string;
|
||||
logo: string;
|
||||
externalId?: string;
|
||||
integrationType: string;
|
||||
calendars?: {
|
||||
primary: true | null;
|
||||
isSelected: boolean;
|
||||
credentialId: number;
|
||||
name?: string | undefined;
|
||||
readOnly?: boolean | undefined;
|
||||
userId?: number | undefined;
|
||||
integration?: string | undefined;
|
||||
externalId: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
const ConnectedCalendarItem = (prop: IConnectedCalendarItem) => {
|
||||
const { name, logo, externalId, calendars, integrationType } = prop;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-row items-center p-4">
|
||||
<img src={logo} alt={name} className="m-1 h-8 w-8" />
|
||||
<div className="mx-4">
|
||||
<p className="font-sans text-sm font-bold leading-5">
|
||||
{name}
|
||||
{/* Temporarily removed till we use it on another place */}
|
||||
{/* <span className="mx-1 rounded-[4px] bg-success py-[2px] px-[6px] font-sans text-xs font-medium text-green-600">
|
||||
{t("default")}
|
||||
</span> */}
|
||||
</p>
|
||||
<div className="fle-row flex">
|
||||
<span
|
||||
title={externalId}
|
||||
className="max-w-44 text-subtle mt-1 overflow-hidden text-ellipsis whitespace-nowrap font-sans text-sm">
|
||||
{externalId}{" "}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* Temporarily removed */}
|
||||
{/* <Button
|
||||
color="minimal"
|
||||
type="button"
|
||||
className="ml-auto flex rounded-md border border-subtle py-[10x] px-4 font-sans text-sm">
|
||||
{t("edit")}
|
||||
</Button> */}
|
||||
</div>
|
||||
<div className="border-subtle h-[1px] w-full border-b" />
|
||||
<div>
|
||||
<ul className="p-4">
|
||||
{calendars?.map((calendar, i) => (
|
||||
<CalendarSwitch
|
||||
credentialId={calendar.credentialId}
|
||||
key={calendar.externalId}
|
||||
externalId={calendar.externalId}
|
||||
title={calendar.name || "Nameless Calendar"}
|
||||
name={calendar.name || "Nameless Calendar"}
|
||||
type={integrationType}
|
||||
isChecked={calendar.isSelected}
|
||||
isLastItemInList={i === calendars.length - 1}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export { ConnectedCalendarItem };
|
||||
@@ -0,0 +1,37 @@
|
||||
import DestinationCalendarSelector from "@calcom/features/calendars/DestinationCalendarSelector";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { RouterInputs } from "@calcom/trpc/react";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
|
||||
interface ICreateEventsOnCalendarSelectProps {
|
||||
calendar?: RouterInputs["viewer"]["setDestinationCalendar"] | null;
|
||||
}
|
||||
|
||||
const CreateEventsOnCalendarSelect = (props: ICreateEventsOnCalendarSelectProps) => {
|
||||
const { calendar } = props;
|
||||
const { t } = useLocale();
|
||||
const mutation = trpc.viewer.setDestinationCalendar.useMutation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mt-6 flex flex-row">
|
||||
<div className="w-full">
|
||||
<label htmlFor="createEventsOn" className="text-default flex text-sm font-medium">
|
||||
{t("create_events_on")}
|
||||
</label>
|
||||
<div className="mt-2">
|
||||
<DestinationCalendarSelector
|
||||
value={calendar ? calendar.externalId : undefined}
|
||||
onChange={(calendar) => {
|
||||
mutation.mutate(calendar);
|
||||
}}
|
||||
hidePlaceholder
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export { CreateEventsOnCalendarSelect };
|
||||
@@ -0,0 +1,17 @@
|
||||
import { SkeletonAvatar, SkeletonText, SkeletonButton } from "@calcom/ui";
|
||||
|
||||
export function StepConnectionLoader() {
|
||||
return (
|
||||
<ul className="bg-default divide-subtle border-subtle divide-y rounded-md border p-0 dark:bg-black">
|
||||
{Array.from({ length: 4 }).map((_item, index) => {
|
||||
return (
|
||||
<li className="flex w-full flex-row justify-center border-b-0 py-6" key={index}>
|
||||
<SkeletonAvatar className="mx-6 h-8 w-8 px-4" />
|
||||
<SkeletonText className="ml-1 mr-4 mt-3 h-5 w-full" />
|
||||
<SkeletonButton className="mr-6 h-8 w-20 rounded-md p-5" />
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user