Files
cal.diy/packages/lib/server/repository/organization.ts
T
c2a07e221d feat: platform onboarding flow and dashboard (#14721)
* add endpoint to fetch managed user from client id

* update typings

* minor tweaks

* custom hook to fetch managed users from client id

* add translations for platform onboarding

* add isPlatformOrg boolean to figure out which is platform and which is not

* set isPlatform hook based on data obtained from org

* add limitWidth prop to control component width

* add props to shell to make sidebar display different tabs based on if the shell isPlattform or not

* platform related pages

* fix merge conflicts

* fix merge conflicts

* platform oauth client form and card

* remove everything related to platform from organization

* update oauth client card and form

* fixup

* fix imports and remove logs

* fixup

* update redirect url

* split oauth client form into separate update and create forms

* separate forms for create and edit oauth clients

* fixup

* fixup

* dynamic routes for oauth client edit page

* fixup fixup

* fix to not show error when redirect uri is empty

* refactor create handler for org

* cleaup comments

* add custom hook to check user billing

* export managed user type

* refactor platform index page

* refactor edit and create pages

* dashboard component containing oauth client list and managed user

* common oauth client form used for create and edit form

* platform pricing helper

* platform pricing component

* fix typing and data response for billing

* use custom hook to check team billing info

* fix type checks

* upgrade conditional rendering for upgrade to org banner

* add isLoading prop to check button loading state

* pass in button handler

* add custom hook to subscribe to stripe and typings

* update typings

* fix incorrect endpoint

* pass in team id as prop

* fix type check

* update stripe success and cancel redirect url

* add and pass redirect url param to custom hook

* custom hooks for platform

* cleanup

* update imports

* fix merge conflicts

* fixup

* fixup fixup

* fixup

* merge conflicts fixup

* merge conlficts battle :(

* minor fixes

* skip admin checks for a platform client

* fix typo

* append slug with _platform for a platform user

* PR feedback

* dashboard refactor

* bring back org form to its orginal state

* add platform folder to ee

* update typings

* use new create platform form

* fixup

* fix typo and update plans

* simplifying rendering

* remove managed users endpoint since it already exists

* url for endpoint

* rename tabs

* pr feedback

* managed users endpoint

* update endpoint

* remove form

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: exception <erik@erosemberg.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2024-05-09 13:01:10 -04:00

162 lines
4.2 KiB
TypeScript

import { getOrgUsernameFromEmail } from "@calcom/features/auth/signup/utils/getOrgUsernameFromEmail";
import { IS_TEAM_BILLING_ENABLED } from "@calcom/lib/constants";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { prisma } from "@calcom/prisma";
import { MembershipRole } from "@calcom/prisma/enums";
import { createAProfileForAnExistingUser } from "../../createAProfileForAnExistingUser";
import { UserRepository } from "./user";
const orgSelect = {
id: true,
name: true,
slug: true,
logoUrl: true,
};
export class OrganizationRepository {
static async createWithExistingUserAsOwner({
orgData,
owner,
}: {
orgData: {
name: string;
slug: string;
isOrganizationConfigured: boolean;
isOrganizationAdminReviewed: boolean;
autoAcceptEmail: string;
seats: number | null;
pricePerSeat: number | null;
isPlatform: boolean;
};
owner: {
id: number;
email: string;
nonOrgUsername: string;
};
}) {
logger.debug("createWithExistingUserAsOwner", safeStringify({ orgData, owner }));
const organization = await this.create(orgData);
const ownerProfile = await createAProfileForAnExistingUser({
user: {
id: owner.id,
email: owner.email,
currentUsername: owner.nonOrgUsername,
},
organizationId: organization.id,
});
await prisma.membership.create({
data: {
userId: owner.id,
role: MembershipRole.OWNER,
accepted: true,
teamId: organization.id,
},
});
return { organization, ownerProfile };
}
static async createWithNonExistentOwner({
orgData,
owner,
}: {
orgData: {
name: string;
slug: string;
isOrganizationConfigured: boolean;
isOrganizationAdminReviewed: boolean;
autoAcceptEmail: string;
seats: number | null;
pricePerSeat: number | null;
isPlatform: boolean;
};
owner: {
email: string;
};
}) {
logger.debug("createWithNonExistentOwner", safeStringify({ orgData, owner }));
const organization = await this.create(orgData);
const ownerUsernameInOrg = getOrgUsernameFromEmail(owner.email, orgData.autoAcceptEmail);
const ownerInDb = await UserRepository.create({
email: owner.email,
username: ownerUsernameInOrg,
organizationId: organization.id,
});
await prisma.membership.create({
data: {
userId: ownerInDb.id,
role: MembershipRole.OWNER,
accepted: true,
teamId: organization.id,
},
});
return {
orgOwner: ownerInDb,
organization,
ownerProfile: {
username: ownerUsernameInOrg,
},
};
}
static async create(orgData: {
name: string;
slug: string;
isOrganizationConfigured: boolean;
isOrganizationAdminReviewed: boolean;
autoAcceptEmail: string;
seats: number | null;
pricePerSeat: number | null;
isPlatform: boolean;
}) {
return await prisma.team.create({
data: {
name: orgData.name,
isOrganization: true,
...(!IS_TEAM_BILLING_ENABLED ? { slug: orgData.slug } : {}),
organizationSettings: {
create: {
isAdminReviewed: orgData.isOrganizationAdminReviewed,
isOrganizationVerified: true,
isOrganizationConfigured: orgData.isOrganizationConfigured,
orgAutoAcceptEmail: orgData.autoAcceptEmail,
},
},
metadata: {
...(IS_TEAM_BILLING_ENABLED ? { requestedSlug: orgData.slug } : {}),
orgSeats: orgData.seats,
orgPricePerSeat: orgData.pricePerSeat,
isPlatform: orgData.isPlatform,
},
isPlatform: orgData.isPlatform,
},
});
}
static async findById({ id }: { id: number }) {
return prisma.team.findUnique({
where: {
id,
isOrganization: true,
},
select: orgSelect,
});
}
static async findByIdIncludeOrganizationSettings({ id }: { id: number }) {
return prisma.team.findUnique({
where: {
id,
isOrganization: true,
},
select: {
...orgSelect,
organizationSettings: true,
},
});
}
}