Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx
Original file line number Diff line number Diff line change
@@ -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";

Expand Down Expand Up @@ -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,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
10 changes: 4 additions & 6 deletions packages/features/ee/teams/components/TeamList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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);

Expand Down Expand Up @@ -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) =>
Expand Down Expand Up @@ -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}
Expand Down
6 changes: 3 additions & 3 deletions packages/features/ee/teams/components/TeamListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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.
Expand Down
16 changes: 9 additions & 7 deletions packages/features/ee/teams/components/TeamsListing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -49,7 +51,7 @@ export function TeamsListing({
}
);

const isCreateTeamButtonDisabled = !!(user?.organizationId && !user?.organization?.isOrgAdmin);
const isCreateTeamButtonDisabled = !!(orgId && !isOrgAdmin);

const features = [
{
Expand Down Expand Up @@ -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
Expand All @@ -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`}>
Expand Down
Loading