diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/(with-loader)/page.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/(with-loader)/page.tsx index 4626d80c511fea..abe5b1861b74c7 100644 --- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/(with-loader)/page.tsx +++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/(with-loader)/page.tsx @@ -10,6 +10,8 @@ import { webhookRouter } from "@calcom/trpc/server/routers/viewer/webhook/_route import { buildLegacyRequest } from "@lib/buildLegacyCtx"; +import { revalidateWebhooksList } from "./actions"; + export const generateMetadata = async () => await _generateMetadata( (t) => t("webhooks"), @@ -28,7 +30,7 @@ const WebhooksViewServerWrapper = async () => { const caller = await createRouterCaller(webhookRouter); const data = await caller.getByViewer(); - return ; + return ; }; export default WebhooksViewServerWrapper; diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/new/page.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/new/page.tsx index 5376fccfc3f7e4..2aca3657f727d6 100644 --- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/new/page.tsx +++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/new/page.tsx @@ -1,3 +1,5 @@ +import { revalidatePath } from "next/cache"; + import { createRouterCaller } from "app/_trpc/context"; import { _generateMetadata } from "app/_utils"; @@ -26,7 +28,12 @@ const Page = async () => { webhookCaller.list(), ]); - return ; + const onInvalidate = async () => { + "use server"; + revalidatePath("/settings/developer/webhooks"); + }; + + return ; }; export default Page; diff --git a/apps/web/app/AppRouterI18nProvider.tsx b/apps/web/app/AppRouterI18nProvider.tsx index 39876e93b6dfed..29166cd1d34d1f 100644 --- a/apps/web/app/AppRouterI18nProvider.tsx +++ b/apps/web/app/AppRouterI18nProvider.tsx @@ -1,15 +1,10 @@ "use client"; -import { createContext, useMemo } from "react"; +import { useMemo } from "react"; import type { ReactNode } from "react"; -type AppRouterI18nContextType = { - translations: Record; - ns: string; - locale: string; -}; - -export const AppRouterI18nContext = createContext(null); +import { AppRouterI18nContext } from "@calcom/lib/i18n/AppRouterI18nContext"; +import type { AppRouterI18nContextType } from "@calcom/lib/i18n/AppRouterI18nContext"; export function AppRouterI18nProvider({ children, @@ -26,7 +21,7 @@ export function AppRouterI18nProvider({ locale, ns, }), - [locale, ns] + [translations, locale, ns] ); return {children}; diff --git a/apps/web/app/CustomI18nProvider.tsx b/apps/web/app/CustomI18nProvider.tsx index aacb30b2664da1..c3a2d4085f9b64 100644 --- a/apps/web/app/CustomI18nProvider.tsx +++ b/apps/web/app/CustomI18nProvider.tsx @@ -1,15 +1,10 @@ "use client"; -import { createContext, useMemo } from "react"; +import { useMemo } from "react"; import type { ReactNode } from "react"; -type CustomI18nContextType = { - translations: Record; - ns: string; - locale: string; -}; - -export const CustomI18nContext = createContext(null); +import { CustomI18nContext } from "@calcom/lib/i18n/CustomI18nContext"; +import type { CustomI18nContextType } from "@calcom/lib/i18n/CustomI18nContext"; export function CustomI18nProvider({ children, @@ -26,7 +21,7 @@ export function CustomI18nProvider({ locale, ns, }), - [locale, ns] + [translations, locale, ns] ); return {children}; diff --git a/packages/features/auth/signup/handlers/calcomHandler.ts b/packages/features/auth/signup/handlers/calcomHandler.ts index 76a95feb71f06a..6bb3912c08ede7 100644 --- a/packages/features/auth/signup/handlers/calcomHandler.ts +++ b/packages/features/auth/signup/handlers/calcomHandler.ts @@ -1,5 +1,6 @@ import { cookies, headers } from "next/headers"; import { NextResponse } from "next/server"; +import type { NextApiRequest } from "next"; import { getPremiumMonthlyPlanPriceId } from "@calcom/app-store/stripepayment/lib/utils"; import { getLocaleFromRequest } from "@calcom/features/auth/lib/getLocaleFromRequest"; @@ -13,6 +14,7 @@ import { checkIfEmailIsBlockedInWatchlistController } from "@calcom/features/wat import { hashPassword } from "@calcom/lib/auth/hashPassword"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { HttpError } from "@calcom/lib/http-error"; +import { buildLegacyRequest } from "@calcom/lib/legacy-request"; import logger from "@calcom/lib/logger"; import type { CustomNextApiHandler } from "@calcom/lib/server/username"; import { usernameHandler } from "@calcom/lib/server/username"; @@ -20,7 +22,6 @@ import { prisma } from "@calcom/prisma"; import { CreationSource } from "@calcom/prisma/enums"; import { IdentityProvider } from "@calcom/prisma/enums"; import { signupSchema } from "@calcom/prisma/zod-utils"; -import { buildLegacyRequest } from "@calcom/web/lib/buildLegacyCtx"; import { joinAnyChildTeamOnOrgInvite } from "../utils/organization"; import { @@ -215,7 +216,9 @@ const handler: CustomNextApiHandler = async (body, usernameStatus) => { } sendEmailVerification({ email, - language: await getLocaleFromRequest(buildLegacyRequest(await headers(), await cookies())), + language: await getLocaleFromRequest( + buildLegacyRequest(await headers(), await cookies()) as unknown as NextApiRequest + ), username: username || "", }); } diff --git a/packages/features/ee/api-keys/components/ApiKeyDialogForm.tsx b/packages/features/ee/api-keys/components/ApiKeyDialogForm.tsx index 5c367e31962c64..26c1d359accf6b 100644 --- a/packages/features/ee/api-keys/components/ApiKeyDialogForm.tsx +++ b/packages/features/ee/api-keys/components/ApiKeyDialogForm.tsx @@ -17,7 +17,6 @@ import { SelectField } from "@calcom/ui/components/form"; import { Switch } from "@calcom/ui/components/form"; import { showToast } from "@calcom/ui/components/toast"; import { Tooltip } from "@calcom/ui/components/tooltip"; -import { revalidateApiKeysList } from "@calcom/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/api-keys/actions"; export default function ApiKeyDialogForm({ defaultValues, @@ -32,7 +31,6 @@ export default function ApiKeyDialogForm({ const updateApiKeyMutation = trpc.viewer.apiKeys.edit.useMutation({ onSuccess() { utils.viewer.apiKeys.list.invalidate(); - revalidateApiKeysList(); showToast(t("api_key_updated"), "success"); handleClose(); }, @@ -147,7 +145,6 @@ export default function ApiKeyDialogForm({ setApiKey(apiKey); setApiKeyDetails({ ...event }); await utils.viewer.apiKeys.list.invalidate(); - revalidateApiKeysList(); setSuccessfulNewApiKeyModal(true); } }} diff --git a/packages/features/ee/api-keys/components/ApiKeyListItem.tsx b/packages/features/ee/api-keys/components/ApiKeyListItem.tsx index 4fda50238948fc..c9fbdc68d73972 100644 --- a/packages/features/ee/api-keys/components/ApiKeyListItem.tsx +++ b/packages/features/ee/api-keys/components/ApiKeyListItem.tsx @@ -17,7 +17,6 @@ import { DropdownMenuTrigger, } from "@calcom/ui/components/dropdown"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateApiKeysList } from "@calcom/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/api-keys/actions"; export type TApiKeys = RouterOutputs["viewer"]["apiKeys"]["list"][number]; @@ -40,7 +39,6 @@ const ApiKeyListItem = ({ const deleteApiKey = trpc.viewer.apiKeys.delete.useMutation({ async onSuccess() { await utils.viewer.apiKeys.list.invalidate(); - revalidateApiKeysList(); showToast(t("api_key_deleted"), "success"); }, onError(err) { diff --git a/packages/features/ee/dsync/components/CreateTeamDialog.tsx b/packages/features/ee/dsync/components/CreateTeamDialog.tsx index dc794856382f3f..8c1bfbdcc89cb3 100644 --- a/packages/features/ee/dsync/components/CreateTeamDialog.tsx +++ b/packages/features/ee/dsync/components/CreateTeamDialog.tsx @@ -3,7 +3,6 @@ import { CreateANewTeamForm } from "@calcom/features/ee/teams/components"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import { DialogContent } from "@calcom/ui/components/dialog"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; interface CreateTeamDialogProps { open: boolean; @@ -25,7 +24,6 @@ const CreateTeamDialog = (props: CreateTeamDialogProps) => { onSuccess={async () => { await utils.viewer.dsync.teamGroupMapping.get.invalidate(); await utils.viewer.teams.list.invalidate(); - revalidateTeamsList(); onOpenChange(false); }} /> diff --git a/packages/features/ee/organizations/components/index.ts b/packages/features/ee/organizations/components/index.ts index eb8816ad496207..39fbcb47351023 100644 --- a/packages/features/ee/organizations/components/index.ts +++ b/packages/features/ee/organizations/components/index.ts @@ -1,4 +1,3 @@ export { CreateANewOrganizationForm } from "./CreateANewOrganizationForm"; export { AboutOrganizationForm } from "./AboutOrganizationForm"; -export { AddNewTeamsForm } from "@calcom/web/modules/settings/organizations/new/_components/AddNewTeamsForm"; export { AdminOnboardingHandover } from "./AdminOnboardingHandover"; diff --git a/packages/features/ee/organizations/pages/settings/attributes/DeleteAttributeModal.tsx b/packages/features/ee/organizations/pages/settings/attributes/DeleteAttributeModal.tsx index 53b9fac436f5eb..e0db01c8609d0c 100644 --- a/packages/features/ee/organizations/pages/settings/attributes/DeleteAttributeModal.tsx +++ b/packages/features/ee/organizations/pages/settings/attributes/DeleteAttributeModal.tsx @@ -6,7 +6,6 @@ import type { RouterOutputs } from "@calcom/trpc/react"; import { trpc } from "@calcom/trpc/react"; import { ConfirmationDialogContent } from "@calcom/ui/components/dialog"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateAttributesList } from "@calcom/web/app/(use-page-wrapper)/settings/organizations/(org-user-only)/members/actions"; type AttributeItemProps = RouterOutputs["viewer"]["attributes"]["list"][number]; @@ -24,7 +23,6 @@ export function DeleteAttributeModal({ onSuccess: () => { showToast(t("attribute_deleted_successfully"), "success"); utils.viewer.attributes.list.invalidate(); - revalidateAttributesList(); }, onError: (err) => { showToast(err.message, "error"); diff --git a/packages/features/ee/organizations/pages/settings/attributes/attributes-create-view.tsx b/packages/features/ee/organizations/pages/settings/attributes/attributes-create-view.tsx index faaff4145135a1..1ad17cf1185d56 100644 --- a/packages/features/ee/organizations/pages/settings/attributes/attributes-create-view.tsx +++ b/packages/features/ee/organizations/pages/settings/attributes/attributes-create-view.tsx @@ -2,32 +2,26 @@ import { useRouter } from "next/navigation"; import { useFormContext } from "react-hook-form"; -import { z } from "zod"; import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import { Button } from "@calcom/ui/components/button"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateAttributesList } from "@calcom/web/app/(use-page-wrapper)/settings/organizations/(org-user-only)/members/actions"; import { AttributeForm } from "./AttributesForm"; -const CreateAttributeSchema = z.object({ - // Calling this name would make sense but conflicts with rhf "watch" "name" field - attrName: z.string().min(1), - type: z.enum(["TEXT", "NUMBER", "SINGLE_SELECT", "MULTI_SELECT"]), - options: z.array(z.object({ value: z.string(), id: z.string() })), -}); - -type FormValues = z.infer; +type FormValues = { + attrName: string; + type: "TEXT" | "NUMBER" | "SINGLE_SELECT" | "MULTI_SELECT"; + options: Array<{ value: string; id: string }>; +}; function CreateAttributesPage() { const router = useRouter(); const mutation = trpc.viewer.attributes.create.useMutation({ onSuccess: () => { showToast("Attribute created successfully", "success"); - revalidateAttributesList(); router.push("/settings/organizations/attributes"); }, onError: (err) => { diff --git a/packages/features/ee/organizations/pages/settings/attributes/attributes-edit-view.tsx b/packages/features/ee/organizations/pages/settings/attributes/attributes-edit-view.tsx index 76f6a2d0612b88..078fb023aed86f 100644 --- a/packages/features/ee/organizations/pages/settings/attributes/attributes-edit-view.tsx +++ b/packages/features/ee/organizations/pages/settings/attributes/attributes-edit-view.tsx @@ -2,25 +2,20 @@ import { useParams } from "next/navigation"; import { useFormContext } from "react-hook-form"; -import { z } from "zod"; import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import { Button } from "@calcom/ui/components/button"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateAttributesList } from "@calcom/web/app/(use-page-wrapper)/settings/organizations/(org-user-only)/members/actions"; import { AttributeForm } from "./AttributesForm"; -const CreateAttributeSchema = z.object({ - // Calling this name would make sense but conflicts with rhf "watch" "name" field - attrName: z.string().min(1), - type: z.enum(["TEXT", "NUMBER", "SINGLE_SELECT", "MULTI_SELECT"]), - options: z.array(z.object({ value: z.string(), id: z.string() })), -}); - -type FormValues = z.infer; +type FormValues = { + attrName: string; + type: "TEXT" | "NUMBER" | "SINGLE_SELECT" | "MULTI_SELECT"; + options: Array<{ value: string; id: string }>; +}; function CreateAttributesPage() { const utils = trpc.useUtils(); @@ -38,7 +33,6 @@ function CreateAttributesPage() { id, }); utils.viewer.attributes.list.invalidate(); - revalidateAttributesList(); }, onError: (err) => { showToast(err.message, "error"); diff --git a/packages/features/ee/organizations/pages/settings/attributes/attributes-list-view.tsx b/packages/features/ee/organizations/pages/settings/attributes/attributes-list-view.tsx index 49c0b7ce6a3ccd..90e2d8b53f1439 100644 --- a/packages/features/ee/organizations/pages/settings/attributes/attributes-list-view.tsx +++ b/packages/features/ee/organizations/pages/settings/attributes/attributes-list-view.tsx @@ -19,7 +19,6 @@ import { import { Switch } from "@calcom/ui/components/form"; import { Icon } from "@calcom/ui/components/icon"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateAttributesList } from "@calcom/web/app/(use-page-wrapper)/settings/organizations/(org-user-only)/members/actions"; import { DeleteAttributeModal } from "./DeleteAttributeModal"; import { ListSkeleton } from "./ListSkeleton"; @@ -47,7 +46,6 @@ function AttributeItem({ const mutation = trpc.viewer.attributes.toggleActive.useMutation({ onSuccess: () => { showToast(t("attribute_updated_successfully"), "success"); - revalidateAttributesList(); }, onError: (err) => { showToast(err.message, "error"); diff --git a/packages/features/ee/organizations/pages/settings/other-team-members-view.tsx b/packages/features/ee/organizations/pages/settings/other-team-members-view.tsx index 7107f59d9c0db3..8c403dec9c754c 100644 --- a/packages/features/ee/organizations/pages/settings/other-team-members-view.tsx +++ b/packages/features/ee/organizations/pages/settings/other-team-members-view.tsx @@ -15,7 +15,6 @@ import { trpc } from "@calcom/trpc/react"; import type { RouterOutputs } from "@calcom/trpc/react"; import { Button } from "@calcom/ui/components/button"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; import MakeTeamPrivateSwitch from "../../../teams/components/MakeTeamPrivateSwitch"; import MemberListItem from "../components/MemberListItem"; @@ -159,7 +158,6 @@ const MembersView = () => { utils.viewer.organizations.getMembers.invalidate(); utils.viewer.organizations.listOtherTeams.invalidate(); utils.viewer.teams.list.invalidate(); - revalidateTeamsList(); utils.viewer.organizations.listOtherTeamMembers.invalidate(); }, }); diff --git a/packages/features/ee/organizations/pages/settings/other-team-profile-view.tsx b/packages/features/ee/organizations/pages/settings/other-team-profile-view.tsx index fb6550d266b9b0..b74818dab8943c 100644 --- a/packages/features/ee/organizations/pages/settings/other-team-profile-view.tsx +++ b/packages/features/ee/organizations/pages/settings/other-team-profile-view.tsx @@ -31,8 +31,6 @@ import { TextField } from "@calcom/ui/components/form"; import { ImageUploader } from "@calcom/ui/components/image-uploader"; import { SkeletonContainer, SkeletonText } from "@calcom/ui/components/skeleton"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateTeamDataCache } from "@calcom/web/app/(booking-page-wrapper)/team/[slug]/[type]/actions"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; import { subdomainSuffix } from "../../../organizations/lib/orgDomains"; @@ -69,10 +67,6 @@ const OtherTeamProfileView = () => { await utils.viewer.teams.get.invalidate(); if (team?.slug) { // Org admins editing another team's profile should purge the cached team data - revalidateTeamDataCache({ - teamSlug: team.slug, - orgSlug: team.parent?.slug ?? null, - }); } showToast(t("your_team_updated_successfully"), "success"); }, @@ -137,7 +131,6 @@ const OtherTeamProfileView = () => { async onSuccess() { await utils.viewer.teams.get.invalidate(); await utils.viewer.teams.list.invalidate(); - revalidateTeamsList(); await utils.viewer.eventTypes.invalidate(); showToast(t("success"), "success"); }, @@ -161,7 +154,7 @@ const OtherTeamProfileView = () => { if (team?.id) deleteTeamMutation.mutate({ teamId: team.id }); } - function leaveTeam() { + function _leaveTeam() { if (team?.id && session.data) removeMemberMutation.mutate({ teamIds: [team.id], @@ -291,7 +284,6 @@ const OtherTeamProfileView = () => {
diff --git a/packages/features/ee/teams/components/CreateANewTeamForm.tsx b/packages/features/ee/teams/components/CreateANewTeamForm.tsx index 690583a0bf7e73..84fbd87377b70b 100644 --- a/packages/features/ee/teams/components/CreateANewTeamForm.tsx +++ b/packages/features/ee/teams/components/CreateANewTeamForm.tsx @@ -12,8 +12,6 @@ import { Button } from "@calcom/ui/components/button"; import { DialogFooter } from "@calcom/ui/components/dialog"; import { Form } from "@calcom/ui/components/form"; import { TextField } from "@calcom/ui/components/form"; -import { revalidateEventTypesList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/event-types/actions"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; import { useOrgBranding } from "../../organizations/context/provider"; import { subdomainSuffix } from "../../organizations/lib/orgDomains"; @@ -44,8 +42,6 @@ export const CreateANewTeamForm = (props: CreateANewTeamFormProps) => { const createTeamMutation = trpc.viewer.teams.create.useMutation({ onSuccess: async (data) => { await utils.viewer.eventTypes.getUserEventGroups.invalidate(); - revalidateEventTypesList(); - revalidateTeamsList(); onSuccess(data); }, diff --git a/packages/features/ee/teams/components/InviteLinkSettingsModal.tsx b/packages/features/ee/teams/components/InviteLinkSettingsModal.tsx index 4efab6743d5017..dacf0261cf0eb4 100644 --- a/packages/features/ee/teams/components/InviteLinkSettingsModal.tsx +++ b/packages/features/ee/teams/components/InviteLinkSettingsModal.tsx @@ -10,7 +10,6 @@ import { Form } from "@calcom/ui/components/form"; import { Label } from "@calcom/ui/components/form"; import { Select } from "@calcom/ui/components/form"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; type InvitationLinkSettingsModalProps = { isOpen: boolean; @@ -33,7 +32,6 @@ export default function InviteLinkSettingsModal(props: InvitationLinkSettingsMod showToast(t("invite_link_deleted"), "success"); trpcContext.viewer.teams.get.invalidate(); trpcContext.viewer.teams.list.invalidate(); - revalidateTeamsList(); props.onExit(); }, onError: (e) => { @@ -46,7 +44,6 @@ export default function InviteLinkSettingsModal(props: InvitationLinkSettingsMod showToast(t("invite_link_updated"), "success"); trpcContext.viewer.teams.get.invalidate(); trpcContext.viewer.teams.list.invalidate(); - revalidateTeamsList(); }, onError: (e) => { showToast(e.message, "error"); diff --git a/packages/features/ee/teams/components/MemberInvitationModal.tsx b/packages/features/ee/teams/components/MemberInvitationModal.tsx index cca733f8453c0c..51cb7f4dc0c712 100644 --- a/packages/features/ee/teams/components/MemberInvitationModal.tsx +++ b/packages/features/ee/teams/components/MemberInvitationModal.tsx @@ -26,7 +26,6 @@ import { Select } from "@calcom/ui/components/form"; import { ToggleGroup } from "@calcom/ui/components/form"; import { Icon } from "@calcom/ui/components/icon"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; import type { PendingMember } from "../lib/types"; import { GoogleWorkspaceInviteButton } from "./GoogleWorkspaceInviteButton"; @@ -90,10 +89,9 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps) ); const createInviteMutation = trpc.viewer.teams.createInvite.useMutation({ - async onSuccess({ inviteLink }) { + async onSuccess() { trpcContext.viewer.teams.get.invalidate(); trpcContext.viewer.teams.list.invalidate(); - revalidateTeamsList(); }, onError: (error) => { showToast(error.message, "error"); @@ -388,7 +386,9 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps) color="minimal" className="me-2 ms-2" onClick={() => { - props.onSettingsOpen && props.onSettingsOpen(); + if (props.onSettingsOpen) { + props.onSettingsOpen(); + } newMemberFormMethods.reset(); }} data-testid="edit-invite-link-button"> @@ -410,18 +410,24 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps) // Credits to https://wolfgangrittner.dev/how-to-use-clipboard-api-in-firefox/ if (typeof ClipboardItem !== "undefined") { const inviteLinkClipbardItem = new ClipboardItem({ - "text/plain": new Promise(async (resolve) => { + "text/plain": new Promise((resolve, reject) => { // Instead of doing async work and then writing to clipboard, do async work in clipboard API itself - const { inviteLink } = await createInviteMutation.mutateAsync({ - teamId: props.teamId, - token: props.token, - }); - showToast(t("invite_link_copied"), "success"); - resolve(new Blob([inviteLink], { type: "text/plain" })); + createInviteMutation + .mutateAsync({ + teamId: props.teamId, + token: props.token, + }) + .then(({ inviteLink }) => { + showToast(t("invite_link_copied"), "success"); + resolve(new Blob([inviteLink], { type: "text/plain" })); + }) + .catch((error) => { + reject(error); + }); }), }); await navigator.clipboard.write([inviteLinkClipbardItem]); - } else { + }else { // Fallback for browsers that don't support ClipboardItem e.g. Firefox const { inviteLink } = await createInviteMutation.mutateAsync({ teamId: props.teamId, diff --git a/packages/features/ee/teams/components/RoundRobinSettings.tsx b/packages/features/ee/teams/components/RoundRobinSettings.tsx index d4aead1b6788e4..f1817276d80823 100644 --- a/packages/features/ee/teams/components/RoundRobinSettings.tsx +++ b/packages/features/ee/teams/components/RoundRobinSettings.tsx @@ -11,7 +11,6 @@ import { trpc } from "@calcom/trpc/react"; import { Button } from "@calcom/ui/components/button"; import { Form } from "@calcom/ui/components/form"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateTeamDataCache } from "@calcom/web/app/(booking-page-wrapper)/team/[slug]/[type]/actions"; import RoundRobinResetInterval from "./RoundRobinResetInterval"; import RoundRobinTimestampBasis from "./RoundRobinTimestampBasis"; @@ -51,10 +50,6 @@ const RoundRobinSettings = ({ team }: RoundRobinSettingsProps) => { await utils.viewer.teams.get.invalidate(); if (team?.slug) { // Rounb robin reset interval / basis governs host selection logic on the booking page. - revalidateTeamDataCache({ - teamSlug: team.slug, - orgSlug: team.parent?.slug ?? null, - }); } showToast(t("round_robin_settings_updated_successfully"), "success"); }, diff --git a/packages/features/ee/teams/components/TeamInviteList.tsx b/packages/features/ee/teams/components/TeamInviteList.tsx index aebb8e47e19974..ca7a5250fac7ae 100644 --- a/packages/features/ee/teams/components/TeamInviteList.tsx +++ b/packages/features/ee/teams/components/TeamInviteList.tsx @@ -4,7 +4,6 @@ import { trackFormbricksAction } from "@calcom/features/formbricks/formbricks-cl import type { MembershipRole } from "@calcom/prisma/enums"; import { trpc } from "@calcom/trpc/react"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; import TeamInviteListItem from "./TeamInviteListItem"; @@ -37,7 +36,6 @@ export default function TeamInviteList(props: Props) { const deleteTeamMutation = trpc.viewer.teams.delete.useMutation({ async onSuccess() { await utils.viewer.teams.list.invalidate(); - revalidateTeamsList(); await utils.viewer.teams.get.invalidate(); await utils.viewer.organizations.listMembers.invalidate(); trackFormbricksAction("team_disbanded"); diff --git a/packages/features/ee/teams/components/TeamInviteListItem.tsx b/packages/features/ee/teams/components/TeamInviteListItem.tsx index 1f522566b45167..e8d087b5b20eb2 100644 --- a/packages/features/ee/teams/components/TeamInviteListItem.tsx +++ b/packages/features/ee/teams/components/TeamInviteListItem.tsx @@ -13,7 +13,6 @@ import { DropdownMenuTrigger, } from "@calcom/ui/components/dropdown"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; interface Props { team: { @@ -44,7 +43,6 @@ export default function TeamInviteListItem(props: Props) { await utils.viewer.teams.get.invalidate(); await utils.viewer.teams.hasTeamPlan.invalidate(); await utils.viewer.teams.list.invalidate(); - revalidateTeamsList(); await utils.viewer.organizations.listMembers.invalidate(); }, }); diff --git a/packages/features/ee/teams/components/TeamList.tsx b/packages/features/ee/teams/components/TeamList.tsx index ebddcbfc07a173..342f06ad0bc16f 100644 --- a/packages/features/ee/teams/components/TeamList.tsx +++ b/packages/features/ee/teams/components/TeamList.tsx @@ -11,7 +11,6 @@ import { trpc } from "@calcom/trpc/react"; import { Card } from "@calcom/ui/components/card"; import { Icon } from "@calcom/ui/components/icon"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; import TeamListItem from "./TeamListItem"; @@ -43,7 +42,6 @@ export default function TeamList(props: Props) { const deleteTeamMutation = trpc.viewer.teams.delete.useMutation({ async onSuccess() { await utils.viewer.teams.list.invalidate(); - revalidateTeamsList(); await utils.viewer.teams.hasTeamPlan.invalidate(); trackFormbricksAction("team_disbanded"); }, diff --git a/packages/features/ee/teams/components/TeamListItem.tsx b/packages/features/ee/teams/components/TeamListItem.tsx index 251b7828678c99..7339a20225d53f 100644 --- a/packages/features/ee/teams/components/TeamListItem.tsx +++ b/packages/features/ee/teams/components/TeamListItem.tsx @@ -30,7 +30,6 @@ import { } from "@calcom/ui/components/dropdown"; import { showToast } from "@calcom/ui/components/toast"; import { Tooltip } from "@calcom/ui/components/tooltip"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; import { TeamRole } from "./TeamPill"; @@ -60,7 +59,6 @@ export default function TeamListItem(props: Props) { showToast(t("success"), "success"); utils.viewer.teams.get.invalidate(); utils.viewer.teams.list.invalidate(); - revalidateTeamsList(); utils.viewer.teams.hasTeamPlan.invalidate(); utils.viewer.teams.listInvites.invalidate(); const userOrganizationId = orgId ?? undefined; diff --git a/packages/features/ee/teams/pages/team-appearance-view.tsx b/packages/features/ee/teams/pages/team-appearance-view.tsx index 38816971303933..42c64984884481 100644 --- a/packages/features/ee/teams/pages/team-appearance-view.tsx +++ b/packages/features/ee/teams/pages/team-appearance-view.tsx @@ -18,7 +18,6 @@ import { Button } from "@calcom/ui/components/button"; import { Form } from "@calcom/ui/components/form"; import { SettingsToggle } from "@calcom/ui/components/form"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateTeamDataCache } from "@calcom/web/app/(booking-page-wrapper)/team/[slug]/[type]/actions"; import ThemeLabel from "../../../settings/ThemeLabel"; @@ -75,10 +74,6 @@ const ProfileView = ({ team }: ProfileViewProps) => { if (res?.slug) { // Appearance changes (theme, colours, branding toggles) are read on the team booking page through // `getCachedTeamData` in `queries.ts`. - await revalidateTeamDataCache({ - teamSlug: res?.slug, - orgSlug: team?.parent?.slug ?? null, - }); } }, }); @@ -204,8 +199,6 @@ const ProfileViewWrapper = () => { const router = useRouter(); const params = useParamsWithFallback(); - const { t } = useLocale(); - const { data: team, isPending, diff --git a/packages/features/ee/teams/pages/team-profile-view.tsx b/packages/features/ee/teams/pages/team-profile-view.tsx index 81249a24cdaee5..34c1874fd20b39 100644 --- a/packages/features/ee/teams/pages/team-profile-view.tsx +++ b/packages/features/ee/teams/pages/team-profile-view.tsx @@ -42,9 +42,6 @@ import { } from "@calcom/ui/components/skeleton"; import { showToast } from "@calcom/ui/components/toast"; import { Tooltip } from "@calcom/ui/components/tooltip"; -import { revalidateTeamDataCache } from "@calcom/web/app/(booking-page-wrapper)/team/[slug]/[type]/actions"; -import { revalidateEventTypesList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/event-types/actions"; -import { revalidateTeamsList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/teams/actions"; const regex = new RegExp("^[a-zA-Z0-9-]*$"); @@ -125,10 +122,8 @@ const ProfileView = () => { const deleteTeamMutation = trpc.viewer.teams.delete.useMutation({ async onSuccess() { - revalidateTeamsList(); await utils.viewer.teams.list.invalidate(); await utils.viewer.eventTypes.getUserEventGroups.invalidate(); - revalidateEventTypesList(); await utils.viewer.eventTypes.getByViewer.invalidate(); showToast(t("your_team_disbanded_successfully"), "success"); router.push(`${WEBAPP_URL}/teams`); @@ -143,7 +138,6 @@ const ProfileView = () => { async onSuccess() { await utils.viewer.teams.get.invalidate(); await utils.viewer.teams.list.invalidate(); - revalidateTeamsList(); await utils.viewer.eventTypes.invalidate(); showToast(t("success"), "success"); }, @@ -184,7 +178,6 @@ const ProfileView = () => {
@@ -280,17 +273,8 @@ const TeamProfileForm = ({ team, teamId }: TeamProfileFormProps) => { }); await utils.viewer.teams.get.invalidate(); await utils.viewer.eventTypes.getUserEventGroups.invalidate(); - revalidateEventTypesList(); // TODO: Not all changes require list invalidation await utils.viewer.teams.list.invalidate(); - revalidateTeamsList(); - - if (res?.slug) { - await revalidateTeamDataCache({ - teamSlug: res.slug, - orgSlug: team?.parent?.slug ?? null, - }); - } showToast(t("your_team_updated_successfully"), "success"); }, @@ -333,7 +317,7 @@ const TeamProfileForm = ({ team, teamId }: TeamProfileFormProps) => { try { await navigator.clipboard.writeText(value); showToast(t("team_id_copied"), "success"); - } catch (error) { + } catch { showToast(t("error_copying_to_clipboard"), "error"); } }; diff --git a/packages/features/ee/teams/pages/team-settings-view.tsx b/packages/features/ee/teams/pages/team-settings-view.tsx index c8ca1eaa686e7f..1eb2e509c9cd87 100644 --- a/packages/features/ee/teams/pages/team-settings-view.tsx +++ b/packages/features/ee/teams/pages/team-settings-view.tsx @@ -21,7 +21,6 @@ import { Form } from "@calcom/ui/components/form"; import { SettingsToggle } from "@calcom/ui/components/form"; import { CheckboxField } from "@calcom/ui/components/form"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateTeamDataCache } from "@calcom/web/app/(booking-page-wrapper)/team/[slug]/[type]/actions"; import DisableTeamImpersonation from "../components/DisableTeamImpersonation"; import { default as InternalNotePresetsView } from "../components/InternalNotePresetsView"; @@ -60,10 +59,6 @@ const BookingLimitsView = ({ team }: ProfileViewProps) => { } if (team?.slug) { // Booking limits are enforced during slot generation, which relies on the same cached team data. - revalidateTeamDataCache({ - teamSlug: team.slug, - orgSlug: team.parent?.slug ?? null, - }); } showToast(t("booking_limits_updated_successfully"), "success"); }, diff --git a/packages/features/eventtypes/components/DuplicateDialog.tsx b/packages/features/eventtypes/components/DuplicateDialog.tsx index 01d64941180510..8eb86f796dad48 100644 --- a/packages/features/eventtypes/components/DuplicateDialog.tsx +++ b/packages/features/eventtypes/components/DuplicateDialog.tsx @@ -21,7 +21,6 @@ import { Editor } from "@calcom/ui/components/editor"; import { Form } from "@calcom/ui/components/form"; import { TextField } from "@calcom/ui/components/form"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateEventTypesList } from "@calcom/web/app/(use-page-wrapper)/(main-nav)/event-types/actions"; const querySchema = z.object({ title: z.string().min(1), @@ -34,7 +33,7 @@ const querySchema = z.object({ parentId: z.coerce.number().optional().nullable(), }); -const DuplicateDialog = () => { +const DuplicateDialog = ({ onInvalidate }: { onInvalidate?: () => void | Promise } = {}) => { const utils = trpc.useUtils(); const searchParams = useCompatSearchParams(); @@ -44,7 +43,7 @@ const DuplicateDialog = () => { const { data: { pageSlug, slug, ...defaultValues }, } = useTypedQuery(querySchema); - const [searchTerm, setSearchTerm] = useState(""); + const [searchTerm, _setSearchTerm] = useState(""); const debouncedSearchTerm = useDebounce(searchTerm, 500); // react hook form @@ -72,10 +71,10 @@ const DuplicateDialog = () => { const duplicateMutation = trpc.viewer.eventTypesHeavy.duplicate.useMutation({ onSuccess: async ({ eventType }) => { + await onInvalidate?.(); await router.replace(`/event-types/${eventType.id}`); await utils.viewer.eventTypes.getUserEventGroups.invalidate(); - revalidateEventTypesList(); await utils.viewer.eventTypes.getEventTypesFromGroup.invalidate({ limit: 10, searchQuery: debouncedSearchTerm, diff --git a/packages/features/eventtypes/components/tabs/webhooks/EventWebhooksTab.tsx b/packages/features/eventtypes/components/tabs/webhooks/EventWebhooksTab.tsx index 9a1cc5d409f4ef..9552c790bf8072 100644 --- a/packages/features/eventtypes/components/tabs/webhooks/EventWebhooksTab.tsx +++ b/packages/features/eventtypes/components/tabs/webhooks/EventWebhooksTab.tsx @@ -19,9 +19,13 @@ import { Button } from "@calcom/ui/components/button"; import { DialogContent } from "@calcom/ui/components/dialog"; import { EmptyScreen } from "@calcom/ui/components/empty-screen"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateEventTypeEditPage } from "@calcom/web/app/(use-page-wrapper)/event-types/[type]/actions"; -export const EventWebhooksTab = ({ eventType }: Pick) => { +export const EventWebhooksTab = ({ + eventType, + onInvalidate +}: Pick & { + onInvalidate?: () => void | Promise; +}) => { const { t } = useLocale(); const utils = trpc.useUtils(); @@ -41,7 +45,6 @@ export const EventWebhooksTab = ({ eventType }: Pick ); })} diff --git a/packages/features/eventtypes/components/tabs/workflows/EventWorkfowsTab.tsx b/packages/features/eventtypes/components/tabs/workflows/EventWorkfowsTab.tsx index 12591e8ac074a9..f3165afb9fc744 100644 --- a/packages/features/eventtypes/components/tabs/workflows/EventWorkfowsTab.tsx +++ b/packages/features/eventtypes/components/tabs/workflows/EventWorkfowsTab.tsx @@ -23,7 +23,6 @@ import { Switch } from "@calcom/ui/components/form"; import { Icon } from "@calcom/ui/components/icon"; import { showToast } from "@calcom/ui/components/toast"; import { Tooltip } from "@calcom/ui/components/tooltip"; -import { revalidateEventTypeEditPage } from "@calcom/web/app/(use-page-wrapper)/event-types/[type]/actions"; type PartialWorkflowType = Pick< WorkflowType, @@ -50,7 +49,6 @@ const WorkflowListItem = (props: ItemProps) => { const activateEventTypeMutation = trpc.viewer.workflows.activateEventType.useMutation({ onSuccess: async () => { const offOn = isActive ? "off" : "on"; - revalidateEventTypeEditPage(eventType.id); await utils.viewer.workflows.getAllActiveWorkflows.invalidate(); await utils.viewer.eventTypes.get.invalidate({ id: eventType.id }); @@ -221,8 +219,7 @@ function EventWorkflowsTab(props: Props) { : allActiveWorkflows.concat(disabledWorkflows); setSortedWorkflows(allSortedWorkflows); } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isPending]); + }, [data?.workflows, workflows, isChildrenManagedEventType, eventType.teamId, workflowsDisableProps.isLocked, isManagedEventType]); const createMutation = trpc.viewer.workflows.create.useMutation({ onSuccess: async ({ workflow }) => { diff --git a/packages/features/shell/user-dropdown/UserDropdown.tsx b/packages/features/shell/user-dropdown/UserDropdown.tsx index aaf25d4151013e..24b6900435a180 100644 --- a/packages/features/shell/user-dropdown/UserDropdown.tsx +++ b/packages/features/shell/user-dropdown/UserDropdown.tsx @@ -48,11 +48,12 @@ export function UserDropdown({ small }: UserDropdownProps) { //@ts-ignore const Beacon = window.Beacon; // window.Beacon is defined when user actually opens up HelpScout and username is available here. On every re-render update session info, so that it is always latest. - Beacon && + if (Beacon) { Beacon("session-data", { username: user?.username || "Unknown", screenResolution: `${screen.width}x${screen.height}`, }); + } }); const [menuOpen, setMenuOpen] = useState(false); diff --git a/packages/features/webhooks/components/EventTypeWebhookListItem.tsx b/packages/features/webhooks/components/EventTypeWebhookListItem.tsx index 49f0b72fa13325..db5cc1b3b9ec7d 100644 --- a/packages/features/webhooks/components/EventTypeWebhookListItem.tsx +++ b/packages/features/webhooks/components/EventTypeWebhookListItem.tsx @@ -17,7 +17,6 @@ import { import { Switch } from "@calcom/ui/components/form"; import { showToast } from "@calcom/ui/components/toast"; import { Tooltip } from "@calcom/ui/components/tooltip"; -import { revalidateEventTypeEditPage } from "@calcom/web/app/(use-page-wrapper)/event-types/[type]/actions"; type WebhookProps = { id: string; @@ -35,6 +34,7 @@ export default function EventTypeWebhookListItem(props: { onEditWebhook: () => void; lastItem: boolean; readOnly?: boolean; + onInvalidate?: () => void | Promise; }) { const { t } = useLocale(); const utils = trpc.useUtils(); @@ -42,7 +42,7 @@ export default function EventTypeWebhookListItem(props: { const deleteWebhook = trpc.viewer.webhook.delete.useMutation({ async onSuccess() { - if (webhook.eventTypeId) revalidateEventTypeEditPage(webhook.eventTypeId); + await props.onInvalidate?.(); showToast(t("webhook_removed_successfully"), "success"); await utils.viewer.webhook.getByViewer.invalidate(); await utils.viewer.webhook.list.invalidate(); @@ -51,7 +51,7 @@ export default function EventTypeWebhookListItem(props: { }); const toggleWebhook = trpc.viewer.webhook.edit.useMutation({ async onSuccess(data) { - if (webhook.eventTypeId) revalidateEventTypeEditPage(webhook.eventTypeId); + await props.onInvalidate?.(); // TODO: Better success message showToast(t(data?.active ? "enabled" : "disabled"), "success"); await utils.viewer.webhook.getByViewer.invalidate(); diff --git a/packages/features/webhooks/components/WebhookListItem.tsx b/packages/features/webhooks/components/WebhookListItem.tsx index ba590b70ac95af..04a098fb37297f 100644 --- a/packages/features/webhooks/components/WebhookListItem.tsx +++ b/packages/features/webhooks/components/WebhookListItem.tsx @@ -17,8 +17,6 @@ import { import { Switch } from "@calcom/ui/components/form"; import { showToast } from "@calcom/ui/components/toast"; import { Tooltip } from "@calcom/ui/components/tooltip"; -import { revalidateEventTypeEditPage } from "@calcom/web/app/(use-page-wrapper)/event-types/[type]/actions"; -import { revalidateWebhooksList } from "@calcom/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/(with-loader)/actions"; type WebhookProps = { id: string; @@ -40,6 +38,7 @@ export default function WebhookListItem(props: { canEditWebhook?: boolean; canDeleteWebhook?: boolean; }; + onInvalidate?: () => void | Promise; }) { const { t } = useLocale(); const utils = trpc.useUtils(); @@ -47,8 +46,7 @@ export default function WebhookListItem(props: { const deleteWebhook = trpc.viewer.webhook.delete.useMutation({ async onSuccess() { - if (webhook.eventTypeId) revalidateEventTypeEditPage(webhook.eventTypeId); - revalidateWebhooksList(); + await props.onInvalidate?.(); showToast(t("webhook_removed_successfully"), "success"); await utils.viewer.webhook.getByViewer.invalidate(); await utils.viewer.webhook.list.invalidate(); @@ -57,8 +55,7 @@ export default function WebhookListItem(props: { }); const toggleWebhook = trpc.viewer.webhook.edit.useMutation({ async onSuccess(data) { - if (webhook.eventTypeId) revalidateEventTypeEditPage(webhook.eventTypeId); - revalidateWebhooksList(); + await props.onInvalidate?.(); // TODO: Better success message showToast(t(data?.active ? "enabled" : "disabled"), "success"); await utils.viewer.webhook.getByViewer.invalidate(); diff --git a/packages/features/webhooks/pages/webhook-edit-view.tsx b/packages/features/webhooks/pages/webhook-edit-view.tsx index 48d87332cbf08e..cb8b1e54b3a952 100644 --- a/packages/features/webhooks/pages/webhook-edit-view.tsx +++ b/packages/features/webhooks/pages/webhook-edit-view.tsx @@ -7,7 +7,6 @@ import type { WebhookTriggerEvents } from "@calcom/prisma/enums"; import { trpc } from "@calcom/trpc/react"; import { SkeletonContainer } from "@calcom/ui/components/skeleton"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateWebhooksList } from "@calcom/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/(with-loader)/actions"; import type { WebhookFormSubmitData } from "../components/WebhookForm"; import WebhookForm from "../components/WebhookForm"; @@ -25,7 +24,13 @@ type WebhookProps = { platform: boolean; }; -export function EditWebhookView({ webhook }: { webhook?: WebhookProps }) { +export function EditWebhookView({ + webhook, + onInvalidate, +}: { + webhook?: WebhookProps; + onInvalidate?: () => void | Promise; +}) { const { t } = useLocale(); const utils = trpc.useUtils(); const router = useRouter(); @@ -46,7 +51,7 @@ export function EditWebhookView({ webhook }: { webhook?: WebhookProps }) { await utils.viewer.webhook.list.invalidate(); await utils.viewer.webhook.get.invalidate({ webhookId: webhook?.id }); showToast(t("webhook_updated_successfully"), "success"); - revalidateWebhooksList(); + await onInvalidate?.(); router.push("/settings/developer/webhooks"); }, onError(error) { diff --git a/packages/features/webhooks/pages/webhook-new-view.tsx b/packages/features/webhooks/pages/webhook-new-view.tsx index e3be7c23e194ec..1c5fe59b993ef7 100644 --- a/packages/features/webhooks/pages/webhook-new-view.tsx +++ b/packages/features/webhooks/pages/webhook-new-view.tsx @@ -10,7 +10,6 @@ import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import type { RouterOutputs } from "@calcom/trpc/react"; import { showToast } from "@calcom/ui/components/toast"; -import { revalidateWebhooksList } from "@calcom/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/(with-loader)/actions"; import type { WebhookFormSubmitData } from "../components/WebhookForm"; import WebhookForm from "../components/WebhookForm"; @@ -19,9 +18,10 @@ import { subscriberUrlReserved } from "../lib/subscriberUrlReserved"; type Props = { webhooks: RouterOutputs["viewer"]["webhook"]["list"]; installedApps: RouterOutputs["viewer"]["apps"]["integrations"]; + onInvalidate?: () => void | Promise; }; -export const NewWebhookView = ({ webhooks, installedApps }: Props) => { +export const NewWebhookView = ({ webhooks, installedApps, onInvalidate }: Props) => { const searchParams = useCompatSearchParams(); const { t } = useLocale(); const utils = trpc.useUtils(); @@ -35,7 +35,7 @@ export const NewWebhookView = ({ webhooks, installedApps }: Props) => { async onSuccess() { showToast(t("webhook_created_successfully"), "success"); await utils.viewer.webhook.list.invalidate(); - revalidateWebhooksList(); + await onInvalidate?.(); router.push("/settings/developer/webhooks"); }, onError(error) { diff --git a/packages/features/webhooks/pages/webhooks-view.tsx b/packages/features/webhooks/pages/webhooks-view.tsx index d6c3460e063e71..fca1cb9c801afc 100644 --- a/packages/features/webhooks/pages/webhooks-view.tsx +++ b/packages/features/webhooks/pages/webhooks-view.tsx @@ -17,17 +17,24 @@ type WebhooksByViewer = RouterOutputs["viewer"]["webhook"]["getByViewer"]; type Props = { data: WebhooksByViewer; + onInvalidate?: () => void | Promise; }; -const WebhooksView = ({ data }: Props) => { +const WebhooksView = ({ data, onInvalidate }: Props) => { return (
- +
); }; -const WebhooksList = ({ webhooksByViewer }: { webhooksByViewer: WebhooksByViewer }) => { +const WebhooksList = ({ + webhooksByViewer, + onInvalidate, +}: { + webhooksByViewer: WebhooksByViewer; + onInvalidate?: () => void | Promise; +}) => { const { t } = useLocale(); const router = useRouter(); const { profiles, webhookGroups } = webhooksByViewer; @@ -72,6 +79,7 @@ const WebhooksList = ({ webhooksByViewer }: { webhooksByViewer: WebhooksByViewer onEditWebhook={() => router.push(`${WEBAPP_URL}/settings/developer/webhooks/${webhook.id}`) } + onInvalidate={onInvalidate} /> ))}
diff --git a/packages/lib/hooks/useLocale.ts b/packages/lib/hooks/useLocale.ts index fed348eb386e4a..337c9a122e38cf 100644 --- a/packages/lib/hooks/useLocale.ts +++ b/packages/lib/hooks/useLocale.ts @@ -4,8 +4,8 @@ import { useContext } from "react"; import { useTranslation } from "react-i18next"; import { useAtomsContext } from "@calcom/atoms/hooks/useAtomsContext"; -import { AppRouterI18nContext } from "@calcom/web/app/AppRouterI18nProvider"; -import { CustomI18nContext } from "@calcom/web/app/CustomI18nProvider"; +import { AppRouterI18nContext } from "@calcom/lib/i18n/AppRouterI18nContext"; +import { CustomI18nContext } from "@calcom/lib/i18n/CustomI18nContext"; type useLocaleReturnType = { i18n: i18n; diff --git a/packages/lib/i18n/AppRouterI18nContext.ts b/packages/lib/i18n/AppRouterI18nContext.ts new file mode 100644 index 00000000000000..ea736824192b98 --- /dev/null +++ b/packages/lib/i18n/AppRouterI18nContext.ts @@ -0,0 +1,9 @@ +import { createContext } from "react"; + +export type AppRouterI18nContextType = { + translations: Record; + ns: string; + locale: string; +}; + +export const AppRouterI18nContext = createContext(null); diff --git a/packages/lib/i18n/CustomI18nContext.ts b/packages/lib/i18n/CustomI18nContext.ts new file mode 100644 index 00000000000000..c750ecfddc3875 --- /dev/null +++ b/packages/lib/i18n/CustomI18nContext.ts @@ -0,0 +1,9 @@ +import { createContext } from "react"; + +export type CustomI18nContextType = { + translations: Record; + ns: string; + locale: string; +}; + +export const CustomI18nContext = createContext(null); diff --git a/packages/lib/legacy-request.ts b/packages/lib/legacy-request.ts new file mode 100644 index 00000000000000..9fbc2bcb9cbee0 --- /dev/null +++ b/packages/lib/legacy-request.ts @@ -0,0 +1,31 @@ +/** + * Shared utilities for building legacy request objects compatible with Pages Router API + * Used by both App Router server components and packages that need Next.js API compatibility + */ + +type HeadersLike = { entries(): IterableIterator<[string, string]> }; +type CookiesLike = { getAll(): { name: string; value: string }[] }; + +const createProxifiedObject = (object: Record) => + new Proxy(object, { + set: () => { + throw new Error("You are trying to modify 'headers' or 'cookies', which is not supported in app dir"); + }, + }); + +const buildLegacyHeaders = (headers: HeadersLike) => { + const headersObject = Object.fromEntries(headers.entries()); + return createProxifiedObject(headersObject); +}; + +const buildLegacyCookies = (cookies: CookiesLike) => { + const cookiesObject = cookies.getAll().reduce>((acc, { name, value }) => { + acc[name] = value; + return acc; + }, {}); + return createProxifiedObject(cookiesObject); +}; + +export const buildLegacyRequest = (headers: HeadersLike, cookies: CookiesLike) => { + return { headers: buildLegacyHeaders(headers), cookies: buildLegacyCookies(cookies) }; +};