Skip to content

Commit

Permalink
Merge branch 'main' into fix/event-moving-with-hour-start-option
Browse files Browse the repository at this point in the history
  • Loading branch information
Dohyung Ahn committed Jul 27, 2022
2 parents 0227397 + 74a9807 commit 087b6dd
Show file tree
Hide file tree
Showing 33 changed files with 1,018 additions and 350 deletions.
14 changes: 9 additions & 5 deletions apps/calendar/examples/00-calendar-app.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,23 @@
<hr />
<div class="sidebar-item">
<input type="checkbox" id="1" value="1" checked />
<label class="checkbox checkbox-1" for="1">My Calendar</label>
<label class="checkbox checkbox-calendar checkbox-1" for="1">My Calendar</label>
</div>
<div class="sidebar-item">
<input type="checkbox" id="2" value="2" checked />
<label class="checkbox checkbox-2" for="2">Work</label>
<label class="checkbox checkbox-calendar checkbox-2" for="2">Work</label>
</div>
<div class="sidebar-item">
<input type="checkbox" id="3" value="3" checked />
<label class="checkbox checkbox-3" for="3">Family</label>
<label class="checkbox checkbox-calendar checkbox-3" for="3">Family</label>
</div>
<div class="sidebar-item">
<input type="checkbox" id="4" value="4" checked />
<label class="checkbox checkbox-4" for="4">Friends</label>
<label class="checkbox checkbox-calendar checkbox-4" for="4">Friends</label>
</div>
<div class="sidebar-item">
<input type="checkbox" id="5" value="5" checked />
<label class="checkbox checkbox-5" for="5">Travel</label>
<label class="checkbox checkbox-calendar checkbox-5" for="5">Travel</label>
</div>
<hr />
<div class="app-footer">© NHN Cloud Corp.</div>
Expand Down Expand Up @@ -107,6 +107,10 @@
/>
</button>
<span class="navbar--range"></span>
<div class="nav-checkbox">
<input class="checkbox-collapse" type="checkbox" id="collapse" value="collapse" />
<label for="collapse">Collapse duplicate events and disable the detail popup</label>
</div>
</nav>
<main id="app"></main>
</section>
Expand Down
20 changes: 18 additions & 2 deletions apps/calendar/examples/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
var dropdownTrigger = $('.dropdown-trigger');
var dropdownTriggerIcon = $('.dropdown-icon');
var dropdownContent = $('.dropdown-content');
var checkboxCollapse = $('.checkbox-collapse');
var sidebar = $('.sidebar');

// App State
Expand Down Expand Up @@ -73,7 +74,7 @@
}

function setAllCheckboxes(checked) {
var checkboxes = $$('input[type="checkbox"]');
var checkboxes = $$('.sidebar-item > input[type="checkbox"]');

checkboxes.forEach(function (checkbox) {
checkbox.checked = checked;
Expand Down Expand Up @@ -125,13 +126,28 @@
});

dropdownContent.addEventListener('click', function (e) {
var targetViewName;

if ('viewName' in e.target.dataset) {
cal.changeView(e.target.dataset.viewName);
targetViewName = e.target.dataset.viewName;
cal.changeView(targetViewName);
checkboxCollapse.disabled = targetViewName === 'month';
toggleDropdownState();
update();
}
});

checkboxCollapse.addEventListener('change', function (e) {
if ('checked' in e.target) {
cal.setOptions({
week: {
collapseDuplicateEvents: !!e.target.checked,
},
useDetailPopup: !e.target.checked,
});
}
});

sidebar.addEventListener('click', function (e) {
if ('value' in e.target) {
if (e.target.value === 'all') {
Expand Down
15 changes: 13 additions & 2 deletions apps/calendar/examples/scripts/mock-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,25 @@ function generateRandomEvent(calendar, renderStart, renderEnd) {
}

function generateRandomEvents(viewName, renderStart, renderEnd) {
var i;
var event;
var i, j;
var event, duplicateEvent;
var events = [];

MOCK_CALENDARS.forEach(function(calendar) {
for (i = 0; i < chance.integer({ min: 20, max: 50 }); i += 1) {
event = generateRandomEvent(calendar, renderStart, renderEnd);
events.push(event);

if (i % 5 === 0) {
for (j = 0; j < chance.integer({min: 0, max: 2}); j+= 1) {
duplicateEvent = JSON.parse(JSON.stringify(event));
duplicateEvent.id += `-${j}`;
duplicateEvent.calendarId = chance.integer({min: 1, max: 5}).toString();
duplicateEvent.goingDuration = 30 * chance.integer({min: 0, max: 4});
duplicateEvent.comingDuration = 30 * chance.integer({min: 0, max: 4});
events.push(duplicateEvent);
}
}
}
});

Expand Down
11 changes: 10 additions & 1 deletion apps/calendar/examples/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@
font-size: 1.25rem;
}

.navbar .nav-checkbox {
margin-left: auto;
}

input:disabled + label {
color: #ccc;
cursor: not-allowed;
}

.toastui-calendar-template-time strong {
color: inherit;
}
Expand All @@ -93,7 +102,7 @@
position: relative;
}

.checkbox:not(.checkbox-all)::before {
.checkbox-calendar::before {
content: "";
position: absolute;
left: -1.5rem;
Expand Down
12 changes: 8 additions & 4 deletions apps/calendar/playwright/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ export const DAY_VIEW_PAGE_URL = generatePageUrl('e2e-day-view--fixed-events');

export const WEEK_VIEW_PAGE_URL = generatePageUrl('e2e-week-view--fixed-events');

export const MONTH_VIEW_EMPTY_PAGE_URL = generatePageUrl('e2e-month-view--empty');

export const MONTH_VIEW_PAGE_URL = generatePageUrl('e2e-month-view--fixed-events');

export const WEEK_VIEW_TIMEZONE_PAGE_URL = generatePageUrl(
'e2e-week-view--different-primary-timezone'
);

export const WEEK_VIEW_DUPLICATE_EVENTS_PAGE_URL = generatePageUrl(
'e2e-week-view--duplicate-events'
);

export const MONTH_VIEW_EMPTY_PAGE_URL = generatePageUrl('e2e-month-view--empty');

export const MONTH_VIEW_PAGE_URL = generatePageUrl('e2e-month-view--fixed-events');
2 changes: 1 addition & 1 deletion apps/calendar/playwright/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export async function getBoundingBox(locator: Locator): Promise<BoundingBox> {
}

export function getTimeEventSelector(title: string): string {
return `[data-testid^="time-event-${title}"]`;
return `[data-testid^="time-event-${title}-"]`;
}

export function getGuideTimeEventSelector(): string {
Expand Down
122 changes: 120 additions & 2 deletions apps/calendar/playwright/week/timeGridEventClick.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { expect, test } from '@playwright/test';

import { mockWeekViewEvents } from '../../stories/mocks/mockWeekViewEvents';
import { WEEK_VIEW_PAGE_URL } from '../configs';
import { WEEK_VIEW_DUPLICATE_EVENTS_PAGE_URL, WEEK_VIEW_PAGE_URL } from '../configs';
import { getBoundingBox, getTimeEventSelector } from '../utils';

test.beforeEach(async ({ page }) => {
await page.goto(WEEK_VIEW_PAGE_URL);
});

const targetEvents = mockWeekViewEvents.filter(({ isAllday }) => !isAllday);

targetEvents.forEach(({ title }) => {
test(`Click event: show popup when ${title} is clicked`, async ({ page }) => {
// Given
Expand All @@ -27,3 +26,122 @@ targetEvents.forEach(({ title }) => {
await expect(detailPopup).toBeVisible();
});
});

test.describe('Collapse duplicate events', () => {
test.beforeEach(async ({ page }) => {
await page.goto(WEEK_VIEW_DUPLICATE_EVENTS_PAGE_URL);
});

const collapsedEvents = mockWeekViewEvents.filter(({ title }) =>
title.match(/duplicate event(\s\d)?$/)
);
const [collapsedEvent] = collapsedEvents;

test('The duplicate events are sorted according to the result of getDuplicateEvents option.', ({
page,
}) => {
// Given
// getDuplicateEvents: sort by calendarId in descending order
const sortedDuplicateEvents = mockWeekViewEvents
.filter(({ title }) => title.startsWith('duplicate event 2'))
.sort((a, b) => (b.calendarId > a.calendarId ? 1 : -1));
let prevX = -1;

// When
// Nothing

// Then
sortedDuplicateEvents.forEach(async (event) => {
const eventLocator = page.locator(getTimeEventSelector(event.title));
const { x } = await getBoundingBox(eventLocator);
expect(prevX).toBeLessThan(x);

prevX = x;
});
});

collapsedEvents.forEach((event) => {
test(`When clicking the collapsed duplicate event, it should be expanded. - ${event.title}`, async ({
page,
}) => {
// Given
const collapsedEventLocator = page.locator(getTimeEventSelector(event.title));
const { x, y, width: widthBeforeClick } = await getBoundingBox(collapsedEventLocator);
const mainEventLocator = page.locator(getTimeEventSelector(`${event.title} - main`));
const { width: mainEventWidth } = await getBoundingBox(mainEventLocator);

// When
await page.mouse.move(x + 2, y + 2);
await page.mouse.down();
await page.mouse.up();

// Then
const { width: widthAfterClick } = await getBoundingBox(collapsedEventLocator);
expect(widthAfterClick).toBeGreaterThan(widthBeforeClick);
expect(widthAfterClick).toBeCloseTo(mainEventWidth, -1);
});
});

const otherEvents = mockWeekViewEvents.filter(({ title }) => {
return (
title === 'duplicate event with durations' || // duplicate event in the same duplicate event group
title === 'duplicate event 2' || // duplicate event but not in the same duplicate event group
title === 'short time event' // normal event
);
});
otherEvents.forEach((otherEvent) => {
test(`When clicking the other event (title: ${otherEvent.title}), the previous expanded event should be collapsed.`, async ({
page,
}) => {
// Given
const collapsedEventLocator = page.locator(getTimeEventSelector(collapsedEvent.title));
const { x, y, width: widthBeforeClick } = await getBoundingBox(collapsedEventLocator);
await page.mouse.move(x + 2, y + 2);
await page.mouse.down();
await page.mouse.up();

// When
const otherEventLocator = page.locator(getTimeEventSelector(otherEvent.title));
const {
x: otherX,
y: otherY,
width: otherWidthBeforeClick,
} = await getBoundingBox(otherEventLocator);
await page.mouse.move(otherX + 2, otherY + 2);
await page.mouse.down();
await page.mouse.up();

// Then
const { width: widthAfterClick } = await getBoundingBox(collapsedEventLocator);
const { width: otherWidthAfterClick } = await getBoundingBox(otherEventLocator);
expect(widthAfterClick).toBeCloseTo(widthBeforeClick, -1);

if (otherEvent.title.includes('duplicate')) {
// if the next clicked event is duplicate, it should be expanded.
expect(otherWidthAfterClick).toBeGreaterThan(otherWidthBeforeClick);
}
});
});

test('When clicking one day of a two-day duplicate event, the other day also should be expanded.', async ({
page,
}) => {
// Given
const longCollapsedEventTitle = 'duplicate long event';
const longCollapsedEventLocator = page.locator(getTimeEventSelector(longCollapsedEventTitle));
const firstDayLocator = longCollapsedEventLocator.first();
const lastDayLocator = longCollapsedEventLocator.last();
const { x, y, width: widthBeforeClick } = await getBoundingBox(firstDayLocator);

// When
await page.mouse.move(x + 2, y + 2);
await page.mouse.down();
await page.mouse.up();

// Then
const { width: widthAfterClick } = await getBoundingBox(firstDayLocator);
const { width: widthAfterClickOnLastDay } = await getBoundingBox(lastDayLocator);
expect(widthAfterClick).toBeGreaterThan(widthBeforeClick);
expect(widthAfterClickOnLastDay).toBeCloseTo(widthAfterClick);
});
});
Loading

0 comments on commit 087b6dd

Please sign in to comment.