fix: improved team upgrade screen to also show unpublished teams (#12492)

* improved team upgrade screen to also show unpublished teams

* Update TeamsListing.tsx

* bunch of stuff

---------

Co-authored-by: Omar López <zomars@me.com>
This commit is contained in:
Peer Richelsen 2023-11-29 21:48:26 +00:00 committed by GitHub
parent 33250652b3
commit 7f23ae156b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 207 additions and 459 deletions

View File

@ -75,22 +75,6 @@ export default function TeamList(props: Props) {
child: t("invite"),
}}
/>
{/* @TODO: uncomment once managed event types is live
<Card
icon={<Unlock className="h-5 w-5 text-blue-700" />}
variant="basic"
title={t("create_a_managed_event")}
description={t("create_a_one_one_template")}
actionButton={{
href:
"/event-types?dialog=new-eventtype&eventPage=team%2F" +
team.slug +
"&teamId=" +
team.id +
"&managed=true",
child: t("create"),
}}
/> */}
<Card
icon={<Users className="h-5 w-5 text-orange-700" />}
variant="basic"

View File

@ -13,6 +13,7 @@ import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import {
Avatar,
Badge,
Button,
ButtonGroup,
ConfirmationDialogContent,
@ -104,11 +105,15 @@ export default function TeamListItem(props: Props) {
<div className="ms-3 inline-block truncate">
<span className="text-default text-sm font-bold">{team.name}</span>
<span className="text-muted block text-xs">
{team.slug
? orgBranding
? `${orgBranding.fullDomain}/${team.slug}`
: `${process.env.NEXT_PUBLIC_WEBSITE_URL}/team/${team.slug}`
: "Unpublished team"}
{team.slug ? (
orgBranding ? (
`${orgBranding.fullDomain}/${team.slug}`
) : (
`${process.env.NEXT_PUBLIC_WEBSITE_URL}/team/${team.slug}`
)
) : (
<Badge>{t("upgrade")}</Badge>
)}
</span>
</div>
</div>
@ -180,13 +185,17 @@ export default function TeamListItem(props: Props) {
)}
<div className={classNames("flex items-center justify-between", !isInvitee && "hover:bg-muted group")}>
{!isInvitee ? (
<Link
data-testid="team-list-item-link"
href={`/settings/teams/${team.id}/profile`}
className="flex-grow cursor-pointer truncate text-sm"
title={`${team.name}`}>
{teamInfo}
</Link>
team.slug ? (
<Link
data-testid="team-list-item-link"
href={`/settings/teams/${team.id}/profile`}
className="flex-grow cursor-pointer truncate text-sm"
title={`${team.name}`}>
{teamInfo}
</Link>
) : (
<TeamPublishSection teamId={team.id}>{teamInfo}</TeamPublishSection>
)
) : (
teamInfo
)}
@ -388,3 +397,26 @@ const TeamPublishButton = ({ teamId }: { teamId: number }) => {
</DropdownMenuItem>
);
};
const TeamPublishSection = ({ children, teamId }: { children: React.ReactNode; teamId: number }) => {
const router = useRouter();
const publishTeamMutation = trpc.viewer.teams.publish.useMutation({
onSuccess(data) {
router.push(data.url);
},
onError: (error) => {
showToast(error.message, "error");
},
});
return (
<button
className="block flex-grow cursor-pointer truncate text-left text-sm"
type="button"
onClick={() => {
publishTeamMutation.mutate({ teamId });
}}>
{children}
</button>
);
};

View File

@ -102,7 +102,6 @@ export function TeamsListing() {
<TeamList teams={invites} pending />
</div>
)}
<UpgradeTip
plan="team"
title={t("calcom_is_better_with_team", { appName: APP_NAME })}

View File

@ -3,6 +3,7 @@ import type { ReactNode } from "react";
import { classNames } from "@calcom/lib";
import { useHasTeamPlan } from "@calcom/lib/hooks/useHasPaidPlan";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc";
export function UpgradeTip({
dark,
@ -29,10 +30,14 @@ export function UpgradeTip({
}) {
const { t } = useLocale();
const { isLoading, hasTeamPlan } = useHasTeamPlan();
const { data } = trpc.viewer.teams.getUpgradeable.useQuery();
const hasEnterprisePlan = false;
//const { isLoading , hasEnterprisePlan } = useHasEnterprisePlan();
if (plan === "team" && hasTeamPlan) return children;
const hasUnpublishedTeam = !!data?.[0];
if (plan === "team" && (hasTeamPlan || hasUnpublishedTeam)) return children;
if (plan === "enterprise" && hasEnterprisePlan) return children;
@ -44,7 +49,7 @@ export function UpgradeTip({
<picture className="absolute min-h-[295px] w-full rounded-lg object-cover">
<source srcSet={`${background}-dark.jpg`} media="(prefers-color-scheme: dark)" />
<img
className="absolute min-h-[295px] w-full rounded-lg object-cover object-left md:object-center select-none"
className="absolute min-h-[295px] w-full select-none rounded-lg object-cover object-left md:object-center"
src={`${background}.jpg`}
loading="lazy"
alt={title}

View File

@ -1,5 +1,5 @@
import authedProcedure from "../../../procedures/authedProcedure";
import { router } from "../../../trpc";
import { importHandler, router } from "../../../trpc";
import { ZAcceptOrLeaveInputSchema } from "./acceptOrLeave.schema";
import { ZChangeMemberRoleInputSchema } from "./changeMemberRole.schema";
import { ZCreateInputSchema } from "./create.schema";
@ -20,457 +20,139 @@ import { ZSetInviteExpirationInputSchema } from "./setInviteExpiration.schema";
import { ZUpdateInputSchema } from "./update.schema";
import { ZUpdateMembershipInputSchema } from "./updateMembership.schema";
type TeamsRouterHandlerCache = {
get?: typeof import("./get.handler").getHandler;
list?: typeof import("./list.handler").listHandler;
listOwnedTeams?: typeof import("./listOwnedTeams.handler").listOwnedTeamsHandler;
create?: typeof import("./create.handler").createHandler;
update?: typeof import("./update.handler").updateHandler;
delete?: typeof import("./delete.handler").deleteHandler;
removeMember?: typeof import("./removeMember.handler").removeMemberHandler;
inviteMember?: typeof import("./inviteMember/inviteMember.handler").inviteMemberHandler;
acceptOrLeave?: typeof import("./acceptOrLeave.handler").acceptOrLeaveHandler;
changeMemberRole?: typeof import("./changeMemberRole.handler").changeMemberRoleHandler;
getMemberAvailability?: typeof import("./getMemberAvailability.handler").getMemberAvailabilityHandler;
getMembershipbyUser?: typeof import("./getMembershipbyUser.handler").getMembershipbyUserHandler;
updateMembership?: typeof import("./updateMembership.handler").updateMembershipHandler;
publish?: typeof import("./publish.handler").publishHandler;
getUpgradeable?: typeof import("./getUpgradeable.handler").getUpgradeableHandler;
listMembers?: typeof import("./listMembers.handler").listMembersHandler;
hasTeamPlan?: typeof import("./hasTeamPlan.handler").hasTeamPlanHandler;
listInvites?: typeof import("./listInvites.handler").listInvitesHandler;
createInvite?: typeof import("./createInvite.handler").createInviteHandler;
setInviteExpiration?: typeof import("./setInviteExpiration.handler").setInviteExpirationHandler;
deleteInvite?: typeof import("./deleteInvite.handler").deleteInviteHandler;
inviteMemberByToken?: typeof import("./inviteMemberByToken.handler").inviteMemberByTokenHandler;
hasEditPermissionForUser?: typeof import("./hasEditPermissionForUser.handler").hasEditPermissionForUser;
resendInvitation?: typeof import("./resendInvitation.handler").resendInvitationHandler;
};
const UNSTABLE_HANDLER_CACHE: TeamsRouterHandlerCache = {};
const NAMESPACE = "teams";
const namespaced = (s: string) => `${NAMESPACE}.${s}`;
export const viewerTeamsRouter = router({
// Retrieves team by id
get: authedProcedure.input(ZGetInputSchema).query(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.get) {
UNSTABLE_HANDLER_CACHE.get = await import("./get.handler").then((mod) => mod.getHandler);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.get) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.get({
ctx,
input,
});
get: authedProcedure.input(ZGetInputSchema).query(async (opts) => {
const handler = await importHandler(namespaced("get"), () => import("./get.handler"));
return handler(opts);
}),
// Returns teams I a member of
list: authedProcedure.query(async ({ ctx }) => {
if (!UNSTABLE_HANDLER_CACHE.list) {
UNSTABLE_HANDLER_CACHE.list = await import("./list.handler").then((mod) => mod.listHandler);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.list) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.list({
ctx,
});
list: authedProcedure.query(async (opts) => {
const handler = await importHandler(namespaced("list"), () => import("./list.handler"));
return handler(opts);
}),
// Returns Teams I am a owner/admin of
listOwnedTeams: authedProcedure.query(async ({ ctx }) => {
if (!UNSTABLE_HANDLER_CACHE.listOwnedTeams) {
UNSTABLE_HANDLER_CACHE.listOwnedTeams = await import("./listOwnedTeams.handler").then(
(mod) => mod.listOwnedTeamsHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.listOwnedTeams) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.listOwnedTeams({
ctx,
});
listOwnedTeams: authedProcedure.query(async (opts) => {
const handler = await importHandler(namespaced("list"), () => import("./list.handler"));
return handler(opts);
}),
create: authedProcedure.input(ZCreateInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.create) {
UNSTABLE_HANDLER_CACHE.create = await import("./create.handler").then((mod) => mod.createHandler);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.create) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.create({
ctx,
input,
});
create: authedProcedure.input(ZCreateInputSchema).mutation(async (opts) => {
const handler = await importHandler(namespaced("create"), () => import("./create.handler"));
return handler(opts);
}),
// Allows team owner to update team metadata
update: authedProcedure.input(ZUpdateInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.update) {
UNSTABLE_HANDLER_CACHE.update = await import("./update.handler").then((mod) => mod.updateHandler);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.update) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.update({
ctx,
input,
});
update: authedProcedure.input(ZUpdateInputSchema).mutation(async (opts) => {
const handler = await importHandler(namespaced("update"), () => import("./update.handler"));
return handler(opts);
}),
delete: authedProcedure.input(ZDeleteInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.delete) {
UNSTABLE_HANDLER_CACHE.delete = await import("./delete.handler").then((mod) => mod.deleteHandler);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.delete) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.delete({
ctx,
input,
});
delete: authedProcedure.input(ZDeleteInputSchema).mutation(async (opts) => {
const handler = await importHandler(namespaced("delete"), () => import("./delete.handler"));
return handler(opts);
}),
removeMember: authedProcedure.input(ZRemoveMemberInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.removeMember) {
UNSTABLE_HANDLER_CACHE.removeMember = await import("./removeMember.handler").then(
(mod) => mod.removeMemberHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.removeMember) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.removeMember({
ctx,
input,
});
removeMember: authedProcedure.input(ZRemoveMemberInputSchema).mutation(async (opts) => {
const handler = await importHandler(namespaced("removeMember"), () => import("./removeMember.handler"));
return handler(opts);
}),
inviteMember: authedProcedure.input(ZInviteMemberInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.inviteMember) {
UNSTABLE_HANDLER_CACHE.inviteMember = await import("./inviteMember/inviteMember.handler").then(
(mod) => mod.inviteMemberHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.inviteMember) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.inviteMember({
ctx,
input,
});
inviteMember: authedProcedure.input(ZInviteMemberInputSchema).mutation(async (opts) => {
const handler = await importHandler(
namespaced("inviteMember"),
() => import("./inviteMember/inviteMember.handler")
);
return handler(opts);
}),
acceptOrLeave: authedProcedure.input(ZAcceptOrLeaveInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.acceptOrLeave) {
UNSTABLE_HANDLER_CACHE.acceptOrLeave = await import("./acceptOrLeave.handler").then(
(mod) => mod.acceptOrLeaveHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.acceptOrLeave) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.acceptOrLeave({
ctx,
input,
});
acceptOrLeave: authedProcedure.input(ZAcceptOrLeaveInputSchema).mutation(async (opts) => {
const handler = await importHandler(namespaced("acceptOrLeave"), () => import("./acceptOrLeave.handler"));
return handler(opts);
}),
changeMemberRole: authedProcedure.input(ZChangeMemberRoleInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.changeMemberRole) {
UNSTABLE_HANDLER_CACHE.changeMemberRole = await import("./changeMemberRole.handler").then(
(mod) => mod.changeMemberRoleHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.changeMemberRole) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.changeMemberRole({
ctx,
input,
});
changeMemberRole: authedProcedure.input(ZChangeMemberRoleInputSchema).mutation(async (opts) => {
const handler = await importHandler(
namespaced("changeMemberRole"),
() => import("./changeMemberRole.handler")
);
return handler(opts);
}),
getMemberAvailability: authedProcedure
.input(ZGetMemberAvailabilityInputSchema)
.query(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.getMemberAvailability) {
UNSTABLE_HANDLER_CACHE.getMemberAvailability = await import("./getMemberAvailability.handler").then(
(mod) => mod.getMemberAvailabilityHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.getMemberAvailability) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.getMemberAvailability({
ctx,
input,
});
}),
getMembershipbyUser: authedProcedure
.input(ZGetMembershipbyUserInputSchema)
.query(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.getMembershipbyUser) {
UNSTABLE_HANDLER_CACHE.getMembershipbyUser = await import("./getMembershipbyUser.handler").then(
(mod) => mod.getMembershipbyUserHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.getMembershipbyUser) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.getMembershipbyUser({
ctx,
input,
});
}),
updateMembership: authedProcedure.input(ZUpdateMembershipInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.updateMembership) {
UNSTABLE_HANDLER_CACHE.updateMembership = await import("./updateMembership.handler").then(
(mod) => mod.updateMembershipHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.updateMembership) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.updateMembership({
ctx,
input,
});
getMemberAvailability: authedProcedure.input(ZGetMemberAvailabilityInputSchema).query(async (opts) => {
const handler = await importHandler(
namespaced("getMemberAvailability"),
() => import("./getMemberAvailability.handler")
);
return handler(opts);
}),
publish: authedProcedure.input(ZPublishInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.publish) {
UNSTABLE_HANDLER_CACHE.publish = await import("./publish.handler").then((mod) => mod.publishHandler);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.publish) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.publish({
ctx,
input,
});
getMembershipbyUser: authedProcedure.input(ZGetMembershipbyUserInputSchema).query(async (opts) => {
const handler = await importHandler(
namespaced("getMembershipbyUser"),
() => import("./getMembershipbyUser.handler")
);
return handler(opts);
}),
updateMembership: authedProcedure.input(ZUpdateMembershipInputSchema).mutation(async (opts) => {
const handler = await importHandler(
namespaced("updateMembership"),
() => import("./updateMembership.handler")
);
return handler(opts);
}),
publish: authedProcedure.input(ZPublishInputSchema).mutation(async (opts) => {
const handler = await importHandler(namespaced("publish"), () => import("./publish.handler"));
return handler(opts);
}),
/** This is a temporal endpoint so we can progressively upgrade teams to the new billing system. */
getUpgradeable: authedProcedure.query(async ({ ctx }) => {
if (!UNSTABLE_HANDLER_CACHE.getUpgradeable) {
UNSTABLE_HANDLER_CACHE.getUpgradeable = await import("./getUpgradeable.handler").then(
(mod) => mod.getUpgradeableHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.getUpgradeable) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.getUpgradeable({
ctx,
});
getUpgradeable: authedProcedure.query(async (opts) => {
const handler = await importHandler(
namespaced("getUpgradeable"),
() => import("./getUpgradeable.handler")
);
return handler(opts);
}),
listMembers: authedProcedure.input(ZListMembersInputSchema).query(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.listMembers) {
UNSTABLE_HANDLER_CACHE.listMembers = await import("./listMembers.handler").then(
(mod) => mod.listMembersHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.listMembers) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.listMembers({
ctx,
input,
});
listMembers: authedProcedure.input(ZListMembersInputSchema).query(async (opts) => {
const handler = await importHandler(namespaced("listMembers"), () => import("./listMembers.handler"));
return handler(opts);
}),
hasTeamPlan: authedProcedure.query(async ({ ctx }) => {
if (!UNSTABLE_HANDLER_CACHE.hasTeamPlan) {
UNSTABLE_HANDLER_CACHE.hasTeamPlan = await import("./hasTeamPlan.handler").then(
(mod) => mod.hasTeamPlanHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.hasTeamPlan) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.hasTeamPlan({
ctx,
});
hasTeamPlan: authedProcedure.query(async (opts) => {
const handler = await importHandler(namespaced("hasTeamPlan"), () => import("./hasTeamPlan.handler"));
return handler(opts);
}),
listInvites: authedProcedure.query(async ({ ctx }) => {
if (!UNSTABLE_HANDLER_CACHE.listInvites) {
UNSTABLE_HANDLER_CACHE.listInvites = await import("./listInvites.handler").then(
(mod) => mod.listInvitesHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.listInvites) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.listInvites({
ctx,
});
listInvites: authedProcedure.query(async (opts) => {
const handler = await importHandler(namespaced("listInvites"), () => import("./listInvites.handler"));
return handler(opts);
}),
createInvite: authedProcedure.input(ZCreateInviteInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.createInvite) {
UNSTABLE_HANDLER_CACHE.createInvite = await import("./createInvite.handler").then(
(mod) => mod.createInviteHandler
);
}
if (!UNSTABLE_HANDLER_CACHE.createInvite) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.createInvite({
ctx,
input,
});
createInvite: authedProcedure.input(ZCreateInviteInputSchema).mutation(async (opts) => {
const handler = await importHandler(namespaced("createInvite"), () => import("./createInvite.handler"));
return handler(opts);
}),
setInviteExpiration: authedProcedure
.input(ZSetInviteExpirationInputSchema)
.mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.setInviteExpiration) {
UNSTABLE_HANDLER_CACHE.setInviteExpiration = await import("./setInviteExpiration.handler").then(
(mod) => mod.setInviteExpirationHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.setInviteExpiration) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.setInviteExpiration({
ctx,
input,
});
}),
deleteInvite: authedProcedure.input(ZDeleteInviteInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.deleteInvite) {
UNSTABLE_HANDLER_CACHE.deleteInvite = await import("./deleteInvite.handler").then(
(mod) => mod.deleteInviteHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.deleteInvite) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.deleteInvite({
ctx,
input,
});
setInviteExpiration: authedProcedure.input(ZSetInviteExpirationInputSchema).mutation(async (opts) => {
const handler = await importHandler(
namespaced("setInviteExpiration"),
() => import("./setInviteExpiration.handler")
);
return handler(opts);
}),
inviteMemberByToken: authedProcedure
.input(ZInviteMemberByTokenSchemaInputSchema)
.mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.inviteMemberByToken) {
UNSTABLE_HANDLER_CACHE.inviteMemberByToken = await import("./inviteMemberByToken.handler").then(
(mod) => mod.inviteMemberByTokenHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.inviteMemberByToken) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.inviteMemberByToken({
ctx,
input,
});
}),
hasEditPermissionForUser: authedProcedure
.input(ZHasEditPermissionForUserSchema)
.query(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.hasEditPermissionForUser) {
UNSTABLE_HANDLER_CACHE.hasEditPermissionForUser = await import(
"./hasEditPermissionForUser.handler"
).then((mod) => mod.hasEditPermissionForUser);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.hasEditPermissionForUser) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.hasEditPermissionForUser({
ctx,
input,
});
}),
resendInvitation: authedProcedure.input(ZResendInvitationInputSchema).mutation(async ({ ctx, input }) => {
if (!UNSTABLE_HANDLER_CACHE.resendInvitation) {
UNSTABLE_HANDLER_CACHE.resendInvitation = await import("./resendInvitation.handler").then(
(mod) => mod.resendInvitationHandler
);
}
// Unreachable code but required for type safety
if (!UNSTABLE_HANDLER_CACHE.resendInvitation) {
throw new Error("Failed to load handler");
}
return UNSTABLE_HANDLER_CACHE.resendInvitation({
ctx,
input,
});
deleteInvite: authedProcedure.input(ZDeleteInviteInputSchema).mutation(async (opts) => {
const handler = await importHandler(namespaced("deleteInvite"), () => import("./deleteInvite.handler"));
return handler(opts);
}),
inviteMemberByToken: authedProcedure.input(ZInviteMemberByTokenSchemaInputSchema).mutation(async (opts) => {
const handler = await importHandler(
namespaced("inviteMemberByToken"),
() => import("./inviteMemberByToken.handler")
);
return handler(opts);
}),
hasEditPermissionForUser: authedProcedure.input(ZHasEditPermissionForUserSchema).query(async (opts) => {
const handler = await importHandler(
namespaced("hasEditPermissionForUser"),
() => import("./hasEditPermissionForUser.handler")
);
return handler(opts);
}),
resendInvitation: authedProcedure.input(ZResendInvitationInputSchema).mutation(async (opts) => {
const handler = await importHandler(
namespaced("resendInvitation"),
() => import("./resendInvitation.handler")
);
return handler(opts);
}),
});

View File

@ -48,3 +48,5 @@ export const acceptOrLeaveHandler = async ({ ctx, input }: AcceptOrLeaveOptions)
}
}
};
export default acceptOrLeaveHandler;

View File

@ -71,3 +71,5 @@ export const changeMemberRoleHandler = async ({ ctx, input }: ChangeMemberRoleOp
// Sync Services: Close.com
closeComUpsertTeamUser(membership.team, membership.user, membership.role);
};
export default changeMemberRoleHandler;

View File

@ -117,3 +117,5 @@ export const createHandler = async ({ ctx, input }: CreateOptions) => {
team: createdTeam,
};
};
export default createHandler;

View File

@ -59,3 +59,5 @@ async function getInviteLink(token = "", isOrg = false, orgMembers = 0) {
if (isOrg || orgMembers > 0) return orgInviteLink;
return teamInviteLink;
}
export default createInviteHandler;

View File

@ -82,3 +82,5 @@ export const deleteHandler = async ({ ctx, input }: DeleteOptions) => {
// Sync Services: Close.cm
closeComDeleteTeam(deletedTeam);
};
export default deleteHandler;

View File

@ -31,3 +31,5 @@ export const deleteInviteHandler = async ({ ctx, input }: DeleteInviteOptions) =
await prisma.verificationToken.delete({ where: { id: verificationToken.id } });
};
export default deleteInviteHandler;

View File

@ -36,3 +36,5 @@ export const getHandler = async ({ ctx, input }: GetOptions) => {
},
};
};
export default getHandler;

View File

@ -54,3 +54,5 @@ export const getMemberAvailabilityHandler = async ({ ctx, input }: GetMemberAvai
{ user: member.user }
);
};
export default getMemberAvailabilityHandler;

View File

@ -29,3 +29,5 @@ export const getMembershipbyUserHandler = async ({ ctx, input }: GetMembershipby
},
});
};
export default getMembershipbyUserHandler;

View File

@ -43,3 +43,5 @@ export const getUpgradeableHandler = async ({ ctx }: GetUpgradeableOptions) => {
});
return teams;
};
export default getUpgradeableHandler;

View File

@ -17,3 +17,5 @@ export const hasEditPermissionForUser = async ({ ctx, input }: HasEditPermission
input,
});
};
export default hasEditPermissionForUser;

View File

@ -23,3 +23,5 @@ export const hasTeamPlanHandler = async ({ ctx }: HasTeamPlanOptions) => {
});
return { hasTeamPlan: !!hasTeamPlan };
};
export default hasTeamPlanHandler;

View File

@ -140,3 +140,5 @@ export const inviteMemberHandler = async ({ ctx, input }: InviteMemberOptions) =
}
return input;
};
export default inviteMemberHandler;

View File

@ -64,3 +64,5 @@ export const inviteMemberByTokenHandler = async ({ ctx, input }: InviteMemberByT
return verificationToken.team.name;
};
export default inviteMemberByTokenHandler;

View File

@ -41,3 +41,5 @@ export const listHandler = async ({ ctx }: ListOptions) => {
inviteToken: inviteTokens.find((token) => token.identifier === `invite-link-for-teamId-${_team.id}`),
}));
};
export default listHandler;

View File

@ -18,3 +18,5 @@ export const listInvitesHandler = async ({ ctx }: ListInvitesOptions) => {
},
});
};
export default listInvitesHandler;

View File

@ -54,3 +54,5 @@ export const listMembersHandler = async ({ ctx, input }: ListMembersOptions) =>
return Object.values(users);
};
export default listMembersHandler;

View File

@ -157,3 +157,5 @@ export const publishHandler = async ({ ctx, input }: PublishOptions) => {
message: "Team published successfully",
};
};
export default publishHandler;

View File

@ -121,3 +121,5 @@ export const removeMemberHandler = async ({ ctx, input }: RemoveMemberOptions) =
closeComDeleteTeamMembership(membership.user);
if (IS_TEAM_BILLING_ENABLED) await updateQuantitySubscriptionFromStripe(input.teamId);
};
export default removeMemberHandler;

View File

@ -58,3 +58,5 @@ export const resendInvitationHandler = async ({ ctx, input }: InviteMemberOption
return input;
};
export default resendInvitationHandler;

View File

@ -39,3 +39,5 @@ export const setInviteExpirationHandler = async ({ ctx, input }: SetInviteExpira
},
});
};
export default setInviteExpirationHandler;

View File

@ -97,3 +97,5 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
darkBrandColor: updatedTeam.darkBrandColor,
};
};
export default updateHandler;

View File

@ -32,3 +32,5 @@ export const updateMembershipHandler = async ({ ctx, input }: UpdateMembershipOp
},
});
};
export default updateMembershipHandler;