diff --git a/package-lock.json b/package-lock.json
index 1c0e7771..2aef8461 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -562,11 +562,33 @@
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
"dev": true
},
+ "angular-calendar": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/angular-calendar/-/angular-calendar-0.19.0.tgz",
+ "integrity": "sha512-RbLciS+OBl9ITgPKVUOjMUXe7sTP5KHPZtCB7Rru3ebUXh8WehdZvELC3Wxz0euS8hqBP2o3ueSqXcAy1pz2bw==",
+ "requires": {
+ "angular-draggable-droppable": "1.0.1",
+ "angular-resizable-element": "1.2.0",
+ "calendar-utils": "0.0.56",
+ "date-fns": "1.28.5",
+ "positioning": "1.3.0"
+ }
+ },
+ "angular-draggable-droppable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/angular-draggable-droppable/-/angular-draggable-droppable-1.0.1.tgz",
+ "integrity": "sha1-etcMMQmUsPmA9A04Lc5ZlG/jDc8="
+ },
"angular-in-memory-web-api": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/angular-in-memory-web-api/-/angular-in-memory-web-api-0.3.2.tgz",
"integrity": "sha1-iDbZ4lNNN7co88taHK9v4ef7vs0="
},
+ "angular-resizable-element": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/angular-resizable-element/-/angular-resizable-element-1.2.0.tgz",
+ "integrity": "sha512-i5xCl4n2VMgGK4gY6Jtho0K5aazbsqNw1bmPYpI9RwlKK+dIOcsMRuMl1JPWzrznHsm4qEsfYg+9KLkYsYy+/g=="
+ },
"ansi-escapes": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz",
@@ -1217,6 +1239,11 @@
"integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=",
"dev": true
},
+ "calendar-utils": {
+ "version": "0.0.56",
+ "resolved": "https://registry.npmjs.org/calendar-utils/-/calendar-utils-0.0.56.tgz",
+ "integrity": "sha512-IvvzvIGmtDdVjSrnIOd5dDJ3ATWLztqdgLOTeIB2IJonN60LMa2R71KDVpdF8w9sKm3drRV4kfgIbocYJAw6+Q=="
+ },
"callsite": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
@@ -1950,6 +1977,11 @@
}
}
},
+ "date-fns": {
+ "version": "1.28.5",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.28.5.tgz",
+ "integrity": "sha1-JXz8RdMi30XvVlhmWWfuhBzXP68="
+ },
"date-now": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
@@ -6462,6 +6494,11 @@
}
}
},
+ "positioning": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/positioning/-/positioning-1.3.0.tgz",
+ "integrity": "sha512-B0BHlhLFsLPV8EWVv792caQCg4QNxuCeZUVXw/DP1jRj4WOF74KmTAg+7t3dDfrFXDT22qBS2vcryQmZYSM7jg=="
+ },
"postcss": {
"version": "5.2.17",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz",
diff --git a/package.json b/package.json
index 9eb2302c..5ebed461 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
"@angular/platform-browser": "^4.3.0",
"@angular/platform-browser-dynamic": "^4.3.0",
"@angular/router": "^4.3.0",
+ "angular-calendar": "^0.19.0",
"angular-in-memory-web-api": "^0.3.2",
"core-js": "^2.4.1",
"firebase": "^4.1.3",
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 6ab85110..14c2b109 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -35,6 +35,10 @@ const appRoutes: Routes = [
path : 'apps/chat',
loadChildren: './main/apps/chat/chat.module#ChatModule'
},
+ {
+ path : 'apps/calendar',
+ loadChildren: './main/apps/calendar/calendar.module#FuseCalendarModule'
+ },
{
path : '**',
redirectTo: 'apps/dashboards/project'
@@ -60,8 +64,6 @@ const appRoutes: Routes = [
FuseLayoutModule,
- // MailModule,
- ChatModule,
ProjectModule,
UIPageLayoutsModule
diff --git a/src/app/core/modules/shared.module.ts b/src/app/core/modules/shared.module.ts
index 2b19e199..61cd37cf 100644
--- a/src/app/core/modules/shared.module.ts
+++ b/src/app/core/modules/shared.module.ts
@@ -11,6 +11,7 @@ import {
FuseMdSidenavTogglerDirective
} from '../directives/md-sidenav-helper/md-sidenav-helper.directive';
import { FusePipesModule } from '../pipes/pipes.module';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [
diff --git a/src/app/main/apps/calendar/calendar.component.html b/src/app/main/apps/calendar/calendar.component.html
new file mode 100644
index 00000000..adc1caa0
--- /dev/null
+++ b/src/app/main/apps/calendar/calendar.component.html
@@ -0,0 +1,117 @@
+
diff --git a/src/app/main/apps/calendar/calendar.component.scss b/src/app/main/apps/calendar/calendar.component.scss
new file mode 100644
index 00000000..3198312b
--- /dev/null
+++ b/src/app/main/apps/calendar/calendar.component.scss
@@ -0,0 +1,126 @@
+@import "node_modules/angular-calendar/scss/angular-calendar";
+
+#calendar {
+ background: #FFFFFF;
+ height: 100%;
+
+ .header {
+ height: 200px;
+ min-height: 200px;
+ max-height: 200px;
+ padding: 24px;
+ position: relative;
+ background-size: 100% auto;
+ background-position: 0 50%;
+ background-repeat: no-repeat;
+ background-color: #FAFAFA;
+ color: #FFFFFF;
+ padding-bottom: 16px;
+
+ &:before {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1;
+ background: rgba(0, 0, 0, 0.45);
+ }
+
+ &.Jan {
+ background-image: url('/assets/images/backgrounds/january.jpg');
+ background-position: 0 45%;
+ }
+ &.Feb {
+ background-image: url('/assets/images/backgrounds/february.jpg');
+ background-position: 0 50%;
+ }
+ &.Mar {
+ background-image: url('/assets/images/backgrounds/march.jpg');
+ background-position: 0 45%;
+ }
+ &.Apr {
+ background-image: url('/assets/images/backgrounds/april.jpg');
+ background-position: 0 48%;
+ }
+ &.May {
+ background-image: url('/assets/images/backgrounds/may.jpg');
+ background-position: 0 47%;
+ }
+ &.Jun {
+ background-image: url('/assets/images/backgrounds/june.jpg');
+ background-position: 0 48%;
+ }
+ &.Jul {
+ background-image: url('/assets/images/backgrounds/july.jpg');
+ background-position: 0 3%;
+ }
+ &.Aug {
+ background-image: url('/assets/images/backgrounds/august.jpg');
+ background-position: 0 61%;
+ }
+ &.Sep {
+ background-image: url('/assets/images/backgrounds/september.jpg');
+ background-position: 0 58%;
+ }
+ &.Oct {
+ background-image: url('/assets/images/backgrounds/october.jpg');
+ background-position: 0 50%;
+ }
+ &.Nov {
+ background-image: url('/assets/images/backgrounds/november.jpg');
+ background-position: 0 46%;
+ }
+ &.Dec {
+ background-image: url('/assets/images/backgrounds/december.jpg');
+ background-position: 0 43%;
+ }
+
+ .header-content {
+ height: 100%;
+
+ .header-top {
+ position: relative;
+ z-index: 2;
+
+ .logo {
+
+ .logo-icon {
+ margin-right: 16px;
+ }
+
+ .logo-text {
+ font-size: 24px;
+ }
+ }
+ }
+
+ .header-bottom {
+ position: relative;
+ z-index: 2;
+
+ .title {
+ font-size: 20px;
+ min-width: 160px;
+ text-align: center;
+ }
+ }
+ }
+
+ .add-event-button {
+ position: absolute;
+ right: 18px;
+ bottom: -32px;
+ z-index: 10;
+ }
+
+ md-icon {
+ color: #FFFFFF;
+ }
+ }
+
+ .content {
+ padding: 24px;
+ }
+}
diff --git a/src/app/main/apps/calendar/calendar.component.ts b/src/app/main/apps/calendar/calendar.component.ts
new file mode 100644
index 00000000..e04bb2fd
--- /dev/null
+++ b/src/app/main/apps/calendar/calendar.component.ts
@@ -0,0 +1,188 @@
+import {
+ ChangeDetectionStrategy,
+ Component,
+ Inject,
+ 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 {
+ 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'
+ }
+};
+
+@Component({
+ selector : 'fuse-calendar',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ templateUrl : './calendar.component.html',
+ styleUrls : ['./calendar.component.scss'],
+ encapsulation : ViewEncapsulation.None
+})
+export class CalendarComponent implements OnInit
+{
+ @ViewChild('dialogContent') dialogContent: TemplateRef;
+
+ view: string;
+
+ viewDate: Date;
+
+ events: CalendarEvent[];
+
+ actions: CalendarEventAction[];
+
+ activeDayIsOpen: boolean;
+
+ refresh: Subject = new Subject();
+
+ dialogRef: any;
+
+ constructor(public dialog: MdDialog)
+ {
+ this.view = 'month';
+ this.viewDate = new Date();
+ this.activeDayIsOpen = true;
+
+ this.actions = [
+ {
+ label : 'edit',
+ onClick: ({event}: { event: CalendarEvent }): void => {
+ this.handleEvent('Edited', event);
+ }
+ },
+ {
+ label : 'close',
+ onClick: ({event}: { event: CalendarEvent }): void => {
+ this.events = this.events.filter(iEvent => iEvent !== event);
+ this.handleEvent('Deleted', 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
+ }
+ ];
+ }
+
+ ngOnInit()
+ {
+ }
+
+ dayClicked({date, events}: { date: Date; events: CalendarEvent[] }): void
+ {
+ if ( isSameMonth(date, this.viewDate) )
+ {
+ if (
+ (isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) ||
+ events.length === 0
+ )
+ {
+ this.activeDayIsOpen = false;
+ }
+ else
+ {
+ this.activeDayIsOpen = true;
+ this.viewDate = date;
+ }
+ }
+ }
+
+ eventTimesChanged({
+ event,
+ newStart,
+ newEnd
+ }: CalendarEventTimesChangedEvent): void
+ {
+ event.start = newStart;
+ event.end = newEnd;
+ this.handleEvent('Dropped or resized', event);
+ this.refresh.next();
+ }
+
+ handleEvent(action: string, event: CalendarEvent): void
+ {
+ console.log(event, action);
+ this.dialogRef = this.dialog.open(EventDialogComponent, {
+ data: {
+ event : event,
+ action: action
+ }
+ });
+ this.dialogRef.afterClosed().subscribe(result => {
+ console.info(result);
+ });
+ }
+
+ 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.refresh.next();
+ }
+}
+
+
diff --git a/src/app/main/apps/calendar/calendar.module.ts b/src/app/main/apps/calendar/calendar.module.ts
new file mode 100644
index 00000000..c9f4175c
--- /dev/null
+++ b/src/app/main/apps/calendar/calendar.module.ts
@@ -0,0 +1,35 @@
+import { NgModule } from '@angular/core';
+import { SharedModule } from '../../../core/modules/shared.module';
+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';
+
+const routes: Routes = [
+ {
+ path : '**', component: CalendarComponent, children: [],
+ resolve: {
+ chat: CalendarService
+ }
+ }
+];
+
+@NgModule({
+ imports : [
+ SharedModule,
+ RouterModule.forChild(routes),
+ CalendarModule.forRoot()
+ ],
+ declarations : [
+ CalendarComponent,
+ EventDialogComponent,
+ ],
+ providers : [
+ CalendarService
+ ],
+ entryComponents: [EventDialogComponent]
+})
+export class FuseCalendarModule
+{
+}
diff --git a/src/app/main/apps/calendar/calendar.service.ts b/src/app/main/apps/calendar/calendar.service.ts
new file mode 100644
index 00000000..5965a3da
--- /dev/null
+++ b/src/app/main/apps/calendar/calendar.service.ts
@@ -0,0 +1,24 @@
+import { Injectable } from '@angular/core';
+import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
+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
+{
+
+ constructor(private http: Http)
+ {
+ }
+
+
+ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any
+ {
+ return new Promise((resolve, reject) => {
+ resolve();
+ });
+ }
+
+}
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
new file mode 100644
index 00000000..7e80af2f
--- /dev/null
+++ b/src/app/main/apps/calendar/event-dialog/event-dialog.component.html
@@ -0,0 +1,20 @@
+
+ Event action occurred
+
+
+
+
+ Action:
+
{{ data.action }}
+
+
+ Event:
+
{{ data.event | json }}
+
+
+
+
+
+
diff --git a/src/app/main/apps/calendar/event-dialog/event-dialog.component.scss b/src/app/main/apps/calendar/event-dialog/event-dialog.component.scss
new file mode 100644
index 00000000..e69de29b
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
new file mode 100644
index 00000000..76b6bc35
--- /dev/null
+++ b/src/app/main/apps/calendar/event-dialog/event-dialog.component.ts
@@ -0,0 +1,22 @@
+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/chat/chat.module.ts b/src/app/main/apps/chat/chat.module.ts
index 284b9406..4cb3e4e5 100644
--- a/src/app/main/apps/chat/chat.module.ts
+++ b/src/app/main/apps/chat/chat.module.ts
@@ -13,7 +13,7 @@ import { ContactSidenavComponent } from './sidenavs/right/contact/contact.compon
const routes: Routes = [
{
- path : 'apps/chat', component: ChatComponent, children: [],
+ path : '**', component: ChatComponent, children: [],
resolve: {
chat: ChatService
}