Skip to content
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: Implement editable OOO events feature #15932

Merged
merged 29 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2b39a67
feat: Implement edit ooo feature
Souptik2001 Jul 26, 2024
b109791
Merge branch 'main' into feature-15828-edit-ooo-events
Souptik2001 Jul 26, 2024
07a0e74
refactor: Refactor button text and gap between buttons
Souptik2001 Jul 26, 2024
b737ad1
fix: Fix entry create and edit edge cases
Souptik2001 Jul 27, 2024
410bdc0
chore: Change "edit ooo event" modal title
Souptik2001 Jul 27, 2024
9625ab3
chore: Add tooltips to entry eidt and delete buttons
Souptik2001 Jul 27, 2024
e8f0dc3
feat: Reset form on form close event
Souptik2001 Jul 27, 2024
cbbbad0
refactor: Refactor reset-form function
Souptik2001 Jul 27, 2024
64127f8
chore: Rename create or edit OOO as suggested
Souptik2001 Jul 28, 2024
825bb46
refactor: Refactor component and function names
Souptik2001 Jul 28, 2024
1cd1df1
feat: Improve ooo events email notifications
Souptik2001 Jul 28, 2024
0862e92
Merge branch 'main' into feature-15828-edit-ooo-events
Souptik2001 Jul 29, 2024
909498e
fix: Fix email templates
Souptik2001 Jul 29, 2024
27d2100
feat: Add e2e test for ooo event edit functionality
Souptik2001 Jul 29, 2024
f0c7a7f
refactor: Create separate test for edit ooo event
Souptik2001 Jul 29, 2024
a3bf1e9
fix: Remove extra user from redirect user configuration test
Souptik2001 Jul 29, 2024
d47952f
Merge branch 'main' into feature-15828-edit-ooo-events
Amit91848 Aug 6, 2024
1a68ebf
chore: code refactor
Amit91848 Aug 7, 2024
b385146
remove log
Amit91848 Aug 7, 2024
298965d
Merge branch 'main' into feature-15828-edit-ooo-events
Amit91848 Aug 7, 2024
53a41a3
chore: Update ooo-input-schema uuid data type
Souptik2001 Aug 7, 2024
95f41ce
Merge branch 'main' into feature-15828-edit-ooo-events
Souptik2001 Aug 7, 2024
92777c7
Merge branch 'main' into feature-15828-edit-ooo-events
Souptik2001 Aug 17, 2024
5c8c10c
fix: Address feedbacks
Souptik2001 Aug 17, 2024
57b7b59
Merge branch 'main' into feature-15828-edit-ooo-events
Amit91848 Aug 29, 2024
acea1ab
chore: code splitting and refactor
Amit91848 Aug 29, 2024
470e01c
Merge branch 'main' into feature-15828-edit-ooo-events
anikdhabal Aug 29, 2024
ea2f347
fix: e2e
Amit91848 Aug 29, 2024
c9f6ec3
Merge branch 'main' into feature-15828-edit-ooo-events
Amit91848 Aug 29, 2024
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
372 changes: 22 additions & 350 deletions apps/web/pages/settings/my-account/out-of-office/index.tsx

Large diffs are not rendered by default.

95 changes: 93 additions & 2 deletions apps/web/playwright/out-of-office.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ test.describe("Out of office", () => {
await user.apiLogin();

await page.goto("/settings/my-account/out-of-office");
await page.waitForLoadState("networkidle");

await page.getByTestId("add_entry_ooo").click();
await page.waitForLoadState("networkidle");
await page.getByTestId("reason_select").click();

await page.getByTestId("select-option-4").click();

await page.getByTestId("notes_input").click();
await page.getByTestId("notes_input").fill("Demo notes");
await page.getByTestId("create-entry-ooo-redirect").click();
await page.getByTestId("create-or-edit-entry-ooo-redirect").click();

await expect(page.locator(`data-testid=table-redirect-n-a`)).toBeVisible();
});
Expand Down Expand Up @@ -62,8 +64,10 @@ test.describe("Out of office", () => {
await user.apiLogin();

await page.goto(`/settings/my-account/out-of-office`);
await page.waitForLoadState("networkidle");

await page.getByTestId("add_entry_ooo").click();
await page.waitForLoadState("networkidle");
await page.getByTestId("reason_select").click();

await page.getByTestId("select-option-4").click();
Expand All @@ -79,12 +83,98 @@ test.describe("Out of office", () => {
await page.locator("#react-select-3-input").press("Enter");

// send request
await page.getByTestId("create-entry-ooo-redirect").click();
await page.getByTestId("create-or-edit-entry-ooo-redirect").click();

// expect table-redirect-toUserId to be visible
await expect(page.locator(`data-testid=table-redirect-${userTo.username}`)).toBeVisible();
});

test("User can edit out of office entry", async ({ page, users }) => {
const user = await users.create({ name: "userOne" });
const userTo = await users.create({ name: "userTwo" });
const userToSecond = await users.create({ name: "userThree" });

const team = await prisma.team.create({
data: {
name: "test-insights",
slug: `test-insights-${Date.now()}-${randomString(5)}}`,
},
});

// create memberships
await prisma.membership.createMany({
data: [
{
userId: user.id,
teamId: team.id,
accepted: true,
role: "ADMIN",
},
{
userId: userTo.id,
teamId: team.id,
accepted: true,
role: "ADMIN",
},
{
userId: userToSecond.id,
teamId: team.id,
accepted: true,
role: "ADMIN",
},
],
});

// Skip creating the ooo entry through front-end as we can assume that it has already been tested above.
const uuid = uuidv4();
await prisma.outOfOfficeEntry.create({
data: {
start: dayjs().startOf("day").toDate(),
end: dayjs().startOf("day").add(1, "w").toDate(),
uuid,
user: { connect: { id: user.id } },
toUser: { connect: { id: userTo.id } },
createdAt: new Date(),
reason: {
connect: {
id: 1,
},
},
},
});

await user.apiLogin();

await page.goto(`/settings/my-account/out-of-office`);
await page.waitForLoadState("networkidle");

// expect table-redirect-toUserId to be visible
await expect(page.locator(`data-testid=table-redirect-${userTo.username}`)).toBeVisible();

// Open the edit modal and change redirect user and note.
await page.getByTestId(`ooo-edit-${userTo.username}`).click();

await page.getByTestId("notes_input").click();
await page.getByTestId("notes_input").fill("Changed notes");

await page.getByTestId("team_username_select").click();

await page.locator("#react-select-3-input").fill("userThree");
await page.locator("#react-select-3-input").press("Enter");

// send request
await page.getByTestId("create-or-edit-entry-ooo-redirect").click();

// expect entry with new username exist.
await expect(page.locator(`data-testid=table-redirect-${userToSecond.username}`)).toBeVisible();

// expect new note to be present.
await expect(page.locator(`data-testid=ooo-entry-note-${userToSecond.username}`)).toBeVisible();
await expect(page.locator(`data-testid=ooo-entry-note-${userToSecond.username}`)).toContainText(
"Changed notes"
);
});

test("Profile redirection", async ({ page, users }) => {
const user = await users.create({ name: "userOne" });
const userTo = await users.create({ name: "userTwo" });
Expand All @@ -106,6 +196,7 @@ test.describe("Out of office", () => {
});

await page.goto(`/${user.username}`);
await page.waitForLoadState("networkidle");

const eventTypeLink = page.locator('[data-testid="event-type-link"]').first();
await eventTypeLink.click();
Expand Down
10 changes: 9 additions & 1 deletion apps/web/public/static/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -2348,7 +2348,13 @@
"success_entry_created": "Successfully created a new entry",
"booking_redirect_email_subject": "Booking redirect notification",
"booking_redirect_email_title": "Booking Redirect Notification",
"booking_redirect_email_description": "You have received a booking redirection from {{toName}} so their profile links will be redirect to yours for the time interval: ",
"booking_redirect_email_description": "You have received a booking redirection from {{eventOwner}} so their profile links will be redirect to yours for the time interval: \"{{dates}}\"",
"booking_redirect_updated_email_subject": "Booking redirect edit notification",
"booking_redirect_updated_email_title": "Booking Redirect Edit Notification",
"booking_redirect_updated_email_description": "Your booking redirection from {{eventOwner}} for interval \"{{oldDates}}\" have been udpated. New time interval for the redirection is: \"{{dates}}\"",
"booking_redirect_cancelled_email_subject": "Booking redirect cancel notification",
"booking_redirect_cancelled_email_title": "Booking Redirect Cancel Notification",
"booking_redirect_cancelled_email_description": "Your booking redirection from {{eventOwner}}, for time interval \"{{dates}}\" have been cancelled.",
"success_accept_booking_redirect": "You have accepted this booking redirect request.",
"success_reject_booking_redirect": "You have rejected this booking redirect request.",
"copy_link_booking_redirect_request": "Copy link to share request",
Expand All @@ -2359,6 +2365,7 @@
"redirect_team_disabled": "Provide a link to a team member when OOO (Team plan required)",
"out_of_office_unavailable_list": "Out of office unavailability list",
"success_deleted_entry_out_of_office": "Successfully deleted entry",
"success_edited_entry_out_of_office": "Successfully edited entry",
"temporarily_out_of_office": "Temporarily Out-Of-Office?",
"add_a_redirect": "Add a redirect",
"create_entry": "Create entry",
Expand Down Expand Up @@ -2486,6 +2493,7 @@
"ooo_create_entry_modal": "Go Out of Office",
"ooo_select_reason": "Select reason",
"create_an_out_of_office": "Go Out of Office",
"edit_an_out_of_office": "Edit Out of Office Entry",
"submit_feedback": "Submit Feedback",
"host_no_show": "Your host didn't show up",
"no_show_description": "You can reschedule another meeting with them",
Expand Down
32 changes: 26 additions & 6 deletions packages/emails/src/templates/BookingRedirectEmailNotification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,39 @@ export const BookingRedirectEmailNotification = (
) => {
return (
<BaseEmailHtml
subject={props.language("booking_redirect_email_subject")}
title={props.language("booking_redirect_email_title")}>
subject={props.language(
{
add: "booking_redirect_email_subject",
update: "booking_redirect_updated_email_subject",
cancel: "booking_redirect_cancelled_email_subject",
}[props.action]
)}
title={props.language(
{
add: "booking_redirect_email_title",
update: "booking_redirect_updated_email_title",
cancel: "booking_redirect_cancelled_email_title",
}[props.action]
)}>
<p
style={{
color: "black",
fontSize: "16px",
lineHeight: "24px",
fontWeight: "400",
}}>
{props.language("booking_redirect_email_description", {
toName: props.toName,
})}
{props.dates}
{props.language(
{
add: "booking_redirect_email_description",
update: "booking_redirect_updated_email_description",
cancel: "booking_redirect_cancelled_email_description",
}[props.action],
{
eventOwner: props.eventOwner,
dates: props.dates,
oldDates: props.oldDates ?? "",
}
)}
<br />
<div
style={{
Expand Down
11 changes: 10 additions & 1 deletion packages/emails/templates/booking-redirect-notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import BaseEmail from "./_base-email";
export interface IBookingRedirect {
language: TFunction;
fromEmail: string;
eventOwner: string;
toEmail: string;
toName: string;
oldDates?: string;
dates: string;
action: "add" | "update" | "cancel";
}

export default class BookingRedirectNotification extends BaseEmail {
Expand All @@ -26,7 +29,13 @@ export default class BookingRedirectNotification extends BaseEmail {
return {
to: `${this.bookingRedirect.toName} <${this.bookingRedirect.toEmail}>`,
from: `${EMAIL_FROM_NAME} <${this.getMailerOptions().from}>`,
subject: this.bookingRedirect.language("booking_redirect_email_subject"),
subject: this.bookingRedirect.language(
{
add: "booking_redirect_email_subject",
update: "booking_redirect_updated_email_subject",
cancel: "booking_redirect_cancelled_email_subject",
}[this.bookingRedirect.action]
),
html: await renderEmail("BookingRedirectEmailNotification", {
...this.bookingRedirect,
}),
Expand Down
Loading
Loading