From 2760fc69581077e581bfd804b9cad4f003d3ae6e Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Sat, 24 Aug 2019 17:03:18 +0100 Subject: [PATCH] feat(day-view): merge the week and day view components BREAKING CHANGE: The day and week view have now merged. For most users this should be a seamless migration, however there are some edge cases that you may need to take account for: Any custom styles you used for the day view will need to be adjusted. The `cal-day-view-theme` sass mixin is now gone as all the styles are shared between the week and day view. The `eventWidth` option is removed, events now fill the available width. If using `[daysInWeek]="1"` on the week view, the date and title formatters for the day view will be used instead. The week view now has a border top applied to the top of the component container, rather than the top of the day headers container. The `getDayView` and `getDayViewHourGrid` functions have been removed from the `CalendarUtils` service. The following interfaces from `calendar-utils` were renamed: `DayViewHourSegment` -> `WeekViewHourSegment`, `DayViewHour` -> `WeekViewHour`, `DayViewEvent` -> `WeekViewTimeEvent` The day view scheduler demo is now based off the week view instead, please check the updated demo code for how to migrate: https://mattlewis92.github.io/angular-calendar/#/day-view-scheduler If using a custom template for the `hourSegmentTemplate`, you must pass `let-isTimeLabel="isTimeLabel"` as a local variable and then change `
` to `
` Closes #889 --- package-lock.json | 6 +- package.json | 2 +- .../src/angular-calendar.scss | 1 - .../modules/common/calendar-utils.provider.ts | 14 - .../src/modules/common/util.ts | 12 +- .../day/calendar-day-view-event.component.ts | 94 --- ...alendar-day-view-hour-segment.component.ts | 44 -- .../day/calendar-day-view.component.ts | 613 ++---------------- .../src/modules/day/calendar-day-view.scss | 141 +--- .../src/modules/day/calendar-day.module.ts | 26 +- .../calendar-week-view-event.component.ts | 18 +- ...lendar-week-view-hour-segment.component.ts | 21 +- .../week/calendar-week-view.component.ts | 24 +- .../src/modules/week/calendar-week-view.scss | 2 + .../test/calendar-day-view.component.spec.ts | 394 ++--------- .../before-view-render/component.ts | 12 +- .../day-view-scheduler.component.ts | 18 +- .../drag-to-create-events/component.ts | 4 +- .../selectable-period/component.ts | 6 +- 19 files changed, 187 insertions(+), 1265 deletions(-) delete mode 100644 projects/angular-calendar/src/modules/day/calendar-day-view-event.component.ts delete mode 100644 projects/angular-calendar/src/modules/day/calendar-day-view-hour-segment.component.ts diff --git a/package-lock.json b/package-lock.json index 3b3a2056a..e2a7bfb1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4631,9 +4631,9 @@ "dev": true }, "calendar-utils": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/calendar-utils/-/calendar-utils-0.5.0.tgz", - "integrity": "sha512-LNLe4wPCU44X/fWTUySXbZaz/6HMCfZLqmP86r1SasqaGgPHSHD6T+V5L5XQR0rq/prbzShQnEf8H4XgVnZ4ig==" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/calendar-utils/-/calendar-utils-0.6.0.tgz", + "integrity": "sha512-USWFfi/jp32b/0g2VO4eSYddMcZwuChqXWHj5YD4hHAF49iKTJsXQtM9ifEfSE4HsdRixU0v/QB2NdOh/8C9aQ==" }, "call-me-maybe": { "version": "1.0.1", diff --git a/package.json b/package.json index b6d42ee8d..7c4ef10d6 100644 --- a/package.json +++ b/package.json @@ -145,7 +145,7 @@ "dependencies": { "angular-draggable-droppable": "^4.3.2", "angular-resizable-element": "^3.2.4", - "calendar-utils": "^0.5.0", + "calendar-utils": "^0.6.0", "positioning": "^2.0.0" }, "sideEffects": [ diff --git a/projects/angular-calendar/src/angular-calendar.scss b/projects/angular-calendar/src/angular-calendar.scss index b5212e65a..5a8c94041 100644 --- a/projects/angular-calendar/src/angular-calendar.scss +++ b/projects/angular-calendar/src/angular-calendar.scss @@ -6,6 +6,5 @@ @mixin cal-theme($overrides) { @include cal-month-view-theme($overrides); @include cal-week-view-theme($overrides); - @include cal-day-view-theme($overrides); @include cal-tooltip-theme($overrides); } diff --git a/projects/angular-calendar/src/modules/common/calendar-utils.provider.ts b/projects/angular-calendar/src/modules/common/calendar-utils.provider.ts index e32415c61..da659ffef 100644 --- a/projects/angular-calendar/src/modules/common/calendar-utils.provider.ts +++ b/projects/angular-calendar/src/modules/common/calendar-utils.provider.ts @@ -5,13 +5,7 @@ import { GetWeekViewHeaderArgs, WeekDay, GetWeekViewArgs, - GetDayViewArgs, - DayView, - GetDayViewHourGridArgs, - DayViewHour, WeekView, - getDayView, - getDayViewHourGrid, getMonthView, getWeekViewHeader, getWeekView @@ -33,12 +27,4 @@ export class CalendarUtils { getWeekView(args: GetWeekViewArgs): WeekView { return getWeekView(this.dateAdapter, args); } - - getDayView(args: GetDayViewArgs): DayView { - return getDayView(this.dateAdapter, args); - } - - getDayViewHourGrid(args: GetDayViewHourGridArgs): DayViewHour[] { - return getDayViewHourGrid(this.dateAdapter, args); - } } diff --git a/projects/angular-calendar/src/modules/common/util.ts b/projects/angular-calendar/src/modules/common/util.ts index 61e11c704..8f36b9be6 100644 --- a/projects/angular-calendar/src/modules/common/util.ts +++ b/projects/angular-calendar/src/modules/common/util.ts @@ -1,8 +1,8 @@ import { CalendarEvent, - DayViewEvent, - DayViewHour, - DayViewHourSegment, + WeekViewTimeEvent, + WeekViewHour, + WeekViewHourSegment, validateEvents as validateEventsWithoutLog, ViewPeriod, WeekDay, @@ -40,15 +40,15 @@ export const trackByWeekDayHeaderDate = (index: number, day: WeekDay) => export const trackByHourSegment = ( index: number, - segment: DayViewHourSegment + segment: WeekViewHourSegment ) => segment.date.toISOString(); -export const trackByHour = (index: number, hour: DayViewHour) => +export const trackByHour = (index: number, hour: WeekViewHour) => hour.segments[0].date.toISOString(); export const trackByDayOrWeekEvent = ( index: number, - weekEvent: WeekViewAllDayEvent | DayViewEvent + weekEvent: WeekViewAllDayEvent | WeekViewTimeEvent ) => (weekEvent.event.id ? weekEvent.event.id : weekEvent.event); const MINUTES_IN_HOUR = 60; diff --git a/projects/angular-calendar/src/modules/day/calendar-day-view-event.component.ts b/projects/angular-calendar/src/modules/day/calendar-day-view-event.component.ts deleted file mode 100644 index 72e235a6b..000000000 --- a/projects/angular-calendar/src/modules/day/calendar-day-view-event.component.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { - Component, - Input, - Output, - EventEmitter, - TemplateRef -} from '@angular/core'; -import { DayViewEvent } from 'calendar-utils'; -import { PlacementArray } from 'positioning'; - -@Component({ - selector: 'mwl-calendar-day-view-event', - template: ` - -
- - - &ngsp; - - -
-
- - - ` -}) -export class CalendarDayViewEventComponent { - @Input() locale: string; - - @Input() dayEvent: DayViewEvent; - - @Input() tooltipPlacement: PlacementArray; - - @Input() tooltipAppendToBody: boolean; - - @Input() customTemplate: TemplateRef; - - @Input() eventTitleTemplate: TemplateRef; - - @Input() eventActionsTemplate: TemplateRef; - - @Input() tooltipTemplate: TemplateRef; - - @Input() tooltipDelay: number | null; - - @Output() eventClicked: EventEmitter = new EventEmitter(); -} diff --git a/projects/angular-calendar/src/modules/day/calendar-day-view-hour-segment.component.ts b/projects/angular-calendar/src/modules/day/calendar-day-view-hour-segment.component.ts deleted file mode 100644 index c22b42821..000000000 --- a/projects/angular-calendar/src/modules/day/calendar-day-view-hour-segment.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, Input, TemplateRef } from '@angular/core'; -import { DayViewHourSegment } from 'calendar-utils'; - -@Component({ - selector: 'mwl-calendar-day-view-hour-segment', - template: ` - -
-
- {{ segment.displayDate | calendarDate: 'dayViewHour':locale }} -
-
-
- - - ` -}) -export class CalendarDayViewHourSegmentComponent { - @Input() segment: DayViewHourSegment; - - @Input() segmentHeight: number; - - @Input() locale: string; - - @Input() customTemplate: TemplateRef; -} diff --git a/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts b/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts index d1bbf9f33..e797f6d33 100644 --- a/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts +++ b/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts @@ -1,70 +1,17 @@ import { Component, Input, - OnChanges, Output, EventEmitter, - ChangeDetectorRef, - LOCALE_ID, - Inject, - OnInit, - OnDestroy, TemplateRef } from '@angular/core'; -import { - CalendarEvent, - DayView, - DayViewHour, - DayViewHourSegment, - DayViewEvent, - ViewPeriod, - WeekViewAllDayEvent -} from 'calendar-utils'; -import { Subject, Subscription } from 'rxjs'; -import { ResizeEvent } from 'angular-resizable-element'; -import { CalendarDragHelper } from '../common/calendar-drag-helper.provider'; -import { CalendarResizeHelper } from '../common/calendar-resize-helper.provider'; -import { - CalendarEventTimesChangedEvent, - CalendarEventTimesChangedEventType -} from '../common/calendar-event-times-changed-event.interface'; -import { CalendarUtils } from '../common/calendar-utils.provider'; -import { - validateEvents, - trackByEventId, - trackByHour, - trackByHourSegment, - getMinutesMoved, - getDefaultEventEnd, - getMinimumEventHeightInMinutes, - trackByDayOrWeekEvent, - isDraggedWithinPeriod, - shouldFireDroppedEvent -} from '../common/util'; -import { DateAdapter } from '../../date-adapters/date-adapter'; -import { - DragEndEvent, - DragMoveEvent, - ValidateDrag -} from 'angular-draggable-droppable'; +import { CalendarEvent } from 'calendar-utils'; +import { Subject } from 'rxjs'; +import { CalendarEventTimesChangedEvent } from '../common/calendar-event-times-changed-event.interface'; import { PlacementArray } from 'positioning'; +import { CalendarWeekViewBeforeRenderEvent } from '../week/calendar-week.module'; -export interface CalendarDayViewBeforeRenderEvent { - body: { - hourGrid: DayViewHour[]; - allDayEvents: CalendarEvent[]; - }; - period: ViewPeriod; -} - -/** - * @hidden - */ -export interface DayViewEventResize { - originalTop: number; - originalHeight: number; - edge: string; -} +export type CalendarDayViewBeforeRenderEvent = CalendarWeekViewBeforeRenderEvent; /** * Shows all events on a given day. Example usage: @@ -79,144 +26,37 @@ export interface DayViewEventResize { @Component({ selector: 'mwl-calendar-day-view', template: ` -
-
- - -
-
-
-
-
- - -
-
-
-
- - -
-
-
+ ` }) -export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy { +export class CalendarDayViewComponent { /** * The current view date */ @@ -258,11 +98,6 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy { */ @Input() dayEndMinute: number = 59; - /** - * The width in pixels of each event on the view - */ - @Input() eventWidth: number = 150; - /** * An observable that when emitted on will re-render the current view */ @@ -327,393 +162,29 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy { /** * Called when an event title is clicked */ - @Output() - eventClicked = new EventEmitter<{ + @Output() eventClicked = new EventEmitter<{ event: CalendarEvent; }>(); /** * Called when an hour segment is clicked */ - @Output() - hourSegmentClicked = new EventEmitter<{ + @Output() hourSegmentClicked = new EventEmitter<{ date: Date; }>(); /** * Called when an event is resized or dragged and dropped */ - @Output() - eventTimesChanged = new EventEmitter(); + @Output() eventTimesChanged = new EventEmitter< + CalendarEventTimesChangedEvent + >(); /** * An output that will be called before the view is rendered for the current day. * If you add the `cssClass` property to an hour grid segment it will add that class to the hour segment in the template */ - @Output() - beforeViewRender = new EventEmitter(); - - /** - * @hidden - */ - hours: DayViewHour[] = []; - - /** - * @hidden - */ - view: DayView; - - /** - * @hidden - */ - width: number = 0; - - /** - * @hidden - */ - refreshSubscription: Subscription; - - /** - * @hidden - */ - currentResizes: Map = new Map(); - - /** - * @hidden - */ - eventDragEnter = 0; - - /** - * @hidden - */ - calendarId = Symbol('angular calendar day view id'); - - /** - * @hidden - */ - dragAlreadyMoved = false; - - /** - * @hidden - */ - currentDrag?: { - dayEvent: DayViewEvent; - originalTop: number; - originalLeft: number; - }; - - /** - * @hidden - */ - validateDrag: ValidateDrag; - - /** - * @hidden - */ - validateResize: (args: any) => boolean; - - /** - * @hidden - */ - trackByEventId = trackByEventId; - - /** - * @hidden - */ - trackByHour = trackByHour; - - /** - * @hidden - */ - trackByHourSegment = trackByHourSegment; - - /** - * @hidden - */ - trackByDayEvent = trackByDayOrWeekEvent; - - /** - * @hidden - */ - constructor( - protected cdr: ChangeDetectorRef, - protected utils: CalendarUtils, - @Inject(LOCALE_ID) locale: string, - protected dateAdapter: DateAdapter - ) { - this.locale = locale; - } - - /** - * @hidden - */ - ngOnInit(): void { - if (this.refresh) { - this.refreshSubscription = this.refresh.subscribe(() => { - this.refreshAll(); - this.cdr.markForCheck(); - }); - } - } - - /** - * @hidden - */ - ngOnDestroy(): void { - if (this.refreshSubscription) { - this.refreshSubscription.unsubscribe(); - } - } - - /** - * @hidden - */ - ngOnChanges(changes: any): void { - const refreshHourGrid = - changes.viewDate || - changes.dayStartHour || - changes.dayStartMinute || - changes.dayEndHour || - changes.dayEndMinute || - changes.hourSegments; - - const refreshView = - changes.viewDate || - changes.events || - changes.dayStartHour || - changes.dayStartMinute || - changes.dayEndHour || - changes.dayEndMinute || - changes.eventWidth || - changes.hourSegments; - - if (refreshHourGrid) { - this.refreshHourGrid(); - } - - if (changes.events) { - validateEvents(this.events); - } - - if (refreshView) { - this.refreshView(); - } - - if (refreshHourGrid || refreshView) { - this.emitBeforeViewRender(); - } - } - - eventDropped( - dropEvent: { dropData?: { event?: CalendarEvent; calendarId?: symbol } }, - date: Date, - allDay: boolean - ): void { - if (shouldFireDroppedEvent(dropEvent, date, allDay, this.calendarId)) { - this.eventTimesChanged.emit({ - type: CalendarEventTimesChangedEventType.Drop, - event: dropEvent.dropData.event, - newStart: date, - allDay - }); - } - } - - resizeStarted( - event: DayViewEvent, - resizeEvent: ResizeEvent, - dayEventsContainer: HTMLElement - ): void { - this.currentResizes.set(event, { - originalTop: event.top, - originalHeight: event.height, - edge: typeof resizeEvent.edges.top !== 'undefined' ? 'top' : 'bottom' - }); - const resizeHelper: CalendarResizeHelper = new CalendarResizeHelper( - dayEventsContainer - ); - this.validateResize = ({ rectangle }) => - resizeHelper.validateResize({ rectangle }); - this.cdr.markForCheck(); - } - - resizing(event: DayViewEvent, resizeEvent: ResizeEvent): void { - const currentResize: DayViewEventResize = this.currentResizes.get(event); - if (typeof resizeEvent.edges.top !== 'undefined') { - event.top = currentResize.originalTop + +resizeEvent.edges.top; - event.height = currentResize.originalHeight - +resizeEvent.edges.top; - } else if (typeof resizeEvent.edges.bottom !== 'undefined') { - event.height = currentResize.originalHeight + +resizeEvent.edges.bottom; - } - } - - resizeEnded(dayEvent: DayViewEvent): void { - const currentResize: DayViewEventResize = this.currentResizes.get(dayEvent); - - const resizingBeforeStart = currentResize.edge === 'top'; - let pixelsMoved: number; - if (resizingBeforeStart) { - pixelsMoved = dayEvent.top - currentResize.originalTop; - } else { - pixelsMoved = dayEvent.height - currentResize.originalHeight; - } - - dayEvent.top = currentResize.originalTop; - dayEvent.height = currentResize.originalHeight; - - const minutesMoved = getMinutesMoved( - pixelsMoved, - this.hourSegments, - this.hourSegmentHeight, - this.eventSnapSize - ); - - let newStart: Date = dayEvent.event.start; - let newEnd: Date = getDefaultEventEnd( - this.dateAdapter, - dayEvent.event, - getMinimumEventHeightInMinutes(this.hourSegments, this.hourSegmentHeight) - ); - if (resizingBeforeStart) { - newStart = this.dateAdapter.addMinutes(newStart, minutesMoved); - } else { - newEnd = this.dateAdapter.addMinutes(newEnd, minutesMoved); - } - - this.eventTimesChanged.emit({ - newStart, - newEnd, - event: dayEvent.event, - type: CalendarEventTimesChangedEventType.Resize - }); - this.currentResizes.delete(dayEvent); - } - - dragStarted( - event: HTMLElement, - dayEventsContainer: HTMLElement, - dayEvent: DayViewEvent - ): void { - const dragHelper: CalendarDragHelper = new CalendarDragHelper( - dayEventsContainer, - event - ); - this.validateDrag = ({ x, y, transform }) => - this.currentResizes.size === 0 && - dragHelper.validateDrag({ - x, - y, - snapDraggedEvents: this.snapDraggedEvents, - dragAlreadyMoved: this.dragAlreadyMoved, - transform - }); - this.eventDragEnter = 0; - this.dragAlreadyMoved = false; - this.currentDrag = { - dayEvent, - originalTop: dayEvent.top, - originalLeft: dayEvent.left - }; - this.cdr.markForCheck(); - } - - /** - * @hidden - */ - dragMove(coords: DragMoveEvent) { - this.dragAlreadyMoved = true; - if (this.snapDraggedEvents) { - this.currentDrag.dayEvent.top = this.currentDrag.originalTop + coords.y; - this.currentDrag.dayEvent.left = this.currentDrag.originalLeft + coords.x; - } - } - - dragEnded(dayEvent: DayViewEvent, dragEndEvent: DragEndEvent): void { - this.currentDrag.dayEvent.top = this.currentDrag.originalTop; - this.currentDrag.dayEvent.left = this.currentDrag.originalLeft; - this.currentDrag = null; - if (this.eventDragEnter > 0) { - let minutesMoved = getMinutesMoved( - dragEndEvent.y, - this.hourSegments, - this.hourSegmentHeight, - this.eventSnapSize - ); - let newStart: Date = this.dateAdapter.addMinutes( - dayEvent.event.start, - minutesMoved - ); - if (dragEndEvent.y < 0 && newStart < this.view.period.start) { - minutesMoved += this.dateAdapter.differenceInMinutes( - this.view.period.start, - newStart - ); - newStart = this.view.period.start; - } - let newEnd: Date; - if (dayEvent.event.end) { - newEnd = this.dateAdapter.addMinutes(dayEvent.event.end, minutesMoved); - } - if (isDraggedWithinPeriod(newStart, newEnd, this.view.period)) { - this.eventTimesChanged.emit({ - newStart, - newEnd, - event: dayEvent.event, - type: CalendarEventTimesChangedEventType.Drag, - allDay: false - }); - } - } - } - - protected refreshHourGrid(): void { - this.hours = this.utils.getDayViewHourGrid({ - viewDate: this.viewDate, - hourSegments: this.hourSegments, - dayStart: { - hour: this.dayStartHour, - minute: this.dayStartMinute - }, - dayEnd: { - hour: this.dayEndHour, - minute: this.dayEndMinute - } - }); - } - - protected refreshView(): void { - this.view = this.utils.getDayView({ - events: this.events, - viewDate: this.viewDate, - hourSegments: this.hourSegments, - dayStart: { - hour: this.dayStartHour, - minute: this.dayStartMinute - }, - dayEnd: { - hour: this.dayEndHour, - minute: this.dayEndMinute - }, - eventWidth: this.eventWidth, - segmentHeight: this.hourSegmentHeight - }); - } - - protected refreshAll(): void { - this.refreshHourGrid(); - this.refreshView(); - this.emitBeforeViewRender(); - } - - protected emitBeforeViewRender(): void { - if (this.hours && this.view) { - this.beforeViewRender.emit({ - body: { - hourGrid: this.hours, - allDayEvents: this.view.allDayEvents - }, - period: this.view.period - }); - } - } + @Output() beforeViewRender = new EventEmitter< + CalendarDayViewBeforeRenderEvent + >(); } diff --git a/projects/angular-calendar/src/modules/day/calendar-day-view.scss b/projects/angular-calendar/src/modules/day/calendar-day-view.scss index 36c4b7a32..bcb871fe5 100644 --- a/projects/angular-calendar/src/modules/day/calendar-day-view.scss +++ b/projects/angular-calendar/src/modules/day/calendar-day-view.scss @@ -1,143 +1,6 @@ -@import '../../variables'; - -$cal-day-view-vars: () !default; -$cal-day-view-vars: map-merge($cal-vars, $cal-day-view-vars); - -@mixin cal-day-view-theme($overrides) { - $theme: map-merge($cal-day-view-vars, $overrides); - - .cal-day-view { - background-color: map-get($theme, bg-primary); - - .cal-hour-rows { - border-color: map-get($theme, border-color); - } - - .cal-hour:nth-child(odd) { - background-color: map-get($theme, bg-secondary); - } - - .cal-hour:not(:last-child) .cal-hour-segment, - .cal-hour:last-child :not(:last-child) .cal-hour-segment { - border-bottom-color: map-get($theme, border-color); - } - - .cal-hour-segment:hover, - .cal-drag-over .cal-hour-segment { - background-color: map-get($theme, bg-active); - } - - .cal-event { - background-color: map-get($theme, event-color-secondary); - border-color: map-get($theme, event-color-primary); - color: map-get($theme, event-color-primary); - } - } -} - .cal-day-view { - * { - box-sizing: border-box; - } - - .cal-hour-rows { - width: 100%; - border: solid 1px; - overflow-x: auto; - position: relative; - } - /* stylelint-disable-next-line selector-type-no-unknown */ - mwl-calendar-day-view-hour-segment, /* fix for https://github.com/mattlewis92/angular-calendar/issues/260*/ - .cal-hour-segment { - display: block; - } - - .cal-hour-segment::after { - content: '\00a0'; - } - - .cal-hour:not(:last-child) .cal-hour-segment, - .cal-hour:last-child :not(:last-child) .cal-hour-segment { - border-bottom: thin dashed; - } - - .cal-time { - font-weight: bold; - width: 70px; - height: 100%; - display: flex; - justify-content: center; - align-items: center; - } - - .cal-hour-segment.cal-after-hour-start { - .cal-time { - display: none; - } - } - - .cal-drag-active .cal-hour-segment { - pointer-events: none; - } - - .cal-event-container { - position: absolute; - cursor: pointer; - - &.resize-active { - z-index: 1; - pointer-events: none; - } - } - - .cal-event { - padding: 5px; - font-size: 12px; - border: 1px solid; - box-sizing: border-box; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - height: 100%; - } - - .cal-all-day-events > * { - cursor: pointer; - } - - .cal-draggable { - cursor: move; - } - - .cal-starts-within-day .cal-event { - border-top-left-radius: 5px; - border-top-right-radius: 5px; - } - - .cal-ends-within-day .cal-event { - border-bottom-left-radius: 5px; - border-bottom-right-radius: 5px; - } - - .cal-drag-active { - z-index: 1; - - & * { - pointer-events: none; - } - } - - .cal-resize-handle { - width: 100%; - height: 4px; - cursor: row-resize; - position: absolute; - - &.cal-resize-handle-after-end { - bottom: 0; - } + mwl-calendar-week-view-header { + display: none; } } - -@include cal-day-view-theme($cal-day-view-vars); diff --git a/projects/angular-calendar/src/modules/day/calendar-day.module.ts b/projects/angular-calendar/src/modules/day/calendar-day.module.ts index 4d834bca0..48f8fe862 100644 --- a/projects/angular-calendar/src/modules/day/calendar-day.module.ts +++ b/projects/angular-calendar/src/modules/day/calendar-day.module.ts @@ -1,11 +1,8 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { ResizableModule } from 'angular-resizable-element'; -import { DragAndDropModule } from 'angular-draggable-droppable'; import { CalendarDayViewComponent } from './calendar-day-view.component'; -import { CalendarDayViewHourSegmentComponent } from './calendar-day-view-hour-segment.component'; -import { CalendarDayViewEventComponent } from './calendar-day-view-event.component'; import { CalendarCommonModule } from '../common/calendar-common.module'; +import { CalendarWeekModule } from '../week/calendar-week.module'; export { CalendarDayViewComponent, @@ -13,23 +10,8 @@ export { } from './calendar-day-view.component'; @NgModule({ - imports: [ - CommonModule, - ResizableModule, - DragAndDropModule, - CalendarCommonModule - ], - declarations: [ - CalendarDayViewComponent, - CalendarDayViewHourSegmentComponent, - CalendarDayViewEventComponent - ], - exports: [ - ResizableModule, - DragAndDropModule, - CalendarDayViewComponent, - CalendarDayViewHourSegmentComponent, - CalendarDayViewEventComponent - ] + imports: [CommonModule, CalendarCommonModule, CalendarWeekModule], + declarations: [CalendarDayViewComponent], + exports: [CalendarDayViewComponent] }) export class CalendarDayModule {} diff --git a/projects/angular-calendar/src/modules/week/calendar-week-view-event.component.ts b/projects/angular-calendar/src/modules/week/calendar-week-view-event.component.ts index 7b505d0a9..eb7331d2d 100644 --- a/projects/angular-calendar/src/modules/week/calendar-week-view-event.component.ts +++ b/projects/angular-calendar/src/modules/week/calendar-week-view-event.component.ts @@ -7,7 +7,7 @@ import { } from '@angular/core'; import { WeekViewAllDayEvent, - DayViewEvent, + WeekViewTimeEvent, WeekViewHourColumn } from 'calendar-utils'; import { PlacementArray } from 'positioning'; @@ -25,6 +25,7 @@ import { PlacementArray } from 'positioning'; let-tooltipDisabled="tooltipDisabled" let-tooltipDelay="tooltipDelay" let-column="column" + let-daysInWeek="daysInWeek" >
@@ -76,7 +79,8 @@ import { PlacementArray } from 'positioning'; tooltipAppendToBody: tooltipAppendToBody, tooltipDisabled: tooltipDisabled, tooltipDelay: tooltipDelay, - column: column + column: column, + daysInWeek: daysInWeek }" > @@ -85,7 +89,7 @@ import { PlacementArray } from 'positioning'; export class CalendarWeekViewEventComponent { @Input() locale: string; - @Input() weekEvent: WeekViewAllDayEvent | DayViewEvent; + @Input() weekEvent: WeekViewAllDayEvent | WeekViewTimeEvent; @Input() tooltipPlacement: PlacementArray; @@ -105,5 +109,7 @@ export class CalendarWeekViewEventComponent { @Input() column: WeekViewHourColumn; - @Output() eventClicked: EventEmitter = new EventEmitter(); + @Input() daysInWeek: number; + + @Output() eventClicked: EventEmitter = new EventEmitter(); } diff --git a/projects/angular-calendar/src/modules/week/calendar-week-view-hour-segment.component.ts b/projects/angular-calendar/src/modules/week/calendar-week-view-hour-segment.component.ts index 5f35cce09..af53f2b37 100644 --- a/projects/angular-calendar/src/modules/week/calendar-week-view-hour-segment.component.ts +++ b/projects/angular-calendar/src/modules/week/calendar-week-view-hour-segment.component.ts @@ -10,9 +10,16 @@ import { WeekViewHourColumn } from 'calendar-utils'; let-locale="locale" let-segmentHeight="segmentHeight" let-isTimeLabel="isTimeLabel" + let-daysInWeek="daysInWeek" >
- {{ segment.displayDate | calendarDate: 'weekViewHour':locale }} + {{ + segment.displayDate + | calendarDate + : (daysInWeek === 1 ? 'dayViewHour' : 'weekViewHour') + : locale + }}
@@ -30,7 +42,8 @@ import { WeekViewHourColumn } from 'calendar-utils'; segment: segment, locale: locale, segmentHeight: segmentHeight, - isTimeLabel: isTimeLabel + isTimeLabel: isTimeLabel, + daysInWeek: daysInWeek }" > @@ -45,5 +58,7 @@ export class CalendarWeekViewHourSegmentComponent { @Input() isTimeLabel: boolean; + @Input() daysInWeek: number; + @Input() customTemplate: TemplateRef; } diff --git a/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts b/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts index fe04a2b16..fdb5e1d5a 100644 --- a/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts +++ b/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts @@ -19,9 +19,9 @@ import { WeekView, ViewPeriod, WeekViewHourColumn, - DayViewEvent, - DayViewHourSegment, - DayViewHour, + WeekViewTimeEvent, + WeekViewHourSegment, + WeekViewHour, WeekViewAllDayEventRow } from 'calendar-utils'; import { ResizeEvent } from 'angular-resizable-element'; @@ -176,6 +176,7 @@ export interface CalendarWeekViewBeforeRenderEvent extends WeekView { [customTemplate]="eventTemplate" [eventTitleTemplate]="eventTitleTemplate" [eventActionsTemplate]="eventActionsTemplate" + [daysInWeek]="daysInWeek" (eventClicked)="eventClicked.emit({ event: allDayEvent.event })" > @@ -215,6 +216,7 @@ export interface CalendarWeekViewBeforeRenderEvent extends WeekView { [locale]="locale" [customTemplate]="hourSegmentTemplate" [isTimeLabel]="true" + [daysInWeek]="daysInWeek" >
@@ -302,6 +304,7 @@ export interface CalendarWeekViewBeforeRenderEvent extends WeekView { [eventTitleTemplate]="eventTitleTemplate" [eventActionsTemplate]="eventActionsTemplate" [column]="column" + [daysInWeek]="daysInWeek" (eventClicked)="eventClicked.emit({ event: timeEvent.event })" > @@ -338,6 +341,7 @@ export interface CalendarWeekViewBeforeRenderEvent extends WeekView { [segmentHeight]="hourSegmentHeight" [locale]="locale" [customTemplate]="hourSegmentTemplate" + [daysInWeek]="daysInWeek" (mwlClick)="hourSegmentClicked.emit({ date: segment.date })" [clickListenerDisabled]=" hourSegmentClicked.observers.length === 0 @@ -724,7 +728,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { */ timeEventResizeStarted( eventsContainer: HTMLElement, - timeEvent: DayViewEvent, + timeEvent: WeekViewTimeEvent, resizeEvent: ResizeEvent ): void { this.timeEventResizes.set(timeEvent.event, resizeEvent); @@ -734,7 +738,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { /** * @hidden */ - timeEventResizing(timeEvent: DayViewEvent, resizeEvent: ResizeEvent) { + timeEventResizing(timeEvent: WeekViewTimeEvent, resizeEvent: ResizeEvent) { this.timeEventResizes.set(timeEvent.event, resizeEvent); const adjustedEvents = new Map(); @@ -757,7 +761,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { /** * @hidden */ - timeEventResizeEnded(timeEvent: DayViewEvent) { + timeEventResizeEnded(timeEvent: WeekViewTimeEvent) { this.view = this.getWeekView(this.events); const lastResizeEvent = this.timeEventResizes.get(timeEvent.event); if (lastResizeEvent) { @@ -909,7 +913,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { dragStarted( eventsContainer: HTMLElement, event: HTMLElement, - dayEvent?: DayViewEvent + dayEvent?: WeekViewTimeEvent ): void { this.dayColumnWidth = this.getDayColumnWidth(eventsContainer); const dragHelper: CalendarDragHelper = new CalendarDragHelper( @@ -951,7 +955,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { /** * @hidden */ - dragMove(dayEvent: DayViewEvent, dragEvent: DragMoveEvent) { + dragMove(dayEvent: WeekViewTimeEvent, dragEvent: DragMoveEvent) { if (this.snapDraggedEvents) { const newEventTimes = this.getDragMovedEventTimes( dayEvent, @@ -986,7 +990,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { * @hidden */ dragEnded( - weekEvent: WeekViewAllDayEvent | DayViewEvent, + weekEvent: WeekViewAllDayEvent | WeekViewTimeEvent, dragEndEvent: DragEndEvent, dayWidth: number, useY = false @@ -1078,7 +1082,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { } protected getDragMovedEventTimes( - weekEvent: WeekViewAllDayEvent | DayViewEvent, + weekEvent: WeekViewAllDayEvent | WeekViewTimeEvent, dragEndEvent: DragEndEvent | DragMoveEvent, dayWidth: number, useY: boolean diff --git a/projects/angular-calendar/src/modules/week/calendar-week-view.scss b/projects/angular-calendar/src/modules/week/calendar-week-view.scss index 6ddb855e8..2afca8e45 100644 --- a/projects/angular-calendar/src/modules/week/calendar-week-view.scss +++ b/projects/angular-calendar/src/modules/week/calendar-week-view.scss @@ -8,9 +8,11 @@ $cal-week-view-vars: map-merge($cal-vars, $cal-week-view-vars); .cal-week-view { background-color: map-get($theme, bg-primary); + border-top: solid 1px map-get($theme, border-color); .cal-day-headers { border-color: map-get($theme, border-color); + border-top: 0; } .cal-day-headers .cal-header { diff --git a/projects/angular-calendar/test/calendar-day-view.component.spec.ts b/projects/angular-calendar/test/calendar-day-view.component.spec.ts index b71772de5..c38519482 100644 --- a/projects/angular-calendar/test/calendar-day-view.component.spec.ts +++ b/projects/angular-calendar/test/calendar-day-view.component.spec.ts @@ -54,7 +54,7 @@ describe('CalendarDayViewComponent component', () => { eventTitle = _eventTitle_; })); - it('should generate the day view', () => { + it('should generate the week view with one day visible', () => { const fixture: ComponentFixture< CalendarDayViewComponent > = TestBed.createComponent(CalendarDayViewComponent); @@ -69,19 +69,17 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); - expect(fixture.componentInstance.view.events.length).to.equal(1); - expect(fixture.componentInstance.view.events[0].event).to.equal( - fixture.componentInstance.events[0] - ); - expect(fixture.componentInstance.hours.length).to.equal(24); + fixture.detectChanges(); + expect( + fixture.nativeElement.querySelectorAll('.cal-day-column').length + ).to.equal(1); }); - it('should generate the week view with default colors for events', () => { + it('should generate the day view with default colors for events', () => { const fixture: ComponentFixture< CalendarDayViewComponent > = TestBed.createComponent(CalendarDayViewComponent); - fixture.componentInstance.ngOnInit(); + fixture.componentInstance.viewDate = new Date('2016-06-01'); fixture.componentInstance.events = [ { @@ -90,7 +88,7 @@ describe('CalendarDayViewComponent component', () => { title: 'foo' } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); const computedStyles: CSSStyleDeclaration = window.getComputedStyle( @@ -123,7 +121,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); fixture.componentInstance.eventClicked.subscribe(val => { expect(val).to.deep.equal({ @@ -149,7 +147,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); fixture.componentInstance.eventClicked.subscribe(val => { expect(val).to.deep.equal({ @@ -175,7 +173,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); expect( fixture.nativeElement @@ -202,11 +200,11 @@ describe('CalendarDayViewComponent component', () => { allDay: true } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); expect( fixture.nativeElement - .querySelector('.cal-all-day-events mwl-calendar-day-view-event') + .querySelector('.cal-all-day-events .cal-event-container') .classList.contains('foo') ).to.equal(true); fixture.destroy(); @@ -217,7 +215,7 @@ describe('CalendarDayViewComponent component', () => { CalendarDayViewComponent > = TestBed.createComponent(CalendarDayViewComponent); fixture.componentInstance.viewDate = new Date('2016-06-01'); - fixture.componentInstance.ngOnChanges({ viewDate: {} }); + fixture.detectChanges(); fixture.componentInstance.hourSegmentClicked.subscribe(val => { expect(val).to.deep.equal({ @@ -231,29 +229,6 @@ describe('CalendarDayViewComponent component', () => { fixture.nativeElement.querySelectorAll('.cal-hour-segment')[3].click(); }); - it('should refresh the view when the refresh observable is emitted on', () => { - const fixture: ComponentFixture< - CalendarDayViewComponent - > = TestBed.createComponent(CalendarDayViewComponent); - fixture.componentInstance.refresh = new Subject(); - fixture.componentInstance.ngOnInit(); - fixture.componentInstance.viewDate = new Date('2016-06-01'); - fixture.componentInstance.ngOnChanges({ viewDate: {} }); - const event: CalendarEvent = { - start: new Date('2016-06-01'), - end: new Date('2016-06-02'), - title: 'foo', - color: { - primary: 'blue', - secondary: 'lightblue' - } - }; - fixture.componentInstance.events.push(event); - fixture.componentInstance.refresh.next(true); - expect(fixture.componentInstance.view.events[0].event).to.deep.equal(event); - fixture.destroy(); - }); - it('should allow the event title to be customised by the calendarConfig provider', () => { const fixture: ComponentFixture< CalendarDayViewComponent @@ -273,7 +248,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); const title: HTMLElement = fixture.nativeElement.querySelector( '.cal-event-title' @@ -281,31 +256,6 @@ describe('CalendarDayViewComponent component', () => { expect(title.innerHTML).to.equal('foo bar'); }); - it('should update the hour grid and event list when the day start changes', () => { - const fixture: ComponentFixture< - CalendarDayViewComponent - > = TestBed.createComponent(CalendarDayViewComponent); - fixture.componentInstance.viewDate = new Date('2016-06-29'); - fixture.componentInstance.events = [ - { - start: new Date('2016-06-29'), - title: 'foo', - color: { - primary: '', - secondary: '' - } - } - ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); - fixture.detectChanges(); - expect(fixture.componentInstance.hours.length).to.equal(24); - expect(fixture.componentInstance.view.events.length).to.equal(1); - fixture.componentInstance.dayStartHour = 6; - fixture.componentInstance.ngOnChanges({ dayStartHour: {} }); - expect(fixture.componentInstance.hours.length).to.equal(18); - expect(fixture.componentInstance.view.events.length).to.equal(0); - }); - it('should add event actions to each event', () => { const fixture: ComponentFixture< CalendarDayViewComponent @@ -331,7 +281,7 @@ describe('CalendarDayViewComponent component', () => { ] } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); const action: HTMLElement = fixture.nativeElement.querySelector( '.cal-event .cal-event-action' @@ -345,34 +295,6 @@ describe('CalendarDayViewComponent component', () => { expect(eventClicked).not.to.have.been.called; }); - it('should allow the event width to be customised', () => { - const fixture: ComponentFixture< - CalendarDayViewComponent - > = TestBed.createComponent(CalendarDayViewComponent); - fixture.componentInstance.viewDate = new Date('2016-06-01'); - fixture.componentInstance.events = [ - { - start: new Date('2016-06-01'), - title: 'foo', - color: { - primary: 'blue', - secondary: '' - } - } - ]; - fixture.componentInstance.eventWidth = 300; - fixture.componentInstance.ngOnChanges({ - viewDate: {}, - events: {}, - eventWidth: {} - }); - fixture.detectChanges(); - expect( - fixture.nativeElement.querySelector('.cal-event-container').style.width - ).to.equal('299px'); - fixture.destroy(); - }); - it('should add a custom CSS class to days via the beforeViewRender output', () => { const fixture: ComponentFixture< CalendarDayViewComponent @@ -380,14 +302,16 @@ describe('CalendarDayViewComponent component', () => { fixture.componentInstance.viewDate = new Date('2016-06-27'); fixture.componentInstance.beforeViewRender .pipe(take(1)) - .subscribe(({ body }) => { - body.hourGrid.forEach(hour => { - hour.segments.forEach(segment => { - segment.cssClass = 'foo'; + .subscribe(({ hourColumns }) => { + hourColumns.forEach(hourColumn => { + hourColumn.hours.forEach(hour => { + hour.segments.forEach(segment => { + segment.cssClass = 'foo'; + }); }); }); }); - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); expect( fixture.nativeElement @@ -417,7 +341,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -482,7 +406,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -547,7 +471,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -599,7 +523,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -661,7 +585,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -727,7 +651,7 @@ describe('CalendarDayViewComponent component', () => { } ]; fixture.componentInstance.eventSnapSize = 1; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -791,7 +715,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); const event: HTMLElement = fixture.nativeElement.querySelector( '.cal-event' @@ -830,7 +754,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); const event: HTMLElement = fixture.nativeElement.querySelector( '.cal-event' @@ -861,7 +785,7 @@ describe('CalendarDayViewComponent component', () => { draggable: true } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -906,80 +830,6 @@ describe('CalendarDayViewComponent component', () => { expect(eventDropped).to.have.been.calledOnce; }); - it('should not allow events to be dragged outside of the calendar', () => { - const fixture: ComponentFixture< - CalendarDayViewComponent - > = TestBed.createComponent(CalendarDayViewComponent); - fixture.componentInstance.viewDate = new Date('2016-06-27'); - fixture.componentInstance.events = [ - { - title: 'foo', - color: { primary: '', secondary: '' }, - start: moment('2016-06-27') - .startOf('day') - .add(4, 'hours') - .toDate(), - end: moment('2016-06-27') - .startOf('day') - .add(6, 'hours') - .toDate(), - draggable: true - } - ]; - fixture.componentInstance.eventSnapSize = 1; - const eventDropped = sinon.spy(); - fixture.componentInstance.eventTimesChanged.subscribe(eventDropped); - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); - fixture.detectChanges(); - document.body.appendChild(fixture.nativeElement); - const event: HTMLElement = fixture.nativeElement.querySelector( - '.cal-event-container' - ); - const eventPosition: ClientRect = event.getBoundingClientRect(); - const calendarPosition: ClientRect = fixture.nativeElement.getBoundingClientRect(); - triggerDomEvent('mousedown', event, { - clientY: eventPosition.top, - clientX: eventPosition.left + 10 - }); - fixture.detectChanges(); - triggerDomEvent('mousemove', document.body, { - clientY: calendarPosition.top, - clientX: eventPosition.left + 10 - }); - fixture.detectChanges(); - expect(event.getBoundingClientRect().top).to.equal(calendarPosition.top); - expect(event.getBoundingClientRect().bottom).to.equal( - calendarPosition.top + eventPosition.height - ); - triggerDomEvent('mousemove', document.body, { - clientY: calendarPosition.top - 60, - clientX: eventPosition.left + 10 - }); - fixture.detectChanges(); - expect(event.getBoundingClientRect().top).to.equal(calendarPosition.top); - expect(event.getBoundingClientRect().bottom).to.equal( - calendarPosition.top + eventPosition.height - ); - triggerDomEvent('mouseup', document.body, { - clientY: calendarPosition.top - 60, - clientX: eventPosition.left + 10 - }); - fixture.detectChanges(); - const { newStart, newEnd } = eventDropped.getCall(0).args[0]; - expect(newStart).to.deep.equal( - moment('2016-06-27') - .startOf('day') - .toDate() - ); - expect(newEnd).to.deep.equal( - moment('2016-06-27') - .startOf('day') - .add(2, 'hours') - .toDate() - ); - fixture.destroy(); - }); - it('should allow events to be dragged outside of the calendar', () => { const fixture: ComponentFixture< CalendarDayViewComponent @@ -1003,7 +853,7 @@ describe('CalendarDayViewComponent component', () => { fixture.componentInstance.snapDraggedEvents = false; const eventDropped = sinon.spy(); fixture.componentInstance.eventTimesChanged.subscribe(eventDropped); - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -1077,7 +927,7 @@ describe('CalendarDayViewComponent component', () => { fixture.componentInstance.snapDraggedEvents = false; const eventDropped = sinon.spy(); fixture.componentInstance.eventTimesChanged.subscribe(eventDropped); - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -1135,7 +985,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -1172,64 +1022,6 @@ describe('CalendarDayViewComponent component', () => { fixture.destroy(); }); - it('should allow external events to be dropped on the day view', () => { - const fixture: ComponentFixture< - CalendarDayViewComponent - > = TestBed.createComponent(CalendarDayViewComponent); - fixture.componentInstance.viewDate = new Date('2016-06-27'); - fixture.componentInstance.events = []; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); - fixture.detectChanges(); - document.body.appendChild(fixture.nativeElement); - - const externalEventFixture: ComponentFixture< - ExternalEventComponent - > = TestBed.createComponent(ExternalEventComponent); - externalEventFixture.detectChanges(); - document.body.appendChild(externalEventFixture.nativeElement); - - const event: HTMLElement = externalEventFixture.nativeElement.querySelector( - '.external-event' - ); - const eventPosition: ClientRect = event.getBoundingClientRect(); - - const segments: any[] = Array.from( - fixture.nativeElement.querySelectorAll('.cal-hour-segment') - ); - const segment: HTMLElement = segments[2].parentNode; - const segmentPosition: ClientRect = segment.getBoundingClientRect(); - - const eventDropped: sinon.SinonSpy = sinon.spy(); - fixture.componentInstance.eventTimesChanged.subscribe(eventDropped); - triggerDomEvent('mousedown', event, { - clientY: eventPosition.top, - clientX: eventPosition.left - }); - fixture.detectChanges(); - triggerDomEvent('mousemove', document.body, { - clientY: segmentPosition.top, - clientX: segmentPosition.left - }); - fixture.detectChanges(); - expect(segment.classList.contains('cal-drag-over')).to.equal(true); - triggerDomEvent('mouseup', document.body, { - clientY: segmentPosition.top, - clientX: segmentPosition.left - }); - fixture.detectChanges(); - fixture.destroy(); - externalEventFixture.destroy(); - expect(eventDropped).to.have.been.calledWith({ - type: 'drop', - event: externalEventFixture.componentInstance.event, - newStart: moment('2016-06-27') - .startOf('day') - .add(1, 'hours') - .toDate(), - allDay: false - }); - }); - it('should respect the event snap size when dragging and dropping', () => { const fixture: ComponentFixture< CalendarDayViewComponent @@ -1251,7 +1043,7 @@ describe('CalendarDayViewComponent component', () => { } ]; fixture.componentInstance.eventSnapSize = 1; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); const event: HTMLElement = fixture.nativeElement.querySelector( @@ -1305,7 +1097,7 @@ describe('CalendarDayViewComponent component', () => { fixture.componentInstance.events = [ { start: 1234, title: '', color: { primary: '', secondary: '' } } ] as any; - fixture.componentInstance.ngOnChanges({ events: {} }); + fixture.componentInstance.viewDate = new Date('2017-01-01'); fixture.detectChanges(); stub.restore(); expect(stub).to.have.been.calledOnce; // tslint:disable-line @@ -1317,10 +1109,9 @@ describe('CalendarDayViewComponent component', () => { > = TestBed.createComponent(CalendarDayViewComponent); fixture.componentInstance.hourSegmentHeight = 45; fixture.componentInstance.viewDate = new Date('2016-06-01'); - fixture.componentInstance.ngOnChanges({ viewDate: {} }); fixture.detectChanges(); expect( - fixture.nativeElement.querySelector('mwl-calendar-day-view-hour-segment') + fixture.nativeElement.querySelector('mwl-calendar-week-view-hour-segment') .style.height ).to.equal('45px'); expect( @@ -1333,8 +1124,8 @@ describe('CalendarDayViewComponent component', () => { CalendarDayViewComponent > = TestBed.createComponent(CalendarDayViewComponent); fixture.componentInstance.refresh = new Subject(); - fixture.componentInstance.ngOnInit(); fixture.componentInstance.viewDate = new Date('2016-06-27'); + fixture.detectChanges(); const beforeViewRenderCalled = sinon.spy(); // use subscription to test that it was only called a max of one times const subscription = fixture.componentInstance.beforeViewRender.subscribe( @@ -1350,16 +1141,15 @@ describe('CalendarDayViewComponent component', () => { const fixture: ComponentFixture< CalendarDayViewComponent > = TestBed.createComponent(CalendarDayViewComponent); - fixture.componentInstance.ngOnInit(); fixture.componentInstance.viewDate = new Date('2016-06-27'); - fixture.componentInstance.ngOnChanges({ viewDate: {} }); + fixture.detectChanges(); const beforeViewRenderCalled = sinon.spy(); // use subscription to test that it was only called a max of one times const subscription = fixture.componentInstance.beforeViewRender.subscribe( beforeViewRenderCalled ); fixture.componentInstance.viewDate = new Date('2016-06-28'); - fixture.componentInstance.ngOnChanges({ viewDate: {} }); + fixture.detectChanges(); expect(beforeViewRenderCalled).to.have.been.calledOnce; subscription.unsubscribe(); fixture.destroy(); @@ -1373,9 +1163,10 @@ describe('CalendarDayViewComponent component', () => { fixture.componentInstance.beforeViewRender .pipe(take(1)) .subscribe(beforeViewRenderCalled); - fixture.componentInstance.ngOnInit(); + fixture.componentInstance.viewDate = new Date('2016-06-27'); - fixture.componentInstance.ngOnChanges({ viewDate: {} }); + fixture.detectChanges(); + const { period } = beforeViewRenderCalled.getCall(0).args[0]; expect(period.start).to.be.an.instanceOf(Date); expect(period.end).to.be.an.instanceOf(Date); @@ -1391,7 +1182,7 @@ describe('CalendarDayViewComponent component', () => { fixture.componentInstance.beforeViewRender .pipe(take(1)) .subscribe(beforeViewRenderCalled); - fixture.componentInstance.ngOnInit(); + fixture.componentInstance.events = [ { start: new Date('2016-05-30'), @@ -1403,16 +1194,24 @@ describe('CalendarDayViewComponent component', () => { end: new Date('2016-06-02'), title: 'bar', allDay: true + }, + { + start: new Date('2017-05-30'), + end: new Date('2017-06-02'), + title: 'bar', + allDay: true } ]; fixture.componentInstance.viewDate = new Date('2016-06-01'); - fixture.componentInstance.ngOnChanges({ viewDate: {} }); + fixture.detectChanges(); + const { - period: { events }, - body: { allDayEvents } + period: { events } } = beforeViewRenderCalled.getCall(0).args[0]; - expect(events).to.deep.equal([fixture.componentInstance.events[0]]); - expect(allDayEvents).to.deep.equal([fixture.componentInstance.events[1]]); + expect(events).to.deep.equal([ + fixture.componentInstance.events[0], + fixture.componentInstance.events[1] + ]); }); it('should drag an all day event onto the time grid', () => { @@ -1436,12 +1235,10 @@ describe('CalendarDayViewComponent component', () => { } ]; fixture.componentInstance.snapDraggedEvents = false; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); - const event = fixture.nativeElement.querySelector( - '.cal-all-day-events mwl-calendar-day-view-event' - ); + const event = fixture.nativeElement.querySelector('.cal-event-container'); const rect: ClientRect = event.getBoundingClientRect(); let dragEvent: CalendarEventTimesChangedEvent; fixture.componentInstance.eventTimesChanged.subscribe(e => { @@ -1453,7 +1250,7 @@ describe('CalendarDayViewComponent component', () => { }); fixture.detectChanges(); const hourSegment = fixture.nativeElement.querySelectorAll( - 'mwl-calendar-day-view-hour-segment' + '.cal-day-columns mwl-calendar-week-view-hour-segment' )[3]; const hourSegmentPosition = hourSegment.getBoundingClientRect(); triggerDomEvent('mousemove', hourSegment, { @@ -1478,71 +1275,6 @@ describe('CalendarDayViewComponent component', () => { }); }); - it('should drag a time event onto the all day events', () => { - const fixture: ComponentFixture< - CalendarDayViewComponent - > = TestBed.createComponent(CalendarDayViewComponent); - fixture.componentInstance.viewDate = new Date('2018-07-29'); - fixture.componentInstance.events = [ - { - start: moment(new Date('2018-07-29')) - .startOf('day') - .add(3, 'hours') - .toDate(), - end: moment(new Date('2018-07-29')) - .startOf('day') - .add(18, 'hours') - .toDate(), - title: 'foo', - draggable: true, - allDay: false - }, - { - start: new Date('2018-07-29'), - allDay: true, - title: 'bar' - } - ]; - fixture.componentInstance.snapDraggedEvents = false; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); - fixture.detectChanges(); - document.body.appendChild(fixture.nativeElement); - const event = fixture.nativeElement.querySelector('.cal-event-container'); - const rect: ClientRect = event.getBoundingClientRect(); - let dragEvent: CalendarEventTimesChangedEvent; - fixture.componentInstance.eventTimesChanged.subscribe(e => { - dragEvent = e; - }); - triggerDomEvent('mousedown', event, { - clientX: rect.left, - clientY: rect.top - }); - fixture.detectChanges(); - const allDayEvents = fixture.nativeElement.querySelector( - '.cal-all-day-events' - ); - const allDayEventsPosition = allDayEvents.getBoundingClientRect(); - triggerDomEvent('mousemove', allDayEvents, { - clientX: allDayEventsPosition.left, - clientY: allDayEventsPosition.top - }); - fixture.detectChanges(); - triggerDomEvent('mouseup', allDayEvents, { - clientX: allDayEventsPosition.left, - clientY: allDayEventsPosition.top - }); - fixture.detectChanges(); - fixture.destroy(); - expect(dragEvent).to.deep.equal({ - type: 'drop', - allDay: true, - event: fixture.componentInstance.events[0], - newStart: moment(new Date('2018-07-29')) - .startOf('day') - .toDate() - }); - }); - it('should allow css variables for colors', () => { const style = document.createElement('style'); style.setAttribute('type', 'text/css'); @@ -1556,7 +1288,7 @@ describe('CalendarDayViewComponent component', () => { const fixture: ComponentFixture< CalendarDayViewComponent > = TestBed.createComponent(CalendarDayViewComponent); - fixture.componentInstance.ngOnInit(); + fixture.componentInstance.viewDate = new Date('2016-06-01'); fixture.componentInstance.events = [ { @@ -1569,7 +1301,7 @@ describe('CalendarDayViewComponent component', () => { } } ]; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); const computedStyles: CSSStyleDeclaration = window.getComputedStyle( diff --git a/projects/demos/app/demo-modules/before-view-render/component.ts b/projects/demos/app/demo-modules/before-view-render/component.ts index 349a819cd..fb483ab35 100644 --- a/projects/demos/app/demo-modules/before-view-render/component.ts +++ b/projects/demos/app/demo-modules/before-view-render/component.ts @@ -56,11 +56,13 @@ export class DemoComponent { } beforeDayViewRender(renderEvent: CalendarDayViewBeforeRenderEvent) { - renderEvent.body.hourGrid.forEach(hour => { - hour.segments.forEach((segment, index) => { - if (segment.date.getHours() >= 2 && segment.date.getHours() <= 5) { - segment.cssClass = 'bg-pink'; - } + renderEvent.hourColumns.forEach(hourColumn => { + hourColumn.hours.forEach(hour => { + hour.segments.forEach(segment => { + if (segment.date.getHours() >= 2 && segment.date.getHours() <= 5) { + segment.cssClass = 'bg-pink'; + } + }); }); }); } diff --git a/projects/demos/app/demo-modules/day-view-scheduler/day-view-scheduler.component.ts b/projects/demos/app/demo-modules/day-view-scheduler/day-view-scheduler.component.ts index 39a2d963a..bb48c1eb2 100644 --- a/projects/demos/app/demo-modules/day-view-scheduler/day-view-scheduler.component.ts +++ b/projects/demos/app/demo-modules/day-view-scheduler/day-view-scheduler.component.ts @@ -1,11 +1,6 @@ import { Component, EventEmitter, Injectable, Output } from '@angular/core'; import { CalendarUtils, CalendarWeekViewComponent } from 'angular-calendar'; -import { - WeekView, - GetWeekViewArgs, - DayViewEvent, - WeekViewAllDayEvent -} from 'calendar-utils'; +import { WeekView, GetWeekViewArgs, WeekViewTimeEvent } from 'calendar-utils'; import { DragEndEvent, DragMoveEvent } from 'angular-draggable-droppable'; const EVENT_WIDTH = 150; @@ -59,6 +54,9 @@ export class DayViewSchedulerCalendarUtils extends CalendarUtils { .cal-time-events { border-top: solid 1px #e1e1e1; } + .cal-week-view { + border-top: 0; + } ` ], providers: [ @@ -83,13 +81,13 @@ export class DayViewSchedulerComponent extends CalendarWeekViewComponent { dragStarted( eventsContainer: HTMLElement, event: HTMLElement, - dayEvent?: DayViewEvent + dayEvent?: WeekViewTimeEvent ) { this.originalLeft = dayEvent.left; super.dragStarted(eventsContainer, event, dayEvent); } - dragMove(dayEvent: DayViewEvent, dragEvent: DragMoveEvent) { + dragMove(dayEvent: WeekViewTimeEvent, dragEvent: DragMoveEvent) { const originalX = dragEvent.x; dragEvent.x = 0; super.dragMove(dayEvent, dragEvent); @@ -104,7 +102,7 @@ export class DayViewSchedulerComponent extends CalendarWeekViewComponent { } dragEnded( - weekEvent: DayViewEvent, + weekEvent: WeekViewTimeEvent, dragEndEvent: DragEndEvent, dayWidth: number, useY = false @@ -116,7 +114,7 @@ export class DayViewSchedulerComponent extends CalendarWeekViewComponent { } } - private getDraggedUserColumn(dayEvent: DayViewEvent, xPixels: number) { + private getDraggedUserColumn(dayEvent: WeekViewTimeEvent, xPixels: number) { const columnsMoved = xPixels / EVENT_WIDTH; const currentColumnIndex = this.view.users.findIndex( user => user === dayEvent.event.meta.user diff --git a/projects/demos/app/demo-modules/drag-to-create-events/component.ts b/projects/demos/app/demo-modules/drag-to-create-events/component.ts index 2a28fe1b7..7764f5386 100644 --- a/projects/demos/app/demo-modules/drag-to-create-events/component.ts +++ b/projects/demos/app/demo-modules/drag-to-create-events/component.ts @@ -9,7 +9,7 @@ import { CalendarEventTitleFormatter, CalendarView } from 'angular-calendar'; -import { DayViewHourSegment } from 'calendar-utils'; +import { WeekViewHourSegment } from 'calendar-utils'; import { fromEvent } from 'rxjs'; import { finalize, takeUntil } from 'rxjs/operators'; import { addDays, addMinutes, endOfWeek } from 'date-fns'; @@ -66,7 +66,7 @@ export class DemoComponent { constructor(private cdr: ChangeDetectorRef) {} startDragToCreate( - segment: DayViewHourSegment, + segment: WeekViewHourSegment, mouseDownEvent: MouseEvent, segmentElement: HTMLElement ) { diff --git a/projects/demos/app/demo-modules/selectable-period/component.ts b/projects/demos/app/demo-modules/selectable-period/component.ts index 2336e7be7..6ef98e7d1 100644 --- a/projects/demos/app/demo-modules/selectable-period/component.ts +++ b/projects/demos/app/demo-modules/selectable-period/component.ts @@ -4,7 +4,7 @@ import { ViewEncapsulation } from '@angular/core'; import { CalendarEvent, CalendarMonthViewDay } from 'angular-calendar'; -import { DayViewHour } from 'calendar-utils'; +import { WeekViewHour } from 'calendar-utils'; @Component({ selector: 'mwl-demo-component', @@ -30,7 +30,7 @@ export class DemoComponent { selectedDayViewDate: Date; - dayView: DayViewHour[]; + dayView: WeekViewHour[]; events: CalendarEvent[] = []; @@ -69,7 +69,7 @@ export class DemoComponent { this.addSelectedDayViewClass(); } - beforeDayViewRender(dayView: DayViewHour[]) { + beforeDayViewRender(dayView: WeekViewHour[]) { this.dayView = dayView; this.addSelectedDayViewClass(); }