From ed06e26647f021b3e2dc1a7c7636174779aa9eba Mon Sep 17 00:00:00 2001 From: mustafahlvc Date: Wed, 26 Jul 2017 10:02:26 +0300 Subject: [PATCH] (Calendar App) Calendar app added. --- package-lock.json | 5 + package.json | 1 + .../confirm-dialog.component.html | 6 + .../confirm-dialog.component.scss} | 0 .../confirm-dialog.component.ts | 21 ++ src/app/core/modules/shared.module.ts | 21 +- src/app/fuse-fake-db/calendar.ts | 97 ++++++ src/app/fuse-fake-db/fuse-fake-db.service.ts | 22 +- .../apps/calendar/calendar.component.html | 20 +- .../apps/calendar/calendar.component.scss | 177 +++++++++++ .../main/apps/calendar/calendar.component.ts | 296 +++++++++++------- src/app/main/apps/calendar/calendar.module.ts | 8 +- .../main/apps/calendar/calendar.service.ts | 37 ++- .../event-detail/event-detail.component.html | 3 + .../event-detail/event-detail.component.scss | 0 .../event-detail/event-detail.component.ts | 19 ++ .../event-dialog/event-dialog.component.html | 20 -- .../event-dialog/event-dialog.component.ts | 22 -- .../event-form/event-form.component.html | 139 ++++++++ .../event-form/event-form.component.scss | 12 + .../event-form/event-form.component.ts | 64 ++++ src/app/main/apps/calendar/event.model.ts | 75 +++++ 22 files changed, 890 insertions(+), 175 deletions(-) create mode 100644 src/app/core/components/confirm-dialog/confirm-dialog.component.html rename src/app/{main/apps/calendar/event-dialog/event-dialog.component.scss => core/components/confirm-dialog/confirm-dialog.component.scss} (100%) create mode 100644 src/app/core/components/confirm-dialog/confirm-dialog.component.ts create mode 100644 src/app/fuse-fake-db/calendar.ts create mode 100644 src/app/main/apps/calendar/event-detail/event-detail.component.html create mode 100644 src/app/main/apps/calendar/event-detail/event-detail.component.scss create mode 100644 src/app/main/apps/calendar/event-detail/event-detail.component.ts delete mode 100644 src/app/main/apps/calendar/event-dialog/event-dialog.component.html delete mode 100644 src/app/main/apps/calendar/event-dialog/event-dialog.component.ts create mode 100644 src/app/main/apps/calendar/event-form/event-form.component.html create mode 100644 src/app/main/apps/calendar/event-form/event-form.component.scss create mode 100644 src/app/main/apps/calendar/event-form/event-form.component.ts create mode 100644 src/app/main/apps/calendar/event.model.ts diff --git a/package-lock.json b/package-lock.json index 2aef8461..c529aa4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5929,6 +5929,11 @@ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", "dev": true }, + "ngx-color-picker": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ngx-color-picker/-/ngx-color-picker-4.2.0.tgz", + "integrity": "sha512-xWFpvOc+0WOD2kppPDlN1q5p58jgQDgUSsier/xi1i0HaVuU+BgNCo7aFPAKHaovw0Gv1WWp5GPAdpjXdUe7KA==" + }, "ngx-perfect-scrollbar": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/ngx-perfect-scrollbar/-/ngx-perfect-scrollbar-4.5.2.tgz", diff --git a/package.json b/package.json index 5ebed461..921a5530 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "core-js": "^2.4.1", "firebase": "^4.1.3", "hammerjs": "^2.0.8", + "ngx-color-picker": "^4.2.0", "ngx-perfect-scrollbar": "^4.5.2", "rxjs": "^5.4.2", "zone.js": "^0.8.13" diff --git a/src/app/core/components/confirm-dialog/confirm-dialog.component.html b/src/app/core/components/confirm-dialog/confirm-dialog.component.html new file mode 100644 index 00000000..d7d60191 --- /dev/null +++ b/src/app/core/components/confirm-dialog/confirm-dialog.component.html @@ -0,0 +1,6 @@ +

Confirm

+
{{confirmMessage}}
+
+ + +
diff --git a/src/app/main/apps/calendar/event-dialog/event-dialog.component.scss b/src/app/core/components/confirm-dialog/confirm-dialog.component.scss similarity index 100% rename from src/app/main/apps/calendar/event-dialog/event-dialog.component.scss rename to src/app/core/components/confirm-dialog/confirm-dialog.component.scss diff --git a/src/app/core/components/confirm-dialog/confirm-dialog.component.ts b/src/app/core/components/confirm-dialog/confirm-dialog.component.ts new file mode 100644 index 00000000..08bb4600 --- /dev/null +++ b/src/app/core/components/confirm-dialog/confirm-dialog.component.ts @@ -0,0 +1,21 @@ +import { Component, OnInit } from '@angular/core'; +import { MdDialogRef } from '@angular/material'; + +@Component({ + selector : 'fuse-confirm-dialog', + templateUrl: './confirm-dialog.component.html', + styleUrls : ['./confirm-dialog.component.scss'] +}) +export class FuseConfirmDialogComponent implements OnInit +{ + public confirmMessage: string; + + constructor(public dialogRef: MdDialogRef) + { + } + + ngOnInit() + { + } + +} diff --git a/src/app/core/modules/shared.module.ts b/src/app/core/modules/shared.module.ts index 61cd37cf..164e6374 100644 --- a/src/app/core/modules/shared.module.ts +++ b/src/app/core/modules/shared.module.ts @@ -11,23 +11,26 @@ import { FuseMdSidenavTogglerDirective } from '../directives/md-sidenav-helper/md-sidenav-helper.directive'; import { FusePipesModule } from '../pipes/pipes.module'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { ColorPickerModule } from 'ngx-color-picker'; +import { FuseConfirmDialogComponent } from '../components/confirm-dialog/confirm-dialog.component'; @NgModule({ - declarations: [ + declarations : [ FuseMdSidenavHelperDirective, - FuseMdSidenavTogglerDirective + FuseMdSidenavTogglerDirective, + FuseConfirmDialogComponent ], - imports : [ + imports : [ FlexLayoutModule, MaterialModule, CommonModule, FormsModule, FusePipesModule, PerfectScrollbarModule, - ReactiveFormsModule + ReactiveFormsModule, + ColorPickerModule ], - exports : [ + exports : [ FlexLayoutModule, MaterialModule, CommonModule, @@ -36,8 +39,10 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; FuseMdSidenavTogglerDirective, FusePipesModule, PerfectScrollbarModule, - ReactiveFormsModule - ] + ReactiveFormsModule, + ColorPickerModule + ], + entryComponents: [FuseConfirmDialogComponent] }) export class SharedModule diff --git a/src/app/fuse-fake-db/calendar.ts b/src/app/fuse-fake-db/calendar.ts new file mode 100644 index 00000000..fab7bc83 --- /dev/null +++ b/src/app/fuse-fake-db/calendar.ts @@ -0,0 +1,97 @@ +import { + startOfDay, + endOfDay, + subDays, + addDays, + endOfMonth, + isSameDay, + isSameMonth, + addHours +} from 'date-fns'; + +export class CalendarFakeDb +{ + + public static data = [ + { + id : 'events', + data: [ + { + start : subDays(startOfDay(new Date()), 1), + end : addDays(new Date(), 1), + title : 'A 3 day event', + allDay : false, + color : { + primary : '#ad2121', + secondary: '#FAE3E3' + }, + resizable: { + beforeStart: true, + afterEnd : true + }, + draggable: true, + meta : { + location: 'Los Angeles', + notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.' + } + }, + { + start : startOfDay(new Date()), + title : 'An event with no end date', + allDay : false, + color : { + primary : '#e3bc08', + secondary: '#FDF1BA' + }, + resizable: { + beforeStart: true, + afterEnd : true + }, + draggable: true, + meta : { + location: 'Los Angeles', + notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.' + } + }, + { + start : subDays(endOfMonth(new Date()), 3), + end : addDays(endOfMonth(new Date()), 3), + title : 'A long event that spans 2 months', + allDay : false, + color : { + primary : '#1e90ff', + secondary: '#D1E8FF' + }, + resizable: { + beforeStart: true, + afterEnd : true + }, + draggable: true, + meta : { + location: 'Los Angeles', + notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.' + } + }, + { + start : addHours(startOfDay(new Date()), 2), + end : new Date(), + title : 'A draggable and resizable event', + allDay : false, + color : { + primary : '#e3bc08', + secondary: '#FDF1BA' + }, + resizable: { + beforeStart: true, + afterEnd : true + }, + draggable: true, + meta : { + location: 'Los Angeles', + notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.' + } + } + ] + } + ]; +} diff --git a/src/app/fuse-fake-db/fuse-fake-db.service.ts b/src/app/fuse-fake-db/fuse-fake-db.service.ts index e8b48d5a..bc80d113 100644 --- a/src/app/fuse-fake-db/fuse-fake-db.service.ts +++ b/src/app/fuse-fake-db/fuse-fake-db.service.ts @@ -1,19 +1,31 @@ import { InMemoryDbService } from 'angular-in-memory-web-api'; import { MailFakeDb } from './mail'; -import {ChatFakeDb} from './chat'; +import { ChatFakeDb } from './chat'; +import { CalendarFakeDb } from './calendar'; +import { + startOfDay, + endOfDay, + subDays, + addDays, + endOfMonth, + isSameDay, + isSameMonth, + addHours +} from 'date-fns'; export class FuseFakeDbService implements InMemoryDbService { createDb() { return { - 'mail-mails' : MailFakeDb.mails, - 'mail-folders': MailFakeDb.folders, - 'mail-filters': MailFakeDb.filters, - 'mail-labels' : MailFakeDb.labels, + 'mail-mails' : MailFakeDb.mails, + 'mail-folders' : MailFakeDb.folders, + 'mail-filters' : MailFakeDb.filters, + 'mail-labels' : MailFakeDb.labels, 'chat-contacts': ChatFakeDb.contacts, 'chat-chats' : ChatFakeDb.chats, 'chat-user' : ChatFakeDb.user, + 'calendar' : CalendarFakeDb.data }; } diff --git a/src/app/main/apps/calendar/calendar.component.html b/src/app/main/apps/calendar/calendar.component.html index adc1caa0..efaee667 100644 --- a/src/app/main/apps/calendar/calendar.component.html +++ b/src/app/main/apps/calendar/calendar.component.html @@ -25,7 +25,9 @@ @@ -54,19 +56,20 @@ mwlCalendarPreviousView [view]="view" [(viewDate)]="viewDate" + (viewDateChange)="selectedDay = {date:$event}" aria-label="Previous"> chevron_left
-

{{ viewDate | calendarDate:(view + 'ViewTitle'):'en' }}

- + {{ viewDate | calendarDate:(view + 'ViewTitle'):'en' }}
@@ -92,23 +95,28 @@ [refresh]="refresh" [activeDayIsOpen]="activeDayIsOpen" (dayClicked)="dayClicked($event.day)" - (eventClicked)="handleEvent('Clicked', $event.event)" - (eventTimesChanged)="eventTimesChanged($event)"> + (eventClicked)="editEvent('edit', $event.event)" + (eventTimesChanged)="eventTimesChanged($event)" + (beforeViewRender)="beforeMonthViewRender($event)"> diff --git a/src/app/main/apps/calendar/calendar.component.scss b/src/app/main/apps/calendar/calendar.component.scss index 3198312b..6e0d17bf 100644 --- a/src/app/main/apps/calendar/calendar.component.scss +++ b/src/app/main/apps/calendar/calendar.component.scss @@ -1,5 +1,179 @@ +@import "src/app/core/scss/fuse"; @import "node_modules/angular-calendar/scss/angular-calendar"; +.cal-month-view { + + .cal-header { + + .cal-cell { + font-weight: 500; + } + } + + .cal-day-cell { + + &.cal-open { + @include mat-elevation(3); + } + } + + .cal-open-day-events { + background: whitesmoke; + box-shadow: inset 0 0 15px 0 rgba(0, 0, 0, 0.13); + padding: 0; + display: flex; + flex-direction: column; + + > div { + padding: 0 16px; + margin: 8px 16px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: start; + background-color: white; + @include mat-elevation(1); + transition: box-shadow 300ms ease; + + &:first-of-type { + margin-top: 24px; + } + + &:last-of-type { + margin-bottom: 24px; + } + + &:hover { + @include mat-elevation(3); + } + + .cal-event { + top: 0; + margin: 0; + } + + mwl-calendar-event-title { + flex: 1; + + .cal-event-title { + display: block; + padding: 21px 24px; + line-height: 1; + text-decoration: none; + color: black; + } + } + + mwl-calendar-event-actions { + + .cal-event-actions { + display: flex; + flex-direction: row; + align-items: center; + + .cal-event-action { + display: block; + line-height: 1; + padding: 8px; + } + } + } + + } + } +} + +.cal-week-view { + + .cal-header > b { + font-weight: 500; + } + + .cal-event { + display: flex; + flex-direction: row; + align-items: center; + + mwl-calendar-event-title { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex: 1; + order: 0; + + .cal-event-title { + display: block; + //padding: 21px 24px; + line-height: 1; + text-decoration: none; + color: black; + } + } + + mwl-calendar-event-actions { + order: 1; + + .cal-event-actions { + display: flex; + flex-direction: row; + align-items: center; + + .cal-event-action { + display: block; + line-height: 1; + padding: 8px; + } + } + } + } +} + +.cal-day-view { + + .cal-time { + font-weight: 500; + } + + .cal-event { + display: flex; + flex-direction: row; + + mwl-calendar-event-title { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex: 1; + order: 0; + + .cal-event-title { + display: block; + height: 26px; + line-height: 26px; + text-decoration: none; + color: black; + } + } + + mwl-calendar-event-actions { + order: 1; + + .cal-event-actions { + display: flex; + flex-direction: row; + align-items: center; + + .cal-event-action { + display: block; + line-height: 1; + padding: 4px; + } + } + } + } +} + #calendar { background: #FFFFFF; height: 100%; @@ -104,6 +278,7 @@ font-size: 20px; min-width: 160px; text-align: center; + font-weight: 500; } } } @@ -121,6 +296,8 @@ } .content { + flex: 1; + overflow: auto; padding: 24px; } } diff --git a/src/app/main/apps/calendar/calendar.component.ts b/src/app/main/apps/calendar/calendar.component.ts index e04bb2fd..b208c028 100644 --- a/src/app/main/apps/calendar/calendar.component.ts +++ b/src/app/main/apps/calendar/calendar.component.ts @@ -1,41 +1,18 @@ -import { - ChangeDetectionStrategy, - Component, - Inject, - OnInit, - TemplateRef, - ViewChild, - ViewEncapsulation -} from '@angular/core'; +import { startOfDay, endOfDay, subDays, addDays, endOfMonth, isSameDay, isSameMonth, addHours } from 'date-fns'; +import { ChangeDetectionStrategy, Component, OnInit, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core'; import { Subject } from 'rxjs/Subject'; -import { CalendarEvent, CalendarEventAction, CalendarEventTimesChangedEvent } from 'angular-calendar'; -import { MD_DIALOG_DATA, MdDialog, MdDialogRef } from '@angular/material'; -import { EventDialogComponent } from './event-dialog/event-dialog.component'; +import { MdDialog, MdDialogRef } from '@angular/material'; +import { EventFormDialogComponent } from './event-form/event-form.component'; +import { FormGroup } from '@angular/forms'; +import { CalendarEventModel } from './event.model'; +import { CalendarService } from './calendar.service'; import { - startOfDay, - endOfDay, - subDays, - addDays, - endOfMonth, - isSameDay, - isSameMonth, - addHours -} from 'date-fns'; - -const colors: any = { - red : { - primary : '#ad2121', - secondary: '#FAE3E3' - }, - blue : { - primary : '#1e90ff', - secondary: '#D1E8FF' - }, - yellow: { - primary : '#e3bc08', - secondary: '#FDF1BA' - } -}; + CalendarEvent, + CalendarEventAction, + CalendarEventTimesChangedEvent, + CalendarMonthViewDay +} from 'angular-calendar'; +import { FuseConfirmDialogComponent } from '../../../core/components/confirm-dialog/confirm-dialog.component'; @Component({ selector : 'fuse-calendar', @@ -54,7 +31,7 @@ export class CalendarComponent implements OnInit events: CalendarEvent[]; - actions: CalendarEventAction[]; + public actions: CalendarEventAction[]; activeDayIsOpen: boolean; @@ -62,75 +39,106 @@ export class CalendarComponent implements OnInit dialogRef: any; - constructor(public dialog: MdDialog) + confirmDialogRef: MdDialogRef; + + selectedDay: any; + + constructor(public dialog: MdDialog, + public calendarService: CalendarService) { this.view = 'month'; this.viewDate = new Date(); this.activeDayIsOpen = true; + this.selectedDay = {date: startOfDay(new Date())}; this.actions = [ { label : 'edit', onClick: ({event}: { event: CalendarEvent }): void => { - this.handleEvent('Edited', event); + this.editEvent('edit', event); } }, { - label : 'close', + label : 'delete', onClick: ({event}: { event: CalendarEvent }): void => { - this.events = this.events.filter(iEvent => iEvent !== event); - this.handleEvent('Deleted', event); + this.deleteEvent(event); } } ]; - this.events = [ - { - start : subDays(startOfDay(new Date()), 1), - end : addDays(new Date(), 1), - title : 'A 3 day event', - color : colors.red, - actions: this.actions - }, - { - start : startOfDay(new Date()), - title : 'An event with no end date', - color : colors.yellow, - actions: this.actions - }, - { - start: subDays(endOfMonth(new Date()), 3), - end : addDays(endOfMonth(new Date()), 3), - title: 'A long event that spans 2 months', - color: colors.blue - }, - { - start : addHours(startOfDay(new Date()), 2), - end : new Date(), - title : 'A draggable and resizable event', - color : colors.yellow, - actions : this.actions, - resizable: { - beforeStart: true, - afterEnd : true - }, - draggable: true - } - ]; + /** + * Get events from service/server + */ + this.setEvents(); } ngOnInit() { + /** + * Watch re-render-refresh for updating db + */ + this.refresh.subscribe(updateDB => { + // console.warn('REFRESH'); + if ( updateDB ) + { + // console.warn('UPDATE DB'); + this.calendarService.updateEvents(this.events); + } + }); + + this.calendarService.onEventsUpdated.subscribe(events => { + this.setEvents(); + this.refresh.next(); + }); } - dayClicked({date, events}: { date: Date; events: CalendarEvent[] }): void + setEvents() { + this.events = this.calendarService.events.map(item => { + item.actions = this.actions; + return new CalendarEventModel(item); + }); + } + + /** + * Before View Renderer + * @param {any} header + * @param {any} body + */ + beforeMonthViewRender({header, body}) + { + // console.info('beforeMonthViewRender'); + /** + * Get the selected day + */ + const _selectedDay = body.find((_day) => { + return _day.date.getTime() === this.selectedDay.date.getTime(); + }); + + if ( _selectedDay ) + { + /** + * Set selectedday style + * @type {string} + */ + _selectedDay.cssClass = 'mat-elevation-z3'; + } + + } + + + /** + * Day clicked + * @param {MonthViewDay} day + */ + dayClicked(day: CalendarMonthViewDay): void + { + const date: Date = day.date; + const events: CalendarEvent[] = day.events; + if ( isSameMonth(date, this.viewDate) ) { - if ( - (isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) || - events.length === 0 - ) + if ( (isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) || events.length === 0 ) { this.activeDayIsOpen = false; } @@ -140,48 +148,120 @@ export class CalendarComponent implements OnInit this.viewDate = date; } } - } - - eventTimesChanged({ - event, - newStart, - newEnd - }: CalendarEventTimesChangedEvent): void - { - event.start = newStart; - event.end = newEnd; - this.handleEvent('Dropped or resized', event); + this.selectedDay = day; this.refresh.next(); } - handleEvent(action: string, event: CalendarEvent): void + /** + * Event times changed + * Event dropped or resized + * @param {CalendarEvent} event + * @param {Date} newStart + * @param {Date} newEnd + */ + eventTimesChanged({event, newStart, newEnd}: CalendarEventTimesChangedEvent): void { - console.log(event, action); - this.dialogRef = this.dialog.open(EventDialogComponent, { - data: { + event.start = newStart; + event.end = newEnd; + // console.warn('Dropped or resized', event); + this.refresh.next(true); + } + + /** + * Delete Event + * @param event + */ + deleteEvent(event) + { + this.confirmDialogRef = this.dialog.open(FuseConfirmDialogComponent, { + disableClose: false + }); + + this.confirmDialogRef.componentInstance.confirmMessage = 'Are you sure you want to delete?'; + + this.confirmDialogRef.afterClosed().subscribe(result => { + if ( result ) + { + const eventIndex = this.events.indexOf(event); + this.events.splice(eventIndex, 1); + this.refresh.next(true); + } + this.confirmDialogRef = null; + }); + + } + + /** + * Edit Event + * @param {string} action + * @param {CalendarEvent} event + */ + editEvent(action: string, event: CalendarEvent) + { + const eventIndex = this.events.indexOf(event); + + this.dialogRef = this.dialog.open(EventFormDialogComponent, { + panelClass: 'event-form-dialog', + data : { event : event, action: action } }); - this.dialogRef.afterClosed().subscribe(result => { - console.info(result); - }); + + this.dialogRef.afterClosed() + .subscribe(response => { + if ( !response ) + { + return; + } + const actionType: string = response[0]; + const formData: FormGroup = response[1]; + switch ( actionType ) + { + /** + * Save + */ + case 'save': + + this.events[eventIndex] = Object.assign(this.events[eventIndex], formData.getRawValue()); + this.refresh.next(true); + + break; + /** + * Delete + */ + case 'delete': + + this.deleteEvent(event); + + break; + } + }); } + /** + * Add Event + */ addEvent(): void { - this.events.push({ - title : 'New event', - start : startOfDay(new Date()), - end : endOfDay(new Date()), - color : colors.red, - draggable: true, - resizable: { - beforeStart: true, - afterEnd : true + this.dialogRef = this.dialog.open(EventFormDialogComponent, { + panelClass: 'event-form-dialog', + data : { + action: 'new', + date : this.selectedDay.date } }); - this.refresh.next(); + this.dialogRef.afterClosed() + .subscribe((response: FormGroup) => { + if ( !response ) + { + return; + } + const newEvent = response.getRawValue(); + newEvent.actions = this.actions; + this.events.push(newEvent); + this.refresh.next(true); + }); } } diff --git a/src/app/main/apps/calendar/calendar.module.ts b/src/app/main/apps/calendar/calendar.module.ts index c9f4175c..ca59bee0 100644 --- a/src/app/main/apps/calendar/calendar.module.ts +++ b/src/app/main/apps/calendar/calendar.module.ts @@ -4,7 +4,8 @@ import { RouterModule, Routes } from '@angular/router'; import { CalendarComponent } from './calendar.component'; import { CalendarService } from './calendar.service'; import { CalendarModule } from 'angular-calendar'; -import { EventDialogComponent } from './event-dialog/event-dialog.component'; +import { EventFormDialogComponent } from './event-form/event-form.component'; +import { EventDetailDialogComponent } from './event-detail/event-detail.component'; const routes: Routes = [ { @@ -23,12 +24,13 @@ const routes: Routes = [ ], declarations : [ CalendarComponent, - EventDialogComponent, + EventFormDialogComponent, + EventDetailDialogComponent, ], providers : [ CalendarService ], - entryComponents: [EventDialogComponent] + entryComponents: [EventFormDialogComponent, EventDetailDialogComponent] }) export class FuseCalendarModule { diff --git a/src/app/main/apps/calendar/calendar.service.ts b/src/app/main/apps/calendar/calendar.service.ts index 5965a3da..c765e74a 100644 --- a/src/app/main/apps/calendar/calendar.service.ts +++ b/src/app/main/apps/calendar/calendar.service.ts @@ -3,21 +3,52 @@ import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/r import { Observable } from 'rxjs/Observable'; import { Http } from '@angular/http'; import { Subject } from 'rxjs/Subject'; -import { BehaviorSubject } from 'rxjs/BehaviorSubject'; @Injectable() export class CalendarService implements Resolve { + events: any; + onEventsUpdated = new Subject(); constructor(private http: Http) { - } + } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any { return new Promise((resolve, reject) => { - resolve(); + Promise.all([ + this.getEvents() + ]).then( + ([events]: [any]) => { + resolve(); + }, + reject + ); + }); + } + + getEvents() + { + return new Promise((resolve, reject) => { + + this.http.get('api/calendar/events') + .subscribe(response => { + this.events = response.json().data.data; + this.onEventsUpdated.next(this.events); + resolve(this.events); + }, reject); + }); + } + + updateEvents(events) + { + return new Promise((resolve, reject) => { + this.http.post('api/calendar/events', {id: 'events', data: [...events]}) + .subscribe(response => { + this.getEvents(); + }, reject); }); } diff --git a/src/app/main/apps/calendar/event-detail/event-detail.component.html b/src/app/main/apps/calendar/event-detail/event-detail.component.html new file mode 100644 index 00000000..026b9043 --- /dev/null +++ b/src/app/main/apps/calendar/event-detail/event-detail.component.html @@ -0,0 +1,3 @@ +

+ event-detail works! +

diff --git a/src/app/main/apps/calendar/event-detail/event-detail.component.scss b/src/app/main/apps/calendar/event-detail/event-detail.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/main/apps/calendar/event-detail/event-detail.component.ts b/src/app/main/apps/calendar/event-detail/event-detail.component.ts new file mode 100644 index 00000000..e9c91f28 --- /dev/null +++ b/src/app/main/apps/calendar/event-detail/event-detail.component.ts @@ -0,0 +1,19 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector : 'fuse-calendar-event-detail-dialog', + templateUrl: './event-detail.component.html', + styleUrls : ['./event-detail.component.scss'] +}) +export class EventDetailDialogComponent implements OnInit +{ + + constructor() + { + } + + ngOnInit() + { + } + +} diff --git a/src/app/main/apps/calendar/event-dialog/event-dialog.component.html b/src/app/main/apps/calendar/event-dialog/event-dialog.component.html deleted file mode 100644 index 7e80af2f..00000000 --- a/src/app/main/apps/calendar/event-dialog/event-dialog.component.html +++ /dev/null @@ -1,20 +0,0 @@ -

-

- - -
-
- Action: -
{{ data.action }}
-
-
- Event: -
{{ data.event | json }}
-
-
-
- - -
diff --git a/src/app/main/apps/calendar/event-dialog/event-dialog.component.ts b/src/app/main/apps/calendar/event-dialog/event-dialog.component.ts deleted file mode 100644 index 76b6bc35..00000000 --- a/src/app/main/apps/calendar/event-dialog/event-dialog.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Component, Inject, OnInit } from '@angular/core'; -import { MD_DIALOG_DATA, MdDialogRef } from '@angular/material'; - -@Component({ - selector : 'fuse-calendar-event-dialog', - templateUrl: './event-dialog.component.html', - styleUrls : ['./event-dialog.component.scss'] -}) -export class EventDialogComponent implements OnInit -{ - - constructor(private dialogRef: MdDialogRef, - @Inject(MD_DIALOG_DATA) private data: any) - { - console.log(data); - } - - ngOnInit() - { - } - -} diff --git a/src/app/main/apps/calendar/event-form/event-form.component.html b/src/app/main/apps/calendar/event-form/event-form.component.html new file mode 100644 index 00000000..ab1141a2 --- /dev/null +++ b/src/app/main/apps/calendar/event-form/event-form.component.html @@ -0,0 +1,139 @@ + +
+ {{dialogTitle}} + +
+
+ +
+ +
+ + + + + +
+ + All Day + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+ + + + + + + + + + +
+ +
+ +
+ + + + + + + +
diff --git a/src/app/main/apps/calendar/event-form/event-form.component.scss b/src/app/main/apps/calendar/event-form/event-form.component.scss new file mode 100644 index 00000000..ce618e53 --- /dev/null +++ b/src/app/main/apps/calendar/event-form/event-form.component.scss @@ -0,0 +1,12 @@ +.event-form-dialog { + .mat-dialog-container { + padding: 0; + max-width: 720px; + width: 720px; + } +} + +:host { + display: flex; + flex-direction: column; +} diff --git a/src/app/main/apps/calendar/event-form/event-form.component.ts b/src/app/main/apps/calendar/event-form/event-form.component.ts new file mode 100644 index 00000000..ccf7f713 --- /dev/null +++ b/src/app/main/apps/calendar/event-form/event-form.component.ts @@ -0,0 +1,64 @@ +import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core'; +import { MD_DIALOG_DATA, MdDialogRef } from '@angular/material'; +import { CalendarEvent } from 'angular-calendar'; +import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; +import 'rxjs/Rx'; +import { CalendarEventModel } from '../event.model'; + +@Component({ + selector : 'fuse-calendar-event-form-dialog', + templateUrl : './event-form.component.html', + styleUrls : ['./event-form.component.scss'], + encapsulation: ViewEncapsulation.None +}) + +export class EventFormDialogComponent implements OnInit +{ + event: CalendarEvent; + dialogTitle: string; + eventForm: FormGroup; + action: string; + + constructor(public dialogRef: MdDialogRef, + @Inject(MD_DIALOG_DATA) private data: any, + private formBuilder: FormBuilder) + { + this.event = data.event; + this.action = data.action; + + if ( this.action === 'edit' ) + { + this.dialogTitle = this.event.title; + } + else + { + this.dialogTitle = 'New Event'; + this.event = new CalendarEventModel({start: data.date, end: data.date}); + } + + this.eventForm = this.createEventForm(); + } + + ngOnInit() + { + } + + createEventForm() + { + return new FormGroup({ + title : new FormControl(this.event.title), + start : new FormControl(this.event.start), + end : new FormControl(this.event.end), + allDay: new FormControl(this.event.allDay), + color : this.formBuilder.group({ + primary : new FormControl(this.event.color.primary), + secondary: new FormControl(this.event.color.secondary) + }), + meta : + this.formBuilder.group({ + location: new FormControl(this.event.meta.location), + notes : new FormControl(this.event.meta.notes) + }) + }); + } +} diff --git a/src/app/main/apps/calendar/event.model.ts b/src/app/main/apps/calendar/event.model.ts new file mode 100644 index 00000000..67008724 --- /dev/null +++ b/src/app/main/apps/calendar/event.model.ts @@ -0,0 +1,75 @@ +import { + CalendarEventAction +} from 'angular-calendar'; + +import { + startOfDay, + endOfDay, + subDays, + addDays, + endOfMonth, + isSameDay, + isSameMonth, + addHours +} from 'date-fns'; +// import { CalendarEvent } from 'calendar-utils/dist/calendar-utils'; + +/* +export interface EventAction +{ + label: string; + cssClass?: string; + + onClick({event}: { + event: CalendarEvent; + }): any; +}*/ + +export class CalendarEventModel +{ + start: Date; + end?: Date; + title: string; + color: { + primary: string; + secondary: string; + }; + actions?: CalendarEventAction[]; + allDay?: boolean; + cssClass?: string; + resizable?: { + beforeStart?: boolean; + afterEnd?: boolean; + }; + draggable?: boolean; + meta?: { + location: string, + notes: string + }; + + constructor(data?) + { + data = data || {}; + this.start = new Date(data.start) || startOfDay(new Date()); + this.end = new Date(data.end) || endOfDay(new Date()); + this.title = data.title || ''; + this.color = { + primary : data.color && data.color.primary || '#1e90ff', + secondary: data.color && data.color.secondary || '#D1E8FF' + }; + this.draggable = data.draggable || true; + this.resizable = { + beforeStart: data.resizable && data.resizable.beforeStart || true, + afterEnd : data.resizable && data.resizable.afterEnd || true + }; + this.actions = data.actions || []; + this.allDay = data.allDay || false; + this.cssClass = data.cssClass || ''; + this.meta = { + location: data.meta && data.meta.location || '', + notes : data.meta && data.meta.notes || '' + }; + } + + +}