diff --git a/src/app/calendar-app/calendar-app.component.html b/src/app/calendar-app/calendar-app.component.html index d539940ae..b0e0b305d 100644 --- a/src/app/calendar-app/calendar-app.component.html +++ b/src/app/calendar-app/calendar-app.component.html @@ -131,6 +131,11 @@

Calendar Menu

Settings

+ + +

Print Calendar

+
+

CalDAV Sync Guide

@@ -198,7 +203,7 @@

Calendar Menu

- + @@ -221,6 +226,16 @@

Calendar Menu

+ + @@ -237,7 +252,7 @@

Calendar Menu

-
+
{ + document.body.classList.remove('calendar-printing'); + }); + it('should display calendars', () => { expect(component).toBeTruthy(); component.calendarservice.syncCaldav(); @@ -228,6 +232,30 @@ END:VCALENDAR expect(icon.style.color).toBe('pink'); }); + it('should display a calendar print option', () => { + fixture.detectChanges(); + + const toolbarButton = fixture.debugElement.nativeElement.querySelector('#printCalendarToolbarButton'); + const menuButton = fixture.debugElement.nativeElement.querySelector('#printCalendarMenuButton'); + + expect(toolbarButton).toBeDefined(); + expect(menuButton).toBeDefined(); + expect(menuButton.innerText).toContain('Print Calendar'); + }); + + it('should print the calendar using print mode styles', () => { + const print = spyOn(window, 'print'); + + component.printCalendar(); + + expect(document.body.classList.contains('calendar-printing')).toBe(true); + expect(print).toHaveBeenCalled(); + + window.dispatchEvent(new Event('afterprint')); + + expect(document.body.classList.contains('calendar-printing')).toBe(false); + }); + it('should display events', () => { mockData['events'] = simpleEvents; component.calendarservice.syncCaldav(true); diff --git a/src/app/calendar-app/calendar-app.component.ts b/src/app/calendar-app/calendar-app.component.ts index 0f1195171..b7a4cca00 100644 --- a/src/app/calendar-app/calendar-app.component.ts +++ b/src/app/calendar-app/calendar-app.component.ts @@ -100,6 +100,12 @@ export class CalendarAppComponent implements OnDestroy { shown_events: RunboxCalendarEvent[] = []; prefGroup = DefaultPrefGroups.Global; + private readonly calendarPrintClass = 'calendar-printing'; + + private readonly clearCalendarPrintMode = (): void => { + document.body.classList.remove(this.calendarPrintClass); + window.removeEventListener('afterprint', this.clearCalendarPrintMode); + }; constructor( public calendarservice: CalendarService, @@ -164,6 +170,7 @@ export class CalendarAppComponent implements OnDestroy { ngOnDestroy() { clearInterval(this.viewRefreshInterval); + this.clearCalendarPrintMode(); } addEvent(on?: Date): void { @@ -328,6 +335,13 @@ export class CalendarAppComponent implements OnDestroy { }); } + printCalendar(): void { + document.body.classList.add(this.calendarPrintClass); + window.removeEventListener('afterprint', this.clearCalendarPrintMode); + window.addEventListener('afterprint', this.clearCalendarPrintMode); + window.print(); + } + setView(view: RunboxCalendarView): void { this.view = view; if (this.settings.lastUsedView !== view) { diff --git a/src/styles.scss b/src/styles.scss index ed7a85188..9a022a20f 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1392,6 +1392,57 @@ app-calendar-app-component mat-nav-list button { } } +@media print { + body.calendar-printing { + overflow: visible !important; + + rmm-headertoolbar, + #mainMenuContainer, + app-calendar-app-component mat-sidenav, + app-calendar-app-component .mat-drawer-backdrop, + app-calendar-app-component .calendarToolbar, + app-calendar-app-component .add-new-event { + display: none !important; + } + + app-calendar-app-component, + app-calendar-app-component mat-sidenav-container, + app-calendar-app-component mat-sidenav-content, + app-calendar-app-component .mat-drawer-content, + app-calendar-app-component .calendarPrintArea { + display: block !important; + position: static !important; + height: auto !important; + min-height: 0 !important; + overflow: visible !important; + transform: none !important; + width: 100% !important; + } + + app-calendar-app-component mat-sidenav-container { + bottom: auto !important; + left: 0 !important; + margin: 0 !important; + right: auto !important; + top: 0 !important; + } + + app-calendar-app-component mat-sidenav-content, + app-calendar-app-component .mat-drawer-content { + margin: 0 !important; + } + + app-calendar-app-component .cal-month-view, + app-calendar-app-component .cal-week-view, + app-calendar-app-component .cal-day-view { + break-inside: avoid; + page-break-inside: avoid; + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + } + } +} + .calendarTitle { font-size: 20px !important; font-weight: bold;