perf: remove me fetching from teams by refactoring (#22444)
This commit is contained in:
@@ -1,13 +1,12 @@
|
||||
import { createRouterCaller } from "app/_trpc/context";
|
||||
import type { SearchParams } from "app/_types";
|
||||
import type { Session } from "next-auth";
|
||||
import { unstable_cache } from "next/cache";
|
||||
|
||||
import { checkAdminOrOwner } from "@calcom/features/auth/lib/checkAdminOrOwner";
|
||||
import { TeamsListing } from "@calcom/features/ee/teams/components/TeamsListing";
|
||||
import { TeamRepository } from "@calcom/lib/server/repository/team";
|
||||
import { TeamService } from "@calcom/lib/server/service/team";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { meRouter } from "@calcom/trpc/server/routers/viewer/me/_router";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
@@ -47,18 +46,24 @@ export const ServerTeamsListing = async ({
|
||||
}
|
||||
}
|
||||
|
||||
const meCaller = await createRouterCaller(meRouter);
|
||||
const [user, teams] = await Promise.all([meCaller.get(), getCachedTeams(userId)]);
|
||||
const teams = await getCachedTeams(userId);
|
||||
const userProfile = session?.user?.profile;
|
||||
const orgId = userProfile?.organizationId ?? session?.user.org?.id;
|
||||
const orgRole =
|
||||
session?.user?.org?.role ??
|
||||
userProfile?.organization?.members.find((m: { userId: number }) => m.userId === userId)?.role;
|
||||
const isOrgAdminOrOwner = checkAdminOrOwner(orgRole);
|
||||
|
||||
return {
|
||||
Main: (
|
||||
<TeamsListing
|
||||
teams={teams}
|
||||
user={user}
|
||||
orgId={orgId ?? null}
|
||||
isOrgAdmin={isOrgAdminOrOwner}
|
||||
teamNameFromInvite={teamNameFromInvite ?? null}
|
||||
errorMsgFromInvite={errorMsgFromInvite}
|
||||
/>
|
||||
),
|
||||
CTA: !user.organizationId || user.organization.isOrgAdmin ? <TeamsCTA /> : null,
|
||||
CTA: !orgId || isOrgAdminOrOwner ? <TeamsCTA /> : null,
|
||||
};
|
||||
};
|
||||
|
||||
+6
-1
@@ -8,7 +8,12 @@ import { buildLegacyRequest } from "@lib/buildLegacyCtx";
|
||||
|
||||
const OrgAdminOnlyLayout = async ({ children }: { children: React.ReactNode }) => {
|
||||
const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
|
||||
const isOrgAdminOrOwner = checkAdminOrOwner(session?.user?.org?.role);
|
||||
const userProfile = session?.user?.profile;
|
||||
const userId = session?.user?.id;
|
||||
const orgRole =
|
||||
session?.user?.org?.role ??
|
||||
userProfile?.organization?.members.find((m: { userId: number }) => m.userId === userId)?.role;
|
||||
const isOrgAdminOrOwner = checkAdminOrOwner(orgRole);
|
||||
|
||||
if (!isOrgAdminOrOwner) {
|
||||
return redirect("/settings/organizations/profile");
|
||||
|
||||
@@ -8,7 +8,12 @@ import { buildLegacyRequest } from "@lib/buildLegacyCtx";
|
||||
|
||||
const OrgAdminOnlyLayout = async ({ children }: { children: React.ReactNode }) => {
|
||||
const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
|
||||
const isOrgAdminOrOwner = checkAdminOrOwner(session?.user?.org?.role);
|
||||
const userProfile = session?.user?.profile;
|
||||
const userId = session?.user?.id;
|
||||
const orgRole =
|
||||
session?.user?.org?.role ??
|
||||
userProfile?.organization?.members.find((m: { userId: number }) => m.userId === userId)?.role;
|
||||
const isOrgAdminOrOwner = checkAdminOrOwner(orgRole);
|
||||
|
||||
if (!isOrgAdminOrOwner) {
|
||||
return redirect("/settings/organizations/profile");
|
||||
|
||||
@@ -17,7 +17,7 @@ import TeamListItem from "./TeamListItem";
|
||||
|
||||
interface Props {
|
||||
teams: RouterOutputs["viewer"]["teams"]["list"];
|
||||
user: RouterOutputs["viewer"]["me"]["get"];
|
||||
orgId: number | null;
|
||||
/**
|
||||
* True for teams that are pending invite acceptance
|
||||
*/
|
||||
@@ -28,7 +28,7 @@ export default function TeamList(props: Props) {
|
||||
const utils = trpc.useUtils();
|
||||
|
||||
const { t } = useLocale();
|
||||
const { user } = props;
|
||||
const { orgId } = props;
|
||||
|
||||
const [hideDropdown, setHideDropdown] = useState(false);
|
||||
|
||||
@@ -56,13 +56,11 @@ export default function TeamList(props: Props) {
|
||||
deleteTeamMutation.mutate({ teamId });
|
||||
}
|
||||
|
||||
if (!user) return null;
|
||||
const isUserAlreadyInAnOrganization = user.profile.organization;
|
||||
return (
|
||||
<ul className="bg-default divide-subtle border-subtle mb-2 divide-y overflow-hidden rounded-md border">
|
||||
{ORG_SELF_SERVE_ENABLED &&
|
||||
!props.pending &&
|
||||
!isUserAlreadyInAnOrganization &&
|
||||
!orgId &&
|
||||
props.teams.length >= ORG_MINIMUM_PUBLISHED_TEAMS_SELF_SERVE_HELPER_DIALOGUE &&
|
||||
props.teams.map(
|
||||
(team, i) =>
|
||||
@@ -116,7 +114,7 @@ export default function TeamList(props: Props) {
|
||||
<TeamListItem
|
||||
key={team?.id as number}
|
||||
team={team}
|
||||
user={user}
|
||||
orgId={orgId}
|
||||
onActionSelect={(action: string) => selectAction(action, team?.id as number)}
|
||||
isPending={deleteTeamMutation.isPending}
|
||||
hideDropdown={hideDropdown}
|
||||
|
||||
@@ -36,7 +36,7 @@ import { TeamRole } from "./TeamPill";
|
||||
|
||||
interface Props {
|
||||
team: RouterOutputs["viewer"]["teams"]["list"][number];
|
||||
user: RouterOutputs["viewer"]["me"]["get"];
|
||||
orgId: number | null;
|
||||
key: number;
|
||||
onActionSelect: (text: string) => void;
|
||||
isPending?: boolean;
|
||||
@@ -48,7 +48,7 @@ export default function TeamListItem(props: Props) {
|
||||
const searchParams = useCompatSearchParams();
|
||||
const { t } = useLocale();
|
||||
const utils = trpc.useUtils();
|
||||
const { team, user } = props;
|
||||
const { team, orgId } = props;
|
||||
|
||||
const showDialog = searchParams?.get("inviteModal") === "true";
|
||||
const [openMemberInvitationModal, setOpenMemberInvitationModal] = useState(showDialog);
|
||||
@@ -63,7 +63,7 @@ export default function TeamListItem(props: Props) {
|
||||
revalidateTeamsList();
|
||||
utils.viewer.teams.hasTeamPlan.invalidate();
|
||||
utils.viewer.teams.listInvites.invalidate();
|
||||
const userOrganizationId = user?.profile?.organization?.id;
|
||||
const userOrganizationId = orgId ?? undefined;
|
||||
const isSubTeamOfDifferentOrg = team.parentId ? team.parentId != userOrganizationId : false;
|
||||
const isDifferentOrg = team.isOrganization && team.id !== userOrganizationId;
|
||||
// If the user team being accepted is a sub-team of different organization or the different organization itself then page must be reloaded to let the session change reflect reliably everywhere.
|
||||
|
||||
@@ -18,14 +18,16 @@ import { UpgradeTip } from "../../../tips";
|
||||
import TeamList from "./TeamList";
|
||||
|
||||
type TeamsListingProps = {
|
||||
user: RouterOutputs["viewer"]["me"]["get"];
|
||||
orgId: number | null;
|
||||
isOrgAdmin: boolean;
|
||||
teams: RouterOutputs["viewer"]["teams"]["list"];
|
||||
teamNameFromInvite: string | null;
|
||||
errorMsgFromInvite: string | null;
|
||||
};
|
||||
|
||||
export function TeamsListing({
|
||||
user,
|
||||
orgId,
|
||||
isOrgAdmin,
|
||||
teams: data,
|
||||
teamNameFromInvite,
|
||||
errorMsgFromInvite,
|
||||
@@ -49,7 +51,7 @@ export function TeamsListing({
|
||||
}
|
||||
);
|
||||
|
||||
const isCreateTeamButtonDisabled = !!(user?.organizationId && !user?.organization?.isOrgAdmin);
|
||||
const isCreateTeamButtonDisabled = !!(orgId && !isOrgAdmin);
|
||||
|
||||
const features = [
|
||||
{
|
||||
@@ -105,18 +107,18 @@ export function TeamsListing({
|
||||
{organizationInvites.length > 0 && (
|
||||
<div className="bg-subtle mb-6 rounded-md p-5">
|
||||
<Label className="text-emphasis pb-2 font-semibold">{t("pending_organization_invites")}</Label>
|
||||
<TeamList user={user} teams={organizationInvites} pending />
|
||||
<TeamList orgId={orgId} teams={organizationInvites} pending />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{teamInvites.length > 0 && (
|
||||
<div className="bg-subtle mb-6 rounded-md p-5">
|
||||
<Label className="text-emphasis pb-2 font-semibold">{t("pending_invites")}</Label>
|
||||
<TeamList user={user} teams={teamInvites} pending />
|
||||
<TeamList orgId={orgId} teams={teamInvites} pending />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{teams.length > 0 && <TeamList user={user} teams={teams} />}
|
||||
{teams.length > 0 && <TeamList orgId={orgId} teams={teams} />}
|
||||
|
||||
{teams.length === 0 && (
|
||||
<UpgradeTip
|
||||
@@ -126,7 +128,7 @@ export function TeamsListing({
|
||||
features={features}
|
||||
background="/tips/teams"
|
||||
buttons={
|
||||
!user?.organizationId || user?.organization.isOrgAdmin ? (
|
||||
!orgId || isOrgAdmin ? (
|
||||
<div className="space-y-2 rtl:space-x-reverse sm:space-x-2">
|
||||
<ButtonGroup>
|
||||
<Button color="primary" href={`${WEBAPP_URL}/settings/teams/new`}>
|
||||
|
||||
Reference in New Issue
Block a user