Skip to content

Commit

Permalink
feat: add time grid to the week view
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Week view events will now appear on the bottom time grid. To restore the old behaviour you can set `allDay: true` on the event to make it appear at the top. 

People extending the `CalendarWeekViewComponent` will probably have to adjust their child component as the template and internal component api has changed significantly.

Closes #593
  • Loading branch information
mattlewis92 authored Jul 31, 2018
1 parent 7e7c374 commit 5cfbfc7
Show file tree
Hide file tree
Showing 25 changed files with 1,907 additions and 256 deletions.
6 changes: 5 additions & 1 deletion demos/demo-modules/draggable-external-events/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@ export class DemoComponent {
eventDropped({
event,
newStart,
newEnd
newEnd,
allDay
}: CalendarEventTimesChangedEvent): void {
const externalIndex = this.externalEvents.indexOf(event);
if (typeof allDay !== 'undefined') {
event.allDay = allDay;
}
if (externalIndex > -1) {
this.externalEvents.splice(externalIndex, 1);
this.events.push(event);
Expand Down
11 changes: 9 additions & 2 deletions demos/demo-modules/kitchen-sink/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,13 @@ export class DemoComponent {
end: addDays(new Date(), 1),
title: 'A 3 day event',
color: colors.red,
actions: this.actions
actions: this.actions,
allDay: true,
resizable: {
beforeStart: true,
afterEnd: true
},
draggable: true
},
{
start: startOfDay(new Date()),
Expand All @@ -94,7 +100,8 @@ export class DemoComponent {
start: subDays(endOfMonth(new Date()), 3),
end: addDays(endOfMonth(new Date()), 3),
title: 'A long event that spans 2 months',
color: colors.blue
color: colors.blue,
allDay: true
},
{
start: addHours(startOfDay(new Date()), 2),
Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@
"@angular/core": ">=6.0.0 <8.0.0"
},
"dependencies": {
"angular-draggable-droppable": "4.0.0-beta.13",
"angular-draggable-droppable": "^4.0.0-beta.16",
"angular-resizable-element": "^3.2.0",
"calendar-utils": "0.2.0-alpha.13",
"calendar-utils": "0.2.0-alpha.15",
"positioning": "^1.4.0"
},
"sideEffects": [
Expand Down
4 changes: 4 additions & 0 deletions src/date-adapters/date-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,8 @@ export abstract class DateAdapter implements BaseDateAdapter {
date: Date | string | number,
options?: { weekStartsOn?: number }
): Date;

abstract getHours(date: Date | string | number): number;

abstract getMinutes(date: Date | string | number): number;
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ export class CalendarAngularDateFormatter
return `Week ${weekNumber} of ${year}`;
}

/**
* The time formatting down the left hand side of the week view
*/
public weekViewHour({ date, locale }: DateFormatterParams): string {
return new DatePipe(locale).transform(date, 'h a', null, locale);
}

/**
* The time formatting down the left hand side of the day view
*/
Expand Down
5 changes: 5 additions & 0 deletions src/modules/common/calendar-date-formatter.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ export interface CalendarDateFormatterInterface {
*/
weekViewTitle({ date: Date }: DateFormatterParams): string;

/**
* The time formatting down the left hand side of the day view
*/
weekViewHour({ date: Date }: DateFormatterParams): string;

/**
* The time formatting down the left hand side of the day view
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export interface CalendarEventTimesChangedEvent<MetaType = any> {
event: CalendarEvent<MetaType>;
newStart: Date;
newEnd?: Date;
allDay?: boolean;
}
9 changes: 9 additions & 0 deletions src/modules/common/calendar-moment-date-formatter.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ export class CalendarMomentDateFormatter
.format('[Week] W [of] YYYY');
}

/**
* The time formatting down the left hand side of the week view
*/
public weekViewHour({ date, locale }: DateFormatterParams): string {
return this.moment(date)
.locale(locale)
.format('ha');
}

/**
* The time formatting down the left hand side of the day view
*/
Expand Down
7 changes: 7 additions & 0 deletions src/modules/common/calendar-native-date-formatter.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ export class CalendarNativeDateFormatter
return `Week ${weekNumber} of ${year}`;
}

/**
* The time formatting down the left hand side of the week view
*/
public weekViewHour({ date, locale }: DateFormatterParams): string {
return new Intl.DateTimeFormat(locale, { hour: 'numeric' }).format(date);
}

/**
* The time formatting down the left hand side of the day view
*/
Expand Down
5 changes: 4 additions & 1 deletion src/modules/common/calendar-resize-helper.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ export class CalendarResizeHelper {
) {}

validateResize({ rectangle }: { rectangle: ClientRect }): boolean {
if (this.minWidth && rectangle.width < this.minWidth) {
if (
this.minWidth &&
Math.ceil(rectangle.width) < Math.ceil(this.minWidth)
) {
return false;
}

Expand Down
72 changes: 63 additions & 9 deletions src/modules/common/util.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import {
CalendarEvent,
DayViewEvent,
DayViewHour,
DayViewHourSegment,
validateEvents as validateEventsWithoutLog,
WeekDay
WeekDay,
WeekViewAllDayEvent
} from 'calendar-utils';
import { DateAdapter } from '../../date-adapters/date-adapter';

export const validateEvents = (events: CalendarEvent[]) => {
const warn = (...args) => console.warn('angular-calendar', ...args);
Expand All @@ -11,14 +16,14 @@ export const validateEvents = (events: CalendarEvent[]) => {

export function isInside(outer: ClientRect, inner: ClientRect): boolean {
return (
outer.left <= inner.left &&
inner.left <= outer.right &&
outer.left <= inner.right &&
inner.right <= outer.right &&
outer.top <= inner.top &&
inner.top <= outer.bottom &&
outer.top <= inner.bottom &&
inner.bottom <= outer.bottom
Math.ceil(outer.left) <= Math.ceil(inner.left) &&
Math.ceil(inner.left) <= Math.ceil(outer.right) &&
Math.ceil(outer.left) <= Math.ceil(inner.right) &&
Math.ceil(inner.right) <= Math.ceil(outer.right) &&
Math.ceil(outer.top) <= Math.ceil(inner.top) &&
Math.ceil(inner.top) <= Math.ceil(outer.bottom) &&
Math.ceil(outer.top) <= Math.ceil(inner.bottom) &&
Math.ceil(inner.bottom) <= Math.ceil(outer.bottom)
);
}

Expand All @@ -33,3 +38,52 @@ export const trackByWeekDayHeaderDate = (index: number, day: WeekDay) =>
day.date.toISOString();

export const trackByIndex = (index: number) => index;

export const trackByHourSegment = (
index: number,
segment: DayViewHourSegment
) => segment.date.toISOString();

export const trackByHour = (index: number, hour: DayViewHour) =>
hour.segments[0].date.toISOString();

export const trackByDayOrWeekEvent = (
index: number,
weekEvent: WeekViewAllDayEvent | DayViewEvent
) => (weekEvent.event.id ? weekEvent.event.id : weekEvent.event);

const MINUTES_IN_HOUR = 60;

export function getMinutesMoved(
movedY: number,
hourSegments: number,
hourSegmentHeight: number,
eventSnapSize: number
): number {
const draggedInPixelsSnapSize = roundToNearest(
movedY,
eventSnapSize || hourSegmentHeight
);
const pixelAmountInMinutes =
MINUTES_IN_HOUR / (hourSegments * hourSegmentHeight);
return draggedInPixelsSnapSize * pixelAmountInMinutes;
}

export function getMinimumEventHeightInMinutes(
hourSegments: number,
hourSegmentHeight: number
) {
return (MINUTES_IN_HOUR / (hourSegments * hourSegmentHeight)) * 30;
}

export function getDefaultEventEnd(
dateAdapter: DateAdapter,
event: CalendarEvent,
minimumMinutes: number
): Date {
if (event.end) {
return event.end;
} else {
return dateAdapter.addMinutes(event.start, minimumMinutes);
}
}
Loading

0 comments on commit 5cfbfc7

Please sign in to comment.