Merge branch 'main' into chore/revert-appDir-2
This commit is contained in:
commit
a49323f599
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@calcom/web",
|
||||
"version": "3.6.0",
|
||||
"version": "3.6.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"analyze": "ANALYZE=true next build",
|
||||
|
|
|
@ -6,6 +6,7 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
|
|||
import { getDefaultEvent } from "@calcom/lib/defaultEvents";
|
||||
import { maybeGetBookingUidFromSeat } from "@calcom/lib/server/maybeGetBookingUidFromSeat";
|
||||
import prisma, { bookingMinimalSelect } from "@calcom/prisma";
|
||||
import { BookingStatus } from "@calcom/prisma/client";
|
||||
|
||||
export default function Type() {
|
||||
// Just redirect to the schedule page to reschedule it.
|
||||
|
@ -63,6 +64,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||
dynamicEventSlugRef: true,
|
||||
dynamicGroupSlugRef: true,
|
||||
user: true,
|
||||
status: true,
|
||||
},
|
||||
});
|
||||
const dynamicEventSlugRef = booking?.dynamicEventSlugRef || "";
|
||||
|
@ -73,6 +75,17 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||
} as const;
|
||||
}
|
||||
|
||||
// If booking is already CANCELLED or REJECTED, we can't reschedule this booking. Take the user to the booking page which would show it's correct status and other details.
|
||||
// A booking that has been rescheduled to a new booking will also have a status of CANCELLED
|
||||
if (booking.status === BookingStatus.CANCELLED || booking.status === BookingStatus.REJECTED) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/booking/${uid}`,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (!booking?.eventType && !booking?.dynamicEventSlugRef) {
|
||||
// TODO: Show something in UI to let user know that this booking is not rescheduleable
|
||||
return {
|
||||
|
|
|
@ -126,6 +126,34 @@ test.describe("pro user", () => {
|
|||
await bookFirstEvent(page);
|
||||
});
|
||||
|
||||
test("Can cancel the recently created booking and shouldn't be allowed to reschedule it", async ({
|
||||
page,
|
||||
users,
|
||||
}, testInfo) => {
|
||||
// Because it tests the entire booking flow + the cancellation + rebooking
|
||||
test.setTimeout(testInfo.timeout * 3);
|
||||
await bookFirstEvent(page);
|
||||
await expect(page.locator(`[data-testid="attendee-email-${testEmail}"]`)).toHaveText(testEmail);
|
||||
await expect(page.locator(`[data-testid="attendee-name-${testName}"]`)).toHaveText(testName);
|
||||
|
||||
const [pro] = users.get();
|
||||
await pro.apiLogin();
|
||||
|
||||
await page.goto("/bookings/upcoming");
|
||||
await page.locator('[data-testid="cancel"]').click();
|
||||
await page.waitForURL((url) => {
|
||||
return url.pathname.startsWith("/booking/");
|
||||
});
|
||||
await page.locator('[data-testid="confirm_cancel"]').click();
|
||||
|
||||
const cancelledHeadline = page.locator('[data-testid="cancelled-headline"]');
|
||||
await expect(cancelledHeadline).toBeVisible();
|
||||
const bookingCancelledId = new URL(page.url()).pathname.split("/booking/")[1];
|
||||
await page.goto(`/reschedule/${bookingCancelledId}`);
|
||||
// Should be redirected to the booking details page which shows the cancelled headline
|
||||
await expect(page.locator('[data-testid="cancelled-headline"]')).toBeVisible();
|
||||
});
|
||||
|
||||
test("can book an event that requires confirmation and then that booking can be accepted by organizer", async ({
|
||||
page,
|
||||
users,
|
||||
|
|
|
@ -535,7 +535,8 @@ type CustomUserOptsKeys =
|
|||
| "locale"
|
||||
| "name"
|
||||
| "email"
|
||||
| "organizationId";
|
||||
| "organizationId"
|
||||
| "role";
|
||||
type CustomUserOpts = Partial<Pick<Prisma.User, CustomUserOptsKeys>> & {
|
||||
timeZone?: TimeZoneEnum;
|
||||
eventTypes?: SupportedTestEventTypes[];
|
||||
|
@ -565,6 +566,7 @@ const createUser = (
|
|||
completedOnboarding: opts?.completedOnboarding ?? true,
|
||||
timeZone: opts?.timeZone ?? TimeZoneEnum.UK,
|
||||
locale: opts?.locale ?? "en",
|
||||
role: opts?.role ?? "USER",
|
||||
...getOrganizationRelatedProps({ organizationId: opts?.organizationId, role: opts?.roleInOrganization }),
|
||||
schedules:
|
||||
opts?.completedOnboarding ?? true
|
||||
|
|
|
@ -354,6 +354,6 @@ export async function doOnOrgDomain(
|
|||
await callback({ page });
|
||||
}
|
||||
|
||||
// When App directory is there, this is the 404 page text. It is commented till it's disabled
|
||||
// export const NotFoundPageText = "This page could not be found";
|
||||
export const NotFoundPageText = "ERROR 404";
|
||||
// When App directory is there, this is the 404 page text. We should work on fixing the 404 page as it changed due to app directory.
|
||||
export const NotFoundPageText = "This page could not be found";
|
||||
// export const NotFoundPageText = "ERROR 404";
|
||||
|
|
|
@ -18,12 +18,14 @@ function capitalize(text: string) {
|
|||
}
|
||||
|
||||
test.describe("Organization", () => {
|
||||
test("should be able to create an organization and complete onboarding", async ({
|
||||
test("Admin should be able to create an organization and complete onboarding", async ({
|
||||
page,
|
||||
users,
|
||||
emails,
|
||||
}) => {
|
||||
const orgOwner = await users.create();
|
||||
const orgOwner = await users.create({
|
||||
role: "ADMIN",
|
||||
});
|
||||
const orgDomain = `${orgOwner.username}-org`;
|
||||
const orgName = capitalize(`${orgOwner.username}-org`);
|
||||
await orgOwner.apiLogin();
|
||||
|
|
|
@ -13,7 +13,9 @@ test.describe("Settings/admin A/B tests", () => {
|
|||
url: "http://localhost:3000",
|
||||
},
|
||||
]);
|
||||
const user = await users.create();
|
||||
const user = await users.create({
|
||||
role: "ADMIN",
|
||||
});
|
||||
await user.apiLogin();
|
||||
|
||||
await page.goto("/settings/admin");
|
||||
|
|
|
@ -109,10 +109,6 @@
|
|||
background: var(--cal-brand);
|
||||
}
|
||||
|
||||
html {
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
body {
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
|
|
@ -13,7 +13,9 @@ import GoogleCalendarService from "../lib/CalendarService";
|
|||
import { createBookingAndFetchGCalEvent, deleteBookingAndEvent, assertValueExists } from "./testUtils";
|
||||
|
||||
test.describe("Google Calendar", async () => {
|
||||
test.describe("Test using the primary calendar", async () => {
|
||||
// Skip till the tests are flaky
|
||||
// eslint-disable-next-line playwright/no-skipped-test
|
||||
test.describe.skip("Test using the primary calendar", async () => {
|
||||
let qaUsername: string;
|
||||
let qaGCalCredential: CredentialPayload;
|
||||
test.beforeAll(async () => {
|
||||
|
|
|
@ -232,6 +232,12 @@ const providers: Provider[] = [
|
|||
if (role !== "ADMIN") return role;
|
||||
// User's identity provider is not "CAL"
|
||||
if (user.identityProvider !== IdentityProvider.CAL) return role;
|
||||
|
||||
if (process.env.NEXT_PUBLIC_IS_E2E) {
|
||||
console.warn("E2E testing is enabled, skipping password and 2FA requirements for Admin");
|
||||
return role;
|
||||
}
|
||||
|
||||
// User's password is valid and two-factor authentication is enabled
|
||||
if (isPasswordValid(credentials.password, false, true) && user.twoFactorEnabled) return role;
|
||||
// Code is running in a development environment
|
||||
|
|
|
@ -383,7 +383,7 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps)
|
|||
try {
|
||||
// Required for Safari but also works on Chrome
|
||||
// Credits to https://wolfgangrittner.dev/how-to-use-clipboard-api-in-firefox/
|
||||
if (typeof ClipboardItem) {
|
||||
if (typeof ClipboardItem !== "undefined") {
|
||||
const inviteLinkClipbardItem = new ClipboardItem({
|
||||
"text/plain": new Promise(async (resolve) => {
|
||||
// Instead of doing async work and then writing to clipboard, do async work in clipboard API itself
|
||||
|
|
|
@ -199,17 +199,19 @@ export default function MemberListItem(props: Props) {
|
|||
StartIcon={Clock}
|
||||
/>
|
||||
</Tooltip> */}
|
||||
<Tooltip content={t("view_public_page")}>
|
||||
<Button
|
||||
target="_blank"
|
||||
href={`${bookerUrl}/${props.member.username}`}
|
||||
color="secondary"
|
||||
className={classNames(!editMode ? "rounded-r-md" : "")}
|
||||
variant="icon"
|
||||
StartIcon={ExternalLink}
|
||||
disabled={!props.member.accepted}
|
||||
/>
|
||||
</Tooltip>
|
||||
{!!props.member.accepted && (
|
||||
<Tooltip content={t("view_public_page")}>
|
||||
<Button
|
||||
target="_blank"
|
||||
href={`${bookerUrl}/${props.member.username}`}
|
||||
color="secondary"
|
||||
className={classNames(!editMode ? "rounded-r-md" : "")}
|
||||
variant="icon"
|
||||
StartIcon={ExternalLink}
|
||||
disabled={!props.member.accepted}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
{editMode && (
|
||||
<Dropdown>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
|
Loading…
Reference in New Issue
Block a user