diff --git a/bower.json b/bower.json index 71a72bd0..a69c53b0 100644 --- a/bower.json +++ b/bower.json @@ -19,6 +19,7 @@ "tests" ], "dependencies": { - "Ionicons": "ionicons#~2.0.1" + "Ionicons": "ionicons#~2.0.1", + "fullcalendar": "^2.7.1" } } diff --git a/config/webpack.common.js b/config/webpack.common.js index 21d2df4e..be6fe415 100644 --- a/config/webpack.common.js +++ b/config/webpack.common.js @@ -166,6 +166,9 @@ module.exports = { * See: http://webpack.github.io/docs/configuration.html#plugins */ plugins: [ + new webpack.ResolverPlugin( + new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin('bower.json', ['main']) + ), /* * Plugin: ForkCheckerPlugin @@ -233,6 +236,8 @@ module.exports = { "L": "leaflet", "Chart": "chart.js", "Chartist": "chartist", + "fullcalendar": "fullcalendar", + "moment": "moment", "EasyPieChart": "easy-pie-chart" }) ], diff --git a/src/app/pages/dashboard/calendar/calendar.component.ts b/src/app/pages/dashboard/calendar/calendar.component.ts new file mode 100644 index 00000000..bb380b7f --- /dev/null +++ b/src/app/pages/dashboard/calendar/calendar.component.ts @@ -0,0 +1,71 @@ +import {Component, ViewEncapsulation} from 'angular2/core'; + +import './calendar.loader.ts'; +import {layoutColors} from "../../../theme/theme.constants"; + +@Component({ + selector: 'calendar', + encapsulation: ViewEncapsulation.None, + styles: [require('fullcalendar/dist/fullcalendar.css'), require('./calendar.scss')], + template: require('./calendar.html') +}) +export class Calendar { + + + ngAfterViewInit() { + this._initCalendar(); + } + + _initCalendar() { + let palette = layoutColors.bgColorPalette; + + let $element = $('#calendar').fullCalendar({ + header: { + left: 'prev,next today', + center: 'title', + right: 'month,agendaWeek,agendaDay' + }, + defaultDate: '2016-03-08', + selectable: true, + selectHelper: true, + select: function (start, end) { + var title = prompt('Event Title:'); + var eventData; + if (title) { + eventData = { + title: title, + start: start, + end: end + }; + $element.fullCalendar('renderEvent', eventData, true); + } + $element.fullCalendar('unselect'); + }, + editable: true, + eventLimit: true, // allow "more" link when too many events + events: [ + { + title: 'All Day Event', + start: '2016-03-01', + color: palette.silverTree + }, + { + title: 'Long Event', + start: '2016-03-07', + end: '2016-03-10', + color: palette.blueStone + }, + { + title: 'Dinner', + start: '2016-03-14T20:00:00', + color: palette.surfieGreen + }, + { + title: 'Birthday Party', + start: '2016-04-01T07:00:00', + color: palette.gossipDark + } + ] + }); + } +} diff --git a/src/app/pages/dashboard/calendar/calendar.html b/src/app/pages/dashboard/calendar/calendar.html new file mode 100644 index 00000000..022b29d7 --- /dev/null +++ b/src/app/pages/dashboard/calendar/calendar.html @@ -0,0 +1 @@ +
diff --git a/src/app/pages/dashboard/calendar/calendar.loader.ts b/src/app/pages/dashboard/calendar/calendar.loader.ts new file mode 100644 index 00000000..031a62b8 --- /dev/null +++ b/src/app/pages/dashboard/calendar/calendar.loader.ts @@ -0,0 +1,2 @@ +require('fullcalendar/dist/fullcalendar.js'); + diff --git a/src/app/pages/dashboard/calendar/calendar.scss b/src/app/pages/dashboard/calendar/calendar.scss new file mode 100644 index 00000000..5860cff9 --- /dev/null +++ b/src/app/pages/dashboard/calendar/calendar.scss @@ -0,0 +1,774 @@ +@import '../../../theme/sass/conf/conf'; + +div.blurCalendar { + font-size: 12px; +} + +.fc { + direction: ltr; + text-align: left; + + button { + box-sizing: border-box; + margin: 0; + height: 2.1em; + padding: 0 .6em; + font-size: 1em; + white-space: nowrap; + cursor: pointer; + &::-moz-focus-inner { + margin: 0; + padding: 0; + } + .fc-icon { + position: relative; + top: 0; + margin: 0; + } + } + + .fc-button-group { + & > * { + float: left; + margin: 0 0 0 -1px; + } + & > :first-child { + margin-left: 0; + } + } + + hr { + height: 0; + margin: 0; + padding: 0 0 2px; + border-style: solid; + border-width: 1px 0; + } + + table { + width: 100%; + table-layout: fixed; + border-collapse: collapse; + border-spacing: 0; + font-size: 1em; + } + + th { + text-align: center; + } + + th, td { + border: 1px solid; + padding: 0; + vertical-align: top; + } + + td.fc-today { + border-style: double; + } + + .fc-row { + border: 0 solid; + } + + .fc-toolbar { + & > * { + & > * { + float: left; + margin-left: .75em; + } + & > :first-child { + margin-left: 0; + + } + } + } + + .fc-axis { + vertical-align: middle; + padding: 0 4px; + white-space: nowrap; + } +} + +.fc-rtl { + text-align: right; +} + +.fc-unthemed { + th, td, hr, thead, tbody, .fc-row, .fc-popover { + border-color: $border; + } + + .fc-popover { + background-color: #ffffff; + border: 1px solid; + + .fc-header { + background: #eee; + + .fc-close { + color: #666666; + font-size: 25px; + margin-top: 4px; + } + } + } + + hr { + background: #eee; + } + + .fc-today { + background: rgba(255, 255, 255, 0.15); + } +} + +.fc-highlight { + background: rgba(255, 255, 255, 0.25); + opacity: .3; +} + +.fc-icon { + display: inline-block; + font-size: 2em; + font-family: "Courier New", Courier, monospace; +} + +.fc-icon-left-single-arrow:after { + content: "\02039"; + font-weight: $font-bold; + font-size: 100%; +} + +.fc-icon-right-single-arrow:after { + content: "\0203A"; + font-weight: $font-bold; + font-size: 100%; +} + +.fc-icon-left-double-arrow:after { + content: "\000AB"; +} + +.fc-icon-right-double-arrow:after { + content: "\000BB"; +} + +.fc-icon-x:after { + content: "\000D7"; +} + +.fc-state-default { + border: 1px solid; + outline: none; + background: #f5f5f5 repeat-x; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1); + color: #333333; + + &.fc-corner-left { + border-top-left-radius: 0px; + border-bottom-left-radius: 0px; + } + + &.fc-corner-right { + border-top-right-radius: 0px; + border-bottom-right-radius: 0px; + } +} + +.fc-state-hover, +.fc-state-down, +.fc-state-active, +.fc-state-disabled { + color: #333333; + background-color: $disabled-bg; +} + +.fc-state-hover { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + transition: background-position 0.1s linear; +} + +.fc-state-down, +.fc-state-active { + background: #cccccc none; +} + +.fc-state-disabled { + cursor: default; + background-image: none; + opacity: 0.65; + box-shadow: none; +} + +.fc-button-group { + display: inline-block; +} + +.fc-popover { + position: absolute; + + .fc-header { + padding: 2px 4px; + } + + .fc-header .fc-title { + margin: 0 2px; + } + + .fc-header .fc-close { + cursor: pointer; + } +} + +.fc-ltr .fc-popover .fc-header .fc-title, +.fc-rtl .fc-popover .fc-header .fc-close { + float: left; +} + +.fc-rtl .fc-popover .fc-header .fc-title, +.fc-ltr .fc-popover .fc-header .fc-close { + float: right; +} + +.fc-popover > .ui-widget-header + .ui-widget-content { + border-top: 0; +} + +.fc-clear { + clear: both; +} + +.fc-bg, +.fc-highlight-skeleton, +.fc-helper-skeleton { + position: absolute; + top: 0; + left: 0; + right: 0; +} + +.fc-bg { + bottom: 0; +} + +.fc-bg table { + height: 100%; +} + +.fc-row { + position: relative; + table { + border-left: 0 hidden transparent; + border-right: 0 hidden transparent; + border-bottom: 0 hidden transparent; + } + + &:first-child table { + border-top: 0 hidden transparent; + } + + .fc-bg { + z-index: 1; + } + + .fc-highlight-skeleton { + z-index: 2; + bottom: 0; + table { + height: 100%; + } + td { + border-color: transparent; + } + } + .fc-content-skeleton { + position: relative; + z-index: 3; + padding-bottom: 2px; + } + + .fc-helper-skeleton { + z-index: 4; + } + + .fc-content-skeleton td, + .fc-helper-skeleton td { + background: none; + border-color: transparent; + border-bottom: 0; + } + + .fc-content-skeleton tbody td, + .fc-helper-skeleton tbody td { + border-top: 0; + } +} + +.fc-scroller { + //overflow-y: scroll; + //overflow-x: hidden; + & > * { + //position: relative; + //width: 100%; + //overflow: hidden; + //height: 100%; + } +} + +.fc-event { + position: relative; + display: block; + font-size: .85em; + line-height: 1.3; + border: 1px solid $primary; + background-color: $primary; + font-weight: $font-normal; +} + +.fc-event, +.fc-event:hover, +.ui-widget .fc-event { + color: #ffffff; + text-decoration: none; +} + +.fc-event[href], +.fc-event.fc-draggable { + cursor: pointer; +} + +.fc-day-grid-event { + margin: 1px 2px 0; + padding: 0 1px; +} + +.fc-ltr .fc-day-grid-event.fc-not-start, +.fc-rtl .fc-day-grid-event.fc-not-end { + margin-left: 0; + border-left-width: 0; + padding-left: 1px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.fc-ltr .fc-day-grid-event.fc-not-end, +.fc-rtl .fc-day-grid-event.fc-not-start { + margin-right: 0; + border-right-width: 0; + padding-right: 1px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.fc-day-grid-event > .fc-content { + white-space: nowrap; + overflow: hidden; +} + +.fc-day-grid-event .fc-time { + font-weight: $font-bold; +} + +.fc-day-grid-event .fc-resizer { + position: absolute; + top: 0; + bottom: 0; + width: 7px; +} + +.fc-ltr .fc-day-grid-event .fc-resizer { + right: -3px; + cursor: e-resize; +} + +.fc-rtl .fc-day-grid-event .fc-resizer { + left: -3px; + cursor: w-resize; +} + +a.fc-more { + margin: 1px 3px; + font-size: .85em; + cursor: pointer; + text-decoration: none; + &:hover { + text-decoration: underline; + } +} + +.fc-limited { + display: none; +} + +.fc-day-grid .fc-row { + z-index: 1; +} + +.fc-more-popover { + z-index: 2; + width: 220px; + + .fc-event-container { + padding: 10px; + } +} + +.fc-toolbar { + text-align: center; + margin-bottom: 1em; + .fc-left { + float: left; + } + .fc-right { + float: right; + } + .fc-center { + display: inline-block; + } + h2 { + margin: 0; + font-size: 24px; + width: 100%; + line-height: 26px; + } + button { + position: relative; + } + + .fc-state-hover, .ui-state-hover { + z-index: 2; + } + + .fc-state-down { + z-index: 3; + } + + .fc-state-active, + .ui-state-active { + z-index: 4; + } + + button:focus { + z-index: 5; + } +} + +.fc-view-container *, +.fc-view-container *:before, +.fc-view-container *:after { + box-sizing: content-box; +} + +.fc-view, +.fc-view > table { + position: relative; + z-index: 1; +} + +.fc-basicWeek-view .fc-content-skeleton, +.fc-basicDay-view .fc-content-skeleton { + padding-top: 1px; + padding-bottom: 1em; +} + +.fc-basic-view tbody .fc-row { + min-height: 4em; + max-height: 70px; +} + +.fc-row.fc-rigid { + overflow: hidden; +} + +.fc-row.fc-rigid .fc-content-skeleton { + position: absolute; + top: 0; + left: 0; + right: 0; +} + +.fc-basic-view .fc-week-number, +.fc-basic-view .fc-day-number { + padding: 0 2px; +} + +.fc-basic-view td.fc-week-number span, +.fc-basic-view td.fc-day-number { + padding-top: 2px; + padding-bottom: 2px; +} + +.fc-basic-view .fc-week-number { + text-align: center; +} + +.fc-basic-view .fc-week-number span { + display: inline-block; + min-width: 1.25em; +} + +.fc-ltr .fc-basic-view .fc-day-number { + text-align: right; +} + +.fc-rtl .fc-basic-view .fc-day-number { + text-align: left; +} + +.fc-day-number.fc-other-month { + opacity: 0.3; +} + +.fc-agenda-view .fc-day-grid { + position: relative; + z-index: 2; +} + +.fc-agenda-view .fc-day-grid .fc-row { + min-height: 3em; +} + +.fc-agenda-view .fc-day-grid .fc-row .fc-content-skeleton { + padding-top: 1px; + padding-bottom: 1em; +} + +.fc-ltr .fc-axis { + text-align: right; +} + +.fc-rtl .fc-axis { + text-align: left; +} + +.ui-widget td.fc-axis { + font-weight: $font-normal; +} + +.fc-time-grid-container, +.fc-time-grid { + position: relative; + z-index: 1; +} + +.fc-time-grid { + min-height: 100%; +} + +.fc-time-grid table { + border: 0 hidden transparent; +} + +.fc-time-grid > .fc-bg { + z-index: 1; +} + +.fc-time-grid .fc-slats, +.fc-time-grid > hr { + position: relative; + z-index: 2; +} + +.fc-time-grid .fc-highlight-skeleton { + z-index: 3; +} + +.fc-time-grid .fc-content-skeleton { + position: absolute; + z-index: 4; + top: 0; + left: 0; + right: 0; +} + +.fc-time-grid > .fc-helper-skeleton { + z-index: 5; +} + +.fc-slats { + td { + height: 1.5em; + border-bottom: 0; + } + + .fc-minor td { + border-top-style: dotted; + } + + .ui-widget-content { + background: none; + } +} + +.fc-time-grid .fc-highlight-container { + position: relative; +} + +.fc-time-grid .fc-highlight { + position: absolute; + left: 0; + right: 0; +} + +.fc-time-grid .fc-event-container { + position: relative; +} + +.fc-ltr .fc-time-grid .fc-event-container { + margin: 0 2.5% 0 2px; +} + +.fc-rtl .fc-time-grid .fc-event-container { + margin: 0 2px 0 2.5%; +} + +.fc-time-grid .fc-event { + position: absolute; + z-index: 1; +} + +.fc-time-grid-event { + overflow: hidden; + + &.fc-not-start { + border-top-width: 0; + padding-top: 1px; + border-top-left-radius: 0; + border-top-right-radius: 0; + } + + &.fc-not-end { + border-bottom-width: 0; + padding-bottom: 1px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + + & > .fc-content { + position: relative; + z-index: 2; + } + + .fc-title { + padding: 0 1px; + } + + .fc-time { + padding: 0 1px; + font-size: .85em; + white-space: nowrap; + } + + .fc-bg { + z-index: 1; + background: #fff; + opacity: .25; + filter: alpha(opacity=25); + } + + &.fc-short { + .fc-content { + white-space: nowrap; + } + + .fc-time { + display: inline-block; + vertical-align: top; + + span { + display: none; + } + + &:before { + content: attr(data-start); + } + + &:after { + content: "\000A0-\000A0"; + } + } + + .fc-title { + display: inline-block; + vertical-align: top; + font-size: .85em; + padding: 0; + } + } + + .fc-resizer { + position: absolute; + z-index: 3; + left: 0; + right: 0; + bottom: 0; + height: 8px; + overflow: hidden; + line-height: 8px; + font-size: 11px; + font-family: monospace; + text-align: center; + cursor: s-resize; + &:after { + content: "="; + } + } +} + +.fc-day-grid-container.fc-scroller { + height: auto !important; +} + +body.badmin-transparent { + + .calendar-panel.card .card-body { + padding: 0; + } + + .fc-body > tr > .fc-widget-content { + border: none; + } + + .fc-head { + color: $default; + background-color: $primary; + td, th { + border: none; + } + div.fc-widget-header { + padding: 5px 0; + } + } + + .fc td { + border-color: rgba(255, 255, 255, 0.1); + } + + .fc-today-button, .fc-month-button, .fc-agendaWeek-button, .fc-agendaDay-button { + display: none; + } + .blurCalendar { + margin-top: 15px; + } + .fc-prev-button, .fc-next-button { + position: absolute; + background: transparent; + box-shadow: none; + border: none; + color: $default; + } + .fc-next-button { + left: 30px; + } + .fc-prev-button { + } + .fc-day-number { + color: $default; + opacity: 0.9; + } +} diff --git a/src/app/pages/dashboard/calendar/index.ts b/src/app/pages/dashboard/calendar/index.ts new file mode 100644 index 00000000..f21db83c --- /dev/null +++ b/src/app/pages/dashboard/calendar/index.ts @@ -0,0 +1 @@ +export * from './calendar.component'; diff --git a/src/app/pages/dashboard/dashboard.component.ts b/src/app/pages/dashboard/dashboard.component.ts index e8814fbf..ed4f8e7a 100644 --- a/src/app/pages/dashboard/dashboard.component.ts +++ b/src/app/pages/dashboard/dashboard.component.ts @@ -7,12 +7,13 @@ import {UsersMap} from './usersMap'; import {LineChart} from './lineChart'; import {Feed} from './feed'; import {Todo} from './todo'; +import {Calendar} from './calendar'; import {BaCard} from '../../theme/components'; @Component({ selector: 'dashboard', pipes: [], - directives: [PopularApp, PieChart, TrafficChart, UsersMap, LineChart, Feed, Todo, BaCard], + directives: [PopularApp, PieChart, TrafficChart, UsersMap, LineChart, Feed, Todo, Calendar, BaCard], encapsulation: ViewEncapsulation.None, styles: [require('./dashboard.scss')], template: require('./dashboard.html') diff --git a/src/app/pages/dashboard/dashboard.html b/src/app/pages/dashboard/dashboard.html index 5f9b8d8f..6ecda209 100644 --- a/src/app/pages/dashboard/dashboard.html +++ b/src/app/pages/dashboard/dashboard.html @@ -44,5 +44,9 @@ baCardClass="xmedium-panel feed-comply-panel with-scroll todo-panel">