chore: bump @trpc/* and @tanstack/react-query (#13335)
Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: Omar López <zomars@me.com> Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: Alex van Andel <me@alexvanandel.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Co-authored-by: Benny Joo <sldisek783@gmail.com> Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com> Co-authored-by: Gergő Móricz <mo.geryy@gmail.com> Co-authored-by: Keith Williams <keithwillcode@gmail.com>
This commit is contained in:
co-authored by
Peer Richelsen
Omar López
CarinaWolli
Alex van Andel
Udit Takkar
Benny Joo
Carina Wollendorfer
Gergő Móricz
Keith Williams
parent
12eec186b2
commit
30ba168fc3
@@ -1,11 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { type DehydratedState, Hydrate } from "@tanstack/react-query";
|
||||
import { type DehydratedState, HydrationBoundary } from "@tanstack/react-query";
|
||||
import { useMemo } from "react";
|
||||
|
||||
import type { DataTransformer } from "@trpc/server";
|
||||
type DataTransformer = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
serialize: (data: any) => any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
deserialize: (data: any) => any;
|
||||
};
|
||||
|
||||
export function createHydrateClient(opts: { transformer?: DataTransformer }) {
|
||||
export function createHydrateClient(opts: { transformer: DataTransformer }) {
|
||||
return function HydrateClient(props: { children: React.ReactNode; state: DehydratedState }) {
|
||||
const { state, children } = props;
|
||||
|
||||
@@ -16,6 +21,6 @@ export function createHydrateClient(opts: { transformer?: DataTransformer }) {
|
||||
return state;
|
||||
}, [state]);
|
||||
|
||||
return <Hydrate state={transformedState}>{children}</Hydrate>;
|
||||
return <HydrationBoundary state={transformedState}>{children}</HydrationBoundary>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,10 +4,7 @@ import { trpc } from "app/_trpc/client";
|
||||
import { useState } from "react";
|
||||
import superjson from "superjson";
|
||||
|
||||
import { httpBatchLink } from "@calcom/trpc/client/links/httpBatchLink";
|
||||
import { httpLink } from "@calcom/trpc/client/links/httpLink";
|
||||
import { loggerLink } from "@calcom/trpc/client/links/loggerLink";
|
||||
import { splitLink } from "@calcom/trpc/client/links/splitLink";
|
||||
import { httpBatchLink, httpLink, loggerLink, splitLink } from "@calcom/trpc/client";
|
||||
import { ENDPOINTS } from "@calcom/trpc/react/shared";
|
||||
|
||||
export type Endpoint = (typeof ENDPOINTS)[number];
|
||||
|
||||
@@ -16,10 +16,10 @@ import { Plus } from "@calcom/ui/components/icon";
|
||||
import { QueryCell } from "@lib/QueryCell";
|
||||
|
||||
interface AdditionalCalendarSelectorProps {
|
||||
isLoading?: boolean;
|
||||
isPending?: boolean;
|
||||
}
|
||||
|
||||
const AdditionalCalendarSelector = ({ isLoading }: AdditionalCalendarSelectorProps): JSX.Element | null => {
|
||||
const AdditionalCalendarSelector = ({ isPending }: AdditionalCalendarSelectorProps): JSX.Element | null => {
|
||||
const { t } = useLocale();
|
||||
const query = trpc.viewer.integrations.useQuery({ variant: "calendar", onlyInstalled: true });
|
||||
|
||||
@@ -42,7 +42,7 @@ const AdditionalCalendarSelector = ({ isLoading }: AdditionalCalendarSelectorPro
|
||||
return (
|
||||
<Dropdown modal={false}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button StartIcon={Plus} color="secondary" {...(isLoading && { loading: isLoading })}>
|
||||
<Button StartIcon={Plus} color="secondary" {...(isPending && { loading: isPending })}>
|
||||
{t("add")}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Link from "next/link";
|
||||
import type { IframeHTMLAttributes } from "react";
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
|
||||
import useAddAppMutation from "@calcom/app-store/_utils/useAddAppMutation";
|
||||
import { AppDependencyComponent, InstallAppButton } from "@calcom/app-store/components";
|
||||
@@ -92,17 +92,19 @@ export const AppPage = ({
|
||||
const [existingCredentials, setExistingCredentials] = useState<number[]>([]);
|
||||
const [showDisconnectIntegration, setShowDisconnectIntegration] = useState(false);
|
||||
|
||||
const appDbQuery = trpc.viewer.appCredentialsByType.useQuery(
|
||||
{ appType: type },
|
||||
{
|
||||
onSettled(data) {
|
||||
const credentialsCount = data?.credentials.length || 0;
|
||||
setShowDisconnectIntegration(
|
||||
data?.userAdminTeams.length ? credentialsCount >= data?.userAdminTeams.length : credentialsCount > 0
|
||||
);
|
||||
setExistingCredentials(data?.credentials.map((credential) => credential.id) || []);
|
||||
},
|
||||
}
|
||||
const appDbQuery = trpc.viewer.appCredentialsByType.useQuery({ appType: type });
|
||||
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
const data = appDbQuery.data;
|
||||
|
||||
const credentialsCount = data?.credentials.length || 0;
|
||||
setShowDisconnectIntegration(
|
||||
data?.userAdminTeams.length ? credentialsCount >= data?.userAdminTeams.length : credentialsCount > 0
|
||||
);
|
||||
setExistingCredentials(data?.credentials.map((credential) => credential.id) || []);
|
||||
},
|
||||
[appDbQuery.data]
|
||||
);
|
||||
|
||||
const dependencyData = trpc.viewer.appsRouter.queryForDependencies.useQuery(dependencies, {
|
||||
@@ -190,7 +192,7 @@ export const AppPage = ({
|
||||
)}
|
||||
</header>
|
||||
</div>
|
||||
{!appDbQuery.isLoading ? (
|
||||
{!appDbQuery.isPending ? (
|
||||
isGlobal ||
|
||||
(existingCredentials.length > 0 && allowedMultipleInstalls ? (
|
||||
<div className="flex space-x-3">
|
||||
@@ -211,7 +213,7 @@ export const AppPage = ({
|
||||
onClick: () => {
|
||||
mutation.mutate({ type, variant, slug });
|
||||
},
|
||||
loading: mutation.isLoading,
|
||||
loading: mutation.isPending,
|
||||
};
|
||||
}
|
||||
return (
|
||||
@@ -250,7 +252,7 @@ export const AppPage = ({
|
||||
onClick: () => {
|
||||
mutation.mutate({ type, variant, slug });
|
||||
},
|
||||
loading: mutation.isLoading,
|
||||
loading: mutation.isPending,
|
||||
};
|
||||
}
|
||||
return (
|
||||
@@ -272,7 +274,7 @@ export const AppPage = ({
|
||||
)}
|
||||
|
||||
{dependencies &&
|
||||
(!dependencyData.isLoading ? (
|
||||
(!dependencyData.isPending ? (
|
||||
<div className="mt-6">
|
||||
<AppDependencyComponent appName={name} dependencyData={dependencyData.data} />
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,7 @@ type Props = {
|
||||
onChanged: () => unknown | Promise<unknown>;
|
||||
fromOnboarding?: boolean;
|
||||
destinationCalendarId?: string;
|
||||
isLoading?: boolean;
|
||||
isPending?: boolean;
|
||||
};
|
||||
|
||||
function CalendarList(props: Props) {
|
||||
@@ -74,7 +74,7 @@ function ConnectedCalendarsList(props: Props) {
|
||||
suspense: true,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
const { fromOnboarding, isLoading } = props;
|
||||
const { fromOnboarding, isPending } = props;
|
||||
return (
|
||||
<QueryCell
|
||||
query={query}
|
||||
@@ -97,7 +97,7 @@ function ConnectedCalendarsList(props: Props) {
|
||||
<div className="flex flex-col xl:flex-row xl:space-x-5">
|
||||
{!!data.connectedCalendars.length && (
|
||||
<div className="flex items-center">
|
||||
<AdditionalCalendarSelector isLoading={isLoading} />
|
||||
<AdditionalCalendarSelector isPending={isPending} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -229,7 +229,7 @@ export function CalendarListContainer(props: { heading?: boolean; fromOnboarding
|
||||
hidePlaceholder
|
||||
value={data.destinationCalendar?.externalId}
|
||||
onChange={mutation.mutate}
|
||||
isLoading={mutation.isLoading}
|
||||
isPending={mutation.isPending}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -239,7 +239,7 @@ export function CalendarListContainer(props: { heading?: boolean; fromOnboarding
|
||||
onChanged={onChanged}
|
||||
fromOnboarding={fromOnboarding}
|
||||
destinationCalendarId={data.destinationCalendar?.externalId}
|
||||
isLoading={mutation.isLoading}
|
||||
isPending={mutation.isPending}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -100,9 +100,9 @@ export const InstallAppButtonChild = ({
|
||||
<DropdownMenuContent
|
||||
className="w-auto"
|
||||
onInteractOutside={(event) => {
|
||||
if (mutation.isLoading) event.preventDefault();
|
||||
if (mutation.isPending) event.preventDefault();
|
||||
}}>
|
||||
{mutation.isLoading && (
|
||||
{mutation.isPending && (
|
||||
<div className="z-1 fixed inset-0 flex items-center justify-center">
|
||||
<Spinner />
|
||||
</div>
|
||||
|
||||
@@ -139,7 +139,7 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
setRejectionDialogIsOpen(true);
|
||||
},
|
||||
icon: Ban,
|
||||
disabled: mutation.isLoading,
|
||||
disabled: mutation.isPending,
|
||||
},
|
||||
// For bookings with payment, only confirm if the booking is paid for
|
||||
...((isPending && !paymentAppData.enabled) ||
|
||||
@@ -153,7 +153,7 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
bookingConfirm(true);
|
||||
},
|
||||
icon: Check,
|
||||
disabled: mutation.isLoading,
|
||||
disabled: mutation.isPending,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
@@ -293,7 +293,7 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
setViewRecordingsDialogIsOpen(true);
|
||||
},
|
||||
color: showCheckRecordingButton ? "secondary" : "primary",
|
||||
disabled: mutation.isLoading,
|
||||
disabled: mutation.isPending,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -348,7 +348,7 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
<DialogFooter>
|
||||
<DialogClose />
|
||||
<Button
|
||||
disabled={mutation.isLoading}
|
||||
disabled={mutation.isPending}
|
||||
data-testid="rejection-confirm"
|
||||
onClick={() => {
|
||||
bookingConfirm(false);
|
||||
|
||||
@@ -65,7 +65,7 @@ export const ChargeCardDialog = (props: IRescheduleDialog) => {
|
||||
<DialogClose />
|
||||
<Button
|
||||
data-testid="send_request"
|
||||
disabled={chargeCardMutation.isLoading || chargeError}
|
||||
disabled={chargeCardMutation.isPending || chargeError}
|
||||
onClick={() =>
|
||||
chargeCardMutation.mutate({
|
||||
bookingId,
|
||||
|
||||
@@ -27,7 +27,7 @@ export const RescheduleDialog = (props: IRescheduleDialog) => {
|
||||
const { isOpenDialog, setIsOpenDialog, bookingUId: bookingId } = props;
|
||||
const [rescheduleReason, setRescheduleReason] = useState("");
|
||||
|
||||
const { mutate: rescheduleApi, isLoading } = trpc.viewer.bookings.requestReschedule.useMutation({
|
||||
const { mutate: rescheduleApi, isPending } = trpc.viewer.bookings.requestReschedule.useMutation({
|
||||
async onSuccess() {
|
||||
showToast(t("reschedule_request_sent"), "success");
|
||||
setIsOpenDialog(false);
|
||||
@@ -65,7 +65,7 @@ export const RescheduleDialog = (props: IRescheduleDialog) => {
|
||||
<DialogClose />
|
||||
<Button
|
||||
data-testid="send_request"
|
||||
disabled={isLoading}
|
||||
disabled={isPending}
|
||||
onClick={() => {
|
||||
rescheduleApi({
|
||||
bookingId,
|
||||
|
||||
@@ -18,7 +18,7 @@ export type EventType = Pick<EventTypeSetupProps, "eventType">["eventType"] &
|
||||
|
||||
export const EventAppsTab = ({ eventType }: { eventType: EventType }) => {
|
||||
const { t } = useLocale();
|
||||
const { data: eventTypeApps, isLoading } = trpc.viewer.integrations.useQuery({
|
||||
const { data: eventTypeApps, isPending } = trpc.viewer.integrations.useQuery({
|
||||
extendsFeature: "EventType",
|
||||
teamId: eventType.team?.id || eventType.parent?.teamId,
|
||||
});
|
||||
@@ -138,7 +138,7 @@ export const EventAppsTab = ({ eventType }: { eventType: EventType }) => {
|
||||
message={t("locked_apps_description")}
|
||||
/>
|
||||
)}
|
||||
{!isLoading && !installedApps?.length ? (
|
||||
{!isPending && !installedApps?.length ? (
|
||||
<EmptyScreen
|
||||
Icon={Grid}
|
||||
headline={t("empty_installed_apps_headline")}
|
||||
@@ -179,7 +179,7 @@ export const EventAppsTab = ({ eventType }: { eventType: EventType }) => {
|
||||
</div>
|
||||
{!shouldLockDisableProps("apps").disabled && (
|
||||
<div className="bg-muted mt-6 rounded-md p-8">
|
||||
{!isLoading && notInstalledApps?.length ? (
|
||||
{!isPending && notInstalledApps?.length ? (
|
||||
<>
|
||||
<h2 className="text-emphasis mb-2 text-xl font-semibold leading-5 tracking-[0.01em]">
|
||||
{t("available_apps_lower_case")}
|
||||
|
||||
@@ -85,7 +85,7 @@ const EventTypeScheduleDetails = memo(
|
||||
const { watch } = useFormContext<FormValues>();
|
||||
|
||||
const scheduleId = watch("schedule");
|
||||
const { isLoading, data: schedule } = trpc.viewer.availability.schedule.get.useQuery(
|
||||
const { isPending, data: schedule } = trpc.viewer.availability.schedule.get.useQuery(
|
||||
{
|
||||
scheduleId:
|
||||
scheduleId || loggedInUser?.defaultScheduleId || selectedScheduleValue?.value || undefined,
|
||||
@@ -112,7 +112,7 @@ const EventTypeScheduleDetails = memo(
|
||||
)}>
|
||||
{day}
|
||||
</span>
|
||||
{isLoading ? (
|
||||
{isPending ? (
|
||||
<SkeletonText className="block h-5 w-60" />
|
||||
) : isAvailable ? (
|
||||
<div className="space-y-3 text-right">
|
||||
@@ -142,7 +142,7 @@ const EventTypeScheduleDetails = memo(
|
||||
{!!schedule?.id && !schedule.isManaged && !schedule.readOnly && (
|
||||
<Button
|
||||
href={`/availability/${schedule.id}`}
|
||||
disabled={isLoading}
|
||||
disabled={isPending}
|
||||
color="minimal"
|
||||
EndIcon={ExternalLink}
|
||||
target="_blank"
|
||||
@@ -169,8 +169,15 @@ const EventTypeSchedule = ({ eventType }: { eventType: EventTypeSetup }) => {
|
||||
const watchSchedule = watch("schedule");
|
||||
const [options, setOptions] = useState<AvailabilityOption[]>([]);
|
||||
|
||||
const { isLoading } = trpc.viewer.availability.list.useQuery(undefined, {
|
||||
onSuccess: ({ schedules }) => {
|
||||
const { data, isPending } = trpc.viewer.availability.list.useQuery(undefined);
|
||||
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
const schedules = data.schedules;
|
||||
|
||||
const options = schedules.map((schedule) => ({
|
||||
value: schedule.id,
|
||||
label: schedule.name,
|
||||
@@ -225,8 +232,8 @@ const EventTypeSchedule = ({ eventType }: { eventType: EventTypeSetup }) => {
|
||||
|
||||
setValue("availability", value);
|
||||
},
|
||||
});
|
||||
|
||||
[data]
|
||||
);
|
||||
const availabilityValue = watch("availability");
|
||||
|
||||
useEffect(() => {
|
||||
@@ -241,8 +248,8 @@ const EventTypeSchedule = ({ eventType }: { eventType: EventTypeSetup }) => {
|
||||
{t("availability")}
|
||||
{shouldLockIndicator("availability")}
|
||||
</label>
|
||||
{isLoading && <SelectSkeletonLoader />}
|
||||
{!isLoading && (
|
||||
{isPending && <SelectSkeletonLoader />}
|
||||
{!isPending && (
|
||||
<Controller
|
||||
name="schedule"
|
||||
render={({ field }) => {
|
||||
|
||||
@@ -446,7 +446,7 @@ function EventTypeSingleLayout({
|
||||
</Suspense>
|
||||
<Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
|
||||
<ConfirmationDialogContent
|
||||
isLoading={deleteMutation.isLoading}
|
||||
isPending={deleteMutation.isPending}
|
||||
variety="danger"
|
||||
title={t(`delete${isManagedEvent}_event_type`)}
|
||||
confirmBtnText={t(`confirm_delete_event_type`)}
|
||||
|
||||
@@ -23,7 +23,7 @@ export const EventWebhooksTab = ({ eventType }: Pick<EventTypeSetupProps, "event
|
||||
|
||||
const { data: webhooks } = trpc.viewer.webhook.list.useQuery({ eventTypeId: eventType.id });
|
||||
|
||||
const { data: installedApps, isLoading } = trpc.viewer.integrations.useQuery({
|
||||
const { data: installedApps, isPending } = trpc.viewer.integrations.useQuery({
|
||||
variant: "other",
|
||||
onlyInstalled: true,
|
||||
});
|
||||
@@ -103,7 +103,7 @@ export const EventWebhooksTab = ({ eventType }: Pick<EventTypeSetupProps, "event
|
||||
|
||||
return (
|
||||
<div>
|
||||
{webhooks && !isLoading && (
|
||||
{webhooks && !isPending && (
|
||||
<>
|
||||
<div>
|
||||
<div>
|
||||
|
||||
@@ -108,7 +108,7 @@ const InstantMeetingWebhooks = ({ eventType }: { eventType: EventTypeSetup }) =>
|
||||
eventTypeId: eventType.id,
|
||||
eventTriggers: [WebhookTriggerEvents.INSTANT_MEETING],
|
||||
});
|
||||
const { data: installedApps, isLoading } = trpc.viewer.integrations.useQuery({
|
||||
const { data: installedApps, isPending } = trpc.viewer.integrations.useQuery({
|
||||
variant: "other",
|
||||
onlyInstalled: true,
|
||||
});
|
||||
@@ -188,7 +188,7 @@ const InstantMeetingWebhooks = ({ eventType }: { eventType: EventTypeSetup }) =>
|
||||
|
||||
return (
|
||||
<div>
|
||||
{webhooks && !isLoading && (
|
||||
{webhooks && !isPending && (
|
||||
<>
|
||||
<div>
|
||||
{webhooks.length ? (
|
||||
|
||||
@@ -8,18 +8,18 @@ interface ManagedEventDialogProps {
|
||||
slugExistsChildrenDialogOpen: ChildrenEventType[];
|
||||
slug: string;
|
||||
onOpenChange: () => void;
|
||||
isLoading: boolean;
|
||||
isPending: boolean;
|
||||
onConfirm: (e: { preventDefault: () => void }) => void;
|
||||
}
|
||||
|
||||
export default function ManagedEventDialog(props: ManagedEventDialogProps) {
|
||||
const { t } = useLocale();
|
||||
const { slugExistsChildrenDialogOpen, slug, onOpenChange, isLoading, onConfirm } = props;
|
||||
const { slugExistsChildrenDialogOpen, slug, onOpenChange, isPending, onConfirm } = props;
|
||||
|
||||
return (
|
||||
<Dialog open={slugExistsChildrenDialogOpen.length > 0} onOpenChange={onOpenChange}>
|
||||
<ConfirmationDialogContent
|
||||
isLoading={isLoading}
|
||||
isPending={isPending}
|
||||
variety="warning"
|
||||
title={t("managed_event_dialog_title", {
|
||||
slug,
|
||||
|
||||
@@ -28,7 +28,7 @@ const AppConnectionItem = (props: IAppConnectionItem) => {
|
||||
color="secondary"
|
||||
disabled={installed}
|
||||
type="button"
|
||||
loading={buttonProps?.isLoading}
|
||||
loading={buttonProps?.isPending}
|
||||
onClick={(event) => {
|
||||
// Save cookie key to return url step
|
||||
document.cookie = `return-to=${window.location.href};path=/;max-age=3600;SameSite=Lax`;
|
||||
|
||||
@@ -31,7 +31,7 @@ const ConnectedCalendars = (props: IConnectCalendarsProps) => {
|
||||
return (
|
||||
<>
|
||||
{/* Already connected calendars */}
|
||||
{!queryConnectedCalendars.isLoading &&
|
||||
{!queryConnectedCalendars.isPending &&
|
||||
firstCalendar &&
|
||||
firstCalendar.integration &&
|
||||
firstCalendar.integration.title &&
|
||||
@@ -76,7 +76,7 @@ const ConnectedCalendars = (props: IConnectCalendarsProps) => {
|
||||
</List>
|
||||
)}
|
||||
|
||||
{queryIntegrations.isLoading && <StepConnectionLoader />}
|
||||
{queryIntegrations.isPending && <StepConnectionLoader />}
|
||||
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -13,7 +13,7 @@ interface ConnectedAppStepProps {
|
||||
|
||||
const ConnectedVideoStep = (props: ConnectedAppStepProps) => {
|
||||
const { nextStep } = props;
|
||||
const { data: queryConnectedVideoApps, isLoading } = trpc.viewer.integrations.useQuery({
|
||||
const { data: queryConnectedVideoApps, isPending } = trpc.viewer.integrations.useQuery({
|
||||
variant: "conferencing",
|
||||
onlyInstalled: false,
|
||||
sortByMostPopular: true,
|
||||
@@ -26,7 +26,7 @@ const ConnectedVideoStep = (props: ConnectedAppStepProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isLoading && (
|
||||
{!isPending && (
|
||||
<List className="bg-default border-subtle divide-subtle scroll-bar mx-1 max-h-[45vh] divide-y !overflow-y-scroll rounded-md border p-0 sm:mx-0">
|
||||
{queryConnectedVideoApps?.items &&
|
||||
queryConnectedVideoApps?.items.map((item) => {
|
||||
@@ -48,7 +48,7 @@ const ConnectedVideoStep = (props: ConnectedAppStepProps) => {
|
||||
</List>
|
||||
)}
|
||||
|
||||
{isLoading && <StepConnectionLoader />}
|
||||
{isPending && <StepConnectionLoader />}
|
||||
<button
|
||||
type="button"
|
||||
data-testid="save-video-button"
|
||||
|
||||
@@ -113,7 +113,7 @@ const UserSettings = (props: IUserSettingsProps) => {
|
||||
<Button
|
||||
type="submit"
|
||||
className="mt-8 flex w-full flex-row justify-center"
|
||||
disabled={mutation.isLoading}>
|
||||
disabled={mutation.isPending}>
|
||||
{t("next_step_text")}
|
||||
<ArrowRight className="ml-2 h-4 w-4 self-center" aria-hidden="true" />
|
||||
</Button>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Check } from "@calcom/ui/components/icon";
|
||||
const StepDone = (props: {
|
||||
currentStep: number;
|
||||
nextStepPath: string;
|
||||
setIsLoading: Dispatch<SetStateAction<boolean>>;
|
||||
setIsPending: Dispatch<SetStateAction<boolean>>;
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const { t } = useLocale();
|
||||
@@ -18,7 +18,7 @@ const StepDone = (props: {
|
||||
name={`wizard-step-${props.currentStep}`}
|
||||
className="flex justify-center space-y-4"
|
||||
onSubmit={(e) => {
|
||||
props.setIsLoading(true);
|
||||
props.setIsPending(true);
|
||||
e.preventDefault();
|
||||
router.replace(props.nextStepPath);
|
||||
}}>
|
||||
|
||||
@@ -293,7 +293,7 @@ const PremiumTextfield = (props: ICustomUsernameProps) => {
|
||||
{usernameChangeCondition === UsernameChangeStatusEnum.UPGRADE && (
|
||||
<Button
|
||||
type="button"
|
||||
loading={updateUsername.isLoading}
|
||||
loading={updateUsername.isPending}
|
||||
data-testid="go-to-billing"
|
||||
href={paymentLink}>
|
||||
<>
|
||||
@@ -305,7 +305,7 @@ const PremiumTextfield = (props: ICustomUsernameProps) => {
|
||||
{usernameChangeCondition !== UsernameChangeStatusEnum.UPGRADE && (
|
||||
<Button
|
||||
type="button"
|
||||
loading={updateUsername.isLoading}
|
||||
loading={updateUsername.isPending}
|
||||
data-testid="save-username"
|
||||
onClick={() => {
|
||||
saveUsername();
|
||||
|
||||
@@ -177,7 +177,7 @@ const UsernameTextfield = (props: ICustomUsernameProps & Partial<React.Component
|
||||
<DialogFooter className="mt-4">
|
||||
<Button
|
||||
type="button"
|
||||
loading={updateUsernameMutation.isLoading}
|
||||
loading={updateUsernameMutation.isPending}
|
||||
data-testid="save-username"
|
||||
onClick={updateUsername}>
|
||||
{t("save")}
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
import type {
|
||||
QueryObserverLoadingErrorResult,
|
||||
QueryObserverLoadingResult,
|
||||
QueryObserverPendingResult,
|
||||
QueryObserverRefetchErrorResult,
|
||||
QueryObserverSuccessResult,
|
||||
QueryObserverLoadingErrorResult,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { TRPCClientErrorLike } from "@calcom/trpc/client";
|
||||
import type { DecorateProcedure } from "@calcom/trpc/react/shared";
|
||||
import type { AnyQueryProcedure, inferProcedureInput, inferProcedureOutput } from "@calcom/trpc/server";
|
||||
import type { AppRouter } from "@calcom/trpc/server/routers/_app";
|
||||
import { Alert, Loader } from "@calcom/ui";
|
||||
|
||||
import type { UseTRPCQueryOptions } from "@trpc/react-query/shared";
|
||||
|
||||
type ErrorLike = {
|
||||
message: string;
|
||||
};
|
||||
@@ -27,7 +21,7 @@ interface QueryCellOptionsBase<TData, TError extends ErrorLike> {
|
||||
error?: (
|
||||
query: QueryObserverLoadingErrorResult<TData, TError> | QueryObserverRefetchErrorResult<TData, TError>
|
||||
) => JSXElementOrNull;
|
||||
loading?: (query: QueryObserverLoadingResult<TData, TError> | null) => JSXElementOrNull;
|
||||
loading?: (query: QueryObserverPendingResult<TData, TError> | null) => JSXElementOrNull;
|
||||
}
|
||||
|
||||
interface QueryCellOptionsNoEmpty<TData, TError extends ErrorLike>
|
||||
@@ -58,8 +52,11 @@ export function QueryCell<TData, TError extends ErrorLike>(
|
||||
const { isLocaleReady } = useLocale();
|
||||
const StatusLoader = opts.customLoader || <Loader />; // Fixes edge case where this can return null form query cell
|
||||
|
||||
if (query.status === "loading" || !isLocaleReady) {
|
||||
return opts.loading?.(query.status === "loading" ? query : null) ?? StatusLoader;
|
||||
if (!isLocaleReady) {
|
||||
return opts.loading?.(query.status === "pending" ? query : null) ?? StatusLoader;
|
||||
}
|
||||
if (query.status === "pending") {
|
||||
return opts.loading?.(query) ?? StatusLoader;
|
||||
}
|
||||
|
||||
if (query.status === "success") {
|
||||
@@ -81,28 +78,3 @@ export function QueryCell<TData, TError extends ErrorLike>(
|
||||
// impossible state
|
||||
return null;
|
||||
}
|
||||
|
||||
type TError = TRPCClientErrorLike<AppRouter>;
|
||||
|
||||
const withQuery = <
|
||||
TQuery extends AnyQueryProcedure,
|
||||
TInput = inferProcedureInput<TQuery>,
|
||||
TOutput = inferProcedureOutput<TQuery>
|
||||
>(
|
||||
queryProcedure: DecorateProcedure<TQuery, inferProcedureInput<TQuery>, inferProcedureOutput<TQuery>>,
|
||||
|
||||
input?: TInput,
|
||||
params?: UseTRPCQueryOptions<TQuery, TInput, TOutput, TOutput, TError>
|
||||
) => {
|
||||
return function WithQuery(
|
||||
opts: Omit<
|
||||
Partial<QueryCellOptionsWithEmpty<TOutput, TError>> & QueryCellOptionsNoEmpty<TOutput, TError>,
|
||||
"query"
|
||||
>
|
||||
) {
|
||||
const query = queryProcedure.useQuery(input, params);
|
||||
return <QueryCell query={query} {...opts} />;
|
||||
};
|
||||
};
|
||||
|
||||
export { withQuery };
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"@sentry/nextjs": "^7.73.0",
|
||||
"@stripe/react-stripe-js": "^1.10.0",
|
||||
"@stripe/stripe-js": "^1.35.0",
|
||||
"@tanstack/react-query": "^4.3.9",
|
||||
"@tanstack/react-query": "^5.17.15",
|
||||
"@tremor/react": "^2.0.0",
|
||||
"@types/turndown": "^5.0.1",
|
||||
"@upstash/ratelimit": "^0.4.3",
|
||||
|
||||
@@ -5,7 +5,7 @@ import classNames from "classnames";
|
||||
import { signIn } from "next-auth/react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { FaGoogle } from "react-icons/fa";
|
||||
import { z } from "zod";
|
||||
@@ -157,15 +157,20 @@ inferSSRProps<typeof getServerSideProps> & WithNonceProps<{}>) {
|
||||
else setErrorMessage(errorMessages[res.error] || t("something_went_wrong"));
|
||||
};
|
||||
|
||||
const { data, isLoading } = trpc.viewer.public.ssoConnections.useQuery(undefined, {
|
||||
onError: (err) => {
|
||||
setErrorMessage(err.message);
|
||||
const { data, isPending, error } = trpc.viewer.public.ssoConnections.useQuery();
|
||||
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (error) {
|
||||
setErrorMessage(error.message);
|
||||
}
|
||||
},
|
||||
});
|
||||
[error]
|
||||
);
|
||||
|
||||
const displaySSOLogin = HOSTED_CAL_FEATURES
|
||||
? true
|
||||
: isSAMLLoginEnabled && !isLoading && data?.connectionExists;
|
||||
: isSAMLLoginEnabled && !isPending && data?.connectionExists;
|
||||
|
||||
return (
|
||||
<div className="dark:bg-brand dark:text-brand-contrast text-emphasis min-h-screen [--cal-brand-emphasis:#101010] [--cal-brand-subtle:#9CA3AF] [--cal-brand-text:white] [--cal-brand:#111827] dark:[--cal-brand-emphasis:#e1e1e1] dark:[--cal-brand-text:black] dark:[--cal-brand:white]">
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function Authorize() {
|
||||
const [selectedAccount, setSelectedAccount] = useState<{ value: string; label: string } | null>();
|
||||
const scopes = scope ? scope.toString().split(",") : [];
|
||||
|
||||
const { data: client, isLoading: isLoadingGetClient } = trpc.viewer.oAuth.getClient.useQuery(
|
||||
const { data: client, isPending: isPendingGetClient } = trpc.viewer.oAuth.getClient.useQuery(
|
||||
{
|
||||
clientId: client_id as string,
|
||||
},
|
||||
@@ -37,7 +37,7 @@ export default function Authorize() {
|
||||
}
|
||||
);
|
||||
|
||||
const { data, isLoading: isLoadingProfiles } = trpc.viewer.teamsAndUserProfilesQuery.useQuery();
|
||||
const { data, isPending: isPendingProfiles } = trpc.viewer.teamsAndUserProfilesQuery.useQuery();
|
||||
|
||||
const generateAuthCodeMutation = trpc.viewer.oAuth.generateAuthCode.useMutation({
|
||||
onSuccess: (data) => {
|
||||
@@ -58,7 +58,7 @@ export default function Authorize() {
|
||||
if (mappedProfiles.length > 0) {
|
||||
setSelectedAccount(mappedProfiles[0]);
|
||||
}
|
||||
}, [isLoadingProfiles]);
|
||||
}, [isPendingProfiles]);
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "unauthenticated") {
|
||||
@@ -69,9 +69,9 @@ export default function Authorize() {
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
const isLoading = isLoadingGetClient || isLoadingProfiles || status !== "authenticated";
|
||||
const isPending = isPendingGetClient || isPendingProfiles || status !== "authenticated";
|
||||
|
||||
if (isLoading) {
|
||||
if (isPending) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,16 +41,16 @@ export function Setup(props: inferSSRProps<typeof getServerSideProps>) {
|
||||
{
|
||||
title: t("administrator_user"),
|
||||
description: t("lets_create_first_administrator_user"),
|
||||
content: (setIsLoading) => (
|
||||
content: (setIsPending) => (
|
||||
<AdminUser
|
||||
onSubmit={() => {
|
||||
setIsLoading(true);
|
||||
setIsPending(true);
|
||||
}}
|
||||
onSuccess={() => {
|
||||
setStep(2);
|
||||
}}
|
||||
onError={() => {
|
||||
setIsLoading(false);
|
||||
setIsPending(false);
|
||||
}}
|
||||
userCount={props.userCount}
|
||||
/>
|
||||
@@ -59,7 +59,7 @@ export function Setup(props: inferSSRProps<typeof getServerSideProps>) {
|
||||
{
|
||||
title: t("choose_a_license"),
|
||||
description: t("choose_license_description"),
|
||||
content: (setIsLoading) => {
|
||||
content: (setIsPending) => {
|
||||
return (
|
||||
<ChooseLicense
|
||||
id="wizard-step-2"
|
||||
@@ -67,7 +67,7 @@ export function Setup(props: inferSSRProps<typeof getServerSideProps>) {
|
||||
value={value}
|
||||
onChange={setValue}
|
||||
onSubmit={() => {
|
||||
setIsLoading(true);
|
||||
setIsPending(true);
|
||||
setStep(3);
|
||||
}}
|
||||
/>
|
||||
@@ -80,14 +80,14 @@ export function Setup(props: inferSSRProps<typeof getServerSideProps>) {
|
||||
steps.push({
|
||||
title: t("step_enterprise_license"),
|
||||
description: t("step_enterprise_license_description"),
|
||||
content: (setIsLoading) => {
|
||||
content: (setIsPending) => {
|
||||
const currentStep = 3;
|
||||
return (
|
||||
<EnterpriseLicense
|
||||
id={`wizard-step-${currentStep}`}
|
||||
name={`wizard-step-${currentStep}`}
|
||||
onSubmit={() => {
|
||||
setIsLoading(true);
|
||||
setIsPending(true);
|
||||
}}
|
||||
onSuccess={() => {
|
||||
setStep(currentStep + 1);
|
||||
@@ -106,7 +106,7 @@ export function Setup(props: inferSSRProps<typeof getServerSideProps>) {
|
||||
title: t("enable_apps"),
|
||||
description: t("enable_apps_description", { appName: APP_NAME }),
|
||||
contentClassname: "!pb-0 mb-[-1px]",
|
||||
content: (setIsLoading) => {
|
||||
content: (setIsPending) => {
|
||||
const currentStep = isFreeLicense ? 3 : 4;
|
||||
return (
|
||||
<AdminAppsList
|
||||
@@ -120,7 +120,7 @@ export function Setup(props: inferSSRProps<typeof getServerSideProps>) {
|
||||
baseURL={`/auth/setup?step=${currentStep}`}
|
||||
useQueryParam={true}
|
||||
onSubmit={() => {
|
||||
setIsLoading(true);
|
||||
setIsPending(true);
|
||||
router.replace("/");
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -44,7 +44,7 @@ function VerifyEmailPage() {
|
||||
<Button
|
||||
color="minimal"
|
||||
className="underline"
|
||||
loading={mutation.isLoading}
|
||||
loading={mutation.isPending}
|
||||
onClick={() => {
|
||||
showToast("Send email", "success");
|
||||
mutation.mutate();
|
||||
|
||||
@@ -93,7 +93,7 @@ export default function Availability() {
|
||||
const fromEventType = searchParams?.get("fromEventType");
|
||||
const { timeFormat } = me.data || { timeFormat: null };
|
||||
const [openSidebar, setOpenSidebar] = useState(false);
|
||||
const { data: schedule, isLoading } = trpc.viewer.availability.schedule.get.useQuery(
|
||||
const { data: schedule, isPending } = trpc.viewer.availability.schedule.get.useQuery(
|
||||
{ scheduleId },
|
||||
{
|
||||
enabled: !!scheduleId,
|
||||
@@ -158,7 +158,7 @@ export default function Availability() {
|
||||
control={form.control}
|
||||
name="name"
|
||||
render={({ field }) => (
|
||||
<EditableHeading isReady={!isLoading} {...field} data-testid="availablity-title" />
|
||||
<EditableHeading isReady={!isPending} {...field} data-testid="availablity-title" />
|
||||
)}
|
||||
/>
|
||||
}
|
||||
@@ -188,7 +188,7 @@ export default function Availability() {
|
||||
</Skeleton>
|
||||
<Switch
|
||||
id="hiddenSwitch"
|
||||
disabled={isLoading || schedule?.isDefault}
|
||||
disabled={isPending || schedule?.isDefault}
|
||||
checked={form.watch("isDefault")}
|
||||
onCheckedChange={(e) => {
|
||||
form.setValue("isDefault", e);
|
||||
@@ -210,7 +210,7 @@ export default function Availability() {
|
||||
/>
|
||||
</DialogTrigger>
|
||||
<ConfirmationDialogContent
|
||||
isLoading={deleteMutation.isLoading}
|
||||
isPending={deleteMutation.isPending}
|
||||
variety="danger"
|
||||
title={t("delete_schedule")}
|
||||
confirmBtnText={t("delete")}
|
||||
@@ -249,7 +249,7 @@ export default function Availability() {
|
||||
/>
|
||||
</DialogTrigger>
|
||||
<ConfirmationDialogContent
|
||||
isLoading={deleteMutation.isLoading}
|
||||
isPending={deleteMutation.isPending}
|
||||
variety="danger"
|
||||
title={t("delete_schedule")}
|
||||
confirmBtnText={t("delete")}
|
||||
@@ -284,7 +284,7 @@ export default function Availability() {
|
||||
</Skeleton>
|
||||
<Switch
|
||||
id="hiddenSwitch"
|
||||
disabled={isLoading || schedule?.isDefault}
|
||||
disabled={isPending || schedule?.isDefault}
|
||||
checked={form.watch("isDefault")}
|
||||
onCheckedChange={(e) => {
|
||||
form.setValue("isDefault", e);
|
||||
@@ -334,7 +334,7 @@ export default function Availability() {
|
||||
className="ml-4 lg:ml-0"
|
||||
type="submit"
|
||||
form="availability-form"
|
||||
loading={updateMutation.isLoading}>
|
||||
loading={updateMutation.isPending}>
|
||||
{t("save")}
|
||||
</Button>
|
||||
<Button
|
||||
|
||||
@@ -15,7 +15,7 @@ import { trpc } from "@calcom/trpc/react";
|
||||
import { EmptyScreen, showToast, ToggleGroup } from "@calcom/ui";
|
||||
import { Clock } from "@calcom/ui/components/icon";
|
||||
|
||||
import { withQuery } from "@lib/QueryCell";
|
||||
import { QueryCell } from "@lib/QueryCell";
|
||||
|
||||
import PageWrapper from "@components/PageWrapper";
|
||||
import SkeletonLoader from "@components/availability/SkeletonLoader";
|
||||
@@ -136,8 +136,17 @@ export function AvailabilityList({ schedules }: RouterOutputs["viewer"]["availab
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const WithQuery = withQuery(trpc.viewer.availability.list as any);
|
||||
function AvailabilityListWithQuery() {
|
||||
const query = trpc.viewer.availability.list.useQuery();
|
||||
|
||||
return (
|
||||
<QueryCell
|
||||
query={query}
|
||||
success={({ data }) => <AvailabilityList {...data} />}
|
||||
customLoader={<SkeletonLoader />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AvailabilityPage() {
|
||||
const { t } = useLocale();
|
||||
@@ -179,14 +188,7 @@ export default function AvailabilityPage() {
|
||||
<NewScheduleButton />
|
||||
</div>
|
||||
}>
|
||||
{searchParams?.get("type") === "team" ? (
|
||||
<AvailabilitySliderTable />
|
||||
) : (
|
||||
<WithQuery
|
||||
success={({ data }) => <AvailabilityList {...data} />}
|
||||
customLoader={<SkeletonLoader />}
|
||||
/>
|
||||
)}
|
||||
{searchParams?.get("type") === "team" ? <AvailabilitySliderTable /> : <AvailabilityListWithQuery />}
|
||||
</ShellMain>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -164,7 +164,7 @@ export default function Bookings() {
|
||||
{query.status === "error" && (
|
||||
<Alert severity="error" title={t("something_went_wrong")} message={query.error.message} />
|
||||
)}
|
||||
{(query.status === "loading" || query.isPaused) && <SkeletonLoader />}
|
||||
{(query.status === "pending" || query.isPaused) && <SkeletonLoader />}
|
||||
{query.status === "success" && !isEmpty && (
|
||||
<>
|
||||
{!!bookingsToday.length && status === "upcoming" && (
|
||||
|
||||
@@ -68,7 +68,7 @@ function ConnectAndJoin() {
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
loading={mutation.isLoading}
|
||||
loading={mutation.isPending}
|
||||
tooltip={isUserPartOfOrg ? t("join_meeting") : t("not_part_of_org")}
|
||||
disabled={!isUserPartOfOrg}
|
||||
onClick={() => {
|
||||
|
||||
@@ -552,7 +552,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
|
||||
eventType={eventType}
|
||||
team={team}
|
||||
availability={availability}
|
||||
isUpdateMutationLoading={updateMutation.isLoading}
|
||||
isUpdateMutationLoading={updateMutation.isPending}
|
||||
formMethods={formMethods}
|
||||
// disableBorder={tabName === "apps" || tabName === "workflows" || tabName === "webhooks"}
|
||||
disableBorder={true}
|
||||
@@ -647,7 +647,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
|
||||
{slugExistsChildrenDialogOpen.length ? (
|
||||
<ManagedEventTypeDialog
|
||||
slugExistsChildrenDialogOpen={slugExistsChildrenDialogOpen}
|
||||
isLoading={formMethods.formState.isSubmitting}
|
||||
isPending={formMethods.formState.isSubmitting}
|
||||
onOpenChange={() => {
|
||||
setSlugExistsChildrenDialogOpen([]);
|
||||
}}
|
||||
|
||||
@@ -686,7 +686,7 @@ export const EventTypeList = ({
|
||||
title={t(`delete${isManagedEventPrefix()}_event_type`)}
|
||||
confirmBtnText={t(`confirm_delete_event_type`)}
|
||||
loadingText={t(`confirm_delete_event_type`)}
|
||||
isLoading={deleteMutation.isLoading}
|
||||
isPending={deleteMutation.isPending}
|
||||
onConfirm={(e) => {
|
||||
e.preventDefault();
|
||||
deleteEventTypeHandler(deleteDialogTypeId);
|
||||
@@ -856,7 +856,7 @@ const Main = ({
|
||||
const searchParams = useCompatSearchParams();
|
||||
const orgBranding = useOrgBranding();
|
||||
|
||||
if (!data || status === "loading") {
|
||||
if (!data || status === "pending") {
|
||||
return <SkeletonLoader />;
|
||||
}
|
||||
|
||||
@@ -934,7 +934,7 @@ const EventTypesPage = () => {
|
||||
// TODO: Maybe useSuspenseQuery to focus on success case only? Remember that it would crash the page when there is an error in query. Also, it won't support skeleton
|
||||
const { data, status, error } = trpc.viewer.eventTypes.getByViewer.useQuery(filters && { filters }, {
|
||||
refetchOnWindowFocus: false,
|
||||
cacheTime: 1 * 60 * 60 * 1000,
|
||||
gcTime: 1 * 60 * 60 * 1000,
|
||||
staleTime: 1 * 60 * 60 * 1000,
|
||||
});
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ const SkeletonLoader = ({ title, description }: { title: string; description: st
|
||||
const ApiKeysView = () => {
|
||||
const { t } = useLocale();
|
||||
|
||||
const { data, isLoading } = trpc.viewer.apiKeys.list.useQuery();
|
||||
const { data, isPending } = trpc.viewer.apiKeys.list.useQuery();
|
||||
|
||||
const [apiKeyModal, setApiKeyModal] = useState(false);
|
||||
const [apiKeyToEdit, setApiKeyToEdit] = useState<(TApiKeys & { neverExpires?: boolean }) | undefined>(
|
||||
@@ -57,7 +57,7 @@ const ApiKeysView = () => {
|
||||
);
|
||||
};
|
||||
|
||||
if (isLoading || !data) {
|
||||
if (isPending || !data) {
|
||||
return (
|
||||
<SkeletonLoader
|
||||
title={t("api_keys")}
|
||||
|
||||
@@ -317,7 +317,7 @@ const AppearanceView = ({
|
||||
<SettingsToggle
|
||||
toggleSwitchAtTheEnd={true}
|
||||
title={t("disable_cal_branding", { appName: APP_NAME })}
|
||||
disabled={!hasPaidPlan || mutation?.isLoading}
|
||||
disabled={!hasPaidPlan || mutation?.isPending}
|
||||
description={t("removes_cal_branding", { appName: APP_NAME })}
|
||||
checked={hasPaidPlan ? hideBrandingValue : false}
|
||||
Badge={<UpgradeTeamsBadge />}
|
||||
@@ -332,12 +332,12 @@ const AppearanceView = ({
|
||||
};
|
||||
|
||||
const AppearanceViewWrapper = () => {
|
||||
const { data: user, isLoading } = trpc.viewer.me.useQuery();
|
||||
const { isLoading: isTeamPlanStatusLoading, hasPaidPlan } = useHasPaidPlan();
|
||||
const { data: user, isPending } = trpc.viewer.me.useQuery();
|
||||
const { isPending: isTeamPlanStatusLoading, hasPaidPlan } = useHasPaidPlan();
|
||||
|
||||
const { t } = useLocale();
|
||||
|
||||
if (isLoading || isTeamPlanStatusLoading || !user)
|
||||
if (isPending || isTeamPlanStatusLoading || !user)
|
||||
return <SkeletonLoader title={t("appearance")} description={t("appearance_description")} />;
|
||||
|
||||
return <AppearanceView user={user} hasPaidPlan={hasPaidPlan} />;
|
||||
|
||||
@@ -51,8 +51,8 @@ interface GeneralViewProps {
|
||||
const GeneralQueryView = () => {
|
||||
const { t } = useLocale();
|
||||
|
||||
const { data: user, isLoading } = trpc.viewer.me.useQuery();
|
||||
if (isLoading) return <SkeletonLoader title={t("general")} description={t("general_description")} />;
|
||||
const { data: user, isPending } = trpc.viewer.me.useQuery();
|
||||
if (isPending) return <SkeletonLoader title={t("general")} description={t("general_description")} />;
|
||||
if (!user) {
|
||||
throw new Error(t("something_went_wrong"));
|
||||
}
|
||||
@@ -233,7 +233,7 @@ const GeneralView = ({ localeProp, user }: GeneralViewProps) => {
|
||||
toggleSwitchAtTheEnd={true}
|
||||
title={t("dynamic_booking")}
|
||||
description={t("allow_dynamic_booking")}
|
||||
disabled={mutation.isLoading}
|
||||
disabled={mutation.isPending}
|
||||
checked={isAllowDynamicBookingChecked}
|
||||
onCheckedChange={(checked) => {
|
||||
setIsAllowDynamicBookingChecked(checked);
|
||||
@@ -246,7 +246,7 @@ const GeneralView = ({ localeProp, user }: GeneralViewProps) => {
|
||||
toggleSwitchAtTheEnd={true}
|
||||
title={t("seo_indexing")}
|
||||
description={t("allow_seo_indexing")}
|
||||
disabled={mutation.isLoading}
|
||||
disabled={mutation.isPending}
|
||||
checked={isAllowSEOIndexingChecked}
|
||||
onCheckedChange={(checked) => {
|
||||
setIsAllowSEOIndexingChecked(checked);
|
||||
@@ -259,7 +259,7 @@ const GeneralView = ({ localeProp, user }: GeneralViewProps) => {
|
||||
toggleSwitchAtTheEnd={true}
|
||||
title={t("monthly_digest_email")}
|
||||
description={t("monthly_digest_email_for_teams")}
|
||||
disabled={mutation.isLoading}
|
||||
disabled={mutation.isPending}
|
||||
checked={isReceiveMonthlyDigestEmailChecked}
|
||||
onCheckedChange={(checked) => {
|
||||
setIsReceiveMonthlyDigestEmailChecked(checked);
|
||||
|
||||
@@ -155,7 +155,7 @@ const OutOfOfficeSection = () => {
|
||||
<Button
|
||||
color="primary"
|
||||
type="submit"
|
||||
disabled={createOutOfOfficeEntry.isLoading}
|
||||
disabled={createOutOfOfficeEntry.isPending}
|
||||
data-testid="create-entry-ooo-redirect">
|
||||
{t("create_entry")}
|
||||
</Button>
|
||||
@@ -168,7 +168,7 @@ const OutOfOfficeSection = () => {
|
||||
const OutOfOfficeEntriesList = () => {
|
||||
const { t } = useLocale();
|
||||
const utils = trpc.useContext();
|
||||
const { data, isLoading } = trpc.viewer.outOfOfficeEntriesList.useQuery();
|
||||
const { data, isPending } = trpc.viewer.outOfOfficeEntriesList.useQuery();
|
||||
const deleteOutOfOfficeEntryMutation = trpc.viewer.outOfOfficeEntryDelete.useMutation({
|
||||
onSuccess: () => {
|
||||
showToast(t("success_deleted_entry_out_of_office"), "success");
|
||||
@@ -207,7 +207,7 @@ const OutOfOfficeEntriesList = () => {
|
||||
type="button"
|
||||
color="minimal"
|
||||
variant="icon"
|
||||
disabled={deleteOutOfOfficeEntryMutation.isLoading}
|
||||
disabled={deleteOutOfOfficeEntryMutation.isPending}
|
||||
StartIcon={Trash2}
|
||||
onClick={() => {
|
||||
deleteOutOfOfficeEntryMutation.mutate({ outOfOfficeUid: item.uuid });
|
||||
@@ -216,7 +216,7 @@ const OutOfOfficeEntriesList = () => {
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
{isLoading && (
|
||||
{isPending && (
|
||||
<TableRow>
|
||||
{new Array(6).fill(0).map((_, index) => (
|
||||
<TableCell key={index}>
|
||||
@@ -226,7 +226,7 @@ const OutOfOfficeEntriesList = () => {
|
||||
</TableRow>
|
||||
)}
|
||||
|
||||
{!isLoading && (data === undefined || data.length === 0) && (
|
||||
{!isPending && (data === undefined || data.length === 0) && (
|
||||
<TableRow>
|
||||
<TableCell colSpan={6} className="text-center">
|
||||
<p className="text-subtle text-sm">{t("no_redirects_found")}</p>
|
||||
|
||||
@@ -84,10 +84,10 @@ const ProfileView = () => {
|
||||
const { t } = useLocale();
|
||||
const utils = trpc.useContext();
|
||||
const { update } = useSession();
|
||||
const { data: user, isLoading } = trpc.viewer.me.useQuery();
|
||||
const { data: user, isPending } = trpc.viewer.me.useQuery();
|
||||
|
||||
const { data: avatarData } = trpc.viewer.avatar.useQuery(undefined, {
|
||||
enabled: !isLoading && !user?.avatarUrl,
|
||||
enabled: !isPending && !user?.avatarUrl,
|
||||
});
|
||||
|
||||
const updateProfileMutation = trpc.viewer.updateProfile.useMutation({
|
||||
@@ -222,7 +222,7 @@ const ProfileView = () => {
|
||||
[ErrorCode.ThirdPartyIdentityProviderEnabled]: t("account_created_with_identity_provider"),
|
||||
};
|
||||
|
||||
if (isLoading || !user) {
|
||||
if (isPending || !user) {
|
||||
return (
|
||||
<SkeletonLoader title={t("profile")} description={t("profile_description", { appName: APP_NAME })} />
|
||||
);
|
||||
@@ -246,7 +246,7 @@ const ProfileView = () => {
|
||||
<ProfileForm
|
||||
key={JSON.stringify(defaultValues)}
|
||||
defaultValues={defaultValues}
|
||||
isLoading={updateProfileMutation.isLoading}
|
||||
isPending={updateProfileMutation.isPending}
|
||||
isFallbackImg={!user.avatarUrl && !avatarData?.avatar}
|
||||
user={user}
|
||||
userOrganization={user.organization}
|
||||
@@ -354,7 +354,7 @@ const ProfileView = () => {
|
||||
<DialogFooter showDivider>
|
||||
<Button
|
||||
color="primary"
|
||||
loading={confirmPasswordMutation.isLoading}
|
||||
loading={confirmPasswordMutation.isPending}
|
||||
onClick={(e) => onConfirmPassword(e)}>
|
||||
{t("confirm")}
|
||||
</Button>
|
||||
@@ -375,7 +375,7 @@ const ProfileView = () => {
|
||||
<DialogFooter>
|
||||
<Button
|
||||
color="primary"
|
||||
loading={updateProfileMutation.isLoading}
|
||||
loading={updateProfileMutation.isPending}
|
||||
onClick={(e) => onConfirmAuthEmailChange(e)}>
|
||||
{t("confirm")}
|
||||
</Button>
|
||||
@@ -391,7 +391,7 @@ const ProfileForm = ({
|
||||
defaultValues,
|
||||
onSubmit,
|
||||
extraField,
|
||||
isLoading = false,
|
||||
isPending = false,
|
||||
isFallbackImg,
|
||||
user,
|
||||
userOrganization,
|
||||
@@ -399,7 +399,7 @@ const ProfileForm = ({
|
||||
defaultValues: FormValues;
|
||||
onSubmit: (values: FormValues) => void;
|
||||
extraField?: React.ReactNode;
|
||||
isLoading: boolean;
|
||||
isPending: boolean;
|
||||
isFallbackImg: boolean;
|
||||
user: RouterOutputs["viewer"]["me"];
|
||||
userOrganization: RouterOutputs["viewer"]["me"]["organization"];
|
||||
@@ -509,7 +509,7 @@ const ProfileForm = ({
|
||||
</div>
|
||||
</div>
|
||||
<SectionBottomActions align="end">
|
||||
<Button loading={isLoading} disabled={isDisabled} color="primary" type="submit">
|
||||
<Button loading={isPending} disabled={isDisabled} color="primary" type="submit">
|
||||
{t("update")}
|
||||
</Button>
|
||||
</SectionBottomActions>
|
||||
|
||||
@@ -69,7 +69,7 @@ const ProfileImpersonationView = ({ user }: { user: RouterOutputs["viewer"]["me"
|
||||
mutation.mutate({ disableImpersonation: !checked });
|
||||
}}
|
||||
switchContainerClassName="rounded-t-none border-t-0"
|
||||
disabled={mutation.isLoading}
|
||||
disabled={mutation.isPending}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
@@ -77,10 +77,10 @@ const ProfileImpersonationView = ({ user }: { user: RouterOutputs["viewer"]["me"
|
||||
};
|
||||
|
||||
const ProfileImpersonationViewWrapper = () => {
|
||||
const { data: user, isLoading } = trpc.viewer.me.useQuery();
|
||||
const { data: user, isPending } = trpc.viewer.me.useQuery();
|
||||
const { t } = useLocale();
|
||||
|
||||
if (isLoading || !user)
|
||||
if (isPending || !user)
|
||||
return <SkeletonLoader title={t("impersonation")} description={t("impersonation_description")} />;
|
||||
|
||||
return <ProfileImpersonationView user={user} />;
|
||||
|
||||
@@ -215,9 +215,9 @@ const PasswordView = ({ user }: PasswordViewProps) => {
|
||||
<Button
|
||||
color="primary"
|
||||
type="submit"
|
||||
loading={passwordMutation.isLoading}
|
||||
loading={passwordMutation.isPending}
|
||||
onClick={() => formMethods.clearErrors("apiError")}
|
||||
disabled={isDisabled || passwordMutation.isLoading || sessionMutation.isLoading}>
|
||||
disabled={isDisabled || passwordMutation.isPending || sessionMutation.isPending}>
|
||||
{t("update")}
|
||||
</Button>
|
||||
</SectionBottomActions>
|
||||
@@ -268,7 +268,7 @@ const PasswordView = ({ user }: PasswordViewProps) => {
|
||||
<SectionBottomActions align="end">
|
||||
<Button
|
||||
color="primary"
|
||||
loading={sessionMutation.isLoading}
|
||||
loading={sessionMutation.isPending}
|
||||
onClick={() => {
|
||||
sessionMutation.mutate({
|
||||
metadata: { ...metadata, sessionTimeout },
|
||||
@@ -277,8 +277,8 @@ const PasswordView = ({ user }: PasswordViewProps) => {
|
||||
}}
|
||||
disabled={
|
||||
initialSessionTimeout === sessionTimeout ||
|
||||
passwordMutation.isLoading ||
|
||||
sessionMutation.isLoading
|
||||
passwordMutation.isPending ||
|
||||
sessionMutation.isPending
|
||||
}>
|
||||
{t("update")}
|
||||
</Button>
|
||||
@@ -293,9 +293,9 @@ const PasswordView = ({ user }: PasswordViewProps) => {
|
||||
};
|
||||
|
||||
const PasswordViewWrapper = () => {
|
||||
const { data: user, isLoading } = trpc.viewer.me.useQuery();
|
||||
const { data: user, isPending } = trpc.viewer.me.useQuery();
|
||||
const { t } = useLocale();
|
||||
if (isLoading || !user)
|
||||
if (isPending || !user)
|
||||
return <SkeletonLoader title={t("password")} description={t("password_description")} />;
|
||||
|
||||
return <PasswordView user={user} />;
|
||||
|
||||
@@ -37,12 +37,12 @@ const TwoFactorAuthView = () => {
|
||||
const utils = trpc.useContext();
|
||||
|
||||
const { t } = useLocale();
|
||||
const { data: user, isLoading } = trpc.viewer.me.useQuery();
|
||||
const { data: user, isPending } = trpc.viewer.me.useQuery();
|
||||
|
||||
const [enableModalOpen, setEnableModalOpen] = useState<boolean>(false);
|
||||
const [disableModalOpen, setDisableModalOpen] = useState<boolean>(false);
|
||||
|
||||
if (isLoading)
|
||||
if (isPending)
|
||||
return <SkeletonLoader title={t("2fa")} description={t("set_up_two_factor_authentication")} />;
|
||||
|
||||
const isCalProvider = user?.identityProvider === "CAL";
|
||||
|
||||
@@ -4,7 +4,7 @@ import superjson from "superjson";
|
||||
|
||||
import { CALCOM_VERSION } from "@calcom/lib/constants";
|
||||
import prisma, { readonlyPrisma } from "@calcom/prisma";
|
||||
import { createProxySSGHelpers } from "@calcom/trpc/react/ssg";
|
||||
import { createServerSideHelpers } from "@calcom/trpc/react/server";
|
||||
import { appRouter } from "@calcom/trpc/server/routers/_app";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
@@ -26,7 +26,7 @@ export async function ssgInit<TParams extends { locale?: string }>(opts: GetStat
|
||||
|
||||
const _i18n = await serverSideTranslations(locale, ["common"]);
|
||||
|
||||
const ssg = createProxySSGHelpers({
|
||||
const ssg = createServerSideHelpers({
|
||||
router: appRouter,
|
||||
transformer: superjson,
|
||||
ctx: {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { forms } from "@calcom/app-store/routing-forms/trpc/procedures/forms";
|
||||
import { getLocale } from "@calcom/features/auth/lib/getLocale";
|
||||
import { map } from "@calcom/features/flags/server/procedures/map";
|
||||
import { CALCOM_VERSION } from "@calcom/lib/constants";
|
||||
import { createProxySSGHelpers } from "@calcom/trpc/react/ssg";
|
||||
import { createServerSideHelpers } from "@calcom/trpc/react/server";
|
||||
import { createContext } from "@calcom/trpc/server/createContext";
|
||||
import { me } from "@calcom/trpc/server/routers/loggedInViewer/procedures/me";
|
||||
import { teamsAndUserProfilesQuery } from "@calcom/trpc/server/routers/loggedInViewer/procedures/teamsAndUserProfilesQuery";
|
||||
@@ -59,7 +59,7 @@ export async function ssrInit(context: GetServerSidePropsContext, options?: { no
|
||||
const locale = await getLocale(context.req);
|
||||
const i18n = await serverSideTranslations(locale, ["common", "vital"]);
|
||||
|
||||
const ssr = createProxySSGHelpers({
|
||||
const ssr = createServerSideHelpers({
|
||||
router: routerSlice,
|
||||
transformer: superjson,
|
||||
ctx: { ...ctx, locale, i18n },
|
||||
|
||||
@@ -71,7 +71,7 @@ export default function OmniInstallAppButton({
|
||||
|
||||
return (
|
||||
<Button
|
||||
loading={mutation.isLoading}
|
||||
loading={mutation.isPending}
|
||||
color="secondary"
|
||||
className="[@media(max-width:260px)]:w-full [@media(max-width:260px)]:justify-center"
|
||||
StartIcon={Plus}
|
||||
|
||||
@@ -32,64 +32,67 @@ function useAddAppMutation(_type: App["type"] | null, allOptions?: UseAddAppMuta
|
||||
AddAppMutationData,
|
||||
Error,
|
||||
{ type?: App["type"]; variant?: string; slug?: string; isOmniInstall?: boolean; teamId?: number } | ""
|
||||
>(async (variables) => {
|
||||
let type: string | null | undefined;
|
||||
let isOmniInstall;
|
||||
const teamId = variables && variables.teamId ? variables.teamId : undefined;
|
||||
if (variables === "") {
|
||||
type = _type;
|
||||
} else {
|
||||
isOmniInstall = variables.isOmniInstall;
|
||||
type = variables.type;
|
||||
}
|
||||
if (type?.endsWith("_other_calendar")) {
|
||||
type = type.split("_other_calendar")[0];
|
||||
}
|
||||
>({
|
||||
...options,
|
||||
mutationFn: async (variables) => {
|
||||
let type: string | null | undefined;
|
||||
let isOmniInstall;
|
||||
const teamId = variables && variables.teamId ? variables.teamId : undefined;
|
||||
if (variables === "") {
|
||||
type = _type;
|
||||
} else {
|
||||
isOmniInstall = variables.isOmniInstall;
|
||||
type = variables.type;
|
||||
}
|
||||
if (type?.endsWith("_other_calendar")) {
|
||||
type = type.split("_other_calendar")[0];
|
||||
}
|
||||
|
||||
if (options?.installGoogleVideo && type !== "google_calendar")
|
||||
throw new Error("Could not install Google Meet");
|
||||
if (options?.installGoogleVideo && type !== "google_calendar")
|
||||
throw new Error("Could not install Google Meet");
|
||||
|
||||
const state: IntegrationOAuthCallbackState = {
|
||||
returnTo:
|
||||
returnTo ||
|
||||
WEBAPP_URL +
|
||||
getInstalledAppPath(
|
||||
{ variant: variables && variables.variant, slug: variables && variables.slug },
|
||||
location.search
|
||||
),
|
||||
...(type === "google_calendar" && { installGoogleVideo: options?.installGoogleVideo }),
|
||||
...(teamId && { teamId }),
|
||||
};
|
||||
const state: IntegrationOAuthCallbackState = {
|
||||
returnTo:
|
||||
returnTo ||
|
||||
WEBAPP_URL +
|
||||
getInstalledAppPath(
|
||||
{ variant: variables && variables.variant, slug: variables && variables.slug },
|
||||
location.search
|
||||
),
|
||||
...(type === "google_calendar" && { installGoogleVideo: options?.installGoogleVideo }),
|
||||
...(teamId && { teamId }),
|
||||
};
|
||||
|
||||
const stateStr = encodeURIComponent(JSON.stringify(state));
|
||||
const searchParams = `?state=${stateStr}${teamId ? `&teamId=${teamId}` : ""}`;
|
||||
const stateStr = encodeURIComponent(JSON.stringify(state));
|
||||
const searchParams = `?state=${stateStr}${teamId ? `&teamId=${teamId}` : ""}`;
|
||||
|
||||
const res = await fetch(`/api/integrations/${type}/add${searchParams}`);
|
||||
const res = await fetch(`/api/integrations/${type}/add${searchParams}`);
|
||||
|
||||
if (!res.ok) {
|
||||
const errorBody = await res.json();
|
||||
throw new Error(errorBody.message || "Something went wrong");
|
||||
}
|
||||
if (!res.ok) {
|
||||
const errorBody = await res.json();
|
||||
throw new Error(errorBody.message || "Something went wrong");
|
||||
}
|
||||
|
||||
const json = await res.json();
|
||||
const externalUrl = /https?:\/\//.test(json.url) && !json.url.startsWith(window.location.origin);
|
||||
if (!isOmniInstall) {
|
||||
gotoUrl(json.url, json.newTab);
|
||||
return { setupPending: externalUrl || json.url.endsWith("/setup") };
|
||||
}
|
||||
|
||||
// Skip redirection only if it is an OmniInstall and redirect URL isn't of some other origin
|
||||
// This allows installation of apps like Stripe to still redirect to their authentication pages.
|
||||
|
||||
// Check first that the URL is absolute, then check that it is of different origin from the current.
|
||||
if (externalUrl) {
|
||||
// TODO: For Omni installation to authenticate and come back to the page where installation was initiated, some changes need to be done in all apps' add callbacks
|
||||
gotoUrl(json.url, json.newTab);
|
||||
return { setupPending: externalUrl };
|
||||
}
|
||||
|
||||
const json = await res.json();
|
||||
const externalUrl = /https?:\/\//.test(json.url) && !json.url.startsWith(window.location.origin);
|
||||
if (!isOmniInstall) {
|
||||
gotoUrl(json.url, json.newTab);
|
||||
return { setupPending: externalUrl || json.url.endsWith("/setup") };
|
||||
}
|
||||
|
||||
// Skip redirection only if it is an OmniInstall and redirect URL isn't of some other origin
|
||||
// This allows installation of apps like Stripe to still redirect to their authentication pages.
|
||||
|
||||
// Check first that the URL is absolute, then check that it is of different origin from the current.
|
||||
if (externalUrl) {
|
||||
// TODO: For Omni installation to authenticate and come back to the page where installation was initiated, some changes need to be done in all apps' add callbacks
|
||||
gotoUrl(json.url, json.newTab);
|
||||
return { setupPending: externalUrl };
|
||||
}
|
||||
|
||||
return { setupPending: externalUrl || json.url.endsWith("/setup") };
|
||||
}, options);
|
||||
},
|
||||
});
|
||||
|
||||
return mutation;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ function AlbySetupPage(props: IAlbySetupProps) {
|
||||
});
|
||||
}, [credentialId, props.clientId, props.clientSecret, saveKeysMutation]);
|
||||
|
||||
if (integrations.isLoading) {
|
||||
if (integrations.isPending) {
|
||||
return <div className="absolute z-50 flex h-screen w-full items-center bg-gray-200" />;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,22 +15,26 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
|
||||
const [selectedProject, setSelectedProject] = useState<undefined | { label: string; value: string }>();
|
||||
const { data } = trpc.viewer.appBasecamp3.projects.useQuery();
|
||||
const setProject = trpc.viewer.appBasecamp3.projectMutation.useMutation();
|
||||
useEffect(() => {
|
||||
setSelectedProject({
|
||||
value: data?.projects.currentProject,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
label: data?.projects?.find((project: any) => project.id === data?.currentProject)?.name,
|
||||
});
|
||||
setProjects(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
data?.projects?.map((project: any) => {
|
||||
return {
|
||||
value: project.id,
|
||||
label: project.name,
|
||||
};
|
||||
})
|
||||
);
|
||||
}, [data]);
|
||||
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
setSelectedProject({
|
||||
value: data?.projects.currentProject,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
label: data?.projects?.find((project: any) => project.id === data?.currentProject)?.name,
|
||||
});
|
||||
setProjects(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
data?.projects?.map((project: any) => {
|
||||
return {
|
||||
value: project.id,
|
||||
label: project.name,
|
||||
};
|
||||
})
|
||||
);
|
||||
},
|
||||
[data]
|
||||
);
|
||||
|
||||
return (
|
||||
<AppCard
|
||||
|
||||
@@ -34,7 +34,7 @@ export const InstallAppButtonWithoutPlanCheck = (
|
||||
onClick: () => {
|
||||
mutation.mutate({ type: props.type });
|
||||
},
|
||||
loading: mutation.isLoading,
|
||||
loading: mutation.isPending,
|
||||
})}
|
||||
</>
|
||||
);
|
||||
@@ -56,10 +56,10 @@ export const InstallAppButton = (
|
||||
disableInstall?: boolean;
|
||||
} & InstallAppButtonProps
|
||||
) => {
|
||||
const { isLoading: isUserLoading, data: user } = trpc.viewer.me.useQuery();
|
||||
const { isPending: isUserLoading, data: user } = trpc.viewer.me.useQuery();
|
||||
const router = useRouter();
|
||||
const proProtectionElementRef = useRef<HTMLDivElement | null>(null);
|
||||
const { isLoading: isTeamPlanStatusLoading, hasTeamPlan } = useHasTeamPlan();
|
||||
const { isPending: isTeamPlanStatusLoading, hasTeamPlan } = useHasTeamPlan();
|
||||
|
||||
useEffect(() => {
|
||||
const el = proProtectionElementRef.current;
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function InstallAppButton(props: InstallAppButtonProps) {
|
||||
onClick() {
|
||||
mutation.mutate("");
|
||||
},
|
||||
loading: mutation.isLoading,
|
||||
loading: mutation.isPending,
|
||||
})}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ export default function InstallAppButton(props: InstallAppButtonProps) {
|
||||
onClick() {
|
||||
mutation.mutate("");
|
||||
},
|
||||
loading: mutation.isLoading,
|
||||
loading: mutation.isPending,
|
||||
})}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -23,15 +23,15 @@ export const SearchDialog = (props: ISearchDialog) => {
|
||||
const [nextOffset, setNextOffset] = useState<number>(0);
|
||||
const [keyword, setKeyword] = useState<string>("");
|
||||
const { isOpenDialog, setIsOpenDialog } = props;
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
const [selectedMode, setSelectedMode] = useState<Mode>(MODE_SEARCH);
|
||||
|
||||
const searchGiphy = async (keyword: string, offset: number) => {
|
||||
if (isLoading) {
|
||||
if (isPending) {
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
setIsPending(true);
|
||||
setErrorMessage("");
|
||||
const res = await fetch("/api/integrations/giphy/search", {
|
||||
method: "POST",
|
||||
@@ -53,15 +53,15 @@ export const SearchDialog = (props: ISearchDialog) => {
|
||||
setErrorMessage("No Result found");
|
||||
}
|
||||
}
|
||||
setIsLoading(false);
|
||||
setIsPending(false);
|
||||
return null;
|
||||
};
|
||||
|
||||
const getGiphyByUrl = async (url: string) => {
|
||||
if (isLoading) {
|
||||
if (isPending) {
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
setIsPending(true);
|
||||
setErrorMessage("");
|
||||
const res = await fetch("/api/integrations/giphy/get", {
|
||||
method: "POST",
|
||||
@@ -81,7 +81,7 @@ export const SearchDialog = (props: ISearchDialog) => {
|
||||
setErrorMessage("No Result found");
|
||||
}
|
||||
}
|
||||
setIsLoading(false);
|
||||
setIsPending(false);
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -139,14 +139,14 @@ export const SearchDialog = (props: ISearchDialog) => {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Button type="submit" tabIndex={-1} color="secondary" loading={isLoading}>
|
||||
<Button type="submit" tabIndex={-1} color="secondary" loading={isPending}>
|
||||
{t("search")}
|
||||
</Button>
|
||||
</form>
|
||||
{gifImage && (
|
||||
<div className="flex flex-col items-center space-x-2 space-y-2 pt-3 rtl:space-x-reverse">
|
||||
<div className="bg-subtle flex w-full items-center justify-center">
|
||||
{isLoading ? (
|
||||
{isPending ? (
|
||||
<div className="flex h-[200px] w-full items-center justify-center bg-gray-400 pb-3 pt-3">
|
||||
<svg
|
||||
className={classNames("mx-4 h-5 w-5 animate-spin", "text-inverted dark:text-emphasis")}
|
||||
@@ -182,7 +182,7 @@ export const SearchDialog = (props: ISearchDialog) => {
|
||||
size="sm"
|
||||
color="secondary"
|
||||
type="button"
|
||||
loading={isLoading}
|
||||
loading={isPending}
|
||||
onClick={() => searchGiphy(keyword, nextOffset)}>
|
||||
Shuffle
|
||||
</Button>
|
||||
|
||||
@@ -59,7 +59,7 @@ export default function MakeSetup({ inviteLink }: InferGetServerSidePropsType<ty
|
||||
setNewApiKeys({ ...newApiKeys, [teamId || ""]: apiKey });
|
||||
}
|
||||
|
||||
if (integrations.isLoading) {
|
||||
if (integrations.isPending) {
|
||||
return <div className="bg-emphasis absolute z-50 flex h-screen w-full items-center" />;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export default function PayPalSetup() {
|
||||
},
|
||||
});
|
||||
|
||||
if (integrations.isLoading) {
|
||||
if (integrations.isPending) {
|
||||
return <div className="absolute z-50 flex h-screen w-full items-center bg-gray-200" />;
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ function NewFormDialog({ appUrl }: { appUrl: string }) {
|
||||
</div>
|
||||
<DialogFooter showDivider className="mt-12">
|
||||
<DialogClose />
|
||||
<Button loading={mutation.isLoading} data-testid="add-form" type="submit">
|
||||
<Button loading={mutation.isPending} data-testid="add-form" type="submit">
|
||||
{t("continue")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
@@ -234,7 +234,7 @@ function Dialogs({
|
||||
<RoutingFormEmbedDialog />
|
||||
<Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
|
||||
<ConfirmationDialogContent
|
||||
isLoading={deleteMutation.isLoading}
|
||||
isPending={deleteMutation.isPending}
|
||||
variety="danger"
|
||||
title={t("delete_form")}
|
||||
confirmBtnText={t("delete_form_action")}
|
||||
@@ -264,12 +264,12 @@ const actionsCtx = createContext({
|
||||
_delete: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
|
||||
onAction: (_arg: { routingForm: RoutingForm | null }) => {},
|
||||
isLoading: false,
|
||||
isPending: false,
|
||||
},
|
||||
toggle: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
|
||||
onAction: (_arg: { routingForm: RoutingForm | null; checked: boolean }) => {},
|
||||
isLoading: false,
|
||||
isPending: false,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -332,7 +332,7 @@ export function FormActionsProvider({ appUrl, children }: { appUrl: string; chil
|
||||
setDeleteDialogOpen(true);
|
||||
setDeleteDialogFormId(routingForm.id);
|
||||
},
|
||||
isLoading: false,
|
||||
isPending: false,
|
||||
},
|
||||
toggle: {
|
||||
onAction: ({ routingForm, checked }) => {
|
||||
@@ -344,7 +344,7 @@ export function FormActionsProvider({ appUrl, children }: { appUrl: string; chil
|
||||
disabled: !checked,
|
||||
});
|
||||
},
|
||||
isLoading: toggleMutation.isLoading,
|
||||
isPending: toggleMutation.isPending,
|
||||
},
|
||||
}}>
|
||||
{children}
|
||||
@@ -446,7 +446,7 @@ export const FormAction = forwardRef(function FormAction<T extends typeof Button
|
||||
},
|
||||
_delete: {
|
||||
onClick: () => _delete.onAction({ routingForm }),
|
||||
loading: _delete.isLoading,
|
||||
loading: _delete.isPending,
|
||||
},
|
||||
create: {
|
||||
onClick: () => openModal({ action: "new", target: "" }),
|
||||
@@ -479,7 +479,7 @@ export const FormAction = forwardRef(function FormAction<T extends typeof Button
|
||||
</div>
|
||||
);
|
||||
},
|
||||
loading: toggle.isLoading,
|
||||
loading: toggle.isPending,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ const Actions = ({
|
||||
}: {
|
||||
form: RoutingFormWithResponseCount;
|
||||
mutation: {
|
||||
isLoading: boolean;
|
||||
isPending: boolean;
|
||||
};
|
||||
}) => {
|
||||
const { t } = useLocale();
|
||||
@@ -218,7 +218,7 @@ const Actions = ({
|
||||
</FormActionsDropdown>
|
||||
</div>
|
||||
<VerticalDivider />
|
||||
<Button data-testid="update-form" loading={mutation.isLoading} type="submit" color="primary">
|
||||
<Button data-testid="update-form" loading={mutation.isPending} type="submit" color="primary">
|
||||
{t("save")}
|
||||
</Button>
|
||||
</div>
|
||||
@@ -518,7 +518,7 @@ function SingleForm({ form, appUrl, Page }: SingleFormComponentProps) {
|
||||
}
|
||||
|
||||
export default function SingleFormWrapper({ form: _form, ...props }: SingleFormComponentProps) {
|
||||
const { data: form, isLoading } = trpc.viewer.appRoutingForms.formQuery.useQuery(
|
||||
const { data: form, isPending } = trpc.viewer.appRoutingForms.formQuery.useQuery(
|
||||
{ id: _form.id },
|
||||
{
|
||||
initialData: _form,
|
||||
@@ -527,7 +527,7 @@ export default function SingleFormWrapper({ form: _form, ...props }: SingleFormC
|
||||
);
|
||||
const { t } = useLocale();
|
||||
|
||||
if (isLoading) {
|
||||
if (isPending) {
|
||||
// It shouldn't be possible because we are passing the data from SSR to it as initialData. So, no need for skeleton here
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ type QueryBuilderUpdatedConfig = typeof QueryBuilderInitialConfig & { fields: Co
|
||||
const Result = ({ formId, jsonLogicQuery }: { formId: string; jsonLogicQuery: JsonLogicQuery | null }) => {
|
||||
const { t } = useLocale();
|
||||
|
||||
const { isLoading, status, data, isFetching, error, isFetchingNextPage, hasNextPage, fetchNextPage } =
|
||||
const { isPending, status, data, isFetching, error, isFetchingNextPage, hasNextPage, fetchNextPage } =
|
||||
trpc.viewer.appRoutingForms.report.useInfiniteQuery(
|
||||
{
|
||||
formId: formId,
|
||||
@@ -57,7 +57,7 @@ const Result = ({ formId, jsonLogicQuery }: { formId: string; jsonLogicQuery: Js
|
||||
|
||||
const headers = useRef<string[] | null>(null);
|
||||
|
||||
if (!isLoading && !data) {
|
||||
if (!isPending && !data) {
|
||||
return <div>Error loading report {error?.message} </div>;
|
||||
}
|
||||
headers.current = (data?.pages && data?.pages[0]?.headers) || headers.current;
|
||||
@@ -81,7 +81,7 @@ const Result = ({ formId, jsonLogicQuery }: { formId: string; jsonLogicQuery: Js
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
{!isLoading &&
|
||||
{!isPending &&
|
||||
data?.pages.map((page) => {
|
||||
return page.responses?.map((responses, rowIndex) => {
|
||||
const isLastRow = page.responses.length - 1 === rowIndex;
|
||||
@@ -113,7 +113,7 @@ const Result = ({ formId, jsonLogicQuery }: { formId: string; jsonLogicQuery: Js
|
||||
});
|
||||
})}
|
||||
</table>
|
||||
{isLoading ? <div className="text-default p-2">{t("loading")}</div> : ""}
|
||||
{isPending ? <div className="text-default p-2">{t("loading")}</div> : ""}
|
||||
{hasNextPage && (
|
||||
<Button
|
||||
type="button"
|
||||
|
||||
@@ -153,7 +153,7 @@ function RoutingForm({ form, profile, ...restProps }: Props) {
|
||||
<div className="mt-4 flex justify-end space-x-2 rtl:space-x-reverse">
|
||||
<Button
|
||||
className="dark:bg-darkmodebrand dark:text-darkmodebrandcontrast dark:hover:border-darkmodebrandcontrast dark:border-transparent"
|
||||
loading={responseMutation.isLoading}
|
||||
loading={responseMutation.isPending}
|
||||
type="submit"
|
||||
color="primary">
|
||||
{t("submit")}
|
||||
|
||||
Vendored
+1
-1
@@ -35,7 +35,7 @@ export interface InstallAppButtonProps {
|
||||
renderProps: ButtonProps & {
|
||||
/** Tells that the default render component should be used */
|
||||
useDefaultComponent?: boolean;
|
||||
isLoading?: boolean;
|
||||
isPending?: boolean;
|
||||
}
|
||||
) => JSX.Element;
|
||||
onChanged?: () => unknown;
|
||||
|
||||
@@ -44,7 +44,7 @@ const wipeMyCalAction = async (props: IWipeMyCalAction) => {
|
||||
export const ConfirmDialog = (props: IConfirmDialogWipe) => {
|
||||
const { t } = useLocale();
|
||||
const { isOpenDialog, setIsOpenDialog } = props;
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
const today = dayjs();
|
||||
const initialDate = today.startOf("day");
|
||||
const endDate = today.endOf("day");
|
||||
@@ -52,9 +52,9 @@ export const ConfirmDialog = (props: IConfirmDialogWipe) => {
|
||||
|
||||
const utils = trpc.useContext();
|
||||
|
||||
const rescheduleApi = useMutation(
|
||||
async () => {
|
||||
setIsLoading(true);
|
||||
const rescheduleApi = useMutation({
|
||||
mutationFn: async () => {
|
||||
setIsPending(true);
|
||||
try {
|
||||
const result = await wipeMyCalAction({
|
||||
initialDate: initialDate.toISOString(),
|
||||
@@ -68,14 +68,12 @@ export const ConfirmDialog = (props: IConfirmDialogWipe) => {
|
||||
showToast(t("unexpected_error_try_again"), "error");
|
||||
// @TODO: notify
|
||||
}
|
||||
setIsLoading(false);
|
||||
setIsPending(false);
|
||||
},
|
||||
{
|
||||
async onSettled() {
|
||||
await utils.viewer.bookings.invalidate();
|
||||
},
|
||||
}
|
||||
);
|
||||
async onSettled() {
|
||||
await utils.viewer.bookings.invalidate();
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<Dialog open={isOpenDialog} onOpenChange={setIsOpenDialog}>
|
||||
@@ -104,7 +102,7 @@ export const ConfirmDialog = (props: IConfirmDialogWipe) => {
|
||||
<Button
|
||||
color="primary"
|
||||
data-testid="send_request"
|
||||
disabled={isLoading}
|
||||
disabled={isPending}
|
||||
onClick={async () => {
|
||||
try {
|
||||
rescheduleApi.mutate();
|
||||
|
||||
@@ -13,7 +13,7 @@ interface IWipeMyCalActionButtonProps {
|
||||
const WipeMyCalActionButton = (props: IWipeMyCalActionButtonProps) => {
|
||||
const { bookingsEmpty, bookingStatus } = props;
|
||||
const [openDialog, setOpenDialog] = useState(false);
|
||||
const { isSuccess, isLoading, data } = trpc.viewer.integrations.useQuery({
|
||||
const { isSuccess, isPending, data } = trpc.viewer.integrations.useQuery({
|
||||
variant: "other",
|
||||
onlyInstalled: undefined,
|
||||
});
|
||||
@@ -27,7 +27,7 @@ const WipeMyCalActionButton = (props: IWipeMyCalActionButtonProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{data && isSuccess && !isLoading && credentialId && (
|
||||
{data && isSuccess && !isPending && credentialId && (
|
||||
<div className="mb-4">
|
||||
<ConfirmDialog isOpenDialog={openDialog} setIsOpenDialog={setOpenDialog} />
|
||||
<Button color="primary" onClick={() => setOpenDialog(true)} data-testid="wipe-today-button">
|
||||
|
||||
@@ -60,7 +60,7 @@ export default function ZapierSetup(props: IZapierSetupProps) {
|
||||
setNewApiKeys({ ...newApiKeys, [teamId || ""]: apiKey });
|
||||
}
|
||||
|
||||
if (integrations.isLoading) {
|
||||
if (integrations.isPending) {
|
||||
return <div className="bg-emphasis absolute z-50 flex h-screen w-full items-center" />;
|
||||
}
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ const AdminAppsListContainer = () => {
|
||||
const { t } = useLocale();
|
||||
const category = searchParams?.get("category") || AppCategories.calendar;
|
||||
|
||||
const { data: apps, isLoading } = trpc.viewer.appsRouter.listLocal.useQuery(
|
||||
const { data: apps, isPending } = trpc.viewer.appsRouter.listLocal.useQuery(
|
||||
{ category },
|
||||
{ enabled: searchParams !== null }
|
||||
);
|
||||
@@ -291,7 +291,7 @@ const AdminAppsListContainer = () => {
|
||||
|
||||
const handleModelOpen = (data: EditModalState) => setModalState({ ...data });
|
||||
|
||||
if (isLoading) return <SkeletonLoader />;
|
||||
if (isPending) return <SkeletonLoader />;
|
||||
|
||||
if (!apps || apps.length === 0) {
|
||||
return (
|
||||
|
||||
@@ -207,7 +207,7 @@ const BookerComponent = ({
|
||||
} = useCalendars();
|
||||
|
||||
useEffect(() => {
|
||||
if (event.isLoading) return setBookerState("loading");
|
||||
if (event.isPending) return setBookerState("loading");
|
||||
if (!selectedDate) return setBookerState("selecting_date");
|
||||
if (!selectedTimeslot) return setBookerState("selecting_time");
|
||||
return setBookerState("booking");
|
||||
@@ -399,7 +399,7 @@ const BookerComponent = ({
|
||||
<BookerSection
|
||||
area="meta"
|
||||
className="max-w-screen flex w-full flex-col md:w-[var(--booker-meta-width)]">
|
||||
<EventMeta event={event.data} isLoading={event.isLoading} />
|
||||
<EventMeta event={event.data} isPending={event.isPending} />
|
||||
{layout !== BookerLayouts.MONTH_VIEW &&
|
||||
!(layout === "mobile" && bookerState === "booking") && (
|
||||
<div className="mt-auto px-5 py-3 ">
|
||||
@@ -434,7 +434,7 @@ const BookerComponent = ({
|
||||
visible={layout === BookerLayouts.WEEK_VIEW}
|
||||
className="border-subtle sticky top-0 ml-[-1px] h-full md:border-l"
|
||||
{...fadeInLeft}>
|
||||
<LargeCalendar extraDays={extraDays} schedule={schedule.data} isLoading={schedule.isLoading} />
|
||||
<LargeCalendar extraDays={extraDays} schedule={schedule.data} isLoading={schedule.isPending} />
|
||||
</BookerSection>
|
||||
|
||||
<BookerSection
|
||||
@@ -456,7 +456,7 @@ const BookerComponent = ({
|
||||
extraDays={extraDays}
|
||||
limitHeight={layout === BookerLayouts.MONTH_VIEW}
|
||||
schedule={schedule?.data}
|
||||
isLoading={schedule.isLoading}
|
||||
isLoading={schedule.isPending}
|
||||
seatsPerTimeSlot={event.data?.seatsPerTimeSlot}
|
||||
showAvailableSeatsCount={event.data?.seatsShowAvailabilityCount}
|
||||
/>
|
||||
|
||||
@@ -63,7 +63,7 @@ export const BookEventForm = ({
|
||||
}, [eventType]);
|
||||
|
||||
if (eventQuery.isError) return <Alert severity="warning" message={t("error_booking_event")} />;
|
||||
if (eventQuery.isLoading || !eventQuery.data) return <FormSkeleton />;
|
||||
if (eventQuery.isPending || !eventQuery.data) return <FormSkeleton />;
|
||||
if (!timeslot)
|
||||
return (
|
||||
<EmptyScreen
|
||||
|
||||
@@ -27,7 +27,7 @@ export const DatePicker = ({
|
||||
|
||||
return (
|
||||
<DatePickerComponent
|
||||
isLoading={schedule.isLoading}
|
||||
isPending={schedule.isPending}
|
||||
onChange={(date: Dayjs | null) => {
|
||||
setSelectedDate(date === null ? date : date.format("YYYY-MM-DD"));
|
||||
}}
|
||||
|
||||
@@ -24,10 +24,10 @@ const TimezoneSelect = dynamic(
|
||||
|
||||
export const EventMeta = ({
|
||||
event,
|
||||
isLoading,
|
||||
isPending,
|
||||
}: {
|
||||
event: useEventReturnType["data"];
|
||||
isLoading: useEventReturnType["isLoading"];
|
||||
isPending: useEventReturnType["isPending"];
|
||||
}) => {
|
||||
const { setTimezone, timeFormat, timezone } = useTimePreferences();
|
||||
const selectedDuration = useBookerStore((state) => state.selectedDuration);
|
||||
@@ -40,7 +40,6 @@ export const EventMeta = ({
|
||||
shallow
|
||||
);
|
||||
const { i18n, t } = useLocale();
|
||||
|
||||
const embedUiConfig = useEmbedUiConfig();
|
||||
const isEmbed = useIsEmbed();
|
||||
const hideEventTypeDetails = isEmbed ? embedUiConfig.hideEventTypeDetails : false;
|
||||
@@ -66,12 +65,12 @@ export const EventMeta = ({
|
||||
|
||||
return (
|
||||
<div className="relative z-10 p-6" data-testid="event-meta">
|
||||
{isLoading && (
|
||||
{isPending && (
|
||||
<m.div {...fadeInUp} initial="visible" layout>
|
||||
<EventMetaSkeleton />
|
||||
</m.div>
|
||||
)}
|
||||
{!isLoading && !!event && (
|
||||
{!isPending && !!event && (
|
||||
<m.div {...fadeInUp} layout transition={{ ...fadeInUp.transition, delay: 0.3 }}>
|
||||
<EventMembers
|
||||
schedulingType={event.schedulingType}
|
||||
|
||||
@@ -74,7 +74,7 @@ export const LargeCalendar = ({
|
||||
return (
|
||||
<div className="h-full [--calendar-dates-sticky-offset:66px]">
|
||||
<Calendar
|
||||
isLoading={isLoading}
|
||||
isPending={isLoading}
|
||||
availableTimeslots={availableSlots}
|
||||
startHour={0}
|
||||
endHour={23}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useRef, useState } from "react";
|
||||
import { useRef, useState, useEffect } from "react";
|
||||
|
||||
import { createPaymentLink } from "@calcom/app-store/stripepayment/lib/client";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
@@ -74,27 +74,33 @@ export const useBookings = ({ event, hashedLink, bookingForm }: IUseBookings) =>
|
||||
enabled: !!bookingId && !hasInstantMeetingTokenExpired,
|
||||
refetchInterval: 2000,
|
||||
refetchIntervalInBackground: true,
|
||||
onSuccess: (data) => {
|
||||
try {
|
||||
showToast(t("something_went_wrong_on_our_end"), "error");
|
||||
|
||||
const locationVideoCallUrl: string | undefined = bookingMetadataSchema.parse(
|
||||
data.booking?.metadata || {}
|
||||
)?.videoCallUrl;
|
||||
|
||||
if (locationVideoCallUrl) {
|
||||
router.push(locationVideoCallUrl);
|
||||
} else {
|
||||
showToast(t("something_went_wrong_on_our_end"), "error");
|
||||
}
|
||||
} catch (err) {
|
||||
showToast(t("something_went_wrong_on_our_end"), "error");
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
const data = _instantBooking.data;
|
||||
if (!data) return;
|
||||
try {
|
||||
showToast(t("something_went_wrong_on_our_end"), "error");
|
||||
|
||||
const createBookingMutation = useMutation(createBooking, {
|
||||
const locationVideoCallUrl: string | undefined = bookingMetadataSchema.parse(
|
||||
data.booking?.metadata || {}
|
||||
)?.videoCallUrl;
|
||||
|
||||
if (locationVideoCallUrl) {
|
||||
router.push(locationVideoCallUrl);
|
||||
} else {
|
||||
showToast(t("something_went_wrong_on_our_end"), "error");
|
||||
}
|
||||
} catch (err) {
|
||||
showToast(t("something_went_wrong_on_our_end"), "error");
|
||||
}
|
||||
},
|
||||
[_instantBooking.data]
|
||||
);
|
||||
|
||||
const createBookingMutation = useMutation({
|
||||
mutationFn: createBooking,
|
||||
onSuccess: (responseData) => {
|
||||
const { uid, paymentUid } = responseData;
|
||||
const fullName = getFullName(bookingForm.getValues("responses.name"));
|
||||
@@ -141,7 +147,8 @@ export const useBookings = ({ event, hashedLink, bookingForm }: IUseBookings) =>
|
||||
},
|
||||
});
|
||||
|
||||
const createInstantBookingMutation = useMutation(createInstantBooking, {
|
||||
const createInstantBookingMutation = useMutation({
|
||||
mutationFn: createInstantBooking,
|
||||
onSuccess: (responseData) => {
|
||||
updateQueryParam("bookingId", responseData.bookingId);
|
||||
setExpiryTime(responseData.expires);
|
||||
@@ -153,7 +160,8 @@ export const useBookings = ({ event, hashedLink, bookingForm }: IUseBookings) =>
|
||||
},
|
||||
});
|
||||
|
||||
const createRecurringBookingMutation = useMutation(createRecurringBooking, {
|
||||
const createRecurringBookingMutation = useMutation({
|
||||
mutationFn: createRecurringBooking,
|
||||
onSuccess: async (responseData) => {
|
||||
const booking = responseData[0] || {};
|
||||
const { uid } = booking;
|
||||
@@ -253,10 +261,10 @@ export const useBookings = ({ event, hashedLink, bookingForm }: IUseBookings) =>
|
||||
|
||||
// A redirect is triggered on mutation success, so keep the loading state while it is happening.
|
||||
const loadingStates = {
|
||||
creatingBooking: createBookingMutation.isLoading || createBookingMutation.isSuccess,
|
||||
creatingBooking: createBookingMutation.isPending || createBookingMutation.isSuccess,
|
||||
creatingRecurringBooking:
|
||||
createRecurringBookingMutation.isLoading || createRecurringBookingMutation.isSuccess,
|
||||
creatingInstantBooking: createInstantBookingMutation.isLoading,
|
||||
createRecurringBookingMutation.isPending || createRecurringBookingMutation.isSuccess,
|
||||
creatingInstantBooking: createInstantBookingMutation.isPending,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
import { shallow } from "zustand/shallow";
|
||||
|
||||
import { useTimePreferences } from "@calcom/features/bookings/lib";
|
||||
@@ -30,7 +31,7 @@ export const useCalendars = () => {
|
||||
shallow
|
||||
);
|
||||
|
||||
const { data: overlayBusyDates } = trpc.viewer.availability.calendarOverlay.useQuery(
|
||||
const { data: overlayBusyDates, isError } = trpc.viewer.availability.calendarOverlay.useQuery(
|
||||
{
|
||||
loggedInUsersTz: timezone || "Europe/London",
|
||||
dateFrom: selectedDate,
|
||||
@@ -42,13 +43,18 @@ export const useCalendars = () => {
|
||||
},
|
||||
{
|
||||
enabled: !!session && set.size > 0 && switchEnabled,
|
||||
onError: () => {
|
||||
clearSet();
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const { data, isLoading } = trpc.viewer.connectedCalendars.useQuery(undefined, {
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (!isError) return;
|
||||
clearSet();
|
||||
},
|
||||
[isError]
|
||||
);
|
||||
|
||||
const { data, isPending } = trpc.viewer.connectedCalendars.useQuery(undefined, {
|
||||
enabled: !!calendarSettingsOverlay || Boolean(searchParams?.get("overlayCalendar")),
|
||||
});
|
||||
|
||||
@@ -56,7 +62,7 @@ export const useCalendars = () => {
|
||||
overlayBusyDates,
|
||||
isOverlayCalendarEnabled: switchEnabled,
|
||||
connectedCalendars: data?.connectedCalendars || [],
|
||||
loadingConnectedCalendar: isLoading,
|
||||
loadingConnectedCalendar: isPending,
|
||||
onToggleCalendar: () => {
|
||||
utils.viewer.availability.calendarOverlay.reset();
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useSession } from "next-auth/react";
|
||||
import { Fragment, useState } from "react";
|
||||
import { Fragment, useMemo } from "react";
|
||||
|
||||
import {
|
||||
FilterCheckboxFieldsContainer,
|
||||
@@ -36,24 +36,24 @@ export const EventTypeFilter = () => {
|
||||
const { data: user } = useSession();
|
||||
const { data: query, pushItemToKey, removeItemByKeyAndValue, removeAllQueryParams } = useFilterQuery();
|
||||
|
||||
const [groupedEventTypes, setGroupedEventTypes] = useState<GroupedEventTypeState>();
|
||||
|
||||
const eventTypes = trpc.viewer.eventTypes.listWithTeam.useQuery(undefined, {
|
||||
onSuccess: (data) => {
|
||||
// Will be handled up the tree to redirect
|
||||
// Group event types by team
|
||||
const grouped = groupBy<IEventTypeFilter>(
|
||||
data.filter((el) => el.team),
|
||||
(item) => item?.team?.name || ""
|
||||
); // Add the team name
|
||||
const individualEvents = data.filter((el) => !el.team);
|
||||
// push indivdual events to the start of grouped array
|
||||
setGroupedEventTypes(
|
||||
individualEvents.length > 0 ? { user_own_event_types: individualEvents, ...grouped } : grouped
|
||||
);
|
||||
},
|
||||
enabled: !!user,
|
||||
});
|
||||
const groupedEventTypes: GroupedEventTypeState | null = useMemo(() => {
|
||||
const data = eventTypes.data;
|
||||
if (!data) {
|
||||
return null;
|
||||
}
|
||||
// Will be handled up the tree to redirect
|
||||
// Group event types by team
|
||||
const grouped = groupBy<IEventTypeFilter>(
|
||||
data.filter((el) => el.team),
|
||||
(item) => item?.team?.name || ""
|
||||
); // Add the team name
|
||||
const individualEvents = data.filter((el) => !el.team);
|
||||
// push indivdual events to the start of grouped array
|
||||
return individualEvents.length > 0 ? { user_own_event_types: individualEvents, ...grouped } : grouped;
|
||||
}, [eventTypes.data]);
|
||||
|
||||
if (!eventTypes.data) return null;
|
||||
const isEmpty = eventTypes.data.length === 0;
|
||||
|
||||
@@ -30,8 +30,8 @@ export const VerifyCodeDialog = ({
|
||||
isUserSessionRequiredToVerify?: boolean;
|
||||
}) => {
|
||||
const { t } = useLocale();
|
||||
// Not using the mutation isLoading flag because after verifying we submit the underlying org creation form
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
// Not using the mutation isPending flag because after verifying we submit the underlying org creation form
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const [value, setValue] = useState("");
|
||||
const [hasVerified, setHasVerified] = useState(false);
|
||||
@@ -49,11 +49,11 @@ export const VerifyCodeDialog = ({
|
||||
|
||||
const verifyCodeMutationUserSessionRequired = trpc.viewer.organizations.verifyCode.useMutation({
|
||||
onSuccess: (data) => {
|
||||
setIsLoading(false);
|
||||
setIsPending(false);
|
||||
onSuccess(data);
|
||||
},
|
||||
onError: (err) => {
|
||||
setIsLoading(false);
|
||||
setIsPending(false);
|
||||
setHasVerified(false);
|
||||
if (err.message === "invalid_code") {
|
||||
setError(t("code_provided_invalid"));
|
||||
@@ -63,11 +63,11 @@ export const VerifyCodeDialog = ({
|
||||
|
||||
const verifyCodeMutationUserSessionNotRequired = trpc.viewer.auth.verifyCodeUnAuthenticated.useMutation({
|
||||
onSuccess: (data) => {
|
||||
setIsLoading(false);
|
||||
setIsPending(false);
|
||||
onSuccess(data);
|
||||
},
|
||||
onError: (err) => {
|
||||
setIsLoading(false);
|
||||
setIsPending(false);
|
||||
setHasVerified(false);
|
||||
if (err.message === "invalid_code") {
|
||||
setError(t("code_provided_invalid"));
|
||||
@@ -77,7 +77,7 @@ export const VerifyCodeDialog = ({
|
||||
|
||||
const verifyCode = useCallback(() => {
|
||||
setError("");
|
||||
setIsLoading(true);
|
||||
setIsPending(true);
|
||||
if (isUserSessionRequiredToVerify) {
|
||||
verifyCodeMutationUserSessionRequired.mutate({
|
||||
code: value,
|
||||
@@ -102,10 +102,10 @@ export const VerifyCodeDialog = ({
|
||||
// trim the input value because "react-digit-input" creates a string of the given length,
|
||||
// even when some digits are missing. And finally we use regex to check if the value consists
|
||||
// of 6 non-empty digits.
|
||||
if (hasVerified || error || isLoading || !/^\d{6}$/.test(value.trim())) return;
|
||||
if (hasVerified || error || isPending || !/^\d{6}$/.test(value.trim())) return;
|
||||
|
||||
verifyCode();
|
||||
}, [error, isLoading, value, verifyCode, hasVerified]);
|
||||
}, [error, isPending, value, verifyCode, hasVerified]);
|
||||
|
||||
useEffect(() => setValue(""), [isOpenDialog]);
|
||||
|
||||
@@ -149,7 +149,7 @@ export const VerifyCodeDialog = ({
|
||||
)}
|
||||
<DialogFooter>
|
||||
<DialogClose />
|
||||
<Button type="submit" onClick={verifyCode} loading={isLoading}>
|
||||
<Button type="submit" onClick={verifyCode} loading={isPending}>
|
||||
{t("submit")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
|
||||
@@ -22,14 +22,8 @@ const CalendarSwitch = (props: ICalendarSwitchProps) => {
|
||||
const [checkedInternal, setCheckedInternal] = useState(isChecked);
|
||||
const utils = trpc.useContext();
|
||||
const { t } = useLocale();
|
||||
const mutation = useMutation<
|
||||
unknown,
|
||||
unknown,
|
||||
{
|
||||
isOn: boolean;
|
||||
}
|
||||
>(
|
||||
async ({ isOn }: { isOn: boolean }) => {
|
||||
const mutation = useMutation({
|
||||
mutationFn: async ({ isOn }: { isOn: boolean }) => {
|
||||
const body = {
|
||||
integration: type,
|
||||
externalId: externalId,
|
||||
@@ -60,24 +54,22 @@ const CalendarSwitch = (props: ICalendarSwitchProps) => {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
async onSettled() {
|
||||
await utils.viewer.integrations.invalidate();
|
||||
await utils.viewer.connectedCalendars.invalidate();
|
||||
},
|
||||
onError() {
|
||||
setCheckedInternal(false);
|
||||
showToast(`Something went wrong when toggling "${title}"`, "error");
|
||||
},
|
||||
}
|
||||
);
|
||||
async onSettled() {
|
||||
await utils.viewer.integrations.invalidate();
|
||||
await utils.viewer.connectedCalendars.invalidate();
|
||||
},
|
||||
onError() {
|
||||
setCheckedInternal(false);
|
||||
showToast(`Something went wrong when toggling "${title}"`, "error");
|
||||
},
|
||||
});
|
||||
return (
|
||||
<div className={classNames("my-2 flex flex-row items-center")}>
|
||||
<div className="flex pl-2">
|
||||
<Switch
|
||||
id={externalId}
|
||||
checked={checkedInternal}
|
||||
disabled={mutation.isLoading}
|
||||
disabled={mutation.isPending}
|
||||
onCheckedChange={async (isOn: boolean) => {
|
||||
setCheckedInternal(isOn);
|
||||
await mutation.mutate({ isOn });
|
||||
@@ -93,7 +85,7 @@ const CalendarSwitch = (props: ICalendarSwitchProps) => {
|
||||
{t("adding_events_to")}
|
||||
</span>
|
||||
)}
|
||||
{mutation.isLoading && <RotateCw className="text-muted h-4 w-4 animate-spin ltr:ml-1 rtl:mr-1" />}
|
||||
{mutation.isPending && <RotateCw className="text-muted h-4 w-4 animate-spin ltr:ml-1 rtl:mr-1" />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ export type DatePickerProps = {
|
||||
/** allows adding classes to the container */
|
||||
className?: string;
|
||||
/** Shows a small loading spinner next to the month name */
|
||||
isLoading?: boolean;
|
||||
isPending?: boolean;
|
||||
/** used to query the multiple selected dates */
|
||||
eventSlug?: string;
|
||||
};
|
||||
@@ -206,7 +206,7 @@ const Days = ({
|
||||
<div key={day === null ? `e-${idx}` : `day-${day.format()}`} className="relative w-full pt-[100%]">
|
||||
{day === null ? (
|
||||
<div key={`e-${idx}`} />
|
||||
) : props.isLoading ? (
|
||||
) : props.isPending ? (
|
||||
<button
|
||||
className="bg-muted text-muted absolute bottom-0 left-0 right-0 top-0 mx-auto flex w-full items-center justify-center rounded-sm border-transparent text-center font-medium opacity-50"
|
||||
key={`e-${idx}`}
|
||||
@@ -226,7 +226,7 @@ const Days = ({
|
||||
</div>
|
||||
))}
|
||||
|
||||
{!props.isLoading && includedDates && includedDates?.length === 0 && (
|
||||
{!props.isPending && includedDates && includedDates?.length === 0 && (
|
||||
<NoAvailabilityOverlay month={month} nextMonthButton={nextMonthButton} />
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Check } from "@calcom/ui/components/icon";
|
||||
|
||||
interface Props {
|
||||
onChange: (value: { externalId: string; integration: string }) => void;
|
||||
isLoading?: boolean;
|
||||
isPending?: boolean;
|
||||
hidePlaceholder?: boolean;
|
||||
/** The external Id of the connected calendar */
|
||||
destinationCalendar?: DestinationCalendar | null;
|
||||
@@ -49,7 +49,7 @@ const OptionComponent = ({ ...props }: OptionProps<Option>) => {
|
||||
|
||||
const DestinationCalendarSelector = ({
|
||||
onChange,
|
||||
isLoading,
|
||||
isPending,
|
||||
value,
|
||||
hidePlaceholder,
|
||||
hideAdvancedText,
|
||||
@@ -173,7 +173,7 @@ const DestinationCalendarSelector = ({
|
||||
externalId,
|
||||
});
|
||||
}}
|
||||
isLoading={isLoading}
|
||||
isLoading={isPending}
|
||||
value={selectedOption}
|
||||
components={{ SingleValue: SingleValueComponent, Option: OptionComponent }}
|
||||
isMulti={false}
|
||||
|
||||
@@ -43,7 +43,7 @@ DatePicker component offers a complete and customizable element for the user to
|
||||
minDate: dayjs("2023-07-23").utc(),
|
||||
maxDate: dayjs("2023-08-30").utc(),
|
||||
selected: dayjs("2023-08-30").utc(),
|
||||
isLoading: false,
|
||||
isPending: false,
|
||||
onChange: (newDate) => console.log(newDate),
|
||||
onMonthChange: (newMonth) => console.log(newMonth),
|
||||
}}
|
||||
@@ -58,7 +58,7 @@ DatePicker component offers a complete and customizable element for the user to
|
||||
control: "date"
|
||||
}
|
||||
}}>
|
||||
{({ weekStart, excludedDates, onChange, onMonthChange, minDate, maxDate, selected, isLoading }) => (
|
||||
{({ weekStart, excludedDates, onChange, onMonthChange, minDate, maxDate, selected, isPending }) => (
|
||||
<VariantsTable titles={["Default"]} columnMinWidth={150}>
|
||||
<VariantRow variant="Default">
|
||||
<DatePicker
|
||||
@@ -69,7 +69,7 @@ DatePicker component offers a complete and customizable element for the user to
|
||||
onChange={onChange}
|
||||
onMonthChange={onMonthChange}
|
||||
selected={dayjs(selected)}
|
||||
isLoading={isLoading}
|
||||
isPending={isPending}
|
||||
/>
|
||||
</VariantRow>
|
||||
</VariantsTable>
|
||||
|
||||
@@ -58,7 +58,7 @@ export function Calendar(props: CalendarComponentProps) {
|
||||
} as React.CSSProperties // This can't live in the css file because it's a dynamic value and css variable gets super
|
||||
}>
|
||||
{hideHeader !== true && <SchedulerHeading />}
|
||||
{props.isLoading && <Spinner />}
|
||||
{props.isPending && <Spinner />}
|
||||
<div
|
||||
ref={container}
|
||||
className="bg-default dark:bg-muted relative isolate flex h-full flex-auto flex-col">
|
||||
|
||||
@@ -121,6 +121,6 @@ export type CalendarState = {
|
||||
hideHeader?: boolean;
|
||||
};
|
||||
|
||||
export type CalendarComponentProps = CalendarPublicActions & CalendarState & { isLoading?: boolean };
|
||||
export type CalendarComponentProps = CalendarPublicActions & CalendarState & { isPending?: boolean };
|
||||
|
||||
export type CalendarStoreProps = CalendarComponentProps & CalendarPrivateActions;
|
||||
|
||||
@@ -82,7 +82,7 @@ const ApiKeyListItem = ({
|
||||
<DropdownItem
|
||||
type="button"
|
||||
color="destructive"
|
||||
disabled={deleteApiKey.isLoading}
|
||||
disabled={deleteApiKey.isPending}
|
||||
onClick={() =>
|
||||
deleteApiKey.mutate({
|
||||
id: apiKey.id,
|
||||
|
||||
@@ -43,7 +43,7 @@ export const AboutOrganizationForm = () => {
|
||||
form={aboutOrganizationFormMethods}
|
||||
className="space-y-5"
|
||||
handleSubmit={(v) => {
|
||||
if (!updateOrganizationMutation.isLoading) {
|
||||
if (!updateOrganizationMutation.isPending) {
|
||||
setServerErrorMessage(null);
|
||||
updateOrganizationMutation.mutate({ ...v, orgId });
|
||||
}
|
||||
@@ -109,7 +109,7 @@ export const AboutOrganizationForm = () => {
|
||||
<div className="flex">
|
||||
<Button
|
||||
disabled={
|
||||
aboutOrganizationFormMethods.formState.isSubmitting || updateOrganizationMutation.isLoading
|
||||
aboutOrganizationFormMethods.formState.isSubmitting || updateOrganizationMutation.isPending
|
||||
}
|
||||
color="primary"
|
||||
EndIcon={ArrowRight}
|
||||
|
||||
@@ -132,7 +132,7 @@ export const AddNewTeamsForm = () => {
|
||||
<Button
|
||||
StartIcon={Plus}
|
||||
color="secondary"
|
||||
disabled={createTeamsMutation.isLoading}
|
||||
disabled={createTeamsMutation.isPending}
|
||||
onClick={handleCounterIncrease}
|
||||
aria-label={t("add_a_team")}
|
||||
className="my-1">
|
||||
@@ -143,7 +143,7 @@ export const AddNewTeamsForm = () => {
|
||||
EndIcon={ArrowRight}
|
||||
color="primary"
|
||||
className="mt-6 w-full justify-center"
|
||||
disabled={!formState.isValid || createTeamsMutation.isLoading || createTeamsMutation.isSuccess}
|
||||
disabled={!formState.isValid || createTeamsMutation.isPending || createTeamsMutation.isSuccess}
|
||||
onClick={handleFormSubmit}>
|
||||
{t("continue")}
|
||||
</Button>
|
||||
|
||||
@@ -80,7 +80,7 @@ export const CreateANewOrganizationForm = ({ slug }: { slug?: string }) => {
|
||||
form={newOrganizationFormMethods}
|
||||
id="createOrg"
|
||||
handleSubmit={(v) => {
|
||||
if (!createOrganizationMutation.isLoading) {
|
||||
if (!createOrganizationMutation.isPending) {
|
||||
setServerErrorMessage(null);
|
||||
createOrganizationMutation.mutate(v);
|
||||
}
|
||||
@@ -188,7 +188,7 @@ export const CreateANewOrganizationForm = ({ slug }: { slug?: string }) => {
|
||||
<div className="flex space-x-2 rtl:space-x-reverse">
|
||||
<Button
|
||||
disabled={
|
||||
newOrganizationFormMethods.formState.isSubmitting || createOrganizationMutation.isLoading
|
||||
newOrganizationFormMethods.formState.isSubmitting || createOrganizationMutation.isPending
|
||||
}
|
||||
color="primary"
|
||||
EndIcon={ArrowRight}
|
||||
|
||||
@@ -61,7 +61,7 @@ export const SetPasswordForm = () => {
|
||||
<Form
|
||||
form={setPasswordFormMethods}
|
||||
handleSubmit={(v) => {
|
||||
if (!setPasswordMutation.isLoading) {
|
||||
if (!setPasswordMutation.isPending) {
|
||||
setServerErrorMessage(null);
|
||||
setPasswordMutation.mutate({ newPassword: v.password });
|
||||
}
|
||||
@@ -97,7 +97,7 @@ export const SetPasswordForm = () => {
|
||||
|
||||
<div className="flex">
|
||||
<Button
|
||||
disabled={setPasswordFormMethods.formState.isSubmitting || setPasswordMutation.isLoading}
|
||||
disabled={setPasswordFormMethods.formState.isSubmitting || setPasswordMutation.isPending}
|
||||
color="primary"
|
||||
EndIcon={ArrowRight}
|
||||
type="submit"
|
||||
|
||||
@@ -44,7 +44,7 @@ export default function OtherTeamList(props: Props) {
|
||||
key={team?.id as number}
|
||||
team={team}
|
||||
onActionSelect={(action: string) => selectAction(action, team?.id as number)}
|
||||
isLoading={deleteTeamMutation.isLoading}
|
||||
isPending={deleteTeamMutation.isPending}
|
||||
hideDropdown={hideDropdown}
|
||||
setHideDropdown={setHideDropdown}
|
||||
/>
|
||||
|
||||
@@ -24,7 +24,7 @@ interface Props {
|
||||
team: RouterOutputs["viewer"]["organizations"]["listOtherTeams"][number];
|
||||
key: number;
|
||||
onActionSelect: (text: string) => void;
|
||||
isLoading?: boolean;
|
||||
isPending?: boolean;
|
||||
hideDropdown: boolean;
|
||||
setHideDropdown: (value: boolean) => void;
|
||||
}
|
||||
@@ -140,7 +140,7 @@ export default function OtherTeamListItem(props: Props) {
|
||||
variety="danger"
|
||||
title={t("disband_team")}
|
||||
confirmBtnText={t("confirm_disband_team")}
|
||||
isLoading={props.isLoading}
|
||||
isPending={props.isPending}
|
||||
onConfirm={() => {
|
||||
props.onActionSelect("disband");
|
||||
}}>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import SkeletonLoaderTeamList from "@calcom/ee/teams/components/SkeletonloaderTeamList";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
@@ -10,21 +8,15 @@ import OtherTeamList from "./OtherTeamList";
|
||||
export function OtherTeamsListing() {
|
||||
const { t } = useLocale();
|
||||
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
const { data: teams, isPending, error } = trpc.viewer.organizations.listOtherTeams.useQuery();
|
||||
|
||||
const { data: teams, isLoading } = trpc.viewer.organizations.listOtherTeams.useQuery(undefined, {
|
||||
onError: (e) => {
|
||||
setErrorMessage(e.message);
|
||||
},
|
||||
});
|
||||
|
||||
if (isLoading) {
|
||||
if (isPending) {
|
||||
return <SkeletonLoaderTeamList />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{!!errorMessage && <Alert severity="error" title={errorMessage} />}
|
||||
{!!error && <Alert severity="error" title={error.message} />}
|
||||
|
||||
{teams && teams.length > 0 ? (
|
||||
<OtherTeamList teams={teams} />
|
||||
|
||||
@@ -98,7 +98,7 @@ const OrgForm = ({
|
||||
required
|
||||
{...form.register("metadata.orgAutoAcceptEmail")}
|
||||
/>
|
||||
<Button type="submit" color="primary" loading={mutation.isLoading}>
|
||||
<Button type="submit" color="primary" loading={mutation.isPending}>
|
||||
{t("save")}
|
||||
</Button>
|
||||
</Form>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
|
||||
@@ -107,7 +107,7 @@ const OrgAppearanceView = ({
|
||||
calVideoLogo: newLogo,
|
||||
});
|
||||
}}
|
||||
disabled={mutation.isLoading}
|
||||
disabled={mutation.isPending}
|
||||
imageSrc={currentOrg?.calVideoLogo ?? undefined}
|
||||
uploadInstruction={t("cal_video_logo_upload_instruction")}
|
||||
triggerButtonColor={currentOrg?.calVideoLogo ? "secondary" : "primary"}
|
||||
@@ -115,7 +115,7 @@ const OrgAppearanceView = ({
|
||||
{currentOrg?.calVideoLogo && (
|
||||
<Button
|
||||
color="destructive"
|
||||
disabled={mutation.isLoading}
|
||||
disabled={mutation.isPending}
|
||||
onClick={() => {
|
||||
mutation.mutate({
|
||||
calVideoLogo: null,
|
||||
@@ -190,7 +190,7 @@ const OrgAppearanceView = ({
|
||||
<SettingsToggle
|
||||
toggleSwitchAtTheEnd={true}
|
||||
title={t("disable_cal_branding", { appName: APP_NAME })}
|
||||
disabled={mutation?.isLoading}
|
||||
disabled={mutation?.isPending}
|
||||
description={t("removes_cal_branding", { appName: APP_NAME })}
|
||||
checked={hideBrandingValue}
|
||||
onCheckedChange={(checked) => {
|
||||
@@ -212,13 +212,18 @@ const OrgAppearanceView = ({
|
||||
const OrgAppearanceViewWrapper = () => {
|
||||
const router = useRouter();
|
||||
const { t } = useLocale();
|
||||
const { data: currentOrg, isLoading } = trpc.viewer.organizations.listCurrent.useQuery(undefined, {
|
||||
onError: () => {
|
||||
router.push("/settings");
|
||||
},
|
||||
});
|
||||
const { data: currentOrg, isPending, error } = trpc.viewer.organizations.listCurrent.useQuery();
|
||||
|
||||
if (isLoading) {
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (error) {
|
||||
router.push("/settings");
|
||||
}
|
||||
},
|
||||
[error]
|
||||
);
|
||||
|
||||
if (isPending) {
|
||||
return <AppearanceSkeletonLoader title={t("appearance")} description={t("appearance_org_description")} />;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
|
||||
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
|
||||
@@ -50,14 +51,23 @@ const OrgGeneralView = () => {
|
||||
const { t } = useLocale();
|
||||
const router = useRouter();
|
||||
|
||||
const { data: currentOrg, isLoading } = trpc.viewer.organizations.listCurrent.useQuery(undefined, {
|
||||
onError: () => {
|
||||
router.push("/settings");
|
||||
},
|
||||
});
|
||||
const {
|
||||
data: currentOrg,
|
||||
isPending,
|
||||
error,
|
||||
} = trpc.viewer.organizations.listCurrent.useQuery(undefined, {});
|
||||
const { data: user } = trpc.viewer.me.useQuery();
|
||||
|
||||
if (isLoading) return <SkeletonLoader title={t("general")} description={t("general_description")} />;
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (error) {
|
||||
router.push("/settings");
|
||||
}
|
||||
},
|
||||
[error]
|
||||
);
|
||||
|
||||
if (isPending) return <SkeletonLoader title={t("general")} description={t("general_description")} />;
|
||||
if (!currentOrg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
"use client";
|
||||
|
||||
// import { debounce } from "lodash";
|
||||
import { keepPreviousData } from "@tanstack/react-query";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
import MemberInvitationModal from "@calcom/ee/teams/components/MemberInvitationModal";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
@@ -71,20 +72,21 @@ const MembersView = () => {
|
||||
// const [queryToFetch, setQueryToFetch] = useState<string | undefined>("");
|
||||
const limit = 20;
|
||||
const [showMemberInvitationModal, setShowMemberInvitationModal] = useState<boolean>(false);
|
||||
const [members, setMembers] = useState<Members>([]);
|
||||
|
||||
const { data: currentOrg } = trpc.viewer.organizations.listCurrent.useQuery(undefined, {
|
||||
enabled: !!session.data?.user?.org,
|
||||
});
|
||||
const { data: team, isLoading: isTeamLoading } = trpc.viewer.organizations.getOtherTeam.useQuery(
|
||||
const {
|
||||
data: team,
|
||||
isPending: isTeamLoading,
|
||||
error: otherTeamError,
|
||||
} = trpc.viewer.organizations.getOtherTeam.useQuery(
|
||||
{ teamId },
|
||||
{
|
||||
enabled: !Number.isNaN(teamId),
|
||||
onError: () => {
|
||||
router.push("/settings");
|
||||
},
|
||||
}
|
||||
);
|
||||
const { data: orgMembersNotInThisTeam, isLoading: isOrgListLoading } =
|
||||
const { data: orgMembersNotInThisTeam, isPending: isOrgListLoading } =
|
||||
trpc.viewer.organizations.getMembers.useQuery(
|
||||
{
|
||||
teamIdToExclude: teamId,
|
||||
@@ -95,24 +97,40 @@ const MembersView = () => {
|
||||
}
|
||||
);
|
||||
|
||||
const { fetchNextPage, isFetchingNextPage, hasNextPage } =
|
||||
trpc.viewer.organizations.listOtherTeamMembers.useInfiniteQuery(
|
||||
{ teamId, limit },
|
||||
{
|
||||
onSuccess: (data) => {
|
||||
const flatData = data?.pages?.flatMap((page) => page.rows) as Members;
|
||||
setMembers(flatData);
|
||||
},
|
||||
enabled: !Number.isNaN(teamId),
|
||||
onError: () => {
|
||||
router.push("/settings");
|
||||
},
|
||||
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
||||
keepPreviousData: true,
|
||||
}
|
||||
);
|
||||
const {
|
||||
fetchNextPage,
|
||||
isFetchingNextPage,
|
||||
hasNextPage,
|
||||
error: otherMembersError,
|
||||
data,
|
||||
} = trpc.viewer.organizations.listOtherTeamMembers.useInfiniteQuery(
|
||||
{ teamId, limit },
|
||||
{
|
||||
enabled: !Number.isNaN(teamId),
|
||||
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
||||
placeholderData: keepPreviousData,
|
||||
}
|
||||
);
|
||||
|
||||
const isLoading = isTeamLoading || isOrgListLoading;
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (otherMembersError || otherTeamError) {
|
||||
router.push("/settings");
|
||||
}
|
||||
},
|
||||
[otherMembersError, otherTeamError]
|
||||
);
|
||||
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (data) {
|
||||
router.push("/settings");
|
||||
}
|
||||
},
|
||||
[data]
|
||||
);
|
||||
|
||||
const isPending = isTeamLoading || isOrgListLoading;
|
||||
const inviteMemberMutation = trpc.viewer.teams.inviteMember.useMutation({
|
||||
onSuccess: () => {
|
||||
utils.viewer.organizations.getMembers.invalidate();
|
||||
@@ -147,7 +165,7 @@ const MembersView = () => {
|
||||
)
|
||||
}
|
||||
/>
|
||||
{!isLoading && (
|
||||
{!isPending && (
|
||||
<>
|
||||
<div>
|
||||
<>
|
||||
@@ -163,7 +181,7 @@ const MembersView = () => {
|
||||
placeholder={`${t("search")}...`}
|
||||
/> */}
|
||||
<MembersList
|
||||
members={members}
|
||||
members={data?.pages?.flatMap((page) => page.rows) ?? []}
|
||||
team={team}
|
||||
fetchNextPage={fetchNextPage}
|
||||
hasNextPage={hasNextPage}
|
||||
@@ -180,7 +198,7 @@ const MembersView = () => {
|
||||
</div>
|
||||
{showMemberInvitationModal && team && (
|
||||
<MemberInvitationModal
|
||||
isLoading={inviteMemberMutation.isLoading}
|
||||
isPending={inviteMemberMutation.isPending}
|
||||
isOpen={showMemberInvitationModal}
|
||||
orgMembers={orgMembersNotInThisTeam}
|
||||
teamId={team.id}
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { Prisma } from "@prisma/client";
|
||||
import { useSession } from "next-auth/react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState, useLayoutEffect } from "react";
|
||||
import { useState, useLayoutEffect, useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -18,7 +18,6 @@ import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
|
||||
import objectKeys from "@calcom/lib/objectKeys";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
import turndown from "@calcom/lib/turndownService";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { SkeletonContainer, SkeletonText } from "@calcom/ui";
|
||||
import {
|
||||
@@ -81,26 +80,39 @@ const OtherTeamProfileView = () => {
|
||||
});
|
||||
const params = useParamsWithFallback();
|
||||
const teamId = Number(params.id);
|
||||
const { data: team, isLoading } = trpc.viewer.organizations.getOtherTeam.useQuery(
|
||||
const {
|
||||
data: team,
|
||||
isPending,
|
||||
error: teamError,
|
||||
} = trpc.viewer.organizations.getOtherTeam.useQuery(
|
||||
{ teamId: teamId },
|
||||
{
|
||||
enabled: !Number.isNaN(teamId),
|
||||
onError: () => {
|
||||
router.push("/settings");
|
||||
},
|
||||
onSuccess: (team: RouterOutputs["viewer"]["organizations"]["getOtherTeam"]) => {
|
||||
if (team) {
|
||||
form.setValue("name", team.name || "");
|
||||
form.setValue("slug", team.slug || "");
|
||||
form.setValue("logo", team.logo || "");
|
||||
form.setValue("bio", team.bio || "");
|
||||
if (team.slug === null && (team?.metadata as Prisma.JsonObject)?.requestedSlug) {
|
||||
form.setValue("slug", ((team?.metadata as Prisma.JsonObject)?.requestedSlug as string) || "");
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (teamError) {
|
||||
router.push("/settings");
|
||||
}
|
||||
},
|
||||
[teamError]
|
||||
);
|
||||
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (team) {
|
||||
form.setValue("name", team.name || "");
|
||||
form.setValue("slug", team.slug || "");
|
||||
form.setValue("logo", team.logo || "");
|
||||
form.setValue("bio", team.bio || "");
|
||||
if (team.slug === null && (team?.metadata as Prisma.JsonObject)?.requestedSlug) {
|
||||
form.setValue("slug", ((team?.metadata as Prisma.JsonObject)?.requestedSlug as string) || "");
|
||||
}
|
||||
}
|
||||
},
|
||||
[team]
|
||||
);
|
||||
|
||||
// This page can only be accessed by team admins (owner/admin)
|
||||
const isAdmin = true;
|
||||
@@ -157,7 +169,7 @@ const OtherTeamProfileView = () => {
|
||||
return (
|
||||
<>
|
||||
<Meta title={t("profile")} description={t("profile_team_description")} />
|
||||
{!isLoading ? (
|
||||
{!isPending ? (
|
||||
<>
|
||||
{isAdmin ? (
|
||||
<Form
|
||||
@@ -249,7 +261,7 @@ const OtherTeamProfileView = () => {
|
||||
/>
|
||||
</div>
|
||||
<p className="text-default mt-2 text-sm">{t("team_description")}</p>
|
||||
<Button color="primary" className="mt-8" type="submit" loading={mutation.isLoading}>
|
||||
<Button color="primary" className="mt-8" type="submit" loading={mutation.isPending}>
|
||||
{t("update")}
|
||||
</Button>
|
||||
{IS_TEAM_BILLING_ENABLED &&
|
||||
|
||||
@@ -4,7 +4,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import type { Prisma } from "@prisma/client";
|
||||
import { LinkIcon } from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState, useLayoutEffect } from "react";
|
||||
import { useState, useLayoutEffect, useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -79,13 +79,22 @@ const OrgProfileView = () => {
|
||||
document.body.focus();
|
||||
}, []);
|
||||
|
||||
const { data: currentOrganisation, isLoading } = trpc.viewer.organizations.listCurrent.useQuery(undefined, {
|
||||
onError: () => {
|
||||
router.push("/settings");
|
||||
},
|
||||
});
|
||||
const {
|
||||
data: currentOrganisation,
|
||||
isPending,
|
||||
error,
|
||||
} = trpc.viewer.organizations.listCurrent.useQuery(undefined, {});
|
||||
|
||||
if (isLoading || !orgBranding || !currentOrganisation) {
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (error) {
|
||||
router.push("/settings");
|
||||
}
|
||||
},
|
||||
[error]
|
||||
);
|
||||
|
||||
if (isPending || !orgBranding || !currentOrganisation) {
|
||||
return <SkeletonLoader title={t("profile")} description={t("profile_org_description")} />;
|
||||
}
|
||||
|
||||
@@ -286,7 +295,7 @@ const OrgProfileForm = ({ defaultValues }: { defaultValues: FormValues }) => {
|
||||
<p className="text-default mt-2 text-sm">{t("org_description")}</p>
|
||||
</div>
|
||||
<SectionBottomActions align="end">
|
||||
<Button color="primary" type="submit" loading={mutation.isLoading} disabled={isDisabled}>
|
||||
<Button color="primary" type="submit" loading={mutation.isPending} disabled={isDisabled}>
|
||||
{t("update")}
|
||||
</Button>
|
||||
</SectionBottomActions>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import ConnectionInfo from "@calcom/ee/sso/components/ConnectionInfo";
|
||||
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
|
||||
import OIDCConnection from "@calcom/features/ee/sso/components/OIDCConnection";
|
||||
@@ -22,23 +20,15 @@ const SkeletonLoader = ({ title, description }: { title: string; description: st
|
||||
};
|
||||
|
||||
export default function SSOConfiguration({ teamId }: { teamId: number | null }) {
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
const { t } = useLocale();
|
||||
|
||||
const { data: connection, isLoading } = trpc.viewer.saml.get.useQuery(
|
||||
{ teamId },
|
||||
{
|
||||
onError: (err) => {
|
||||
setErrorMessage(err.message);
|
||||
},
|
||||
}
|
||||
);
|
||||
const { data: connection, isPending, error } = trpc.viewer.saml.get.useQuery({ teamId });
|
||||
|
||||
if (isLoading) {
|
||||
if (isPending) {
|
||||
return <SkeletonLoader title={t("sso_configuration")} description={t("sso_configuration_description")} />;
|
||||
}
|
||||
|
||||
if (errorMessage) {
|
||||
if (error) {
|
||||
return (
|
||||
<>
|
||||
<Meta
|
||||
@@ -46,7 +36,7 @@ export default function SSOConfiguration({ teamId }: { teamId: number | null })
|
||||
description={t("sso_configuration_description")}
|
||||
borderInShellHeader={true}
|
||||
/>
|
||||
<Alert severity="warning" message={t(errorMessage)} className="mt-4" />
|
||||
<Alert severity="warning" message={t(error.message)} className="mt-4" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,14 +19,7 @@ const SAMLSSO = () => {
|
||||
|
||||
const teamId = Number(params.id);
|
||||
|
||||
const { data: team, isLoading } = trpc.viewer.teams.get.useQuery(
|
||||
{ teamId },
|
||||
{
|
||||
onError: () => {
|
||||
router.push("/settings");
|
||||
},
|
||||
}
|
||||
);
|
||||
const { data: team, isPending, error } = trpc.viewer.teams.get.useQuery({ teamId });
|
||||
|
||||
useEffect(() => {
|
||||
if (!HOSTED_CAL_FEATURES) {
|
||||
@@ -34,7 +27,15 @@ const SAMLSSO = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (isLoading) {
|
||||
useEffect(
|
||||
function refactorMeWithoutEffect() {
|
||||
if (error) {
|
||||
router.push("/settings");
|
||||
}
|
||||
},
|
||||
[error]
|
||||
);
|
||||
if (isPending) {
|
||||
return <SkeletonLoader />;
|
||||
}
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) {
|
||||
<div className="my-2 flex justify-end">
|
||||
<Button
|
||||
disabled={disableSubmit}
|
||||
loading={mutation.isLoading}
|
||||
loading={mutation.isPending}
|
||||
onClick={async () => {
|
||||
if (rating && comment) {
|
||||
await sendFeedback(rating, comment);
|
||||
|
||||
@@ -79,7 +79,7 @@ export const AddNewTeamMembersForm = ({
|
||||
const [memberInviteModal, setMemberInviteModal] = useState(showDialog);
|
||||
const [inviteLinkSettingsModal, setInviteLinkSettingsModal] = useState(false);
|
||||
|
||||
const { data: team, isLoading } = trpc.viewer.teams.get.useQuery({ teamId, isOrg }, { enabled: !!teamId });
|
||||
const { data: team, isPending } = trpc.viewer.teams.get.useQuery({ teamId, isOrg }, { enabled: !!teamId });
|
||||
const { data: orgMembersNotInThisTeam } = trpc.viewer.organizations.getMembers.useQuery(
|
||||
{
|
||||
teamIdToExclude: teamId,
|
||||
@@ -126,12 +126,12 @@ export const AddNewTeamMembersForm = ({
|
||||
{isOrg ? t("add_org_members") : t("add_team_member")}
|
||||
</Button>
|
||||
</div>
|
||||
{isLoading ? (
|
||||
{isPending ? (
|
||||
<SkeletonButton />
|
||||
) : (
|
||||
<>
|
||||
<MemberInvitationModal
|
||||
isLoading={inviteMemberMutation.isLoading}
|
||||
isPending={inviteMemberMutation.isPending}
|
||||
isOpen={memberInviteModal}
|
||||
orgMembers={orgMembersNotInThisTeam}
|
||||
teamId={teamId}
|
||||
@@ -199,7 +199,7 @@ export const AddNewTeamMembersForm = ({
|
||||
EndIcon={!orgBranding || isOrg ? ArrowRight : undefined}
|
||||
color="primary"
|
||||
className="w-full justify-center"
|
||||
disabled={publishTeamMutation.isLoading}
|
||||
disabled={publishTeamMutation.isPending}
|
||||
onClick={() => {
|
||||
let uri = `/settings/teams/${teamId}/profile`;
|
||||
if (isOrg) {
|
||||
|
||||
@@ -71,7 +71,7 @@ export const CreateANewTeamForm = () => {
|
||||
<Form
|
||||
form={newTeamFormMethods}
|
||||
handleSubmit={(v) => {
|
||||
if (!createTeamMutation.isLoading) {
|
||||
if (!createTeamMutation.isPending) {
|
||||
setServerErrorMessage(null);
|
||||
createTeamMutation.mutate(v);
|
||||
}
|
||||
@@ -95,7 +95,7 @@ export const CreateANewTeamForm = () => {
|
||||
<TextField
|
||||
disabled={
|
||||
/* E2e is too fast and it tries to fill this way before the form is ready */
|
||||
!isLocaleReady || createTeamMutation.isLoading
|
||||
!isLocaleReady || createTeamMutation.isPending
|
||||
}
|
||||
className="mt-2"
|
||||
placeholder="Acme Inc."
|
||||
@@ -146,14 +146,14 @@ export const CreateANewTeamForm = () => {
|
||||
|
||||
<div className="flex space-x-2 rtl:space-x-reverse">
|
||||
<Button
|
||||
disabled={createTeamMutation.isLoading}
|
||||
disabled={createTeamMutation.isPending}
|
||||
color="secondary"
|
||||
href={returnToParam}
|
||||
className="w-full justify-center">
|
||||
{t("cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={newTeamFormMethods.formState.isSubmitting || createTeamMutation.isLoading}
|
||||
disabled={newTeamFormMethods.formState.isSubmitting || createTeamMutation.isPending}
|
||||
color="primary"
|
||||
EndIcon={ArrowRight}
|
||||
type="submit"
|
||||
|
||||
@@ -26,14 +26,14 @@ const DisableTeamImpersonation = ({
|
||||
},
|
||||
});
|
||||
const [allowImpersonation, setAllowImpersonation] = useState(!query.data?.disableImpersonation ?? true);
|
||||
if (query.isLoading) return <></>;
|
||||
if (query.isPending) return <></>;
|
||||
|
||||
return (
|
||||
<>
|
||||
<SettingsToggle
|
||||
toggleSwitchAtTheEnd={true}
|
||||
title={t("user_impersonation_heading")}
|
||||
disabled={disabled || mutation?.isLoading}
|
||||
disabled={disabled || mutation?.isPending}
|
||||
description={t("team_impersonation_description")}
|
||||
checked={allowImpersonation}
|
||||
onCheckedChange={(_allowImpersonation) => {
|
||||
|
||||
@@ -76,14 +76,14 @@ export function GoogleWorkspaceInviteButton(
|
||||
}}
|
||||
className="w-full justify-center gap-2"
|
||||
StartIcon={UsersIcon}
|
||||
loading={mutation.isLoading}>
|
||||
loading={mutation.isPending}>
|
||||
{t("import_from_google_workspace")}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip content="Remove workspace connection">
|
||||
<Button
|
||||
color="secondary"
|
||||
loading={removeConnectionMutation.isLoading}
|
||||
loading={removeConnectionMutation.isPending}
|
||||
StartIcon={XIcon}
|
||||
onClick={() => {
|
||||
removeConnectionMutation.mutate();
|
||||
|
||||
@@ -34,7 +34,7 @@ const MakeTeamPrivateSwitch = ({
|
||||
<SettingsToggle
|
||||
toggleSwitchAtTheEnd={true}
|
||||
title={t("make_team_private")}
|
||||
disabled={disabled || mutation?.isLoading}
|
||||
disabled={disabled || mutation?.isPending}
|
||||
description={t("make_team_private_description")}
|
||||
checked={isTeamPrivate}
|
||||
onCheckedChange={(checked) => {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user