Compare commits

...

18 Commits

Author SHA1 Message Date
Sercan Yemen
43b85ca3b6 Reverted the ngx-dnd back to 3.1.0
+ Added missing debounceTime imports to prevent errors
2018-02-05 17:04:22 +03:00
Sercan Yemen
99696cabf7 Finished up the Analytics Dashboard
+ Updated the Angular Material version along with couple other libraries
+ Increased the version number of the Fuse
2018-02-05 15:08:18 +03:00
Sercan Yemen
f246fab1f4 Make sure the splash screen element exists before adding an event to it 2018-02-05 11:29:30 +03:00
Sercan Yemen
b0101a1f8c Fix the wrong api url 2018-02-05 11:28:24 +03:00
Sercan Yemen
8f5e947c28 Added a new dashboard (Analytics) 2018-02-01 15:30:44 +03:00
Sercan Yemen
dfd430712d Fixed some naming inconsistencies in Project dashboard
+ Added fake db for Analytics Dashboard
2018-02-01 15:30:30 +03:00
Sercan Yemen
8431c19133 Added Chart.js
+ Some improvements on Helper classes and Fuse Card
2018-02-01 15:28:40 +03:00
Sercan Yemen
6ee6934e0d Fixed a small typo in multi-language component page 2018-01-30 15:18:50 +03:00
Sercan Yemen
3253fbfaf4 Updated readme with slack workspace invitation 2018-01-29 11:24:47 +03:00
mustafahlvc
985a8dd3a9 ngrx updated to v5.0.0 2018-01-23 13:37:58 +03:00
Sercan Yemen
0c99c075f3 Updated Angular CLI and couple other packages to fix the devkit issue
+ Increase the Fuse version number
2018-01-23 12:47:31 +03:00
Sercan Yemen
c79db27092 Updated package-lock.json file 2018-01-18 13:37:57 +03:00
Sercan Yemen
a92cb8b7b6 Quick panel width is too wide for smaller screens
+ (Academy app) Course page doesn't scroll on mobile
2018-01-18 13:18:09 +03:00
Sercan Yemen
bb3d6d4839 Updated Angular, Angular Material and various other packages
+ Increased the Fuse version
+ Replaced datatable icons
+ Removed broken css imports
2018-01-18 13:13:40 +03:00
Sercan Yemen
9c06622efb Small fixes 2018-01-12 10:19:10 +03:00
Sercan Yemen
8b590408b0 Updated Angular & Angular Material
+ Increased the Fuse version
2018-01-11 12:57:38 +03:00
Sercan Yemen
18b2bdf5ab Mail-Ngrx app throws errors for certain rxjs operators
+ Various other small code fixes
2018-01-11 12:31:06 +03:00
Sercan Yemen
ba49621e79 Update perfect scrollbar on document click...
This isn't the most elegant solution but there is no other way
of knowing when the contents of the scrollable container changes.
Therefore, we update scrollbars on every document click.
2018-01-09 11:30:11 +03:00
42 changed files with 7123 additions and 1611 deletions

View File

@@ -2,6 +2,12 @@
Material Design Admin Template with Angular 5+ and Angular Material 2
## The Community
Share your ideas, discuss Fuse and help each other.
[Click here](https://join.slack.com/t/fuse-theme/shared_invite/enQtMzA1NDE4NzYwMjcyLWQxODE4ODM1MWU4MWJjMDhlMGEwYzM4Mzg3N2E4YzVlZThhZjNlOTQ1Y2Q5OTBlNDNkMzJhZDIwMjgxOWQ3YWU) to join our Slack workspace.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.

6697
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "fuse2",
"version": "1.3.2",
"version": "1.3.6",
"license": "https://themeforest.net/licenses/terms/regular",
"scripts": {
"ng": "ng",
@@ -19,66 +19,67 @@
"private": true,
"dependencies": {
"@agm/core": "1.0.0-beta.2",
"@angular/animations": "5.1.3",
"@angular/cdk": "5.0.3",
"@angular/common": "5.1.3",
"@angular/compiler": "5.1.3",
"@angular/core": "5.1.3",
"@angular/animations": "5.2.3",
"@angular/cdk": "5.1.1",
"@angular/common": "5.2.3",
"@angular/compiler": "5.2.3",
"@angular/core": "5.2.3",
"@angular/flex-layout": "2.0.0-beta.12",
"@angular/forms": "5.1.3",
"@angular/http": "5.1.3",
"@angular/material": "5.0.3",
"@angular/material-moment-adapter": "5.0.3",
"@angular/platform-browser": "5.1.3",
"@angular/platform-browser-dynamic": "5.1.3",
"@angular/router": "5.1.3",
"@ngrx/effects": "4.1.1",
"@ngrx/router-store": "4.1.1",
"@ngrx/store": "4.1.1",
"@ngrx/store-devtools": "4.1.1",
"@ngx-translate/core": "9.0.2",
"@angular/forms": "5.2.3",
"@angular/http": "5.2.3",
"@angular/material": "5.1.1",
"@angular/material-moment-adapter": "5.1.1",
"@angular/platform-browser": "5.2.3",
"@angular/platform-browser-dynamic": "5.2.3",
"@angular/router": "5.2.3",
"@ngrx/effects": "5.0.0",
"@ngrx/router-store": "5.0.0",
"@ngrx/store": "5.0.0",
"@ngrx/store-devtools": "5.0.0",
"@ngx-translate/core": "9.1.1",
"@swimlane/ngx-charts": "7.0.1",
"@swimlane/ngx-datatable": "11.1.7",
"@swimlane/ngx-dnd": "3.1.0",
"@types/prismjs": "1.9.0",
"angular-calendar": "0.23.1",
"angular-in-memory-web-api": "0.5.2",
"angular-calendar": "0.23.3",
"angular-in-memory-web-api": "0.5.3",
"chart.js": "2.7.1",
"classlist.js": "1.1.20150312",
"core-js": "2.5.3",
"d3": "4.12.2",
"d3": "4.13.0",
"hammerjs": "2.0.8",
"intl": "1.2.5",
"moment": "2.20.1",
"ngrx-store-freeze": "0.2.0",
"ngx-color-picker": "5.3.0",
"ngx-cookie-service": "1.0.9",
"ng2-charts": "1.6.0",
"ngrx-store-freeze": "0.2.1",
"ngx-color-picker": "5.3.1",
"ngx-cookie-service": "1.0.10",
"perfect-scrollbar": "1.3.0",
"prismjs": "1.9.0",
"prismjs": "1.11.0",
"rxjs": "5.5.6",
"web-animations-js": "2.3.1",
"zone.js": "0.8.19"
"zone.js": "0.8.20"
},
"devDependencies": {
"@angular/cli": "1.6.3",
"@angular/compiler-cli": "5.1.3",
"@angular/language-service": "5.1.3",
"@angular/cli": "1.6.7",
"@angular/compiler-cli": "5.2.3",
"@angular/language-service": "5.2.3",
"@angularclass/hmr": "2.1.3",
"@types/jasmine": "2.5.54",
"@types/jasmine": "2.8.6",
"@types/jasminewd2": "2.0.3",
"@types/node": "6.0.96",
"codelyzer": "4.0.2",
"jasmine-core": "2.6.4",
"jasmine-spec-reporter": "4.1.1",
"karma": "1.7.1",
"karma-chrome-launcher": "2.1.1",
"karma-cli": "1.0.1",
"karma-coverage-istanbul-reporter": "1.3.3",
"codelyzer": "4.1.0",
"jasmine-core": "2.8.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "2.0.0",
"karma-chrome-launcher": "2.2.0",
"karma-coverage-istanbul-reporter": "1.4.1",
"karma-jasmine": "1.1.1",
"karma-jasmine-html-reporter": "0.2.2",
"protractor": "5.1.2",
"ts-node": "3.2.2",
"tslint": "5.7.0",
"typescript": "2.4.2",
"webpack-bundle-analyzer": "2.9.2"
"ts-node": "4.1.0",
"tslint": "5.9.1",
"typescript": "2.6.2",
"webpack-bundle-analyzer": "2.10.0"
}
}

View File

@@ -42,7 +42,7 @@ const appRoutes: Routes = [
},
{
path : '**',
redirectTo: 'apps/dashboards/project'
redirectTo: 'apps/dashboards/analytics'
}
];

View File

@@ -1,8 +1,8 @@
import { AfterViewInit, Directive, ElementRef, OnDestroy, OnInit } from '@angular/core';
import PerfectScrollbar from 'perfect-scrollbar';
import { AfterViewInit, Directive, ElementRef, HostListener, OnDestroy } from '@angular/core';
import { FuseConfigService } from '../../services/config.service';
import { Subscription } from 'rxjs/Subscription';
import { Platform } from '@angular/cdk/platform';
import PerfectScrollbar from 'perfect-scrollbar';
@Directive({
selector: '[fusePerfectScrollbar]'
@@ -13,7 +13,7 @@ export class FusePerfectScrollbarDirective implements AfterViewInit, OnDestroy
isDisableCustomScrollbars = false;
isMobile = false;
isInitialized = true;
ps;
ps: PerfectScrollbar;
constructor(
public element: ElementRef,
@@ -62,6 +62,21 @@ export class FusePerfectScrollbarDirective implements AfterViewInit, OnDestroy
this.ps.destroy();
}
@HostListener('document:click', ['$event'])
documentClick(event: Event): void
{
if ( !this.isInitialized || !this.ps )
{
return;
}
// Update the scrollbar on document click..
// This isn't the most elegant solution but there is no other way
// of knowing when the contents of the scrollable container changes.
// Therefore, we update scrollbars on every document click.
this.ps.update();
}
update()
{
if ( !this.isInitialized )

View File

@@ -22,6 +22,7 @@ import { FuseMaterialColorPickerComponent } from '../components/material-color-p
import { FuseTranslationLoaderService } from '../services/translation-loader.service';
import { CookieService } from 'ngx-cookie-service';
import { TranslateModule } from '@ngx-translate/core';
import { ChartsModule } from 'ng2-charts';
@NgModule({
declarations : [
@@ -43,7 +44,8 @@ import { TranslateModule } from '@ngx-translate/core';
ReactiveFormsModule,
ColorPickerModule,
NgxDnDModule,
NgxDatatableModule
NgxDatatableModule,
ChartsModule
],
exports : [
FlexLayoutModule,
@@ -62,7 +64,8 @@ import { TranslateModule } from '@ngx-translate/core';
NgxDatatableModule,
FuseIfOnDomDirective,
FuseMaterialColorPickerComponent,
TranslateModule
TranslateModule,
ChartsModule
],
entryComponents: [
FuseConfirmDialogComponent

View File

@@ -1,9 +1,9 @@
// ngx-datatable
@import '~@swimlane/ngx-datatable/release/index.css';
@import '~@swimlane/ngx-datatable/release/themes/material.css';
@import '~@swimlane/ngx-datatable/release/assets/icons.css';
@import '~@swimlane/ngx-datatable/release/themes/material';
// Perfect scrollbar
@import '~perfect-scrollbar/css/perfect-scrollbar.css';
@import '~perfect-scrollbar/css/perfect-scrollbar';
// Fuse
@import "fuse";

View File

@@ -9,6 +9,11 @@
min-width: 0;
}
&.auto-width {
min-width: 0;
max-width: none;
}
// Buttons
.mat-button {
min-width: 0 !important;

View File

@@ -215,4 +215,31 @@ $border-style: 1px solid rgba(0, 0, 0, 0.12);
// ######################
.border-radius-100 {
border-radius: 100%;
}
.border-radius-2 {
border-radius: 2px;
}
.border-radius-4 {
border-radius: 4px;
}
.border-radius-8 {
border-radius: 8px;
}
.border-radius-16 {
border-radius: 16px;
}
// ######################
// CURSOR HELPERS
// ######################
.cursor-pointer {
cursor: pointer;
}
.cursor-default {
cursor: default;
}

View File

@@ -98,3 +98,68 @@
}
}
}
[class*="datatable-icon-"] {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased;
}
.datatable-icon-filter:before {
content: "filter_list";
}
.datatable-icon-collapse:before {
content: "unfold_less";
}
.datatable-icon-expand:before {
content: "unfold_more";
}
.datatable-icon-close:before {
content: "close";
}
.datatable-icon-up:before {
content: "keyboard_arrow_up";
}
.datatable-icon-down:before {
content: "keyboard_arrow_down";
}
.datatable-icon-sort:before {
content: "sort";
}
.datatable-icon-done:before {
content: "done";
}
.datatable-icon-done-all:before {
content: "done_all";
}
.datatable-icon-search:before {
content: "search";
}
.datatable-icon-pin:before {
content: "lock";
}
.datatable-icon-add:before {
content: "add";
}
.datatable-icon-left:before {
content: "chevron_left";
}
.datatable-icon-right:before {
content: "chevron_right";
}
.datatable-icon-skip:before {
content: "skip_next";
}
.datatable-icon-prev:before {
content: "skip_previous";
}

View File

@@ -15,18 +15,27 @@ export class FuseSplashScreenService
private router: Router
)
{
// Get the splash screen element
this.splashScreenEl = this.document.body.querySelector('#fuse-splash-screen');
const hideOnLoad = this.router.events.subscribe((event) => {
if ( event instanceof NavigationEnd )
{
setTimeout(() => {
this.hide();
hideOnLoad.unsubscribe();
}, 0);
// If the splash screen element exists...
if ( this.splashScreenEl )
{
// Hide it on the first NavigationEnd event
const hideOnLoad = this.router.events.subscribe((event) => {
if ( event instanceof NavigationEnd )
{
setTimeout(() => {
this.hide();
// Unsubscribe from this event so it
// won't get triggered again
hideOnLoad.unsubscribe();
}, 0);
}
}
}
);
);
}
}
show()

View File

@@ -0,0 +1,602 @@
export class AnalyticsDashboardDb
{
public static widgets = {
widget1: {
chartType: 'line',
datasets : {
'2015': [
{
label: 'Sales',
data : [1.9, 3, 3.4, 2.2, 2.9, 3.9, 2.5, 3.8, 4.1, 3.8, 3.2, 2.9],
fill : 'start'
}
],
'2016': [
{
label: 'Sales',
data : [2.2, 2.9, 3.9, 2.5, 3.8, 3.2, 2.9, 1.9, 3, 3.4, 4.1, 3.8],
fill : 'start'
}
],
'2017': [
{
label: 'Sales',
data : [3.9, 2.5, 3.8, 4.1, 1.9, 3, 3.8, 3.2, 2.9, 3.4, 2.2, 2.9],
fill : 'start'
}
]
},
labels : ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'],
colors : [
{
borderColor : '#42a5f5',
backgroundColor : '#42a5f5',
pointBackgroundColor : '#1e88e5',
pointHoverBackgroundColor: '#1e88e5',
pointBorderColor : '#ffffff',
pointHoverBorderColor : '#ffffff'
}
],
options : {
spanGaps : false,
legend : {
display: false
},
maintainAspectRatio: false,
layout : {
padding: {
top : 32,
left : 32,
right: 32
}
},
elements : {
point: {
radius : 4,
borderWidth : 2,
hoverRadius : 4,
hoverBorderWidth: 2
},
line : {
tension: 0
}
},
scales : {
xAxes: [
{
gridLines: {
display : false,
drawBorder : false,
tickMarkLength: 18
},
ticks : {
fontColor: '#ffffff'
}
}
],
yAxes: [
{
display: false,
ticks : {
min : 1.5,
max : 5,
stepSize: 0.5
}
}
]
},
plugins : {
filler : {
propagate: false
},
xLabelsOnTop: {
active: true
}
}
}
},
widget2: {
conversion: {
value : 492,
ofTarget: 13
},
chartType : 'bar',
datasets : [
{
label: 'Conversion',
data : [221, 428, 492, 471, 413, 344, 294]
}
],
labels : ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
colors : [
{
borderColor : '#42a5f5',
backgroundColor: '#42a5f5'
}
],
options : {
spanGaps : false,
legend : {
display: false
},
maintainAspectRatio: false,
layout : {
padding: {
top : 24,
left : 16,
right : 16,
bottom: 16
}
},
scales : {
xAxes: [
{
display: false
}
],
yAxes: [
{
display: false,
ticks : {
min: 100,
max: 500
}
}
]
}
}
},
widget3: {
impressions: {
value : '87k',
ofTarget: 12
},
chartType : 'line',
datasets : [
{
label: 'Impression',
data : [67000, 54000, 82000, 57000, 72000, 57000, 87000, 72000, 89000, 98700, 112000, 136000, 110000, 149000, 98000],
fill : false
}
],
labels : ['Jan 1', 'Jan 2', 'Jan 3', 'Jan 4', 'Jan 5', 'Jan 6', 'Jan 7', 'Jan 8', 'Jan 9', 'Jan 10', 'Jan 11', 'Jan 12', 'Jan 13', 'Jan 14', 'Jan 15'],
colors : [
{
borderColor: '#5c84f1'
}
],
options : {
spanGaps : false,
legend : {
display: false
},
maintainAspectRatio: false,
elements : {
point: {
radius : 2,
borderWidth : 1,
hoverRadius : 2,
hoverBorderWidth: 1
},
line : {
tension: 0
}
},
layout : {
padding: {
top : 24,
left : 16,
right : 16,
bottom: 16
}
},
scales : {
xAxes: [
{
display: false
}
],
yAxes: [
{
display: false,
ticks : {
// min: 100,
// max: 500
}
}
]
}
}
},
widget4: {
visits : {
value : 882,
ofTarget: -9
},
chartType: 'bar',
datasets : [
{
label: 'Visits',
data : [432, 428, 327, 363, 456, 267, 231]
}
],
labels : ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
colors : [
{
borderColor : '#f44336',
backgroundColor: '#f44336'
}
],
options : {
spanGaps : false,
legend : {
display: false
},
maintainAspectRatio: false,
layout : {
padding: {
top : 24,
left : 16,
right : 16,
bottom: 16
}
},
scales : {
xAxes: [
{
display: false
}
],
yAxes: [
{
display: false,
ticks : {
min: 150,
max: 500
}
}
]
}
}
},
widget5: {
chartType: 'line',
datasets : {
'yesterday': [
{
label: 'Visitors',
data : [190, 300, 340, 220, 290, 390, 250, 380, 410, 380, 320, 290],
fill : 'start'
},
{
label: 'Page views',
data : [2200, 2900, 3900, 2500, 3800, 3200, 2900, 1900, 3000, 3400, 4100, 3800],
fill : 'start'
}
],
'today' : [
{
label: 'Visitors',
data : [410, 380, 320, 290, 190, 390, 250, 380, 300, 340, 220, 290],
fill : 'start'
},
{
label: 'Page Views',
data : [3000, 3400, 4100, 3800, 2200, 3200, 2900, 1900, 2900, 3900, 2500, 3800],
fill : 'start'
}
]
},
labels : ['12am', '2am', '4am', '6am', '8am', '10am', '12pm', '2pm', '4pm', '6pm', '8pm', '10pm'],
colors : [
{
borderColor : '#3949ab',
backgroundColor : '#3949ab',
pointBackgroundColor : '#3949ab',
pointHoverBackgroundColor: '#3949ab',
pointBorderColor : '#ffffff',
pointHoverBorderColor : '#ffffff'
},
{
borderColor : 'rgba(30, 136, 229, 0.87)',
backgroundColor : 'rgba(30, 136, 229, 0.87)',
pointBackgroundColor : 'rgba(30, 136, 229, 0.87)',
pointHoverBackgroundColor: 'rgba(30, 136, 229, 0.87)',
pointBorderColor : '#ffffff',
pointHoverBorderColor : '#ffffff'
}
],
options : {
spanGaps : false,
legend : {
display: false
},
maintainAspectRatio: false,
tooltips : {
position : 'nearest',
mode : 'index',
intersect: false
},
layout : {
padding: {
left : 24,
right: 32
}
},
elements : {
point: {
radius : 4,
borderWidth : 2,
hoverRadius : 4,
hoverBorderWidth: 2
}
},
scales : {
xAxes: [
{
gridLines: {
display: false
},
ticks : {
fontColor: 'rgba(0,0,0,0.54)'
}
}
],
yAxes: [
{
gridLines: {
tickMarkLength: 16
},
ticks : {
stepSize: 1000
}
}
]
},
plugins : {
filler: {
propagate: false
}
}
}
},
widget6: {
markers: [
{
lat : 52,
lng : -73,
label: '120'
},
{
lat : 37,
lng : -104,
label: '498'
},
{
lat : 21,
lng : -7,
label: '443'
},
{
lat : 55,
lng : 75,
label: '332'
},
{
lat : 51,
lng : 7,
label: '50'
},
{
lat : 31,
lng : 12,
label: '221'
},
{
lat : 45,
lng : 44,
label: '455'
},
{
lat : -26,
lng : 134,
label: '231'
},
{
lat : -9,
lng : -60,
label: '67'
},
{
lat : 33,
lng : 104,
label: '665'
}
],
styles : [
{
'featureType': 'administrative',
'elementType': 'labels.text.fill',
'stylers' : [
{
'color': '#444444'
}
]
},
{
'featureType': 'landscape',
'elementType': 'all',
'stylers' : [
{
'color': '#f2f2f2'
}
]
},
{
'featureType': 'poi',
'elementType': 'all',
'stylers' : [
{
'visibility': 'off'
}
]
},
{
'featureType': 'road',
'elementType': 'all',
'stylers' : [
{
'saturation': -100
},
{
'lightness': 45
}
]
},
{
'featureType': 'road.highway',
'elementType': 'all',
'stylers' : [
{
'visibility': 'simplified'
}
]
},
{
'featureType': 'road.arterial',
'elementType': 'labels.icon',
'stylers' : [
{
'visibility': 'off'
}
]
},
{
'featureType': 'transit',
'elementType': 'all',
'stylers' : [
{
'visibility': 'off'
}
]
},
{
'featureType': 'water',
'elementType': 'all',
'stylers' : [
{
'color': '#039be5'
},
{
'visibility': 'on'
}
]
}
]
},
widget7: {
scheme : {
domain: ['#4867d2', '#5c84f1', '#89a9f4']
},
devices: [
{
name : 'Desktop',
value : 92.8,
change: -0.6
},
{
name : 'Mobile',
value : 6.1,
change: 0.7
},
{
name : 'Tablet',
value : 1.1,
change: 0.1
}
]
},
widget8: {
scheme : {
domain: ['#5c84f1']
},
today : '12,540',
change : {
value : 321,
percentage: 2.05
},
data : [
{
name : 'Sales',
series: [
{
name : 'Jan 1',
value: 540
},
{
name : 'Jan 2',
value: 539
},
{
name : 'Jan 3',
value: 538
},
{
name : 'Jan 4',
value: 539
},
{
name : 'Jan 5',
value: 540
},
{
name : 'Jan 6',
value: 539
},
{
name : 'Jan 7',
value: 540
}
]
}
],
dataMin: 538,
dataMax: 541
},
widget9: {
rows: [
{
title : 'Holiday Travel',
clicks : 3621,
conversion: 90
},
{
title : 'Get Away Deals',
clicks : 703,
conversion: 7
},
{
title : 'Airfare',
clicks : 532,
conversion: 0
},
{
title : 'Vacation',
clicks : 201,
conversion: 8
},
{
title : 'Hotels',
clicks : 94,
conversion: 4
}
]
}
};
}

View File

@@ -1,4 +1,4 @@
export class ProjectsDashboardDb
export class ProjectDashboardDb
{
public static projects = [
{

View File

@@ -1,62 +1,97 @@
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { MailFakeDb } from './mail';
import { ChatFakeDb } from './chat';
import { ProjectDashboardDb } from './dashboard-project';
import { AnalyticsDashboardDb } from './dashboard-analytics';
import { CalendarFakeDb } from './calendar';
import { TodoFakeDb } from './todo';
import { ProfileFakeDb } from './profile';
import { ContactsFakeDb } from './contacts';
import { InvoiceFakeDb } from './invoice';
import { FileManagerFakeDb } from './file-manager';
import { SearchFakeDb } from './search';
import { QuickPanelFakeDb } from './quick-panel';
import { IconsFakeDb } from './icons';
import { ProjectsDashboardDb } from './projects-dashboard';
import { ScrumboardFakeDb } from './scrumboard';
import { FaqFakeDb } from './faq';
import { KnowledgeBaseFakeDb } from './knowledge-base';
import { ECommerceFakeDb } from './e-commerce';
import { AcademyFakeDb } from './academy';
import { MailFakeDb } from './mail';
import { ChatFakeDb } from './chat';
import { FileManagerFakeDb } from './file-manager';
import { ContactsFakeDb } from './contacts';
import { TodoFakeDb } from './todo';
import { ScrumboardFakeDb } from './scrumboard';
import { InvoiceFakeDb } from './invoice';
import { ProfileFakeDb } from './profile';
import { SearchFakeDb } from './search';
import { FaqFakeDb } from './faq';
import { KnowledgeBaseFakeDb } from './knowledge-base';
import { IconsFakeDb } from './icons';
import { QuickPanelFakeDb } from './quick-panel';
export class FuseFakeDbService implements InMemoryDbService
{
createDb()
{
return {
'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,
'todo-todos' : TodoFakeDb.todos,
'todo-filters' : TodoFakeDb.filters,
'todo-tags' : TodoFakeDb.tags,
'profile-timeline' : ProfileFakeDb.timeline,
'profile-photos-videos' : ProfileFakeDb.photosVideos,
'profile-about' : ProfileFakeDb.about,
'contacts-contacts' : ContactsFakeDb.contacts,
'contacts-user' : ContactsFakeDb.user,
'invoice' : InvoiceFakeDb.invoice,
'file-manager' : FileManagerFakeDb.files,
'search-classic' : SearchFakeDb.classic,
'search-table' : SearchFakeDb.table,
'quick-panel-notes' : QuickPanelFakeDb.notes,
'quick-panel-events' : QuickPanelFakeDb.events,
'icons' : IconsFakeDb.icons,
'projects-dashboard-projects': ProjectsDashboardDb.projects,
'projects-dashboard-widgets' : ProjectsDashboardDb.widgets,
'scrumboard-boards' : ScrumboardFakeDb.boards,
'faq' : FaqFakeDb.data,
'knowledge-base' : KnowledgeBaseFakeDb.data,
'e-commerce-dashboard' : ECommerceFakeDb.dashboard,
'e-commerce-products' : ECommerceFakeDb.products,
'e-commerce-orders' : ECommerceFakeDb.orders,
'academy-categories' : AcademyFakeDb.categories,
'academy-courses' : AcademyFakeDb.courses,
'academy-course' : AcademyFakeDb.course
// Dashboards
'project-dashboard-projects' : ProjectDashboardDb.projects,
'project-dashboard-widgets' : ProjectDashboardDb.widgets,
'analytics-dashboard-widgets': AnalyticsDashboardDb.widgets,
// Calendar
'calendar': CalendarFakeDb.data,
// E-Commerce
'e-commerce-dashboard': ECommerceFakeDb.dashboard,
'e-commerce-products' : ECommerceFakeDb.products,
'e-commerce-orders' : ECommerceFakeDb.orders,
// Academy
'academy-categories': AcademyFakeDb.categories,
'academy-courses' : AcademyFakeDb.courses,
'academy-course' : AcademyFakeDb.course,
// Mail
'mail-mails' : MailFakeDb.mails,
'mail-folders': MailFakeDb.folders,
'mail-filters': MailFakeDb.filters,
'mail-labels' : MailFakeDb.labels,
// Chat
'chat-contacts': ChatFakeDb.contacts,
'chat-chats' : ChatFakeDb.chats,
'chat-user' : ChatFakeDb.user,
// File Manager
'file-manager': FileManagerFakeDb.files,
// Contacts
'contacts-contacts': ContactsFakeDb.contacts,
'contacts-user' : ContactsFakeDb.user,
// Todo
'todo-todos' : TodoFakeDb.todos,
'todo-filters': TodoFakeDb.filters,
'todo-tags' : TodoFakeDb.tags,
// Scrumboard
'scrumboard-boards': ScrumboardFakeDb.boards,
// Invoice
'invoice': InvoiceFakeDb.invoice,
// Profile
'profile-timeline' : ProfileFakeDb.timeline,
'profile-photos-videos': ProfileFakeDb.photosVideos,
'profile-about' : ProfileFakeDb.about,
// Search
'search-classic': SearchFakeDb.classic,
'search-table' : SearchFakeDb.table,
// FAQ
'faq': FaqFakeDb.data,
// Knowledge base
'knowledge-base': KnowledgeBaseFakeDb.data,
// Icons
'icons': IconsFakeDb.icons,
// Quick Panel
'quick-panel-notes' : QuickPanelFakeDb.notes,
'quick-panel-events': QuickPanelFakeDb.events
};
}
}

View File

@@ -161,6 +161,7 @@
bottom: 0;
left: 0;
padding: 48px;
overflow: auto;
@media (max-width: 720px) {
padding: 0 0 120px 0;

View File

@@ -8,6 +8,10 @@ const routes = [
path : 'dashboards/project',
loadChildren: './dashboards/project/project.module#FuseProjectDashboardModule'
},
{
path : 'dashboards/analytics',
loadChildren: './dashboards/analytics/analytics.module#FuseAnalyticsDashboardModule'
},
{
path : 'mail',
loadChildren: './mail/mail.module#FuseMailModule'

View File

@@ -25,21 +25,13 @@ import { fuseAnimations } from '../../../../core/animations';
export class FuseCalendarComponent implements OnInit
{
view: string;
viewDate: Date;
events: CalendarEvent[];
public actions: CalendarEventAction[];
activeDayIsOpen: boolean;
refresh: Subject<any> = new Subject();
dialogRef: any;
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
selectedDay: any;
constructor(

View File

@@ -1,6 +1,7 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ChatService } from '../../../chat.service';
import { FormControl, FormGroup } from '@angular/forms';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
@Component({

View File

@@ -4,6 +4,7 @@ import { fuseAnimations } from '../../../../core/animations';
import { FormControl, FormGroup } from '@angular/forms';
import { FuseContactsContactFormDialogComponent } from './contact-form/contact-form.component';
import { MatDialog } from '@angular/material';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import { Subscription } from 'rxjs/Subscription';

View File

@@ -0,0 +1,510 @@
<div id="dashboard-analytics" class="page-layout blank grey-100-bg" fusePerfectScrollbar>
<div class="main-widget">
<div class="position-relative p-24 mat-blue-600-bg"
fxLayout="row" fxLayoutAlign="space-between center">
<div fxLayout="column" fxLayoutAlign="start start">
<span class="h2">Visitors</span>
<span class="h5 secondary-text">Unique visitors by month</span>
</div>
<div fxLayout="row" fxLayoutAlign="start center">
<div class="py-8 px-12 border-radius-2 line-height-1 mr-8 cursor-pointer"
(click)="widget1SelectedYear = '2015'"
[ngClass]="{'blue-300-bg': widget1SelectedYear === '2015'}">
2015
</div>
<div class="py-8 px-12 border-radius-2 line-height-1 mr-8 cursor-pointer"
(click)="widget1SelectedYear = '2016'"
[ngClass]="{'blue-300-bg': widget1SelectedYear === '2016'}">
2016
</div>
<div class="py-8 px-12 border-radius-2 line-height-1 cursor-pointer"
(click)="widget1SelectedYear = '2017'"
[ngClass]="{'blue-300-bg': widget1SelectedYear === '2017'}">
2017
</div>
</div>
</div>
<div class="position-relative h-256 pb-16 mat-blue-600-bg">
<canvas baseChart
[datasets]="widgets.widget1.datasets[widget1SelectedYear]"
[labels]="widgets.widget1.labels"
[colors]="widgets.widget1.colors"
[options]="widgets.widget1.options"
[chartType]="widgets.widget1.chartType">
</canvas>
</div>
</div>
<div class="content">
<div class="left mr-32">
<div class="pb-24 font-size-18 font-weight-300">
How are your active users trending over time?
</div>
<div fxLayout="column" fxLayoutAlign="start"
fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start start">
<!-- Widget 2 -->
<div class="widget" fxFlex="100" fxFlex.gt-sm="33">
<div class="fuse-card auto-width mb-32" [ngClass.gt-sm]="'mb-0 mr-32'">
<div class="p-16 pb-0" fxLayout="row" fxLayoutAlign="start end" fxLayoutWrap>
<div class="pr-16">
<div class="h3 secondary-text">Conversion</div>
<div class="font-size-54 font-weight-300 line-height-1 mt-8">
{{widgets.widget2.conversion.value}}
</div>
</div>
<div class="py-4 font-size-16" fxLayout="row" fxLayoutAlign="start center">
<div fxFlex="row" fxLayoutAlign="start center" class="green-fg"
*ngIf="widgets.widget2.conversion.ofTarget > 0">
<mat-icon class="green-fg mr-4">trending_up</mat-icon>
<span>{{widgets.widget2.conversion.ofTarget}}%</span>
</div>
<div fxFlex="row" fxLayoutAlign="start center" class="red-fg"
*ngIf="widgets.widget2.conversion.ofTarget < 0">
<mat-icon class="red-fg mr-4">trending_down</mat-icon>
<span>{{widgets.widget2.conversion.ofTarget}}%</span>
</div>
<div class="ml-4 text-nowrap">of target</div>
</div>
</div>
<div class="h-96 w-100-p">
<canvas baseChart
[datasets]="widgets.widget2.datasets"
[labels]="widgets.widget2.labels"
[colors]="widgets.widget2.colors"
[options]="widgets.widget2.options"
[chartType]="widgets.widget2.chartType">
</canvas>
</div>
</div>
</div>
<!-- / Widget 2 -->
<!-- Widget 3 -->
<div class="widget" fxFlex="100" fxFlex.gt-sm="34">
<div class="fuse-card auto-width mb-32" [ngClass.gt-sm]="'mb-0 mr-32'">
<div class="p-16 pb-0" fxLayout="row" fxLayoutAlign="start end" fxLayoutWrap>
<div class="pr-16">
<div class="h3 secondary-text">Impressions</div>
<div class="font-size-54 font-weight-300 line-height-1 mt-8">
{{widgets.widget3.impressions.value}}
</div>
</div>
<div class="py-4 font-size-16" fxLayout="row" fxLayoutAlign="start center">
<div fxFlex="row" fxLayoutAlign="start center" class="green-fg"
*ngIf="widgets.widget3.impressions.ofTarget > 0">
<mat-icon class="green-fg mr-4">trending_up</mat-icon>
<span>{{widgets.widget3.impressions.ofTarget}}%</span>
</div>
<div fxFlex="row" fxLayoutAlign="start center" class="red-fg"
*ngIf="widgets.widget3.impressions.ofTarget < 0">
<mat-icon class="red-fg mr-4">trending_down</mat-icon>
<span>{{widgets.widget3.impressions.ofTarget}}%</span>
</div>
<div class="ml-4 text-nowrap">of target</div>
</div>
</div>
<div class="h-96 w-100-p">
<canvas baseChart
[datasets]="widgets.widget3.datasets"
[labels]="widgets.widget3.labels"
[colors]="widgets.widget3.colors"
[options]="widgets.widget3.options"
[chartType]="widgets.widget3.chartType">
</canvas>
</div>
</div>
</div>
<!-- / Widget 3 -->
<!-- Widget 4 -->
<div class="widget" fxFlex="100" fxFlex.gt-sm="33">
<div class="fuse-card auto-width">
<div class="p-16 pb-0" fxLayout="row" fxLayoutAlign="start end" fxLayoutWrap>
<div class="pr-16">
<div class="h3 secondary-text">Visits</div>
<div class="font-size-54 font-weight-300 line-height-1 mt-8">
{{widgets.widget4.visits.value}}
</div>
</div>
<div class="py-4 font-size-16" fxLayout="row" fxLayoutAlign="start center">
<div fxFlex="row" fxLayoutAlign="start center" class="green-fg"
*ngIf="widgets.widget4.visits.ofTarget > 0">
<mat-icon class="green-fg mr-4">trending_up</mat-icon>
<span>{{widgets.widget4.visits.ofTarget}}%</span>
</div>
<div fxFlex="row" fxLayoutAlign="start center" class="red-fg"
*ngIf="widgets.widget4.visits.ofTarget < 0">
<mat-icon class="red-fg mr-4">trending_down</mat-icon>
<span>{{widgets.widget4.visits.ofTarget}}%</span>
</div>
<div class="ml-4 text-nowrap">of target</div>
</div>
</div>
<div class="h-96 w-100-p">
<canvas baseChart
[datasets]="widgets.widget4.datasets"
[labels]="widgets.widget4.labels"
[colors]="widgets.widget4.colors"
[options]="widgets.widget4.options"
[chartType]="widgets.widget4.chartType">
</canvas>
</div>
</div>
</div>
<!-- / Widget 4 -->
</div>
<!-- Widget 5 -->
<div class="pt-48 pb-24 font-size-18 font-weight-300">
How many pages your users visit?
</div>
<div class="fuse-card auto-width">
<div class="position-relative p-24"
fxLayout="row" fxLayoutAlign="space-between center">
<div fxLayout="column" fxLayoutAlign="start start">
<span class="h2">Visitors & Page views</span>
</div>
<div fxLayout="row" fxLayoutAlign="start center">
<div class="py-8 px-12 border-radius-2 line-height-1 mr-8 cursor-pointer"
(click)="widget5SelectedDay = 'yesterday'"
[ngClass]="{'grey-300-bg': widget5SelectedDay === 'yesterday'}">
Yesterday
</div>
<div class="py-8 px-12 border-radius-2 line-height-1 mr-8 cursor-pointer"
(click)="widget5SelectedDay = 'today'"
[ngClass]="{'grey-300-bg': widget5SelectedDay === 'today'}">
Today
</div>
</div>
</div>
<div class="position-relative h-368 pb-16">
<canvas baseChart
[datasets]="widgets.widget5.datasets[widget5SelectedDay]"
[labels]="widgets.widget5.labels"
[colors]="widgets.widget5.colors"
[options]="widgets.widget5.options"
[chartType]="widgets.widget5.chartType">
</canvas>
</div>
</div>
<!-- / Widget 5 -->
<!-- Widget 6 -->
<div class="pt-48 pb-24 font-size-18 font-weight-300">
Where are your users?
</div>
<div class="fuse-card auto-width p-16">
<agm-map class="h-640 w-100-p"
[minZoom]="2"
[maxZoom]="2"
[fullscreenControl]="false"
[rotateControl]="false"
[zoomControl]="false"
[scaleControl]="false"
[streetViewControl]="false"
[scrollwheel]="false"
[styles]="widgets.widget6.styles">
<agm-marker
*ngFor="let marker of widgets.widget6.markers"
[latitude]="marker.lat"
[longitude]="marker.lng">
<agm-info-window>
<strong>{{marker.label}}</strong>
</agm-info-window>
</agm-marker>
</agm-map>
</div>
<!-- / Widget 6 -->
</div>
<div class="right">
<div fxLayout="row" fxLayoutWrap
fxLayout.gt-md="column">
<!-- Widget 7 -->
<div class="mb-48" [ngClass.lt-lg]="'mr-32'">
<div class="pb-24 font-size-18 font-weight-300">
What are your top devices?
</div>
<div class="fuse-card">
<div class="p-16">
<div class="h1 font-weight-300">Sessions by device</div>
</div>
<div class="h-200">
<ngx-charts-pie-chart
*fuseIfOnDom
[scheme]="widgets.widget7.scheme"
[results]="widgets.widget7.devices"
[doughnut]="true">
</ngx-charts-pie-chart>
</div>
<div class="p-16" fxLayout="row" fxLayoutAlign="center center">
<div class="px-16" fxLayout="column" fxLayoutAlign="start center"
*ngFor="let device of widgets.widget7.devices">
<div class="h4 secondary-text">{{device.name}}</div>
<div class="h2 font-weight-300 py-8">{{device.value}}%</div>
<div fxLayout="row" fxLayoutAlign="center center">
<mat-icon class="s-18 pr-4 red-fg"
*ngIf="device.change < 0">
arrow_downward
</mat-icon>
<mat-icon class="s-18 pr-4 green-fg"
*ngIf="device.change > 0">
arrow_upward
</mat-icon>
<div class="h5 red-fg"
[ngClass]="{'red-fg': device.change < 0, 'green-fg': device.change > 0}">
{{device.change}}%
</div>
</div>
</div>
</div>
<div class="card-divider mb-0"></div>
<div class="px-16" fxLayout="row" fxLayoutAlign="space-between center">
<mat-form-field>
<mat-select class="simplified" value="7days">
<mat-option value="today">Today</mat-option>
<mat-option value="yesterday">Yesterday</mat-option>
<mat-option value="7days">Last 7 days</mat-option>
<mat-option value="28days">Last 28 days</mat-option>
<mat-option value="90days">Last 90 days</mat-option>
</mat-select>
</mat-form-field>
<button mat-button color="accent">OVERVIEW</button>
</div>
</div>
</div>
<!-- / Widget 7 -->
<!-- Widget 8 -->
<div class="mb-48" [ngClass.lt-lg]="'mr-32'">
<div class="pb-24 font-size-18 font-weight-300">
How are your sales?
</div>
<div class="fuse-card">
<div class="mat-light-blue-600-bg">
<div class="p-16" fxLayout="row" fxLayoutAlign="space-between center">
<div class="pr-16">
<div class="h1 font-weight-300">Sales</div>
<div class="h5 secondary-text">Lifetime sum of your sales</div>
</div>
<div>
<button mat-icon-button [matMenuTriggerFor]="card19Menu" aria-label="more">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #card19Menu="matMenu">
<button mat-menu-item>
<mat-icon>trending_up</mat-icon>
<span>Trend</span>
</button>
<button mat-menu-item>
<mat-icon>history</mat-icon>
<span>History</span>
</button>
<button mat-menu-item>
<mat-icon>notifications_off</mat-icon>
<span>Disable alerts</span>
</button>
</mat-menu>
</div>
</div>
<div class="p-16 pt-8" fxLayout="row" fxLayoutAlign="space-between end">
<div class="font-size-48 font-weight-300 line-height-1">{{widgets.widget8.today}}</div>
<div fxLayout="row" fxLayoutAlign="start center">
<mat-icon *ngIf="widgets.widget8.change.value > 0">trending_up</mat-icon>
<mat-icon *ngIf="widgets.widget8.change.value < 0">trending_down</mat-icon>
<div class="ml-8">{{widgets.widget8.change.value}}
({{widgets.widget8.change.percentage}}%)
</div>
</div>
</div>
</div>
<mat-tab-group backgroundColor="accent">
<mat-tab label="1DAY">
<div class="h-200 my-16">
<ngx-charts-line-chart
*fuseIfOnDom
[scheme]="widgets.widget8.scheme"
[results]="widgets.widget8.data"
[xAxis]="false"
[yAxis]="true"
[yScaleMin]="widgets.widget8.dataMin"
[yScaleMax]="widgets.widget8.dataMax">
</ngx-charts-line-chart>
</div>
</mat-tab>
<mat-tab label="1WEEK">
<div class="h-200 my-16">
<ngx-charts-line-chart
*fuseIfOnDom
[scheme]="widgets.widget8.scheme"
[results]="widgets.widget8.data"
[xAxis]="false"
[yAxis]="true"
[yScaleMin]="widgets.widget8.dataMin"
[yScaleMax]="widgets.widget8.dataMax">
</ngx-charts-line-chart>
</div>
</mat-tab>
<mat-tab label="1MONTH">
<div class="h-200 my-16">
<ngx-charts-line-chart
*fuseIfOnDom
[scheme]="widgets.widget8.scheme"
[results]="widgets.widget8.data"
[xAxis]="false"
[yAxis]="true"
[yScaleMin]="widgets.widget8.dataMin"
[yScaleMax]="widgets.widget8.dataMax">
</ngx-charts-line-chart>
</div>
</mat-tab>
</mat-tab-group>
</div>
</div>
<!-- / Widget 8 -->
<!-- Widget 9 -->
<div class="mb-48" [ngClass.lt-lg]="'mr-32'">
<div class="pb-24 font-size-18 font-weight-300" [ngClass.lt-lg]="'pt-0'">
What are your top campaigns?
</div>
<div class="fuse-card">
<div class="p-16" fxLayout="row" fxLayoutAlign="space-between center">
<div class="h1 pr-16">Top campaigns</div>
<div>
<button mat-icon-button [matMenuTriggerFor]="card20Menu" aria-label="more">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #card20Menu="matMenu">
<button fxLayout="row" fxLayoutAlign="start center" mat-menu-item>
<mat-icon color="accent">check_box</mat-icon>
<span>Show Clicks</span>
</button>
<button fxLayout="row" fxLayoutAlign="start center" mat-menu-item>
<mat-icon color="accent">check_box</mat-icon>
<span>Show Conversion</span>
</button>
<button fxLayout="row" fxLayoutAlign="start center" mat-menu-item>
<mat-icon>check_box_outline_blank</mat-icon>
<span>Show CPC</span>
</button>
</mat-menu>
</div>
</div>
<table class="simple clickable">
<thead>
<tr>
<th></th>
<th class="text-right">Clicks</th>
<th class="text-right">Conv</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of widgets.widget9.rows">
<td>{{row.title}}</td>
<td class="text-right">{{row.clicks}}</td>
<td class="text-right">{{row.conversion}}</td>
</tr>
</tbody>
</table>
<div class="card-divider full-width"></div>
<div class="p-8 pt-16" fxLayout="row" fxLayoutAlign="start center">
<button mat-button color="accent">GO TO CAMPAIGNS</button>
</div>
</div>
</div>
<!-- / widget 9 -->
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,49 @@
@import "src/app/core/scss/fuse";
#dashboard-analytics {
.main-widget {
display: flex;
flex-direction: column;
}
.content {
display: flex;
flex: 1 1 auto;
padding: 32px;
min-width: 0;
@include media-breakpoint-down('md') {
flex-direction: column;
}
.left {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-width: 0;
.widget {
flex: 1 1 auto;
min-width: 0;
}
}
.right {
display: flex;
flex: 0 0 auto;
width: 320px;
min-width: 320px;
max-width: 320px;
@include media-breakpoint-down('md') {
flex: 1 0 100%;
margin-top: 32px;
width: 100%;
min-width: 0;
max-width: none;
}
}
}
}

View File

@@ -0,0 +1,91 @@
import { Component, ViewEncapsulation } from '@angular/core';
import { AnalyticsDashboardService } from './analytics.service';
import { fuseAnimations } from '../../../../../core/animations';
@Component({
selector : 'fuse-analytics-dashboard',
templateUrl : './analytics.component.html',
styleUrls : ['./analytics.component.scss'],
encapsulation: ViewEncapsulation.None,
animations : fuseAnimations
})
export class FuseAnalyticsDashboardComponent
{
widgets: any;
widget1SelectedYear = '2016';
widget5SelectedDay = 'today';
constructor(
private analyticsDashboardService: AnalyticsDashboardService
)
{
// Get the widgets from the service
this.widgets = this.analyticsDashboardService.widgets;
// Register the custom chart.js plugin
this.registerCustomChartJSPlugin();
}
/**
* Register a custom plugin
*/
registerCustomChartJSPlugin()
{
(<any>window).Chart.plugins.register({
afterDatasetsDraw: function (chart, easing) {
// Only activate the plugin if it's made available
// in the options
if (
!chart.options.plugins.xLabelsOnTop ||
(chart.options.plugins.xLabelsOnTop && chart.options.plugins.xLabelsOnTop.active === false)
)
{
return;
}
// To only draw at the end of animation, check for easing === 1
const ctx = chart.ctx;
chart.data.datasets.forEach(function (dataset, i) {
const meta = chart.getDatasetMeta(i);
if ( !meta.hidden )
{
meta.data.forEach(function (element, index) {
// Draw the text in black, with the specified font
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
const fontSize = 13;
const fontStyle = 'normal';
const fontFamily = 'Roboto, Helvetica Neue, Arial';
ctx.font = (<any>window).Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
// Just naively convert to string for now
const dataString = dataset.data[index].toString() + 'k';
// Make sure alignment settings are correct
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
const padding = 15;
const startY = 24;
const position = element.tooltipPosition();
ctx.fillText(dataString, position.x, startY);
ctx.save();
ctx.beginPath();
ctx.setLineDash([5, 3]);
ctx.moveTo(position.x, startY + padding);
ctx.lineTo(position.x, position.y - padding);
ctx.strokeStyle = 'rgba(255,255,255,0.12)';
ctx.stroke();
ctx.restore();
});
}
});
}
});
}
}

View File

@@ -0,0 +1,41 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { SharedModule } from '../../../../../core/modules/shared.module';
import { NgxChartsModule } from '@swimlane/ngx-charts';
import { AgmCoreModule } from '@agm/core';
import { FuseAnalyticsDashboardComponent } from './analytics.component';
import { AnalyticsDashboardService } from './analytics.service';
import { FuseWidgetModule } from '../../../../../core/components/widget/widget.module';
const routes: Routes = [
{
path : '**',
component: FuseAnalyticsDashboardComponent,
resolve : {
data: AnalyticsDashboardService
}
}
];
@NgModule({
imports : [
SharedModule,
RouterModule.forChild(routes),
FuseWidgetModule,
NgxChartsModule,
AgmCoreModule.forRoot({
apiKey: 'AIzaSyD81ecsCj4yYpcXSLFcYU97PvRsE_X8Bx8'
})
],
declarations: [
FuseAnalyticsDashboardComponent
],
providers : [
AnalyticsDashboardService
]
})
export class FuseAnalyticsDashboardModule
{
}

View File

@@ -0,0 +1,48 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class AnalyticsDashboardService implements Resolve<any>
{
widgets: any[];
constructor(
private http: HttpClient
)
{
}
/**
* Resolve
* @param {ActivatedRouteSnapshot} route
* @param {RouterStateSnapshot} state
* @returns {Observable<any> | Promise<any> | any}
*/
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
{
return new Promise((resolve, reject) => {
Promise.all([
this.getWidgets()
]).then(
() => {
resolve();
},
reject
);
});
}
getWidgets(): Promise<any>
{
return new Promise((resolve, reject) => {
this.http.get('api/analytics-dashboard-widgets')
.subscribe((response: any) => {
this.widgets = response;
resolve(response);
}, reject);
});
}
}

View File

@@ -10,7 +10,9 @@
<div fxLayout="row" fxLayoutAlign="space-between start">
<span class="mat-display-1 mb-0 welcome-message" *fuseIfOnDom [@animate]="{value:'*',params:{x:'50px'}}">Welcome back, John!</span>
<span class="mat-display-1 mb-0 welcome-message" *fuseIfOnDom
[@animate]="{value:'*',params:{x:'50px'}}">Welcome back, John!
</span>
<button mat-icon-button fuseMatSidenavToggler="dashboards-right-sidenav" fxHide.gt-md>
<mat-icon>menu</mat-icon>
@@ -21,7 +23,8 @@
<div class="selected-project">{{selectedProject.name}}</div>
<button mat-icon-button class="project-selector" [matMenuTriggerFor]="projectsMenu" aria-label="Select project">
<button mat-icon-button class="project-selector" [matMenuTriggerFor]="projectsMenu"
aria-label="Select project">
<mat-icon>more_horiz</mat-icon>
</button>
@@ -41,16 +44,20 @@
<mat-tab label="Home">
<div class="widget-group p-12" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom [@animateStagger]="{value:'50'}">
<div class="widget-group grey-100-bg p-12" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom
[@animateStagger]="{value:'50'}">
<!-- WIDGET 1 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
fxLayoutAlign="space-between center">
<mat-form-field>
<mat-select class="simplified font-size-16" [(ngModel)]="widgets.widget1.currentRange"
<mat-select class="simplified font-size-16"
[(ngModel)]="widgets.widget1.currentRange"
aria-label="Change range">
<mat-option *ngFor="let range of widgets.widget1.ranges | keys"
[value]="range.key">
@@ -67,12 +74,17 @@
<div class="light-blue-fg font-size-72 line-height-72">
{{widgets.widget1.data.count[widgets.widget1.currentRange]}}
</div>
<div class="h3 secondary-text font-weight-500">{{widgets.widget1.data.label}}</div>
<div class="h3 secondary-text font-weight-500">{{widgets.widget1.data.label}}
</div>
</div>
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
<span class="h4 secondary-text text-truncate">{{widgets.widget1.data.extra.label}}:</span>
<span class="h4 ml-8">{{widgets.widget1.data.extra.count[widgets.widget1.currentRange]}}</span>
<span class="h4 secondary-text text-truncate">
{{widgets.widget1.data.extra.label}}:
</span>
<span class="h4 ml-8">
{{widgets.widget1.data.extra.count[widgets.widget1.currentRange]}}
</span>
</div>
</div>
<!-- / Front -->
@@ -94,14 +106,17 @@
<!-- / WIDGET 1 -->
<!-- WIDGET 2 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
fxLayoutAlign="space-between center">
<div class="h3">{{widgets.widget2.title}}</div>
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button" aria-label="more">
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
aria-label="more">
<mat-icon>more_vert</mat-icon>
</button>
</div>
@@ -110,11 +125,14 @@
<div class="red-fg font-size-72 line-height-72">
{{widgets.widget2.data.count}}
</div>
<div class="h3 secondary-text font-weight-500">{{widgets.widget2.data.label}}</div>
<div class="h3 secondary-text font-weight-500">{{widgets.widget2.data.label}}
</div>
</div>
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
<span class="h4 secondary-text text-truncate">{{widgets.widget2.data.extra.label}}:</span>
<span class="h4 secondary-text text-truncate">
{{widgets.widget2.data.extra.label}}:
</span>
<span class="h4 ml-8">{{widgets.widget2.data.extra.count}}</span>
</div>
</div>
@@ -137,14 +155,17 @@
<!-- / WIDGET 2 -->
<!-- WIDGET 3 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
fxLayoutAlign="space-between center">
<div class="h3">{{widgets.widget3.title}}</div>
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button" aria-label="more">
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
aria-label="more">
<mat-icon>more_vert</mat-icon>
</button>
</div>
@@ -153,11 +174,14 @@
<div class="orange-fg font-size-72 line-height-72">
{{widgets.widget3.data.count}}
</div>
<div class="h3 secondary-text font-weight-500">{{widgets.widget3.data.label}}</div>
<div class="h3 secondary-text font-weight-500">{{widgets.widget3.data.label}}
</div>
</div>
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
<span class="h4 secondary-text text-truncate">{{widgets.widget3.data.extra.label}}:</span>
<span class="h4 secondary-text text-truncate">
{{widgets.widget3.data.extra.label}}:
</span>
<span class="h4 ml-8">{{widgets.widget3.data.extra.count}}</span>
</div>
</div>
@@ -180,26 +204,33 @@
<!-- / WIDGET 3 -->
<!-- WIDGET 4 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
fxLayoutAlign="space-between center">
<div class="h3">{{widgets.widget4.title}}</div>
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button" aria-label="more">
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
aria-label="more">
<mat-icon>more_vert</mat-icon>
</button>
</div>
<div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
<div class="blue-grey-fg font-size-72 line-height-72">{{widgets.widget4.data.count}}
<div class="blue-grey-fg font-size-72 line-height-72">
{{widgets.widget4.data.count}}
</div>
<div class="h3 secondary-text font-weight-500">{{widgets.widget4.data.label}}
</div>
<div class="h3 secondary-text font-weight-500">{{widgets.widget4.data.label}}</div>
</div>
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
<span class="h4 secondary-text text-truncate">{{widgets.widget4.data.extra.label}}:</span>
<span class="h4 secondary-text text-truncate">
{{widgets.widget4.data.extra.label}}:
</span>
<span class="h4 ml-8">{{widgets.widget4.data.extra.count}}</span>
</div>
</div>
@@ -221,18 +252,19 @@
</fuse-widget>
<!-- / WIDGET 4 -->
<!-- WIDGET 5 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row" fxFlex="100">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" fxLayout="row" fxFlex="100"
class="widget widget5">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
<div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center" fxLayoutWrap>
<div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center"
fxLayoutWrap>
<div fxFlex class="py-8 h3">{{widgets.widget5.title}}</div>
<div fxFlex class="py-16 h3">{{widgets.widget5.title}}</div>
<div fxFlex="0 1 auto" class="py-8" fxLayout="row">
<div fxFlex="0 1 auto" class="py-16" fxLayout="row">
<button mat-button class="px-16"
*ngFor="let range of widgets.widget5.ranges | keys"
(click)="widget5.currentRange = range.key"
@@ -242,8 +274,9 @@
</div>
</div>
<div fxLayout="row" fxLayoutAlign="start end" fxLayoutWrap>
<div class="h-420 mb-16" fxLayout="row" fxFlex="100" fxFlex.gt-sm="50">
<div fxLayout="row" fxLayoutAlign="start start" fxLayoutWrap>
<div class="h-420 my-16" fxLayout="row" fxFlex="100" fxFlex.gt-sm="50">
<ngx-charts-bar-vertical-stacked
*fuseIfOnDom
[scheme]="widget5.scheme"
@@ -260,10 +293,12 @@
</ngx-charts-bar-vertical-stacked>
</div>
<div class="mb-16" fxFlex="100" fxFlex.gt-sm="50" fxLayoutAlign="row" fxLayoutWrap>
<div class="my-16" fxFlex="100" fxFlex.gt-sm="50" fxLayoutAlign="row"
fxLayoutWrap>
<div fxLayout="column" fxFlex="100" fxFlex.gt-sm="50" fxLayoutAlign="center"
*ngFor="let widget of widgets.widget5.supporting | keys">
*ngFor="let widget of widgets.widget5.supporting | keys"
class="mb-24">
<div class="px-24">
<div class="h4 secondary-text">{{widget.value.label}}</div>
@@ -297,17 +332,19 @@
</fuse-widget>
<!-- / WIDGET 5 -->
<!-- WIDGET 6 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-sm="50">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
fxFlex="100" fxFlex.gt-sm="50">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
<div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center">
<div class="px-16 py-8 border-bottom" fxLayout="row"
fxLayoutAlign="space-between center">
<div class="h3">{{widgets.widget6.title}}</div>
<mat-form-field>
<mat-select class="simplified" [(ngModel)]="widget6.currentRange" aria-label="Change range">
<mat-select class="simplified" [(ngModel)]="widget6.currentRange"
aria-label="Change range">
<mat-option *ngFor="let range of widgets.widget6.ranges | keys"
[value]="range.key">
{{range.value}}
@@ -330,14 +367,21 @@
</ngx-charts-pie-chart>
</div>
<div class="py-8 mh-16 border-top" fxLayout="row" fxLayoutAlign="start center" fxLayoutWrap>
<div class="py-8 border-right" fxLayout="column" fxLayoutAlign="center center" fxFlex="100" fxFlex.gt-sm="50">
<span class="mat-display-1 mb-0">{{widgets.widget6.footerLeft.count[widget6.currentRange]}}</span>
<div class="py-8 mh-16 border-top" fxLayout="row" fxLayoutAlign="start center"
fxLayoutWrap>
<div class="py-8 border-right" fxLayout="column" fxLayoutAlign="center center"
fxFlex="100" fxFlex.gt-sm="50">
<span class="mat-display-1 mb-0">
{{widgets.widget6.footerLeft.count[widget6.currentRange]}}
</span>
<span class="h4">{{widgets.widget6.footerLeft.title}}</span>
</div>
<div class="py-8" fxLayout="column" fxLayoutAlign="center center" fxFlex="100" fxFlex.gt-sm="50">
<span class="mat-display-1 mb-0">{{widgets.widget6.footerRight.count[widget6.currentRange]}}</span>
<div class="py-8" fxLayout="column" fxLayoutAlign="center center" fxFlex="100"
fxFlex.gt-sm="50">
<span class="mat-display-1 mb-0">
{{widgets.widget6.footerRight.count[widget6.currentRange]}}
</span>
<span class="h4">{{widgets.widget6.footerRight.title}}</span>
</div>
</div>
@@ -349,12 +393,14 @@
<!-- / WIDGET 6 -->
<!-- WIDGET 7 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-sm="50">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
fxFlex="100" fxFlex.gt-sm="50">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
<div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center">
<div class="px-16 py-8 border-bottom" fxLayout="row"
fxLayoutAlign="space-between center">
<div class="h3">{{widgets.widget7.title}}</div>
<mat-form-field>
<mat-select class="simplified" [(ngModel)]="widget7.currentRange"
@@ -391,20 +437,21 @@
</div>
<!-- / WIDGET GROUP -->
</mat-tab>
<mat-tab label="Budget Summary">
<!-- WIDGET GROUP -->
<div class="widget-group" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom [@animateStagger]="{value:'50'}">
<div class="widget-group grey-100-bg" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom
[@animateStagger]="{value:'50'}">
<!-- WIDGET 8 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-sm="50">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
fxFlex="100" fxFlex.gt-sm="50">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
<div class="h3 p-16">
<div class="h3 px-16 py-24">
{{widgets.widget8.title}}
</div>
@@ -431,11 +478,13 @@
<!-- / WIDGET 8 -->
<!-- WIDGET 9 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-sm="50">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
fxFlex="100" fxFlex.gt-sm="50">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
<div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center">
<div class="px-16 py-12 border-bottom" fxLayout="row"
fxLayoutAlign="space-between center">
<div class="h3">{{widgets.widget9.title}}</div>
<mat-form-field>
<mat-select [(ngModel)]="widget9.currentRange" aria-label="Change range">
@@ -447,7 +496,7 @@
</mat-form-field>
</div>
<div class="p-16" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
<div class="px-16 py-24" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
fxLayoutAlign.gt-xs="space-between end">
<div fxFlex="0 1 auto">
<div class="h4 secondary-text">{{widgets.widget9.weeklySpent.title}}</div>
@@ -474,7 +523,7 @@
</div>
</div>
<div class="p-16" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
<div class="px-16 py-24" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
fxLayoutAlign.gt-xs="space-between end">
<div fxFlex="0 1 auto">
<div class="h4 secondary-text">{{widgets.widget9.totalSpent.title}}</div>
@@ -501,7 +550,7 @@
</div>
</div>
<div class="p-16" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
<div class="px-16 py-24" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
fxLayoutAlign.gt-xs="space-between end">
<div fxFlex="0 1 auto">
<div class="h4 secondary-text">{{widgets.widget9.remaining.title}}</div>
@@ -528,7 +577,7 @@
</div>
</div>
<div class="p-16 border-top">
<div class="px-16 py-24 border-top">
<div class="h4 secondary-text">{{widgets.widget9.totalBudget.title}}</div>
<div class="pt-8 mat-display-1 m-0 font-weight-300">
<span class="secondary-text">$</span>
@@ -543,7 +592,8 @@
<!-- / WIDGET 9 -->
<!-- WIDGET 10 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row" fxFlex="100">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row"
fxFlex="100">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
@@ -569,7 +619,8 @@
<span class="p-4" [ngClass]="cell.classes">
{{cell.value}}
</span>
<mat-icon *ngIf="cell.icon" class="s-16">{{cell.icon}}</mat-icon>
<mat-icon *ngIf="cell.icon" class="s-16">{{cell.icon}}
</mat-icon>
</td>
</tr>
</tbody>
@@ -590,17 +641,21 @@
<mat-tab label="Team Members">
<!-- WIDGET GROUP -->
<div class="widget-group" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom [@animateStagger]="{value:'50'}">
<div class="widget-group grey-100-bg" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom
[@animateStagger]="{value:'50'}">
<!-- WIDGET 11 -->
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row" fxFlex="100">
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row"
fxFlex="100">
<!-- Front -->
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
<div class="p-24 mb-8 border-bottom" fxLayout="row" fxLayoutAlign="space-between center">
<div class="p-24 mb-8 border-bottom" fxLayout="row"
fxLayoutAlign="space-between center">
<div class="h2">{{widgets.widget11.title}}</div>
<div class="text-boxed red-bg white-fg m-0">{{widgets.widget11.table.rows.length}}
<div class="text-boxed red-bg white-fg m-0">
{{widgets.widget11.table.rows.length}}
members
</div>
</div>
@@ -620,13 +675,15 @@
<ng-container cdkColumnDef="name">
<mat-header-cell *cdkHeaderCellDef>Name</mat-header-cell>
<mat-cell *cdkCellDef="let contact">
<p class="text-truncate font-weight-600">{{contact.name}} {{contact.lastName}}</p>
<p class="text-truncate font-weight-600">{{contact.name}}
{{contact.lastName}}</p>
</mat-cell>
</ng-container>
<!-- Position Column -->
<ng-container cdkColumnDef="position">
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-sm>Position</mat-header-cell>
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-sm>Position
</mat-header-cell>
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-sm>
<p class="position text-truncate">
{{contact.position}}
@@ -636,7 +693,8 @@
<!-- Office Column -->
<ng-container cdkColumnDef="office">
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-md>Office</mat-header-cell>
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-md>Office
</mat-header-cell>
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-md>
<p class="office text-truncate">
{{contact.office}}
@@ -644,10 +702,10 @@
</mat-cell>
</ng-container>
<!-- Email Column -->
<ng-container cdkColumnDef="email">
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-sm>Email</mat-header-cell>
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-sm>Email
</mat-header-cell>
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-sm>
<p class="email text-truncate">
{{contact.email}}
@@ -657,7 +715,8 @@
<!-- Phone Column -->
<ng-container cdkColumnDef="phone">
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-md>Phone</mat-header-cell>
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-md>Phone
</mat-header-cell>
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-md>
<p class="phone text-truncate">
{{contact.phone}}
@@ -665,7 +724,8 @@
</mat-cell>
</ng-container>
<mat-header-row *cdkHeaderRowDef="widgets.widget11.table.columns"></mat-header-row>
<mat-header-row
*cdkHeaderRowDef="widgets.widget11.table.columns"></mat-header-row>
<mat-row *cdkRowDef="let contact; columns: widgets.widget11.table.columns;">
</mat-row>
</mat-table>
@@ -688,7 +748,8 @@
<!-- / CENTER -->
<!-- SIDENAV -->
<mat-sidenav class="sidenav" align="end" mode="side" opened="true" fuseMatSidenavHelper="dashboards-right-sidenav" mat-is-locked-open="gt-md">
<mat-sidenav class="sidenav" align="end" mode="side" opened="true"
fuseMatSidenavHelper="dashboards-right-sidenav" mat-is-locked-open="gt-md">
<div class="sidenav-content" fusePerfectScrollbar>
@@ -768,7 +829,8 @@
<div class="p-16 pb-32" fxLayout="column" fxLayoutAlign="center center">
<div fxLayout="row" fxLayoutAlign="center center">
<mat-icon fontSet="meteocons" [fontIcon]="widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].icon"
<mat-icon fontSet="meteocons"
[fontIcon]="widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].icon"
class="icon s-40 mr-16"></mat-icon>
<span class="mat-display-2 m-0 font-weight-300 secondary-text">
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].temp[widgets.weatherWidget.tempUnit]}}
@@ -789,12 +851,16 @@
<div fxLayout="row" fxLayoutAlign="start center">
<mat-icon fontSet="meteocons" fontIcon="icon-compass" class="mr-8 s-16"></mat-icon>
<span>{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].windDirection}}</span>
<span>
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].windDirection}}
</span>
</div>
<div fxLayout="row" fxLayoutAlign="start center">
<mat-icon fontSet="meteocons" fontIcon="icon-rainy" class="mr-8 s-16"></mat-icon>
<span>{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].rainProbability}}</span>
<span>
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].rainProbability}}
</span>
</div>
</div>
@@ -806,7 +872,9 @@
<mat-icon fontSet="meteocons" [fontIcon]="day.icon" class="mr-16"></mat-icon>
<span class="h2">{{day.temp[widgets.weatherWidget.tempUnit]}}</span>
<span class="h2 font-weight-300 secondary-text text-super">&deg;</span>
<span class="h2 font-weight-300 secondary-text">{{widgets.weatherWidget.tempUnit}}</span>
<span class="h2 font-weight-300 secondary-text">
{{widgets.weatherWidget.tempUnit}}
</span>
</div>
</div>
</div>

View File

@@ -56,5 +56,15 @@
min-width: 250px !important;
max-width: 250px !important;
}
.widget {
&.widget5 {
.gridline-path.gridline-path-horizontal {
display: none;
}
}
}
}
}

View File

@@ -1,19 +1,20 @@
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { ProjectsDashboardService } from './projects.service';
import * as shape from 'd3-shape';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { DataSource } from '@angular/cdk/collections';
import { ProjectDashboardService } from './project.service';
import { fuseAnimations } from '../../../../../core/animations';
@Component({
selector : 'fuse-project',
selector : 'fuse-project-dashboard',
templateUrl : './project.component.html',
styleUrls : ['./project.component.scss'],
encapsulation: ViewEncapsulation.None,
animations : fuseAnimations
})
export class FuseProjectComponent implements OnInit, OnDestroy
export class FuseProjectDashboardComponent implements OnInit, OnDestroy
{
projects: any[];
selectedProject: any;
@@ -28,13 +29,11 @@ export class FuseProjectComponent implements OnInit, OnDestroy
dateNow = Date.now();
constructor(private projectsDashboardService: ProjectsDashboardService)
constructor(private projectDashboardService: ProjectDashboardService)
{
this.projects = this.projectsDashboardService.projects;
this.projects = this.projectDashboardService.projects;
this.selectedProject = this.projects[0];
this.widgets = this.projectsDashboardService.widgets;
this.widgets = this.projectDashboardService.widgets;
/**
* Widget 5

View File

@@ -1,17 +1,18 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FuseProjectComponent } from './project.component';
import { SharedModule } from '../../../../../core/modules/shared.module';
import { ProjectsDashboardService } from './projects.service';
import { FuseProjectDashboardComponent } from './project.component';
import { ProjectDashboardService } from './project.service';
import { FuseWidgetModule } from '../../../../../core/components/widget/widget.module';
import { NgxChartsModule } from '@swimlane/ngx-charts';
const routes: Routes = [
{
path : '**',
component: FuseProjectComponent,
component: FuseProjectDashboardComponent,
resolve : {
data: ProjectsDashboardService
data: ProjectDashboardService
}
}
];
@@ -24,10 +25,10 @@ const routes: Routes = [
NgxChartsModule
],
declarations: [
FuseProjectComponent
FuseProjectDashboardComponent
],
providers : [
ProjectsDashboardService
ProjectDashboardService
]
})
export class FuseProjectDashboardModule

View File

@@ -4,7 +4,7 @@ import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class ProjectsDashboardService implements Resolve<any>
export class ProjectDashboardService implements Resolve<any>
{
projects: any[];
widgets: any[];
@@ -41,7 +41,7 @@ export class ProjectsDashboardService implements Resolve<any>
getProjects(): Promise<any>
{
return new Promise((resolve, reject) => {
this.http.get('api/projects-dashboard-projects')
this.http.get('api/project-dashboard-projects')
.subscribe((response: any) => {
this.projects = response;
resolve(response);
@@ -52,7 +52,7 @@ export class ProjectsDashboardService implements Resolve<any>
getWidgets(): Promise<any>
{
return new Promise((resolve, reject) => {
this.http.get('api/projects-dashboard-widgets')
this.http.get('api/project-dashboard-widgets')
.subscribe((response: any) => {
this.widgets = response;
resolve(response);

View File

@@ -41,7 +41,7 @@ export class EcommerceDashboardService implements Resolve<any>
getProjects(): Promise<any>
{
return new Promise((resolve, reject) => {
this.http.get('api/projects-dashboard-projects')
this.http.get('api/project-dashboard-projects')
.subscribe((response: any) => {
this.projects = response;
resolve(response);

View File

@@ -7,6 +7,8 @@ import { locale as english } from './i18n/en';
import { locale as turkish } from './i18n/tr';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import * as fromStore from './store';
import { FuseConfigService } from '../../../../core/services/config.service';

View File

@@ -4,6 +4,7 @@ import { Actions, Effect } from '@ngrx/effects';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { map, mergeMap, exhaustMap, withLatestFrom } from 'rxjs/operators';
import 'rxjs/add/operator/debounceTime';
import { getRouterState, State } from '../../../../../../store/reducers';
import { getMailsState } from '../selectors';
import * as MailsActions from '../actions/mails.actions';

View File

@@ -4,8 +4,8 @@
position: relative;
display: block;
width: 100%;
margin: 16px 0;
background-color: white;
margin: 16px 0 !important;
background-color: white !important;
color: #000;
border-radius: 2px;
transition: box-shadow 150ms ease;

View File

@@ -4,7 +4,7 @@
width: 344px;
min-width: 344px;
max-width: 344px;
padding-right: 24px;
padding-right: 24px !important;
height: 100%;
.list {
@@ -36,6 +36,7 @@
position: relative;
min-height: 32px;
padding: 0 16px;
background: mat-color($mat-grey, 200) !important;
}
}

View File

@@ -5,6 +5,7 @@ import { Subscription } from 'rxjs/Subscription';
import { FormBuilder, FormGroup } from '@angular/forms';
import { FuseUtils } from '../../../../../core/fuseUtils';
import { fuseAnimations } from '../../../../../core/animations';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
@Component({

View File

@@ -10,13 +10,6 @@
flex-shrink: 0;
background: #FFFFFF;
&.todo-item-placeholder {
background: rgba(0, 0, 0, 0.12);
* {
opacity: 0;
}
}
.handle {
height: 48px;
line-height: 48px;

View File

@@ -4,6 +4,7 @@ import { TodoService } from './todo.service';
import { FormControl } from '@angular/forms';
import { Todo } from './todo.model';
import { fuseAnimations } from '../../../../core/animations';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
@Component({

View File

@@ -13,6 +13,7 @@
.card {
display: flex;
align-items: flex-start;
padding: 24px 24px 48px 24px;
margin-bottom: 96px;

View File

@@ -56,7 +56,7 @@
// i18n/tr.ts
export const locale = {
lang: 'en',
lang: 'tr',
data: {
'MAIL': {
'COMPOSE': 'YENİ E-POSTA'

View File

@@ -3,6 +3,7 @@ import { FormControl } from '@angular/forms';
import { Subscription } from 'rxjs/Subscription';
import { FaqService } from './faq.service';
import { FuseUtils } from '../../../../core/fuseUtils';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
@Component({

View File

@@ -1,8 +1,8 @@
fuse-quick-panel {
display: flex;
width: 330px;
min-width: 330px;
max-width: 330px;
width: 280px;
min-width: 280px;
max-width: 280px;
z-index: 99;
flex-direction: column;

View File

@@ -21,12 +21,18 @@ export class FuseNavigationModel implements FuseNavigationModelInterface
'type' : 'collapse',
'icon' : 'dashboard',
'children' : [
{
'id' : 'analytics',
'title': 'Analytics',
'type' : 'item',
'url' : '/apps/dashboards/analytics'
},
{
'id' : 'project',
'title': 'Project',
'type' : 'item',
'url' : '/apps/dashboards/project'
}
},
]
},
{