-
Notifications
You must be signed in to change notification settings - Fork 7.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: new org onboarding wizard #13139
Changes from all commits
3e86dfd
09b3424
594bc9f
613105f
f5fa46c
a0ab667
a49da46
ef4e4ba
88904d0
23e8ecd
cc0f200
553b551
755f0fb
3af2f04
eb0ba77
fea6fd7
e83e48a
a4861d5
0a86e78
ef565fe
11e397c
87dff01
978c13b
2442795
a5fc88a
274266e
0a1847b
2743d29
456a53b
91ea7b8
02b3153
60cd45f
5ef33ae
ac4ff80
87992b4
fc89050
330e514
a8de971
7d72736
c2ee412
ed1d547
6b264a8
acf11bb
a206b14
70d422f
dfc4ef7
af6ed4b
49928eb
0183958
6d0d0d9
6ded450
bd01671
10c26c0
4368116
631141b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -107,17 +107,22 @@ | |
isOrgVerified, | ||
hasSubteam, | ||
organizationId, | ||
isDnsSetup, | ||
index, | ||
}: { | ||
user: { id: number; email: string; username: string | null; role?: MembershipRole }; | ||
isUnpublished?: boolean; | ||
isOrg?: boolean; | ||
isOrgVerified?: boolean; | ||
isDnsSetup?: boolean; | ||
hasSubteam?: true; | ||
organizationId?: number | null; | ||
index?: number; | ||
}, | ||
workerInfo: WorkerInfo | ||
) => { | ||
const slug = `${isOrg ? "org" : "team"}-${workerInfo.workerIndex}-${Date.now()}`; | ||
const slugIndex = index ? `-count-${index}` : ""; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If an index is passed in (when called in loop we append it to the slug to prevent duplicates for this run) |
||
const slug = `${isOrg ? "org" : "team"}-${workerInfo.workerIndex}-${Date.now()}${slugIndex}`; | ||
const data: PrismaType.TeamCreateInput = { | ||
name: `user-id-${user.id}'s ${isOrg ? "Org" : "Team"}`, | ||
isOrganization: isOrg, | ||
|
@@ -128,9 +133,9 @@ | |
if (isOrg) { | ||
data.organizationSettings = { | ||
create: { | ||
isOrganizationVerified: !!isOrgVerified, | ||
orgAutoAcceptEmail: user.email.split("@")[1], | ||
isOrganizationConfigured: false, | ||
isOrganizationVerified: !!isOrgVerified, | ||
isOrganizationConfigured: isDnsSetup, | ||
}, | ||
}; | ||
} | ||
|
@@ -211,6 +216,7 @@ | |
scenario: { | ||
seedRoutingForms?: boolean; | ||
hasTeam?: true; | ||
numberOfTeams?: number; | ||
teamRole?: MembershipRole; | ||
teammates?: CustomUserOpts[]; | ||
schedulingType?: SchedulingType; | ||
|
@@ -219,6 +225,7 @@ | |
teamEventLength?: number; | ||
isOrg?: boolean; | ||
isOrgVerified?: boolean; | ||
isDnsSetup?: boolean; | ||
hasSubteam?: true; | ||
isUnpublished?: true; | ||
} = {} | ||
|
@@ -382,103 +389,108 @@ | |
include: userIncludes, | ||
}); | ||
if (scenario.hasTeam) { | ||
const team = await createTeamAndAddUser( | ||
{ | ||
user: { | ||
id: user.id, | ||
email: user.email, | ||
username: user.username, | ||
role: scenario.teamRole || "OWNER", | ||
}, | ||
isUnpublished: scenario.isUnpublished, | ||
isOrg: scenario.isOrg, | ||
isOrgVerified: scenario.isOrgVerified, | ||
hasSubteam: scenario.hasSubteam, | ||
organizationId: opts?.organizationId, | ||
}, | ||
workerInfo | ||
); | ||
store.teams.push(team); | ||
const teamEvent = await createTeamEventType(user, team, scenario); | ||
if (scenario.teammates) { | ||
// Create Teammate users | ||
const teamMates = []; | ||
for (const teammateObj of scenario.teammates) { | ||
const teamUser = await prisma.user.create({ | ||
data: createUser(workerInfo, teammateObj), | ||
}); | ||
|
||
// Add teammates to the team | ||
await prisma.membership.create({ | ||
data: { | ||
teamId: team.id, | ||
userId: teamUser.id, | ||
role: MembershipRole.MEMBER, | ||
accepted: true, | ||
}, | ||
}); | ||
|
||
// Add teammate to the host list of team event | ||
await prisma.host.create({ | ||
data: { | ||
userId: teamUser.id, | ||
eventTypeId: teamEvent.id, | ||
isFixed: scenario.schedulingType === SchedulingType.COLLECTIVE ? true : false, | ||
const numberOfTeams = scenario.numberOfTeams || 1; | ||
for (let i = 0; i < numberOfTeams; i++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If a number of teams is passed in -> create X amount of them |
||
const team = await createTeamAndAddUser( | ||
{ | ||
user: { | ||
id: user.id, | ||
email: user.email, | ||
username: user.username, | ||
role: scenario.teamRole || "OWNER", | ||
}, | ||
}); | ||
|
||
const teammateFixture = createUserFixture( | ||
await prisma.user.findUniqueOrThrow({ | ||
where: { id: teamUser.id }, | ||
include: userIncludes, | ||
}), | ||
store.page | ||
); | ||
teamMates.push(teamUser); | ||
store.users.push(teammateFixture); | ||
} | ||
// Add Teammates to OrgUsers | ||
if (scenario.isOrg) { | ||
const orgProfilesCreate = teamMates | ||
.map((teamUser) => ({ | ||
user: { | ||
connect: { | ||
id: teamUser.id, | ||
}, | ||
isUnpublished: scenario.isUnpublished, | ||
isOrg: scenario.isOrg, | ||
isOrgVerified: scenario.isOrgVerified, | ||
isDnsSetup: scenario.isDnsSetup, | ||
hasSubteam: scenario.hasSubteam, | ||
organizationId: opts?.organizationId, | ||
}, | ||
workerInfo | ||
); | ||
store.teams.push(team); | ||
const teamEvent = await createTeamEventType(user, team, scenario); | ||
if (scenario.teammates) { | ||
// Create Teammate users | ||
const teamMates = []; | ||
for (const teammateObj of scenario.teammates) { | ||
const teamUser = await prisma.user.create({ | ||
data: createUser(workerInfo, teammateObj), | ||
}); | ||
|
||
// Add teammates to the team | ||
await prisma.membership.create({ | ||
data: { | ||
teamId: team.id, | ||
userId: teamUser.id, | ||
role: MembershipRole.MEMBER, | ||
accepted: true, | ||
}, | ||
uid: v4(), | ||
username: teamUser.username || teamUser.email.split("@")[0], | ||
})) | ||
.concat([ | ||
{ | ||
user: { connect: { id: user.id } }, | ||
uid: v4(), | ||
username: user.username || user.email.split("@")[0], | ||
}); | ||
|
||
// Add teammate to the host list of team event | ||
await prisma.host.create({ | ||
data: { | ||
userId: teamUser.id, | ||
eventTypeId: teamEvent.id, | ||
isFixed: scenario.schedulingType === SchedulingType.COLLECTIVE ? true : false, | ||
}, | ||
]); | ||
}); | ||
|
||
const teammateFixture = createUserFixture( | ||
await prisma.user.findUniqueOrThrow({ | ||
where: { id: teamUser.id }, | ||
include: userIncludes, | ||
}), | ||
store.page | ||
); | ||
teamMates.push(teamUser); | ||
store.users.push(teammateFixture); | ||
} | ||
// Add Teammates to OrgUsers | ||
if (scenario.isOrg) { | ||
const orgProfilesCreate = teamMates | ||
.map((teamUser) => ({ | ||
user: { | ||
connect: { | ||
id: teamUser.id, | ||
}, | ||
}, | ||
uid: v4(), | ||
username: teamUser.username || teamUser.email.split("@")[0], | ||
})) | ||
.concat([ | ||
{ | ||
user: { connect: { id: user.id } }, | ||
uid: v4(), | ||
username: user.username || user.email.split("@")[0], | ||
}, | ||
]); | ||
|
||
const existingProfiles = await prisma.profile.findMany({ | ||
where: { | ||
userId: _user.id, | ||
}, | ||
}); | ||
const existingProfiles = await prisma.profile.findMany({ | ||
where: { | ||
userId: _user.id, | ||
}, | ||
}); | ||
|
||
await prisma.team.update({ | ||
where: { | ||
id: team.id, | ||
}, | ||
data: { | ||
orgProfiles: _user.profiles.length | ||
? { | ||
connect: _user.profiles.map((profile) => ({ id: profile.id })), | ||
} | ||
: { | ||
create: orgProfilesCreate.filter( | ||
(profile) => !existingProfiles.map((p) => p.userId).includes(profile.user.connect.id) | ||
), | ||
}, | ||
}, | ||
}); | ||
await prisma.team.update({ | ||
where: { | ||
id: team.id, | ||
}, | ||
data: { | ||
orgProfiles: _user.profiles.length | ||
? { | ||
connect: _user.profiles.map((profile) => ({ id: profile.id })), | ||
} | ||
: { | ||
create: orgProfilesCreate.filter( | ||
(profile) => | ||
!existingProfiles.map((p) => p.userId).includes(profile.user.connect.id) | ||
), | ||
}, | ||
}, | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
|
@@ -842,7 +854,7 @@ | |
) { | ||
const csrfToken = await page | ||
.context() | ||
.request.get("/api/auth/csrf") | ||
Check failure on line 857 in apps/web/playwright/fixtures/users.ts
|
||
.then((response) => response.json()) | ||
.then((json) => json.csrfToken); | ||
const data = { | ||
|
@@ -877,7 +889,7 @@ | |
await page.fill('[name="name"]', "Stripe Stripeson"); | ||
await page.fill('[name="email"]', "test@example.com"); | ||
|
||
await Promise.all([page.waitForURL("/payment/*"), page.press('[name="email"]', "Enter")]); | ||
Check failure on line 892 in apps/web/playwright/fixtures/users.ts
|
||
|
||
await makePaymentUsingStripe(page); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -196,7 +196,7 @@ | |
previewLink = `/forms/${formId}`; | ||
} | ||
|
||
await page.goto(`${previewLink}${queryString ? `?${queryString}` : ""}`); | ||
Check failure on line 199 in apps/web/playwright/lib/testUtils.ts
|
||
|
||
// HACK: There seems to be some issue with the inputs to the form getting reset if we don't wait. | ||
await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
|
@@ -347,6 +347,8 @@ | |
await page.fill("[name=cardExpiry]", "12/30"); | ||
await page.fill("[name=cardCvc]", "111"); | ||
await page.fill("[name=billingName]", "Stripe Stripeson"); | ||
await page.selectOption("[name=billingCountry]", "US"); | ||
await page.fill("[name=billingPostalCode]", "12345"); | ||
Comment on lines
+350
to
+351
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stripe seems to have added this in the checkout page? |
||
await page.click(".SubmitButton--complete-Shimmer"); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not an optional step now. User has to click the Continue/Checkout button