From 6fc9e9315d2da4c7d6632e6e51501d86df42cbd4 Mon Sep 17 00:00:00 2001 From: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Date: Tue, 9 May 2023 17:53:23 +0100 Subject: [PATCH] Bug/checkbox calendar sync state (#8677) * switch wip * Implement calendar switch component * Checked default * Add spinner to improve UX * Add connected calendar reivaluate * Remove local state * Move back to middleware * Fix spacing issue * fix: spacing Signed-off-by: Udit Takkar --------- Signed-off-by: Udit Takkar Co-authored-by: Udit Takkar --- .../components/apps/CalendarListContainer.tsx | 88 ++----------------- .../components/ConnectedCalendarItem.tsx | 2 +- .../components/settings/CalendarSwitch.tsx | 85 ------------------ .../pages/settings/my-account/calendars.tsx | 10 ++- .../features/calendars}/CalendarSwitch.tsx | 23 ++++- 5 files changed, 31 insertions(+), 177 deletions(-) delete mode 100644 apps/web/components/settings/CalendarSwitch.tsx rename {apps/web/components/getting-started/components => packages/features/calendars}/CalendarSwitch.tsx (67%) diff --git a/apps/web/components/apps/CalendarListContainer.tsx b/apps/web/components/apps/CalendarListContainer.tsx index c66596f138..8afd92845e 100644 --- a/apps/web/components/apps/CalendarListContainer.tsx +++ b/apps/web/components/apps/CalendarListContainer.tsx @@ -1,9 +1,9 @@ -import { useMutation } from "@tanstack/react-query"; import Link from "next/link"; import { Fragment } from "react"; import { InstallAppButton } from "@calcom/app-store/components"; import DisconnectIntegration from "@calcom/features/apps/components/DisconnectIntegration"; +import { CalendarSwitch } from "@calcom/features/calendars/CalendarSwitch"; import DestinationCalendarSelector from "@calcom/features/calendars/DestinationCalendarSelector"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; @@ -12,12 +12,10 @@ import { Button, EmptyScreen, List, - showToast, AppSkeletonLoader as SkeletonLoader, - Switch, ShellSubHeading, } from "@calcom/ui"; -import { ArrowLeft, Calendar, Plus } from "@calcom/ui/components/icon"; +import { Calendar, Plus } from "@calcom/ui/components/icon"; import { QueryCell } from "@lib/QueryCell"; @@ -31,83 +29,6 @@ type Props = { destinationCalendarId?: string; }; -function CalendarSwitch(props: { - type: string; - externalId: string; - title: string; - defaultSelected: boolean; - destination?: boolean; -}) { - const { t } = useLocale(); - const utils = trpc.useContext(); - - const mutation = useMutation< - unknown, - unknown, - { - isOn: boolean; - } - >( - async ({ isOn }) => { - const body = { - integration: props.type, - externalId: props.externalId, - }; - if (isOn) { - const res = await fetch("/api/availability/calendar", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(body), - }); - if (!res.ok) { - throw new Error("Something went wrong"); - } - } else { - const res = await fetch("/api/availability/calendar", { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(body), - }); - - if (!res.ok) { - throw new Error("Something went wrong"); - } - } - }, - { - async onSettled() { - await utils.viewer.integrations.invalidate(); - }, - onError() { - showToast(`Something went wrong when toggling "${props.title}""`, "error"); - }, - } - ); - return ( -
- { - mutation.mutate({ isOn }); - }} - /> - {!!props.destination && ( - - - {t("adding_events_to")} - - )} -
- ); -} - function CalendarList(props: Props) { const { t } = useLocale(); const query = trpc.viewer.integrations.useQuery({ variant: "calendar", onlyInstalled: false }); @@ -185,14 +106,15 @@ function ConnectedCalendarsList(props: Props) { {!fromOnboarding && ( <>

{t("toggle_calendars_conflict")}

-
    +
      {item.calendars.map((cal) => ( ))} diff --git a/apps/web/components/getting-started/components/ConnectedCalendarItem.tsx b/apps/web/components/getting-started/components/ConnectedCalendarItem.tsx index b2e6d905e1..f859274a5e 100644 --- a/apps/web/components/getting-started/components/ConnectedCalendarItem.tsx +++ b/apps/web/components/getting-started/components/ConnectedCalendarItem.tsx @@ -1,4 +1,4 @@ -import { CalendarSwitch } from "./CalendarSwitch"; +import { CalendarSwitch } from "@calcom/features/calendars/CalendarSwitch"; interface IConnectedCalendarItem { name: string; diff --git a/apps/web/components/settings/CalendarSwitch.tsx b/apps/web/components/settings/CalendarSwitch.tsx deleted file mode 100644 index 8d58bf72dd..0000000000 --- a/apps/web/components/settings/CalendarSwitch.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { useMutation } from "@tanstack/react-query"; - -import { useLocale } from "@calcom/lib/hooks/useLocale"; -import { trpc } from "@calcom/trpc/react"; -import { Badge, showToast, Switch } from "@calcom/ui"; -import { ArrowLeft } from "@calcom/ui/components/icon"; - -export function CalendarSwitch(props: { - type: string; - externalId: string; - title: string; - defaultSelected: boolean; - isSelected: boolean; -}) { - const { t } = useLocale(); - - const utils = trpc.useContext(); - - const mutation = useMutation< - unknown, - unknown, - { - isOn: boolean; - } - >( - async ({ isOn }) => { - const body = { - integration: props.type, - externalId: props.externalId, - }; - if (isOn) { - const res = await fetch("/api/availability/calendar", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(body), - }); - if (!res.ok) { - throw new Error("Something went wrong"); - } - } else { - const res = await fetch("/api/availability/calendar", { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(body), - }); - - if (!res.ok) { - throw new Error("Something went wrong"); - } - } - }, - { - async onSettled() { - await utils.viewer.integrations.invalidate(); - }, - onError() { - showToast(`Something went wrong when toggling "${props.title}""`, "error"); - }, - } - ); - return ( -
      - { - mutation.mutate({ isOn }); - }} - /> - {props.defaultSelected && ( - -
      - {t("adding_events_to")} -
      -
      - )} -
      - ); -} diff --git a/apps/web/pages/settings/my-account/calendars.tsx b/apps/web/pages/settings/my-account/calendars.tsx index 97afcdddda..063db71aa0 100644 --- a/apps/web/pages/settings/my-account/calendars.tsx +++ b/apps/web/pages/settings/my-account/calendars.tsx @@ -4,6 +4,7 @@ import { useRouter } from "next/router"; import { Fragment } from "react"; import DisconnectIntegration from "@calcom/features/apps/components/DisconnectIntegration"; +import { CalendarSwitch } from "@calcom/features/calendars/CalendarSwitch"; import DestinationCalendarSelector from "@calcom/features/calendars/DestinationCalendarSelector"; import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout"; import { classNames } from "@calcom/lib"; @@ -29,7 +30,6 @@ import { Plus, Calendar } from "@calcom/ui/components/icon"; import { QueryCell } from "@lib/QueryCell"; import PageWrapper from "@components/PageWrapper"; -import { CalendarSwitch } from "@components/settings/CalendarSwitch"; const SkeletonLoader = () => { return ( @@ -178,15 +178,17 @@ const CalendarsView = () => {

      {t("toggle_calendars_conflict")}

      -
        +
          {item.calendars.map((cal) => ( ))}
        diff --git a/apps/web/components/getting-started/components/CalendarSwitch.tsx b/packages/features/calendars/CalendarSwitch.tsx similarity index 67% rename from apps/web/components/getting-started/components/CalendarSwitch.tsx rename to packages/features/calendars/CalendarSwitch.tsx index e067c5f44d..75ec99fa5e 100644 --- a/apps/web/components/getting-started/components/CalendarSwitch.tsx +++ b/packages/features/calendars/CalendarSwitch.tsx @@ -1,9 +1,11 @@ import { useMutation } from "@tanstack/react-query"; +import { useState } from "react"; +import { classNames } from "@calcom/lib"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import { showToast, Switch } from "@calcom/ui"; - -import classNames from "@lib/classNames"; +import { ArrowLeft, RotateCcw } from "@calcom/ui/components/icon"; interface ICalendarSwitchProps { title: string; @@ -12,10 +14,13 @@ interface ICalendarSwitchProps { isChecked: boolean; name: string; isLastItemInList?: boolean; + destination?: boolean; } const CalendarSwitch = (props: ICalendarSwitchProps) => { const { title, externalId, type, isChecked, name, isLastItemInList = false } = props; + const [checkedInternal, setCheckedInternal] = useState(isChecked); const utils = trpc.useContext(); + const { t } = useLocale(); const mutation = useMutation< unknown, unknown, @@ -58,19 +63,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"); }, } ); return ( -
        +
        { + setCheckedInternal(isOn); mutation.mutate({ isOn }); }} /> @@ -78,6 +86,13 @@ const CalendarSwitch = (props: ICalendarSwitchProps) => { + {!!props.destination && ( + + + {t("adding_events_to")} + + )} + {mutation.isLoading && }
        ); };