mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-12-22 13:17:09 +00:00
Compare commits
81 Commits
v6.0.1-ske
...
v6.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75b7e4e270 | ||
|
|
9efab7ed20 | ||
|
|
65523c3c95 | ||
|
|
22b3a3c799 | ||
|
|
2b4bd45ad6 | ||
|
|
1e47c79f15 | ||
|
|
58ab766edf | ||
|
|
8db1206c91 | ||
|
|
562ae61098 | ||
|
|
e43ae86a58 | ||
|
|
5459579d04 | ||
|
|
95759be710 | ||
|
|
edb4683dcb | ||
|
|
58dd3b93c3 | ||
|
|
91e8d88488 | ||
|
|
ddcf1d5483 | ||
|
|
0b5727ff15 | ||
|
|
20f80e3fe4 | ||
|
|
5bf9fd177b | ||
|
|
507fe97e84 | ||
|
|
a6a7442607 | ||
|
|
43189728e5 | ||
|
|
9c88524185 | ||
|
|
52cfeec2e7 | ||
|
|
ffb134f1ec | ||
|
|
8520ca77be | ||
|
|
a174c00072 | ||
|
|
42ab15d9e1 | ||
|
|
a87e68251e | ||
|
|
436bd0aa91 | ||
|
|
d5f1fcfefa | ||
|
|
234dec3d6a | ||
|
|
928be05725 | ||
|
|
bcf5a9e6cb | ||
|
|
e79bfb7bce | ||
|
|
86815b7737 | ||
|
|
73a81699ec | ||
|
|
c2970e34ba | ||
|
|
7d6a92fada | ||
|
|
acbed8e305 | ||
|
|
b46f81b6ac | ||
|
|
a284063d22 | ||
|
|
1c8cc35693 | ||
|
|
6cc7d03430 | ||
|
|
f8f97f8ad4 | ||
|
|
bd79830cb4 | ||
|
|
5ed04c3925 | ||
|
|
90fe94a417 | ||
|
|
a39021188e | ||
|
|
ba35ebae94 | ||
|
|
97f864bb76 | ||
|
|
ea15a8b832 | ||
|
|
5c1f2ad1e3 | ||
|
|
420d8d1a1b | ||
|
|
f693298f3a | ||
|
|
a29c4b01ad | ||
|
|
1b94d8d14e | ||
|
|
232b4de752 | ||
|
|
b918fa4122 | ||
|
|
83c395b866 | ||
|
|
387077882b | ||
|
|
70d895c6ed | ||
|
|
0ac4e6c220 | ||
|
|
850e43c653 | ||
|
|
1e6bd8139c | ||
|
|
c6969cf9df | ||
|
|
745c51878d | ||
|
|
9635165316 | ||
|
|
02f305be1f | ||
|
|
27197a55dc | ||
|
|
5d000a849d | ||
|
|
07341c5ffa | ||
|
|
742da904da | ||
|
|
880529ad62 | ||
|
|
126ba35d3d | ||
|
|
0039f44936 | ||
|
|
ced0853af8 | ||
|
|
3d483b5a4b | ||
|
|
96813406a2 | ||
|
|
7fa892d7cc | ||
|
|
832a08208a |
@@ -1,13 +1,6 @@
|
||||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
charset=utf-8
|
||||
end_of_line=lf
|
||||
insert_final_newline=false
|
||||
indent_style=space
|
||||
indent_size=4
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Fuse2
|
||||
# Fuse - Angular
|
||||
|
||||
Material Design Admin Template with Angular 6+ and Angular Material 2
|
||||
Material Design Admin Template with Angular 6+ and Angular Material
|
||||
|
||||
## The Community
|
||||
|
||||
|
||||
11
angular.json
11
angular.json
@@ -24,7 +24,8 @@
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
"src/assets",
|
||||
"src/app/main/angular-material-elements"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
@@ -102,7 +103,9 @@
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
"**/node_modules/**",
|
||||
"**/src/app/fake-db/**/*",
|
||||
"**/src/assets/angular-material-examples/**/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -124,7 +127,9 @@
|
||||
"options": {
|
||||
"tsConfig": "e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
"**/node_modules/**",
|
||||
"**/src/app/fake-db/**/*",
|
||||
"**/src/assets/angular-material-examples/**/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
2151
package-lock.json
generated
2151
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
80
package.json
80
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fuse",
|
||||
"version": "6.0.1",
|
||||
"version": "6.1.0",
|
||||
"license": "https://themeforest.net/licenses/terms/regular",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
@@ -18,71 +18,71 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@agm/core": "1.0.0-beta.2",
|
||||
"@angular/animations": "6.0.0",
|
||||
"@angular/cdk": "6.0.1",
|
||||
"@angular/common": "6.0.0",
|
||||
"@angular/compiler": "6.0.0",
|
||||
"@angular/core": "6.0.0",
|
||||
"@angular/flex-layout": "6.0.0-beta.15",
|
||||
"@angular/forms": "6.0.0",
|
||||
"@angular/http": "6.0.0",
|
||||
"@angular/material": "6.0.1",
|
||||
"@angular/material-moment-adapter": "6.0.1",
|
||||
"@angular/platform-browser": "6.0.0",
|
||||
"@angular/platform-browser-dynamic": "6.0.0",
|
||||
"@angular/router": "6.0.0",
|
||||
"@ngrx/effects": "6.0.0-beta.1",
|
||||
"@ngrx/router-store": "6.0.0-beta.1",
|
||||
"@ngrx/store": "6.0.0-beta.1",
|
||||
"@ngrx/store-devtools": "6.0.0-beta.1",
|
||||
"@ngx-translate/core": "10.0.1",
|
||||
"@swimlane/ngx-charts": "8.0.0",
|
||||
"@swimlane/ngx-datatable": "12.0.0",
|
||||
"@agm/core": "1.0.0-beta.3",
|
||||
"@angular/animations": "6.0.5",
|
||||
"@angular/cdk": "6.2.1",
|
||||
"@angular/common": "6.0.5",
|
||||
"@angular/compiler": "6.0.5",
|
||||
"@angular/core": "6.0.5",
|
||||
"@angular/flex-layout": "6.0.0-beta.16",
|
||||
"@angular/forms": "6.0.5",
|
||||
"@angular/http": "6.0.5",
|
||||
"@angular/material": "6.2.1",
|
||||
"@angular/material-moment-adapter": "6.2.1",
|
||||
"@angular/platform-browser": "6.0.5",
|
||||
"@angular/platform-browser-dynamic": "6.0.5",
|
||||
"@angular/router": "6.0.5",
|
||||
"@ngrx/effects": "6.0.1",
|
||||
"@ngrx/router-store": "6.0.1",
|
||||
"@ngrx/store": "6.0.1",
|
||||
"@ngrx/store-devtools": "6.0.1",
|
||||
"@ngx-translate/core": "10.0.2",
|
||||
"@swimlane/ngx-charts": "8.1.0",
|
||||
"@swimlane/ngx-datatable": "13.0.1",
|
||||
"@swimlane/ngx-dnd": "4.0.0",
|
||||
"@types/prismjs": "1.9.0",
|
||||
"angular-calendar": "0.24.0",
|
||||
"angular-calendar": "0.25.2",
|
||||
"angular-in-memory-web-api": "0.6.0",
|
||||
"chart.js": "2.7.2",
|
||||
"classlist.js": "1.1.20150312",
|
||||
"core-js": "2.5.6",
|
||||
"d3": "5.2.0",
|
||||
"core-js": "2.5.7",
|
||||
"d3": "5.4.0",
|
||||
"hammerjs": "2.0.8",
|
||||
"lodash": "4.17.10",
|
||||
"moment": "2.22.1",
|
||||
"moment": "2.22.2",
|
||||
"ng2-charts": "1.6.0",
|
||||
"ngrx-store-freeze": "0.2.2",
|
||||
"ngx-color-picker": "6.0.0",
|
||||
"ngrx-store-freeze": "0.2.4",
|
||||
"ngx-color-picker": "6.3.3",
|
||||
"ngx-cookie-service": "1.0.10",
|
||||
"perfect-scrollbar": "1.3.0",
|
||||
"perfect-scrollbar": "1.4.0",
|
||||
"prismjs": "1.14.0",
|
||||
"rxjs": "6.1.0",
|
||||
"rxjs-compat": "6.1.0",
|
||||
"rxjs": "6.2.1",
|
||||
"rxjs-compat": "6.2.1",
|
||||
"web-animations-js": "2.3.1",
|
||||
"zone.js": "0.8.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "6.0.0",
|
||||
"@angular/compiler-cli": "6.0.0",
|
||||
"@angular/language-service": "6.0.0",
|
||||
"@angular-devkit/build-angular": "0.6.0",
|
||||
"@angular/cli": "6.0.8",
|
||||
"@angular/compiler-cli": "6.0.5",
|
||||
"@angular/language-service": "6.0.5",
|
||||
"@angular-devkit/build-angular": "0.6.8",
|
||||
"@angularclass/hmr": "2.1.3",
|
||||
"@types/jasmine": "2.8.7",
|
||||
"@types/jasmine": "2.8.8",
|
||||
"@types/jasminewd2": "2.0.3",
|
||||
"@types/lodash": "4.14.108",
|
||||
"@types/lodash": "4.14.109",
|
||||
"@types/node": "8.9.5",
|
||||
"codelyzer": "4.2.1",
|
||||
"jasmine-core": "2.99.1",
|
||||
"jasmine-spec-reporter": "4.2.1",
|
||||
"karma": "1.7.1",
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "1.4.2",
|
||||
"karma-coverage-istanbul-reporter": "2.0.1",
|
||||
"karma-jasmine": "1.1.2",
|
||||
"karma-jasmine-html-reporter": "0.2.2",
|
||||
"protractor": "5.3.1",
|
||||
"protractor": "5.3.2",
|
||||
"ts-node": "5.0.1",
|
||||
"tslint": "5.9.1",
|
||||
"typescript": "2.7.2",
|
||||
"webpack-bundle-analyzer": "2.11.1"
|
||||
"webpack-bundle-analyzer": "2.13.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,10 +187,14 @@ export const fuseAnimations = [
|
||||
transition('* => void', animate('300ms ease-in'))
|
||||
]),
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Router animations
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
trigger('routerTransitionLeft', [
|
||||
|
||||
transition('* => *', [
|
||||
query('fuse-content > :enter, fuse-content > :leave', [
|
||||
query('content > :enter, content > :leave', [
|
||||
style({
|
||||
position: 'absolute',
|
||||
top : 0,
|
||||
@@ -199,7 +203,7 @@ export const fuseAnimations = [
|
||||
right : 0
|
||||
})
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
query('content > :enter', [
|
||||
style({
|
||||
transform: 'translateX(100%)',
|
||||
opacity : 0
|
||||
@@ -207,7 +211,7 @@ export const fuseAnimations = [
|
||||
], {optional: true}),
|
||||
sequence([
|
||||
group([
|
||||
query('fuse-content > :leave', [
|
||||
query('content > :leave', [
|
||||
style({
|
||||
transform: 'translateX(0)',
|
||||
opacity : 1
|
||||
@@ -218,7 +222,7 @@ export const fuseAnimations = [
|
||||
opacity : 0
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
query('content > :enter', [
|
||||
style({transform: 'translateX(100%)'}),
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
@@ -227,8 +231,8 @@ export const fuseAnimations = [
|
||||
}))
|
||||
], {optional: true})
|
||||
]),
|
||||
query('fuse-content > :leave', animateChild(), {optional: true}),
|
||||
query('fuse-content > :enter', animateChild(), {optional: true})
|
||||
query('content > :leave', animateChild(), {optional: true}),
|
||||
query('content > :enter', animateChild(), {optional: true})
|
||||
])
|
||||
])
|
||||
]),
|
||||
@@ -236,7 +240,7 @@ export const fuseAnimations = [
|
||||
trigger('routerTransitionRight', [
|
||||
|
||||
transition('* => *', [
|
||||
query('fuse-content > :enter, fuse-content > :leave', [
|
||||
query('content > :enter, content > :leave', [
|
||||
style({
|
||||
position: 'absolute',
|
||||
top : 0,
|
||||
@@ -245,7 +249,7 @@ export const fuseAnimations = [
|
||||
right : 0
|
||||
})
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
query('content > :enter', [
|
||||
style({
|
||||
transform: 'translateX(-100%)',
|
||||
opacity : 0
|
||||
@@ -253,7 +257,7 @@ export const fuseAnimations = [
|
||||
], {optional: true}),
|
||||
sequence([
|
||||
group([
|
||||
query('fuse-content > :leave', [
|
||||
query('content > :leave', [
|
||||
style({
|
||||
transform: 'translateX(0)',
|
||||
opacity : 1
|
||||
@@ -264,7 +268,7 @@ export const fuseAnimations = [
|
||||
opacity : 0
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
query('content > :enter', [
|
||||
style({transform: 'translateX(-100%)'}),
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
@@ -273,8 +277,8 @@ export const fuseAnimations = [
|
||||
}))
|
||||
], {optional: true})
|
||||
]),
|
||||
query('fuse-content > :leave', animateChild(), {optional: true}),
|
||||
query('fuse-content > :enter', animateChild(), {optional: true})
|
||||
query('content > :leave', animateChild(), {optional: true}),
|
||||
query('content > :enter', animateChild(), {optional: true})
|
||||
])
|
||||
])
|
||||
]),
|
||||
@@ -282,7 +286,7 @@ export const fuseAnimations = [
|
||||
trigger('routerTransitionUp', [
|
||||
|
||||
transition('* => *', [
|
||||
query('fuse-content > :enter, fuse-content > :leave', [
|
||||
query('content > :enter, content > :leave', [
|
||||
style({
|
||||
position: 'absolute',
|
||||
top : 0,
|
||||
@@ -291,14 +295,14 @@ export const fuseAnimations = [
|
||||
right : 0
|
||||
})
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
query('content > :enter', [
|
||||
style({
|
||||
transform: 'translateY(100%)',
|
||||
opacity : 0
|
||||
})
|
||||
], {optional: true}),
|
||||
group([
|
||||
query('fuse-content > :leave', [
|
||||
query('content > :leave', [
|
||||
style({
|
||||
transform: 'translateY(0)',
|
||||
opacity : 1
|
||||
@@ -309,7 +313,7 @@ export const fuseAnimations = [
|
||||
opacity : 0
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
query('content > :enter', [
|
||||
style({transform: 'translateY(100%)'}),
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
@@ -318,15 +322,15 @@ export const fuseAnimations = [
|
||||
}))
|
||||
], {optional: true})
|
||||
]),
|
||||
query('fuse-content > :leave', animateChild(), {optional: true}),
|
||||
query('fuse-content > :enter', animateChild(), {optional: true})
|
||||
query('content > :leave', animateChild(), {optional: true}),
|
||||
query('content > :enter', animateChild(), {optional: true})
|
||||
])
|
||||
]),
|
||||
|
||||
trigger('routerTransitionDown', [
|
||||
|
||||
transition('* => *', [
|
||||
query('fuse-content > :enter, fuse-content > :leave', [
|
||||
query('content > :enter, content > :leave', [
|
||||
style({
|
||||
position: 'absolute',
|
||||
top : 0,
|
||||
@@ -335,7 +339,7 @@ export const fuseAnimations = [
|
||||
right : 0
|
||||
})
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
query('content > :enter', [
|
||||
style({
|
||||
transform: 'translateY(-100%)',
|
||||
opacity : 0
|
||||
@@ -343,7 +347,7 @@ export const fuseAnimations = [
|
||||
], {optional: true}),
|
||||
sequence([
|
||||
group([
|
||||
query('fuse-content > :leave', [
|
||||
query('content > :leave', [
|
||||
style({
|
||||
transform: 'translateY(0)',
|
||||
opacity : 1
|
||||
@@ -354,7 +358,7 @@ export const fuseAnimations = [
|
||||
opacity : 0
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
query('content > :enter', [
|
||||
style({transform: 'translateY(-100%)'}),
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
@@ -363,8 +367,8 @@ export const fuseAnimations = [
|
||||
}))
|
||||
], {optional: true})
|
||||
]),
|
||||
query('fuse-content > :leave', animateChild(), {optional: true}),
|
||||
query('fuse-content > :enter', animateChild(), {optional: true})
|
||||
query('content > :leave', animateChild(), {optional: true}),
|
||||
query('content > :enter', animateChild(), {optional: true})
|
||||
])
|
||||
])
|
||||
]),
|
||||
@@ -373,7 +377,7 @@ export const fuseAnimations = [
|
||||
|
||||
transition('* => *', group([
|
||||
|
||||
query('fuse-content > :enter, fuse-content > :leave ', [
|
||||
query('content > :enter, content > :leave ', [
|
||||
style({
|
||||
position: 'absolute',
|
||||
top : 0,
|
||||
@@ -383,12 +387,12 @@ export const fuseAnimations = [
|
||||
})
|
||||
], {optional: true}),
|
||||
|
||||
query('fuse-content > :enter', [
|
||||
query('content > :enter', [
|
||||
style({
|
||||
opacity: 0
|
||||
})
|
||||
], {optional: true}),
|
||||
query('fuse-content > :leave', [
|
||||
query('content > :leave', [
|
||||
style({
|
||||
opacity: 1
|
||||
}),
|
||||
@@ -397,7 +401,7 @@ export const fuseAnimations = [
|
||||
opacity: 0
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
query('content > :enter', [
|
||||
style({
|
||||
opacity: 0
|
||||
}),
|
||||
@@ -406,8 +410,8 @@ export const fuseAnimations = [
|
||||
opacity: 1
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', animateChild(), {optional: true}),
|
||||
query('fuse-content > :leave', animateChild(), {optional: true})
|
||||
query('content > :enter', animateChild(), {optional: true}),
|
||||
query('content > :leave', animateChild(), {optional: true})
|
||||
]))
|
||||
])
|
||||
];
|
||||
|
||||
@@ -10,7 +10,14 @@ export class FuseConfirmDialogComponent
|
||||
{
|
||||
public confirmMessage: string;
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<FuseConfirmDialogComponent>)
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MatDialogRef<FuseConfirmDialogComponent>} dialogRef
|
||||
*/
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<FuseConfirmDialogComponent>
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
import { interval } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { interval, Subject } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import * as moment from 'moment';
|
||||
|
||||
@Component({
|
||||
@@ -10,46 +8,82 @@ import * as moment from 'moment';
|
||||
templateUrl: './countdown.component.html',
|
||||
styleUrls : ['./countdown.component.scss']
|
||||
})
|
||||
export class FuseCountdownComponent implements OnInit
|
||||
export class FuseCountdownComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@Input('eventDate') eventDate;
|
||||
// Event date
|
||||
@Input('eventDate')
|
||||
eventDate;
|
||||
|
||||
countdown: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
// Set the defaults
|
||||
this.countdown = {
|
||||
days : '',
|
||||
hours : '',
|
||||
minutes: '',
|
||||
seconds: ''
|
||||
};
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
const currDate = moment();
|
||||
const eventDate = moment(this.eventDate);
|
||||
|
||||
// Get the difference in between the current date and event date
|
||||
let diff = eventDate.diff(currDate, 'seconds');
|
||||
|
||||
const countDown = interval(1000).pipe(
|
||||
map(value => {
|
||||
return diff = diff - 1;
|
||||
}),
|
||||
map(value => {
|
||||
const timeLeft = moment.duration(value, 'seconds');
|
||||
// Create a subscribable interval
|
||||
const countDown = interval(1000)
|
||||
.pipe(
|
||||
map(value => {
|
||||
return diff = diff - 1;
|
||||
}),
|
||||
map(value => {
|
||||
const timeLeft = moment.duration(value, 'seconds');
|
||||
|
||||
return {
|
||||
days : timeLeft.asDays().toFixed(0),
|
||||
hours : timeLeft.hours(),
|
||||
minutes: timeLeft.minutes(),
|
||||
seconds: timeLeft.seconds()
|
||||
};
|
||||
})
|
||||
);
|
||||
return {
|
||||
days : timeLeft.asDays().toFixed(0),
|
||||
hours : timeLeft.hours(),
|
||||
minutes: timeLeft.minutes(),
|
||||
seconds: timeLeft.seconds()
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
countDown.subscribe(value => {
|
||||
this.countdown = value;
|
||||
});
|
||||
// Subscribe to the countdown interval
|
||||
countDown
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(value => {
|
||||
this.countdown = value;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ import { Component } from '@angular/core';
|
||||
})
|
||||
export class FuseDemoContentComponent
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,99 +1,99 @@
|
||||
<div class="demo-sidenav">
|
||||
<div class="demo-sidebar">
|
||||
<mat-list>
|
||||
<h3 matSubheader>Sidenav Demo</h3>
|
||||
<h3 matSubheader>Sidebar Demo</h3>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 1</span>
|
||||
<span>Sidebar Item 1</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 2</span>
|
||||
<span>Sidebar Item 2</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 3</span>
|
||||
<span>Sidebar Item 3</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 4</span>
|
||||
<span>Sidebar Item 4</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 5</span>
|
||||
<span>Sidebar Item 5</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 6</span>
|
||||
<span>Sidebar Item 6</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 7</span>
|
||||
<span>Sidebar Item 7</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 8</span>
|
||||
<span>Sidebar Item 8</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 9</span>
|
||||
<span>Sidebar Item 9</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 10</span>
|
||||
<span>Sidebar Item 10</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 11</span>
|
||||
<span>Sidebar Item 11</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 12</span>
|
||||
<span>Sidebar Item 12</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 13</span>
|
||||
<span>Sidebar Item 13</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 14</span>
|
||||
<span>Sidebar Item 14</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 15</span>
|
||||
<span>Sidebar Item 15</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 16</span>
|
||||
<span>Sidebar Item 16</span>
|
||||
</mat-list-item>
|
||||
|
||||
</mat-list>
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-demo-sidebar',
|
||||
templateUrl: './demo-sidebar.component.html',
|
||||
styleUrls : ['./demo-sidebar.component.scss']
|
||||
})
|
||||
export class FuseDemoSidebarComponent
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-demo-sidenav',
|
||||
templateUrl: './demo-sidenav.component.html',
|
||||
styleUrls : ['./demo-sidenav.component.scss']
|
||||
})
|
||||
export class FuseDemoSidenavComponent
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,12 @@ import { RouterModule } from '@angular/router';
|
||||
import { MatDividerModule, MatListModule } from '@angular/material';
|
||||
|
||||
import { FuseDemoContentComponent } from './demo-content/demo-content.component';
|
||||
import { FuseDemoSidenavComponent } from './demo-sidenav/demo-sidenav.component';
|
||||
import { FuseDemoSidebarComponent } from './demo-sidebar/demo-sidebar.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseDemoContentComponent,
|
||||
FuseDemoSidenavComponent
|
||||
FuseDemoSidebarComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule,
|
||||
@@ -19,7 +19,7 @@ import { FuseDemoSidenavComponent } from './demo-sidenav/demo-sidenav.component'
|
||||
],
|
||||
exports : [
|
||||
FuseDemoContentComponent,
|
||||
FuseDemoSidenavComponent
|
||||
FuseDemoSidebarComponent
|
||||
]
|
||||
})
|
||||
export class FuseDemoModule
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
padding: 8px;
|
||||
background: #263238;
|
||||
cursor: text;
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -1,28 +1,55 @@
|
||||
import { Component, ContentChild, ElementRef, Input, OnInit } from '@angular/core';
|
||||
import { Component, ContentChild, ElementRef, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import * as Prism from 'prismjs/prism';
|
||||
import './prism-languages';
|
||||
import '@fuse/components/highlight/prism-languages';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-highlight',
|
||||
template : ' ',
|
||||
template : '',
|
||||
styleUrls: ['./highlight.component.scss']
|
||||
})
|
||||
export class FuseHighlightComponent implements OnInit
|
||||
export class FuseHighlightComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@ContentChild('source') source: ElementRef;
|
||||
@Input('lang') lang: string;
|
||||
@Input('path') path: string;
|
||||
// Source
|
||||
@ContentChild('source')
|
||||
source: ElementRef;
|
||||
|
||||
// Lang
|
||||
@Input('lang')
|
||||
lang: string;
|
||||
|
||||
// Path
|
||||
@Input('path')
|
||||
path: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ElementRef} _elementRef
|
||||
* @param {HttpClient} _httpClient
|
||||
*/
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
private http: HttpClient
|
||||
private _elementRef: ElementRef,
|
||||
private _httpClient: HttpClient
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// If there is no language defined, return...
|
||||
if ( !this.lang )
|
||||
@@ -34,11 +61,13 @@ export class FuseHighlightComponent implements OnInit
|
||||
if ( this.path )
|
||||
{
|
||||
// Get the source
|
||||
this.http.get(this.path, {responseType: 'text'}).subscribe((response) => {
|
||||
this._httpClient.get(this.path, {responseType: 'text'})
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((response) => {
|
||||
|
||||
// Highlight it
|
||||
this.highlight(response);
|
||||
});
|
||||
// Highlight it
|
||||
this.highlight(response);
|
||||
});
|
||||
}
|
||||
|
||||
// If the path is not defined and the source element exists...
|
||||
@@ -49,7 +78,26 @@ export class FuseHighlightComponent implements OnInit
|
||||
}
|
||||
}
|
||||
|
||||
highlight(sourceCode)
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Highlight the given source code
|
||||
*
|
||||
* @param sourceCode
|
||||
*/
|
||||
highlight(sourceCode): void
|
||||
{
|
||||
// Split the source into lines
|
||||
const sourceLines = sourceCode.split('\n');
|
||||
@@ -94,9 +142,8 @@ export class FuseHighlightComponent implements OnInit
|
||||
const highlightedCode = Prism.highlight(source, Prism.languages[this.lang]);
|
||||
|
||||
// Replace the innerHTML of the component with the highlighted code
|
||||
this.elementRef.nativeElement.innerHTML =
|
||||
this._elementRef.nativeElement.innerHTML =
|
||||
'<pre><code class="highlight language-' + this.lang + '">' + highlightedCode + '</code></pre>';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'prismjs/prism';
|
||||
import 'prismjs/components/prism-bash';
|
||||
import 'prismjs/components/prism-c';
|
||||
import 'prismjs/components/prism-cpp';
|
||||
import 'prismjs/components/prism-csharp';
|
||||
|
||||
@@ -13,22 +13,78 @@ import { MatColors } from '@fuse/mat-colors';
|
||||
export class FuseMaterialColorPickerComponent implements OnChanges
|
||||
{
|
||||
colors: any;
|
||||
selectedColor: any;
|
||||
hues: string[];
|
||||
view = 'palettes';
|
||||
selectedColor: any;
|
||||
view: string;
|
||||
|
||||
@Input() selectedPalette = '';
|
||||
@Input() selectedHue = '';
|
||||
@Input() selectedFg = '';
|
||||
@Input() value: any;
|
||||
@Output() onValueChange = new EventEmitter();
|
||||
@Output() selectedPaletteChange = new EventEmitter();
|
||||
@Output() selectedHueChange = new EventEmitter();
|
||||
@Output() selectedClassChange = new EventEmitter();
|
||||
@Output() selectedBgChange = new EventEmitter();
|
||||
@Output() selectedFgChange = new EventEmitter();
|
||||
@Input()
|
||||
selectedPalette: string;
|
||||
|
||||
_selectedClass = '';
|
||||
@Input()
|
||||
selectedHue: string;
|
||||
|
||||
@Input()
|
||||
selectedFg: string;
|
||||
|
||||
@Input()
|
||||
value: any;
|
||||
|
||||
@Output()
|
||||
onValueChange: EventEmitter<any>;
|
||||
|
||||
@Output()
|
||||
selectedPaletteChange: EventEmitter<any>;
|
||||
|
||||
@Output()
|
||||
selectedHueChange: EventEmitter<any>;
|
||||
|
||||
@Output()
|
||||
selectedClassChange: EventEmitter<any>;
|
||||
|
||||
@Output()
|
||||
selectedBgChange: EventEmitter<any>;
|
||||
|
||||
@Output()
|
||||
selectedFgChange: EventEmitter<any>;
|
||||
|
||||
// Private
|
||||
_selectedClass: string;
|
||||
_selectedBg: string;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
// Set the defaults
|
||||
this.colors = MatColors.all;
|
||||
this.hues = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700'];
|
||||
this.selectedFg = '';
|
||||
this.selectedHue = '';
|
||||
this.selectedPalette = '';
|
||||
this.view = 'palettes';
|
||||
|
||||
this.onValueChange = new EventEmitter();
|
||||
this.selectedPaletteChange = new EventEmitter();
|
||||
this.selectedHueChange = new EventEmitter();
|
||||
this.selectedClassChange = new EventEmitter();
|
||||
this.selectedBgChange = new EventEmitter();
|
||||
this.selectedFgChange = new EventEmitter();
|
||||
|
||||
// Set the private defaults
|
||||
this._selectedClass = '';
|
||||
this._selectedBg = '';
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Selected class
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
@Input()
|
||||
set selectedClass(value)
|
||||
{
|
||||
@@ -54,7 +110,11 @@ export class FuseMaterialColorPickerComponent implements OnChanges
|
||||
return this._selectedClass;
|
||||
}
|
||||
|
||||
_selectedBg = '';
|
||||
/**
|
||||
* Selected bg
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
@Input()
|
||||
set selectedBg(value)
|
||||
{
|
||||
@@ -86,13 +146,16 @@ export class FuseMaterialColorPickerComponent implements OnChanges
|
||||
return this._selectedBg;
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
this.colors = MatColors.all;
|
||||
this.hues = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700'];
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
ngOnChanges(changes: any)
|
||||
/**
|
||||
* On changes
|
||||
*
|
||||
* @param changes
|
||||
*/
|
||||
ngOnChanges(changes: any): void
|
||||
{
|
||||
if ( changes.selectedBg && changes.selectedBg.currentValue === '' ||
|
||||
changes.selectedClass && changes.selectedClass.currentValue === '' ||
|
||||
@@ -106,21 +169,38 @@ export class FuseMaterialColorPickerComponent implements OnChanges
|
||||
this.updateSelectedColor();
|
||||
}
|
||||
}
|
||||
|
||||
selectPalette(palette)
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Select palette
|
||||
*
|
||||
* @param palette
|
||||
*/
|
||||
selectPalette(palette): void
|
||||
{
|
||||
this.selectedPalette = palette;
|
||||
this.updateSelectedColor();
|
||||
this.view = 'hues';
|
||||
}
|
||||
|
||||
selectHue(hue)
|
||||
/**
|
||||
* Select hue
|
||||
*
|
||||
* @param hue
|
||||
*/
|
||||
selectHue(hue): void
|
||||
{
|
||||
this.selectedHue = hue;
|
||||
this.updateSelectedColor();
|
||||
}
|
||||
|
||||
removeColor()
|
||||
/**
|
||||
* Remove color
|
||||
*/
|
||||
removeColor(): void
|
||||
{
|
||||
this.selectedPalette = '';
|
||||
this.selectedHue = '';
|
||||
@@ -128,7 +208,10 @@ export class FuseMaterialColorPickerComponent implements OnChanges
|
||||
this.view = 'palettes';
|
||||
}
|
||||
|
||||
updateSelectedColor()
|
||||
/**
|
||||
* Update selected color
|
||||
*/
|
||||
updateSelectedColor(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -168,12 +251,18 @@ export class FuseMaterialColorPickerComponent implements OnChanges
|
||||
});
|
||||
}
|
||||
|
||||
backToPaletteSelection()
|
||||
/**
|
||||
* Go back to palette selection
|
||||
*/
|
||||
backToPaletteSelection(): void
|
||||
{
|
||||
this.view = 'palettes';
|
||||
}
|
||||
|
||||
onMenuOpen()
|
||||
/**
|
||||
* On menu open
|
||||
*/
|
||||
onMenuOpen(): void
|
||||
{
|
||||
if ( this.selectedPalette === '' )
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
|
||||
import { MatButtonModule, MatIconModule, MatMenuModule, MatRippleModule } from '@angular/material';
|
||||
|
||||
import { FusePipesModule } from '@fuse/pipes/pipes.module';
|
||||
|
||||
@@ -31,18 +31,19 @@
|
||||
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
|
||||
{{item.badge.title}}
|
||||
</span>
|
||||
<mat-icon class="collapse-arrow">keyboard_arrow_right</mat-icon>
|
||||
<mat-icon class="collapsable-arrow">keyboard_arrow_right</mat-icon>
|
||||
</ng-template>
|
||||
|
||||
<div class="children" [ngClass]="{'open': isOpen}">
|
||||
|
||||
<div class="{{fuseSettings.colorClasses.navbar}}">
|
||||
<div class="{{fuseConfig.layout.navbar.background}}">
|
||||
|
||||
<ng-container *ngFor="let item of item.children">
|
||||
<fuse-nav-horizontal-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-horizontal-item>
|
||||
<fuse-nav-horizontal-collapse *ngIf="item.type=='collapse'"
|
||||
[item]="item"></fuse-nav-horizontal-collapse>
|
||||
<fuse-nav-horizontal-collapse *ngIf="item.type=='group'" [item]="item"></fuse-nav-horizontal-collapse>
|
||||
<fuse-nav-horizontal-collapsable *ngIf="item.type=='collapsable'"
|
||||
[item]="item"></fuse-nav-horizontal-collapsable>
|
||||
<fuse-nav-horizontal-collapsable *ngIf="item.type=='group'"
|
||||
[item]="item"></fuse-nav-horizontal-collapsable>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,86 @@
|
||||
import { Component, HostBinding, HostListener, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-horizontal-collapsable',
|
||||
templateUrl: './collapsable.component.html',
|
||||
styleUrls : ['./collapsable.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseNavHorizontalCollapsableComponent implements OnInit, OnDestroy
|
||||
{
|
||||
fuseConfig: any;
|
||||
isOpen = false;
|
||||
|
||||
@HostBinding('class')
|
||||
classes = 'nav-collapsable nav-item';
|
||||
|
||||
@Input()
|
||||
item: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
constructor(
|
||||
private _fuseConfigService: FuseConfigService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to config changes
|
||||
this._fuseConfigService.config
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(
|
||||
(config) => {
|
||||
this.fuseConfig = config;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Open
|
||||
*/
|
||||
@HostListener('mouseenter')
|
||||
open(): void
|
||||
{
|
||||
this.isOpen = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close
|
||||
*/
|
||||
@HostListener('mouseleave')
|
||||
close(): void
|
||||
{
|
||||
this.isOpen = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Component, HostBinding, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-horizontal-item',
|
||||
templateUrl: './item.component.html',
|
||||
styleUrls : ['./item.component.scss']
|
||||
})
|
||||
export class FuseNavHorizontalItemComponent
|
||||
{
|
||||
@HostBinding('class')
|
||||
classes = 'nav-item';
|
||||
|
||||
@Input()
|
||||
item: any;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import { Component, HostBinding, HostListener, Input, OnDestroy } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { fuseAnimations } from '../../../../animations/index';
|
||||
import { FuseConfigService } from '../../../../services/config.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-horizontal-collapse',
|
||||
templateUrl: './nav-horizontal-collapse.component.html',
|
||||
styleUrls : ['./nav-horizontal-collapse.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseNavHorizontalCollapseComponent implements OnDestroy
|
||||
{
|
||||
onConfigChanged: Subscription;
|
||||
fuseSettings: any;
|
||||
isOpen = false;
|
||||
|
||||
@HostBinding('class') classes = 'nav-item nav-collapse';
|
||||
@Input() item: any;
|
||||
|
||||
@HostListener('mouseenter')
|
||||
open()
|
||||
{
|
||||
this.isOpen = true;
|
||||
}
|
||||
|
||||
@HostListener('mouseleave')
|
||||
close()
|
||||
{
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private fuseConfig: FuseConfigService
|
||||
)
|
||||
{
|
||||
this.onConfigChanged =
|
||||
this.fuseConfig.onConfigChanged
|
||||
.subscribe(
|
||||
(newSettings) => {
|
||||
this.fuseSettings = newSettings;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
{
|
||||
this.onConfigChanged.unsubscribe();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Component, HostBinding, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-horizontal-item',
|
||||
templateUrl: './nav-horizontal-item.component.html',
|
||||
styleUrls : ['./nav-horizontal-item.component.scss']
|
||||
})
|
||||
export class FuseNavHorizontalItemComponent
|
||||
{
|
||||
@HostBinding('class') classes = 'nav-item';
|
||||
@Input() item: any;
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<ng-container *ngFor="let item of navigation">
|
||||
|
||||
<fuse-nav-vertical-group *ngIf="item.type=='group'" [item]="item"></fuse-nav-vertical-group>
|
||||
<fuse-nav-vertical-collapse *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-vertical-collapse>
|
||||
<fuse-nav-vertical-collapsable *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-vertical-collapsable>
|
||||
<fuse-nav-vertical-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-vertical-item>
|
||||
|
||||
</ng-container>
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
<ng-container *ngFor="let item of navigation">
|
||||
|
||||
<fuse-nav-horizontal-collapse *ngIf="item.type=='group'" [item]="item"></fuse-nav-horizontal-collapse>
|
||||
<fuse-nav-horizontal-collapse *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-horizontal-collapse>
|
||||
<fuse-nav-horizontal-collapsable *ngIf="item.type=='group'" [item]="item"></fuse-nav-horizontal-collapsable>
|
||||
<fuse-nav-horizontal-collapsable *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-horizontal-collapsable>
|
||||
<fuse-nav-horizontal-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-horizontal-item>
|
||||
|
||||
</ng-container>
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { Component, Input, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-navigation',
|
||||
@@ -6,13 +10,45 @@ import { Component, Input, ViewEncapsulation } from '@angular/core';
|
||||
styleUrls : ['./navigation.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class FuseNavigationComponent
|
||||
export class FuseNavigationComponent implements OnInit
|
||||
{
|
||||
@Input() layout = 'vertical';
|
||||
@Input() navigation: any;
|
||||
@Input()
|
||||
layout = 'vertical';
|
||||
|
||||
constructor()
|
||||
@Input()
|
||||
navigation: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Load the navigation either from the input or from the service
|
||||
this.navigation = this.navigation || this._fuseNavigationService.getCurrentNavigation();
|
||||
|
||||
// Subscribe to the current navigation changes
|
||||
this._fuseNavigationService.onNavigationChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(() => {
|
||||
this.navigation = this._fuseNavigationService.getCurrentNavigation();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import { MatIconModule, MatRippleModule } from '@angular/material';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { FuseNavigationComponent } from './navigation.component';
|
||||
import { FuseNavVerticalItemComponent } from './vertical/nav-item/nav-vertical-item.component';
|
||||
import { FuseNavVerticalCollapseComponent } from './vertical/nav-collapse/nav-vertical-collapse.component';
|
||||
import { FuseNavVerticalGroupComponent } from './vertical/nav-group/nav-vertical-group.component';
|
||||
import { FuseNavHorizontalItemComponent } from './horizontal/nav-item/nav-horizontal-item.component';
|
||||
import { FuseNavHorizontalCollapseComponent } from './horizontal/nav-collapse/nav-horizontal-collapse.component';
|
||||
import { FuseNavVerticalItemComponent } from './vertical/item/item.component';
|
||||
import { FuseNavVerticalCollapsableComponent } from './vertical/collapsable/collapsable.component';
|
||||
import { FuseNavVerticalGroupComponent } from './vertical/group/group.component';
|
||||
import { FuseNavHorizontalItemComponent } from './horizontal/item/item.component';
|
||||
import { FuseNavHorizontalCollapsableComponent } from './horizontal/collapsable/collapsable.component';
|
||||
|
||||
@NgModule({
|
||||
imports : [
|
||||
@@ -29,9 +29,9 @@ import { FuseNavHorizontalCollapseComponent } from './horizontal/nav-collapse/na
|
||||
FuseNavigationComponent,
|
||||
FuseNavVerticalGroupComponent,
|
||||
FuseNavVerticalItemComponent,
|
||||
FuseNavVerticalCollapseComponent,
|
||||
FuseNavVerticalCollapsableComponent,
|
||||
FuseNavHorizontalItemComponent,
|
||||
FuseNavHorizontalCollapseComponent
|
||||
FuseNavHorizontalCollapsableComponent
|
||||
]
|
||||
})
|
||||
export class FuseNavigationModule
|
||||
|
||||
@@ -1,34 +1,161 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class FuseNavigationService
|
||||
{
|
||||
flatNavigation: any[] = [];
|
||||
|
||||
onItemCollapsed: Subject<any> = new Subject;
|
||||
onItemCollapseToggled: Subject<any> = new Subject;
|
||||
onItemCollapsed: Subject<any>;
|
||||
onItemCollapseToggled: Subject<any>;
|
||||
|
||||
// Private
|
||||
private _onNavigationChanged: BehaviorSubject<any>;
|
||||
private _onNavigationRegistered: BehaviorSubject<any>;
|
||||
private _onNavigationUnregistered: BehaviorSubject<any>;
|
||||
|
||||
private _currentNavigationKey: string;
|
||||
private _registry: { [key: string]: any } = {};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
// Set the defaults
|
||||
this.onItemCollapsed = new Subject();
|
||||
this.onItemCollapseToggled = new Subject();
|
||||
|
||||
// Set the private defaults
|
||||
this._currentNavigationKey = null;
|
||||
this._onNavigationChanged = new BehaviorSubject(null);
|
||||
this._onNavigationRegistered = new BehaviorSubject(null);
|
||||
this._onNavigationUnregistered = new BehaviorSubject(null);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get onNavigationChanged
|
||||
*
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
get onNavigationChanged(): Observable<any>
|
||||
{
|
||||
return this._onNavigationChanged.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get onNavigationRegistered
|
||||
*
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
get onNavigationRegistered(): Observable<any>
|
||||
{
|
||||
return this._onNavigationRegistered.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get onNavigationUnregistered
|
||||
*
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
get onNavigationUnregistered(): Observable<any>
|
||||
{
|
||||
return this._onNavigationUnregistered.asObservable();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Register the given navigation
|
||||
* with the given key
|
||||
*
|
||||
* @param key
|
||||
* @param navigation
|
||||
*/
|
||||
register(key, navigation): void
|
||||
{
|
||||
// Check if the key already being used
|
||||
if ( this._registry[key] )
|
||||
{
|
||||
console.error(`The navigation with the key '${key}' already exists. Either unregister it first or use a unique key.`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Add to the registry
|
||||
this._registry[key] = navigation;
|
||||
|
||||
// Notify the subject
|
||||
this._onNavigationRegistered.next([key, navigation]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the navigation from the registry
|
||||
* @param key
|
||||
*/
|
||||
unregister(key): void
|
||||
{
|
||||
// Check if the navigation exists
|
||||
if ( !this._registry[key] )
|
||||
{
|
||||
console.warn(`The navigation with the key '${key}' doesn't exist in the registry.`);
|
||||
}
|
||||
|
||||
// Unregister the sidebar
|
||||
delete this._registry[key];
|
||||
|
||||
// Notify the subject
|
||||
this._onNavigationUnregistered.next(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get navigation from registry by key
|
||||
*
|
||||
* @param key
|
||||
* @returns {any}
|
||||
*/
|
||||
getNavigation(key): any
|
||||
{
|
||||
// Check if the navigation exists
|
||||
if ( !this._registry[key] )
|
||||
{
|
||||
console.warn(`The navigation with the key '${key}' doesn't exist in the registry.`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Return the sidebar
|
||||
return this._registry[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get flattened navigation array
|
||||
*
|
||||
* @param navigation
|
||||
* @returns {any[]}
|
||||
*/
|
||||
getFlatNavigation(navigation)
|
||||
getFlatNavigation(navigation): any
|
||||
{
|
||||
for ( const navItem of navigation )
|
||||
{
|
||||
if ( navItem.type === 'item' )
|
||||
{
|
||||
this.flatNavigation.push({
|
||||
title: navItem.title,
|
||||
type : navItem.type,
|
||||
icon : navItem.icon || false,
|
||||
url : navItem.url
|
||||
id : navItem.id || null,
|
||||
title : navItem.title || null,
|
||||
translate : navItem.translate || null,
|
||||
type : navItem.type,
|
||||
icon : navItem.icon || null,
|
||||
url : navItem.url || null,
|
||||
function : navItem.function || null,
|
||||
exactMatch: navItem.exactMatch || false,
|
||||
badge : navItem.badge || null
|
||||
});
|
||||
|
||||
continue;
|
||||
@@ -45,4 +172,186 @@ export class FuseNavigationService
|
||||
|
||||
return this.flatNavigation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current navigation
|
||||
*
|
||||
* @returns {any}
|
||||
*/
|
||||
getCurrentNavigation(): any
|
||||
{
|
||||
if ( !this._currentNavigationKey )
|
||||
{
|
||||
console.warn(`The current navigation is not set.`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return this.getNavigation(this._currentNavigationKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the navigation with the key
|
||||
* as the current navigation
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
setCurrentNavigation(key): void
|
||||
{
|
||||
// Check if the sidebar exists
|
||||
if ( !this._registry[key] )
|
||||
{
|
||||
console.warn(`The navigation with the key '${key}' doesn't exist in the registry.`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the current navigation key
|
||||
this._currentNavigationKey = key;
|
||||
|
||||
// Notify the subject
|
||||
this._onNavigationChanged.next(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get navigation item by id from the
|
||||
* current navigation
|
||||
*
|
||||
* @param id
|
||||
* @param {any} navigation
|
||||
* @returns {any | boolean}
|
||||
*/
|
||||
getNavigationItem(id, navigation = null): any | boolean
|
||||
{
|
||||
if ( !navigation )
|
||||
{
|
||||
navigation = this.getCurrentNavigation();
|
||||
}
|
||||
|
||||
for ( const item of navigation )
|
||||
{
|
||||
if ( item.id === id )
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
if ( item.children )
|
||||
{
|
||||
const childItem = this.getNavigationItem(id, item.children);
|
||||
|
||||
if ( childItem )
|
||||
{
|
||||
return childItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent of the navigation item
|
||||
* with the id
|
||||
*
|
||||
* @param id
|
||||
* @param {any} navigation
|
||||
* @param parent
|
||||
*/
|
||||
getNavigationItemParent(id, navigation = null, parent = null): any
|
||||
{
|
||||
if ( !navigation )
|
||||
{
|
||||
navigation = this.getCurrentNavigation();
|
||||
parent = navigation;
|
||||
}
|
||||
|
||||
for ( const item of navigation )
|
||||
{
|
||||
if ( item.id === id )
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
if ( item.children )
|
||||
{
|
||||
const childItem = this.getNavigationItemParent(id, item.children, item);
|
||||
|
||||
if ( childItem )
|
||||
{
|
||||
return childItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a navigation item to the specified location
|
||||
*
|
||||
* @param item
|
||||
* @param id
|
||||
*/
|
||||
addNavigationItem(item, id): void
|
||||
{
|
||||
// Get the current navigation
|
||||
const navigation: any[] = this.getCurrentNavigation();
|
||||
|
||||
// Add to the end of the navigation
|
||||
if ( id === 'end' )
|
||||
{
|
||||
navigation.push(item);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Add to the start of the navigation
|
||||
if ( id === 'start' )
|
||||
{
|
||||
navigation.unshift(item);
|
||||
}
|
||||
|
||||
// Add it to a specific location
|
||||
const parent: any = this.getNavigationItem(id);
|
||||
|
||||
if ( parent )
|
||||
{
|
||||
// Check if parent has a children entry,
|
||||
// and add it if it doesn't
|
||||
if ( !parent.children )
|
||||
{
|
||||
parent.children = [];
|
||||
}
|
||||
|
||||
// Add the item
|
||||
parent.children.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove navigation item with the given id
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
removeNavigationItem(id): void
|
||||
{
|
||||
const item = this.getNavigationItem(id);
|
||||
|
||||
// Return, if there is not such an item
|
||||
if ( !item )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the parent of the item
|
||||
let parent = this.getNavigationItemParent(id);
|
||||
|
||||
// This check is required because of the first level
|
||||
// of the navigation, since the first level is not
|
||||
// inside the 'children' array
|
||||
parent = parent.children || parent;
|
||||
|
||||
// Remove the item
|
||||
parent.splice(parent.indexOf(item), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,24 +6,40 @@
|
||||
</a>
|
||||
|
||||
<!-- item.url -->
|
||||
<a class="nav-link" *ngIf="item.url && !item.function" (click)="toggleOpen($event)"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<a class="nav-link" *ngIf="item.url && !item.externalUrl && !item.function" (click)="toggleOpen($event)"
|
||||
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
|
||||
[target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.externalUrl -->
|
||||
<a class="nav-link" *ngIf="item.url && item.externalUrl && !item.function" (click)="toggleOpen($event)"
|
||||
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.function -->
|
||||
<span class="nav-link" *ngIf="!item.url && item.function" (click)="toggleOpen($event);item.function()" matRipple>
|
||||
<span class="nav-link" *ngIf="!item.url && item.function"
|
||||
(click)="toggleOpen($event);item.function()" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</span>
|
||||
|
||||
<!-- item.url && item.function -->
|
||||
<a class="nav-link" *ngIf="item.url && item.function" (click)="toggleOpen($event);item.function()"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
<a class="nav-link" *ngIf="item.url && !item.externalUrl && item.function"
|
||||
(click)="toggleOpen($event);item.function()"
|
||||
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.externalUrl && item.function -->
|
||||
<a class="nav-link" *ngIf="item.url && item.externalUrl && item.function"
|
||||
(click)="toggleOpen($event);item.function()"
|
||||
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<ng-template #itemContent>
|
||||
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
|
||||
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
|
||||
@@ -31,13 +47,14 @@
|
||||
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
|
||||
{{item.badge.title}}
|
||||
</span>
|
||||
<mat-icon class="collapse-arrow">keyboard_arrow_right</mat-icon>
|
||||
<mat-icon class="collapsable-arrow">keyboard_arrow_right</mat-icon>
|
||||
</ng-template>
|
||||
|
||||
<div class="children" [@slideInOut]="isOpen">
|
||||
<ng-container *ngFor="let item of item.children">
|
||||
<fuse-nav-vertical-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-vertical-item>
|
||||
<fuse-nav-vertical-collapse *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-vertical-collapse>
|
||||
<fuse-nav-vertical-collapsable *ngIf="item.type=='collapsable'"
|
||||
[item]="item"></fuse-nav-vertical-collapsable>
|
||||
<fuse-nav-vertical-group *ngIf="item.type=='group'" [item]="item"></fuse-nav-vertical-group>
|
||||
</ng-container>
|
||||
</div>
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
.nav-link {
|
||||
|
||||
.collapse-arrow {
|
||||
.collapsable-arrow {
|
||||
transition: transform .3s ease-in-out, opacity .25s ease-in-out .1s;
|
||||
transform: rotate(0);
|
||||
}
|
||||
@@ -34,13 +34,9 @@
|
||||
|
||||
> .nav-link {
|
||||
|
||||
.collapse-arrow {
|
||||
.collapsable-arrow {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
> .children {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,46 +1,79 @@
|
||||
import { Component, HostBinding, Input, OnInit } from '@angular/core';
|
||||
import { FuseNavigationService } from '../../navigation.service';
|
||||
import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { fuseAnimations } from '../../../../animations/index';
|
||||
import { Subject } from 'rxjs';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseNavigationItem } from '@fuse/types';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-vertical-collapse',
|
||||
templateUrl: './nav-vertical-collapse.component.html',
|
||||
styleUrls : ['./nav-vertical-collapse.component.scss'],
|
||||
selector : 'fuse-nav-vertical-collapsable',
|
||||
templateUrl: './collapsable.component.html',
|
||||
styleUrls : ['./collapsable.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseNavVerticalCollapseComponent implements OnInit
|
||||
export class FuseNavVerticalCollapsableComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@Input() item: any;
|
||||
@HostBinding('class') classes = 'nav-collapse nav-item';
|
||||
@HostBinding('class.open') public isOpen = false;
|
||||
@Input()
|
||||
item: FuseNavigationItem;
|
||||
|
||||
@HostBinding('class')
|
||||
classes = 'nav-collapsable nav-item';
|
||||
|
||||
@HostBinding('class.open')
|
||||
public isOpen = false;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseNavigationService} _fuseNavigationService
|
||||
* @param {Router} _router
|
||||
*/
|
||||
constructor(
|
||||
private navigationService: FuseNavigationService,
|
||||
private router: Router
|
||||
private _fuseNavigationService: FuseNavigationService,
|
||||
private _router: Router
|
||||
)
|
||||
{
|
||||
// Listen for route changes
|
||||
router.events.subscribe(
|
||||
(event) => {
|
||||
if ( event instanceof NavigationEnd )
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Listen for router events
|
||||
this._router.events
|
||||
.pipe(
|
||||
filter(event => event instanceof NavigationEnd),
|
||||
takeUntil(this._unsubscribeAll)
|
||||
)
|
||||
.subscribe((event: NavigationEnd) => {
|
||||
|
||||
// Check if the url can be found in
|
||||
// one of the children of this item
|
||||
if ( this.isUrlInChildren(this.item, event.urlAfterRedirects) )
|
||||
{
|
||||
// Check if the url can be found in
|
||||
// one of the children of this item
|
||||
if ( this.isUrlInChildren(this.item, event.urlAfterRedirects) )
|
||||
{
|
||||
this.expand();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.collapse();
|
||||
}
|
||||
this.expand();
|
||||
}
|
||||
}
|
||||
);
|
||||
else
|
||||
{
|
||||
this.collapse();
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for collapsing of any navigation item
|
||||
this.navigationService.onItemCollapsed
|
||||
this._fuseNavigationService.onItemCollapsed
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(
|
||||
(clickedItem) => {
|
||||
if ( clickedItem && clickedItem.children )
|
||||
@@ -54,7 +87,7 @@ export class FuseNavVerticalCollapseComponent implements OnInit
|
||||
|
||||
// Check if the url can be found in
|
||||
// one of the children of this item
|
||||
if ( this.isUrlInChildren(this.item, this.router.url) )
|
||||
if ( this.isUrlInChildren(this.item, this._router.url) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -67,13 +100,10 @@ export class FuseNavVerticalCollapseComponent implements OnInit
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
// Check if the url can be found in
|
||||
// one of the children of this item
|
||||
if ( this.isUrlInChildren(this.item, this.router.url) )
|
||||
if ( this.isUrlInChildren(this.item, this._router.url) )
|
||||
{
|
||||
this.expand();
|
||||
}
|
||||
@@ -83,26 +113,40 @@ export class FuseNavVerticalCollapseComponent implements OnInit
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle collapse
|
||||
*
|
||||
* @param ev
|
||||
*/
|
||||
toggleOpen(ev)
|
||||
toggleOpen(ev): void
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
this.isOpen = !this.isOpen;
|
||||
|
||||
// Navigation collapse toggled...
|
||||
this.navigationService.onItemCollapsed.next(this.item);
|
||||
this.navigationService.onItemCollapseToggled.next();
|
||||
this._fuseNavigationService.onItemCollapsed.next(this.item);
|
||||
this._fuseNavigationService.onItemCollapseToggled.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the collapsable navigation
|
||||
*/
|
||||
expand()
|
||||
expand(): void
|
||||
{
|
||||
if ( this.isOpen )
|
||||
{
|
||||
@@ -110,13 +154,13 @@ export class FuseNavVerticalCollapseComponent implements OnInit
|
||||
}
|
||||
|
||||
this.isOpen = true;
|
||||
this.navigationService.onItemCollapseToggled.next();
|
||||
this._fuseNavigationService.onItemCollapseToggled.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapse the collapsable navigation
|
||||
*/
|
||||
collapse()
|
||||
collapse(): void
|
||||
{
|
||||
if ( !this.isOpen )
|
||||
{
|
||||
@@ -124,7 +168,7 @@ export class FuseNavVerticalCollapseComponent implements OnInit
|
||||
}
|
||||
|
||||
this.isOpen = false;
|
||||
this.navigationService.onItemCollapseToggled.next();
|
||||
this._fuseNavigationService.onItemCollapseToggled.next();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,9 +177,9 @@ export class FuseNavVerticalCollapseComponent implements OnInit
|
||||
*
|
||||
* @param parent
|
||||
* @param item
|
||||
* @return {any}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isChildrenOf(parent, item)
|
||||
isChildrenOf(parent, item): boolean
|
||||
{
|
||||
if ( !parent.children )
|
||||
{
|
||||
@@ -162,9 +206,9 @@ export class FuseNavVerticalCollapseComponent implements OnInit
|
||||
*
|
||||
* @param parent
|
||||
* @param url
|
||||
* @returns {any}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isUrlInChildren(parent, url)
|
||||
isUrlInChildren(parent, url): boolean
|
||||
{
|
||||
if ( !parent.children )
|
||||
{
|
||||
@@ -7,7 +7,8 @@
|
||||
<div class="group-items">
|
||||
<ng-container *ngFor="let item of item.children">
|
||||
<fuse-nav-vertical-group *ngIf="item.type=='group'" [item]="item"></fuse-nav-vertical-group>
|
||||
<fuse-nav-vertical-collapse *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-vertical-collapse>
|
||||
<fuse-nav-vertical-collapsable *ngIf="item.type=='collapsable'"
|
||||
[item]="item"></fuse-nav-vertical-collapsable>
|
||||
<fuse-nav-vertical-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-vertical-item>
|
||||
</ng-container>
|
||||
</div>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Component, HostBinding, Input } from '@angular/core';
|
||||
|
||||
import { FuseNavigationItem } from '@fuse/types';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-vertical-group',
|
||||
templateUrl: './group.component.html',
|
||||
styleUrls : ['./group.component.scss']
|
||||
})
|
||||
export class FuseNavVerticalGroupComponent
|
||||
{
|
||||
@HostBinding('class')
|
||||
classes = 'nav-group nav-item';
|
||||
|
||||
@Input()
|
||||
item: FuseNavigationItem;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<ng-container *ngIf="!item.hidden">
|
||||
|
||||
<!-- item.url -->
|
||||
<a class="nav-link" *ngIf="item.url && !item.externalUrl && !item.function"
|
||||
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
|
||||
[target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.externalUrl -->
|
||||
<a class="nav-link" *ngIf="item.url && item.externalUrl && !item.function"
|
||||
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.function -->
|
||||
<span class="nav-link" *ngIf="!item.url && item.function"
|
||||
(click)="item.function()" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</span>
|
||||
|
||||
<!-- item.url && item.function -->
|
||||
<a class="nav-link" *ngIf="item.url && !item.externalUrl && item.function" (click)="item.function()"
|
||||
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
|
||||
[target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.externalUrl && item.function -->
|
||||
<a class="nav-link" *ngIf="item.url && item.externalUrl && item.function" (click)="item.function()"
|
||||
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<ng-template #itemContent>
|
||||
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
|
||||
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
|
||||
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
|
||||
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
|
||||
{{item.badge.title}}
|
||||
</span>
|
||||
</ng-template>
|
||||
|
||||
</ng-container>
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Component, HostBinding, Input } from '@angular/core';
|
||||
|
||||
import { FuseNavigationItem } from '@fuse/types';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-vertical-item',
|
||||
templateUrl: './item.component.html',
|
||||
styleUrls : ['./item.component.scss']
|
||||
})
|
||||
export class FuseNavVerticalItemComponent
|
||||
{
|
||||
@HostBinding('class')
|
||||
classes = 'nav-item';
|
||||
|
||||
@Input()
|
||||
item: FuseNavigationItem;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { Component, HostBinding, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-vertical-group',
|
||||
templateUrl: './nav-vertical-group.component.html',
|
||||
styleUrls : ['./nav-vertical-group.component.scss']
|
||||
})
|
||||
export class FuseNavVerticalGroupComponent
|
||||
{
|
||||
@HostBinding('class') classes = 'nav-group nav-item';
|
||||
@Input() item: any;
|
||||
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<ng-container *ngIf="!item.hidden">
|
||||
|
||||
<!-- item.url -->
|
||||
<a class="nav-link" *ngIf="item.url && !item.function"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.function -->
|
||||
<span class="nav-link" *ngIf="!item.url && item.function" (click)="item.function()" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</span>
|
||||
|
||||
<!-- item.url && item.function -->
|
||||
<a class="nav-link" *ngIf="item.url && item.function" (click)="item.function()"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<ng-template #itemContent>
|
||||
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
|
||||
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
|
||||
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
|
||||
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
|
||||
{{item.badge.title}}
|
||||
</span>
|
||||
</ng-template>
|
||||
|
||||
</ng-container>
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Component, HostBinding, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-vertical-item',
|
||||
templateUrl: './nav-vertical-item.component.html',
|
||||
styleUrls : ['./nav-vertical-item.component.scss']
|
||||
})
|
||||
export class FuseNavVerticalItemComponent
|
||||
{
|
||||
@HostBinding('class') classes = 'nav-item';
|
||||
@Input() item: any;
|
||||
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
<div class="fuse-search-bar" [ngClass]="{'expanded':!collapsed}">
|
||||
|
||||
<div class="fuse-search-bar-content" [ngClass]="toolbarColor">
|
||||
<div class="fuse-search-bar-content" [ngClass]="fuseConfig.layout.toolbar.background">
|
||||
|
||||
<label for="fuse-search-bar-input">
|
||||
<button mat-icon-button class="fuse-search-bar-expander" aria-label="Expand Search Bar" (click)="expand()"
|
||||
*ngIf="collapsed">
|
||||
<mat-icon class="s-24">search</mat-icon>
|
||||
<mat-icon class="s-24 secondary-text">search</mat-icon>
|
||||
</button>
|
||||
<!--<span class="fuse-search-bar-loader" fxLayout="row" fxLayoutAlign="center center" *ngIf="!collapsed">
|
||||
<mat-progress-spinner color="mat-accent" mode="indeterminate"></mat-progress-spinner>
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<button mat-icon-button class="fuse-search-bar-collapser" (click)="collapse()"
|
||||
aria-label="Collapse Search Bar">
|
||||
<mat-icon class="s-24">close</mat-icon>
|
||||
<mat-icon class="s-24 secondary-text">close</mat-icon>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Component, EventEmitter, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
|
||||
@@ -8,42 +9,91 @@ import { FuseConfigService } from '@fuse/services/config.service';
|
||||
templateUrl: './search-bar.component.html',
|
||||
styleUrls : ['./search-bar.component.scss']
|
||||
})
|
||||
export class FuseSearchBarComponent
|
||||
export class FuseSearchBarComponent implements OnInit, OnDestroy
|
||||
{
|
||||
collapsed: boolean;
|
||||
toolbarColor: string;
|
||||
@Output() onInput: EventEmitter<any> = new EventEmitter();
|
||||
onConfigChanged: Subscription;
|
||||
fuseConfig: any;
|
||||
|
||||
@Output()
|
||||
input: EventEmitter<any>;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseConfigService} _fuseConfigService
|
||||
*/
|
||||
constructor(
|
||||
private fuseConfig: FuseConfigService
|
||||
private _fuseConfigService: FuseConfigService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.input = new EventEmitter();
|
||||
this.collapsed = true;
|
||||
this.onConfigChanged =
|
||||
this.fuseConfig.onConfigChanged
|
||||
.subscribe(
|
||||
(newSettings) => {
|
||||
this.toolbarColor = newSettings.colorClasses.toolbar;
|
||||
}
|
||||
);
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
collapse()
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to config changes
|
||||
this._fuseConfigService.config
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(
|
||||
(config) => {
|
||||
this.fuseConfig = config;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Collapse
|
||||
*/
|
||||
collapse(): void
|
||||
{
|
||||
this.collapsed = true;
|
||||
}
|
||||
|
||||
expand()
|
||||
/**
|
||||
* Expand
|
||||
*/
|
||||
expand(): void
|
||||
{
|
||||
this.collapsed = false;
|
||||
}
|
||||
|
||||
search(event)
|
||||
/**
|
||||
* Search
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
search(event): void
|
||||
{
|
||||
const value = event.target.value;
|
||||
|
||||
this.onInput.emit(value);
|
||||
this.input.emit(event.target.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="shortcuts" fxHide fxShow.gt-sm [ngClass]="toolbarColor">
|
||||
<div class="shortcuts" fxHide fxShow.gt-sm>
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="space-between center" fxFlex="0 1 auto">
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { Component, ElementRef, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
|
||||
import { ObservableMedia } from '@angular/flex-layout';
|
||||
|
||||
import { Subscription } from 'rxjs';
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseMatchMediaService } from '@fuse/services/match-media.service';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-shortcuts',
|
||||
@@ -15,48 +14,67 @@ import { FuseConfigService } from '@fuse/services/config.service';
|
||||
})
|
||||
export class FuseShortcutsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
shortcutItems: any[] = [];
|
||||
shortcutItems: any[];
|
||||
navigationItems: any[];
|
||||
filteredNavigationItems: any[];
|
||||
searching = false;
|
||||
mobileShortcutsPanelActive = false;
|
||||
toolbarColor: string;
|
||||
matchMediaSubscription: Subscription;
|
||||
onConfigChanged: Subscription;
|
||||
searching: boolean;
|
||||
mobileShortcutsPanelActive: boolean;
|
||||
|
||||
@Input() navigation: any;
|
||||
@Input()
|
||||
navigation: any;
|
||||
|
||||
@ViewChild('searchInput') searchInputField;
|
||||
@ViewChild('shortcuts') shortcutsEl: ElementRef;
|
||||
@ViewChild('searchInput')
|
||||
searchInputField;
|
||||
|
||||
@ViewChild('shortcuts')
|
||||
shortcutsEl: ElementRef;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {Renderer2} _renderer
|
||||
* @param {CookieService} _cookieService
|
||||
* @param {FuseMatchMediaService} _fuseMatchMediaService
|
||||
* @param {FuseNavigationService} _fuseNavigationService
|
||||
* @param {ObservableMedia} _observableMedia
|
||||
*/
|
||||
constructor(
|
||||
private renderer: Renderer2,
|
||||
private observableMedia: ObservableMedia,
|
||||
private fuseMatchMedia: FuseMatchMediaService,
|
||||
private fuseNavigationService: FuseNavigationService,
|
||||
private fuseConfig: FuseConfigService,
|
||||
private cookieService: CookieService
|
||||
private _cookieService: CookieService,
|
||||
private _fuseMatchMediaService: FuseMatchMediaService,
|
||||
private _fuseNavigationService: FuseNavigationService,
|
||||
private _observableMedia: ObservableMedia,
|
||||
private _renderer: Renderer2
|
||||
)
|
||||
{
|
||||
this.onConfigChanged =
|
||||
this.fuseConfig.onConfigChanged
|
||||
.subscribe(
|
||||
(newSettings) => {
|
||||
this.toolbarColor = newSettings.colorClasses.toolbar;
|
||||
}
|
||||
);
|
||||
// Set the defaults
|
||||
this.shortcutItems = [];
|
||||
this.searching = false;
|
||||
this.mobileShortcutsPanelActive = false;
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Get the navigation items and flatten them
|
||||
this.filteredNavigationItems = this.navigationItems = this.fuseNavigationService.getFlatNavigation(this.navigation);
|
||||
this.filteredNavigationItems = this.navigationItems = this._fuseNavigationService.getFlatNavigation(this.navigation);
|
||||
|
||||
const cookieExists = this.cookieService.check('FUSE2.shortcuts');
|
||||
const cookieExists = this._cookieService.check('FUSE2.shortcuts');
|
||||
|
||||
if ( cookieExists )
|
||||
{
|
||||
this.shortcutItems = JSON.parse(this.cookieService.get('FUSE2.shortcuts'));
|
||||
this.shortcutItems = JSON.parse(this._cookieService.get('FUSE2.shortcuts'));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -64,46 +82,61 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy
|
||||
this.shortcutItems = [
|
||||
{
|
||||
'title': 'Calendar',
|
||||
'type' : 'nav-item',
|
||||
'type' : 'item',
|
||||
'icon' : 'today',
|
||||
'url' : '/apps/calendar'
|
||||
},
|
||||
{
|
||||
'title': 'Mail',
|
||||
'type' : 'nav-item',
|
||||
'type' : 'item',
|
||||
'icon' : 'email',
|
||||
'url' : '/apps/mail'
|
||||
},
|
||||
{
|
||||
'title': 'Contacts',
|
||||
'type' : 'nav-item',
|
||||
'type' : 'item',
|
||||
'icon' : 'account_box',
|
||||
'url' : '/apps/contacts'
|
||||
},
|
||||
{
|
||||
'title': 'To-Do',
|
||||
'type' : 'nav-item',
|
||||
'type' : 'item',
|
||||
'icon' : 'check_box',
|
||||
'url' : '/apps/todo'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
this.matchMediaSubscription =
|
||||
this.fuseMatchMedia.onMediaChange.subscribe(() => {
|
||||
if ( this.observableMedia.isActive('gt-sm') )
|
||||
this._fuseMatchMediaService.onMediaChange
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(() => {
|
||||
if ( this._observableMedia.isActive('gt-sm') )
|
||||
{
|
||||
this.hideMobileShortcutsPanel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
this.matchMediaSubscription.unsubscribe();
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
search(event)
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Search
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
search(event): void
|
||||
{
|
||||
const value = event.target.value.toLowerCase();
|
||||
|
||||
@@ -122,7 +155,13 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy
|
||||
});
|
||||
}
|
||||
|
||||
toggleShortcut(event, itemToToggle)
|
||||
/**
|
||||
* Toggle shortcut
|
||||
*
|
||||
* @param event
|
||||
* @param itemToToggle
|
||||
*/
|
||||
toggleShortcut(event, itemToToggle): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
|
||||
@@ -133,7 +172,7 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy
|
||||
this.shortcutItems.splice(i, 1);
|
||||
|
||||
// Save to the cookies
|
||||
this.cookieService.set('FUSE2.shortcuts', JSON.stringify(this.shortcutItems));
|
||||
this._cookieService.set('FUSE2.shortcuts', JSON.stringify(this.shortcutItems));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -142,32 +181,47 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy
|
||||
this.shortcutItems.push(itemToToggle);
|
||||
|
||||
// Save to the cookies
|
||||
this.cookieService.set('FUSE2.shortcuts', JSON.stringify(this.shortcutItems));
|
||||
this._cookieService.set('FUSE2.shortcuts', JSON.stringify(this.shortcutItems));
|
||||
}
|
||||
|
||||
isInShortcuts(navigationItem)
|
||||
/**
|
||||
* Is in shortcuts?
|
||||
*
|
||||
* @param navigationItem
|
||||
* @returns {any}
|
||||
*/
|
||||
isInShortcuts(navigationItem): any
|
||||
{
|
||||
return this.shortcutItems.find(item => {
|
||||
return item.url === navigationItem.url;
|
||||
});
|
||||
}
|
||||
|
||||
onMenuOpen()
|
||||
/**
|
||||
* On menu open
|
||||
*/
|
||||
onMenuOpen(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.searchInputField.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
|
||||
showMobileShortcutsPanel()
|
||||
/**
|
||||
* Show mobile shortcuts
|
||||
*/
|
||||
showMobileShortcutsPanel(): void
|
||||
{
|
||||
this.mobileShortcutsPanelActive = true;
|
||||
this.renderer.addClass(this.shortcutsEl.nativeElement, 'show-mobile-panel');
|
||||
this._renderer.addClass(this.shortcutsEl.nativeElement, 'show-mobile-panel');
|
||||
}
|
||||
|
||||
hideMobileShortcutsPanel()
|
||||
/**
|
||||
* Hide mobile shortcuts
|
||||
*/
|
||||
hideMobileShortcutsPanel(): void
|
||||
{
|
||||
this.mobileShortcutsPanelActive = false;
|
||||
this.renderer.removeClass(this.shortcutsEl.nativeElement, 'show-mobile-panel');
|
||||
this._renderer.removeClass(this.shortcutsEl.nativeElement, 'show-mobile-panel');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,17 +11,15 @@ fuse-sidebar {
|
||||
min-width: 280px;
|
||||
max-width: 280px;
|
||||
z-index: 1000;
|
||||
transition-property: transform, width, min-width, max-width;
|
||||
transition-duration: 150ms;
|
||||
transition-timing-function: ease-in-out;
|
||||
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.35);
|
||||
background: white;
|
||||
|
||||
&.left-aligned {
|
||||
&.left-positioned {
|
||||
left: 0;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
&.right-aligned {
|
||||
&.right-positioned {
|
||||
right: 0;
|
||||
transform: translateX(100%);
|
||||
}
|
||||
@@ -46,6 +44,12 @@ fuse-sidebar {
|
||||
max-width: 64px;
|
||||
}
|
||||
}
|
||||
|
||||
&.animations-enabled {
|
||||
transition-property: transform, width, min-width, max-width;
|
||||
transition-duration: 150ms;
|
||||
transition-timing-function: ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
.fuse-sidebar-overlay {
|
||||
@@ -54,7 +58,11 @@ fuse-sidebar {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 3;
|
||||
z-index: 999;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
opacity: 0;
|
||||
|
||||
&.fuse-sidebar-overlay-invisible {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Component, ElementRef, HostBinding, HostListener, Input, OnDestroy, OnInit, Renderer2, ViewEncapsulation } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, ElementRef, HostBinding, HostListener, Input, OnDestroy, OnInit, Renderer2, RendererStyleFlags2, ViewEncapsulation } from '@angular/core';
|
||||
import { animate, AnimationBuilder, AnimationPlayer, style } from '@angular/animations';
|
||||
import { ObservableMedia } from '@angular/flex-layout';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import { FuseSidebarService } from './sidebar.service';
|
||||
import { FuseMatchMediaService } from '@fuse/services/match-media.service';
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
import { takeUntil } from 'rxjs/internal/operators';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-sidebar',
|
||||
@@ -19,9 +20,9 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
@Input()
|
||||
name: string;
|
||||
|
||||
// Align
|
||||
// Position
|
||||
@Input()
|
||||
align: 'left' | 'right';
|
||||
position: 'left' | 'right';
|
||||
|
||||
// Open
|
||||
@HostBinding('class.open')
|
||||
@@ -35,6 +36,63 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
@HostBinding('class.locked-open')
|
||||
isLockedOpen: boolean;
|
||||
|
||||
// Folded unfolded
|
||||
@HostBinding('class.unfolded')
|
||||
unfolded: boolean;
|
||||
|
||||
// Invisible overlay
|
||||
@Input()
|
||||
invisibleOverlay: boolean;
|
||||
|
||||
// Private
|
||||
private _folded: boolean;
|
||||
private _fuseConfig: any;
|
||||
private _wasActive: boolean;
|
||||
private _backdrop: HTMLElement | null = null;
|
||||
private _player: AnimationPlayer;
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
@HostBinding('class.animations-enabled')
|
||||
private _animationsEnabled: boolean;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {AnimationBuilder} _animationBuilder
|
||||
* @param {ChangeDetectorRef} _changeDetectorRef
|
||||
* @param {ElementRef} _elementRef
|
||||
* @param {FuseConfigService} _fuseConfigService
|
||||
* @param {FuseMatchMediaService} _fuseMatchMediaService
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
* @param {ObservableMedia} _observableMedia
|
||||
* @param {Renderer2} _renderer
|
||||
*/
|
||||
constructor(
|
||||
private _animationBuilder: AnimationBuilder,
|
||||
private _changeDetectorRef: ChangeDetectorRef,
|
||||
private _elementRef: ElementRef,
|
||||
private _fuseConfigService: FuseConfigService,
|
||||
private _fuseMatchMediaService: FuseMatchMediaService,
|
||||
private _fuseSidebarService: FuseSidebarService,
|
||||
private _observableMedia: ObservableMedia,
|
||||
private _renderer: Renderer2
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.folded = false;
|
||||
this.opened = false;
|
||||
this.position = 'left';
|
||||
this.invisibleOverlay = false;
|
||||
|
||||
// Set the private defaults
|
||||
this._animationsEnabled = false;
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// Folded
|
||||
@HostBinding('class.folded')
|
||||
@Input()
|
||||
@@ -50,22 +108,22 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
this._folded = value;
|
||||
|
||||
// Programmatically add/remove margin to the element
|
||||
// that comes after or before based on the alignment
|
||||
// that comes after or before based on the position
|
||||
let sibling,
|
||||
styleRule;
|
||||
|
||||
const styleValue = '64px';
|
||||
|
||||
// Get the sibling and set the style rule
|
||||
if ( this.align === 'left' )
|
||||
if ( this.position === 'left' )
|
||||
{
|
||||
sibling = this.elementRef.nativeElement.nextElementSibling;
|
||||
styleRule = 'marginLeft';
|
||||
sibling = this._elementRef.nativeElement.nextElementSibling;
|
||||
styleRule = 'margin-left';
|
||||
}
|
||||
else
|
||||
{
|
||||
sibling = this.elementRef.nativeElement.previousElementSibling;
|
||||
styleRule = 'marginRight';
|
||||
sibling = this._elementRef.nativeElement.previousElementSibling;
|
||||
styleRule = 'margin-right';
|
||||
}
|
||||
|
||||
// If there is no sibling, return...
|
||||
@@ -78,13 +136,13 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
if ( value )
|
||||
{
|
||||
// Set the style
|
||||
this.renderer.setStyle(sibling, styleRule, styleValue);
|
||||
this._renderer.setStyle(sibling, styleRule, styleValue, RendererStyleFlags2.Important + RendererStyleFlags2.DashCase);
|
||||
}
|
||||
// If unfolded...
|
||||
else
|
||||
{
|
||||
// Remove the style
|
||||
this.renderer.removeStyle(sibling, styleRule);
|
||||
this._renderer.removeStyle(sibling, styleRule);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,54 +151,30 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
return this._folded;
|
||||
}
|
||||
|
||||
// Folded unfolded
|
||||
@HostBinding('class.unfolded')
|
||||
unfolded: boolean;
|
||||
|
||||
// Private
|
||||
private _folded: boolean;
|
||||
private _wasActive: boolean;
|
||||
private _backdrop: HTMLElement | null = null;
|
||||
private _player: AnimationPlayer;
|
||||
private _onMediaChangeSubscription: Subscription;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {Renderer2} renderer
|
||||
* @param {ElementRef} elementRef
|
||||
* @param {AnimationBuilder} animationBuilder
|
||||
* @param {ObservableMedia} observableMedia
|
||||
* @param {FuseConfigService} fuseConfigService
|
||||
* @param {FuseSidebarService} fuseSidebarService
|
||||
* @param {FuseMatchMediaService} fuseMatchMediaService
|
||||
*/
|
||||
constructor(
|
||||
private renderer: Renderer2,
|
||||
private elementRef: ElementRef,
|
||||
private animationBuilder: AnimationBuilder,
|
||||
private observableMedia: ObservableMedia,
|
||||
private fuseConfigService: FuseConfigService,
|
||||
private fuseSidebarService: FuseSidebarService,
|
||||
private fuseMatchMediaService: FuseMatchMediaService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.opened = false;
|
||||
this.folded = false;
|
||||
this.align = 'left';
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Register the sidebar
|
||||
this.fuseSidebarService.register(this.name, this);
|
||||
// Subscribe to config changes
|
||||
this._fuseConfigService.config
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((config) => {
|
||||
this._fuseConfig = config;
|
||||
});
|
||||
|
||||
// Setup alignment
|
||||
this._setupAlignment();
|
||||
// Register the sidebar
|
||||
this._fuseSidebarService.register(this.name, this);
|
||||
|
||||
// Setup visibility
|
||||
this._setupVisibility();
|
||||
|
||||
// Setup position
|
||||
this._setupPosition();
|
||||
|
||||
// Setup lockedOpen
|
||||
this._setupLockedOpen();
|
||||
@@ -158,28 +192,47 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
}
|
||||
|
||||
// Unregister the sidebar
|
||||
this.fuseSidebarService.unregister(this.name);
|
||||
this._fuseSidebarService.unregister(this.name);
|
||||
|
||||
// Unsubscribe from the media watcher subscription
|
||||
this._onMediaChangeSubscription.unsubscribe();
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the sidebar alignment
|
||||
* Setup the visibility of the sidebar
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _setupAlignment(): void
|
||||
private _setupVisibility(): void
|
||||
{
|
||||
// Remove the existing box-shadow
|
||||
this._renderer.setStyle(this._elementRef.nativeElement, 'box-shadow', 'none');
|
||||
|
||||
// Make the sidebar invisible
|
||||
this._renderer.setStyle(this._elementRef.nativeElement, 'visibility', 'hidden');
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the sidebar position
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _setupPosition(): void
|
||||
{
|
||||
// Add the correct class name to the sidebar
|
||||
// element depending on the align attribute
|
||||
if ( this.align === 'right' )
|
||||
// element depending on the position attribute
|
||||
if ( this.position === 'right' )
|
||||
{
|
||||
this.renderer.addClass(this.elementRef.nativeElement, 'right-aligned');
|
||||
this._renderer.addClass(this._elementRef.nativeElement, 'right-positioned');
|
||||
}
|
||||
else
|
||||
{
|
||||
this.renderer.addClass(this.elementRef.nativeElement, 'left-aligned');
|
||||
this._renderer.addClass(this._elementRef.nativeElement, 'left-positioned');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,19 +246,23 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
// Return if the lockedOpen wasn't set
|
||||
if ( !this.lockedOpen )
|
||||
{
|
||||
// Return
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the wasActive for the first time
|
||||
this._wasActive = false;
|
||||
|
||||
// Act on every media change
|
||||
this._onMediaChangeSubscription =
|
||||
// Show the sidebar
|
||||
this._showSidebar();
|
||||
|
||||
this.fuseMatchMediaService.onMediaChange.subscribe(() => {
|
||||
// Act on every media change
|
||||
this._fuseMatchMediaService.onMediaChange
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(() => {
|
||||
|
||||
// Get the active status
|
||||
const isActive = this.observableMedia.isActive(this.lockedOpen);
|
||||
const isActive = this._observableMedia.isActive(this.lockedOpen);
|
||||
|
||||
// If the both status are the same, don't act
|
||||
if ( this._wasActive === isActive )
|
||||
@@ -219,18 +276,21 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
// Set the lockedOpen status
|
||||
this.isLockedOpen = true;
|
||||
|
||||
// Show the sidebar
|
||||
this._showSidebar();
|
||||
|
||||
// Force the the opened status to true
|
||||
this.opened = true;
|
||||
|
||||
// Read the folded setting from the config
|
||||
// and fold the sidebar if it's true
|
||||
if ( this.fuseConfigService.config.layout.navigationFolded )
|
||||
if ( this._fuseConfig.layout.navbar.folded )
|
||||
{
|
||||
this.fold();
|
||||
}
|
||||
|
||||
// Hide the backdrop if any exists
|
||||
this.hideBackdrop();
|
||||
this._hideBackdrop();
|
||||
}
|
||||
// De-Activate the lockedOpen
|
||||
else
|
||||
@@ -243,6 +303,9 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
|
||||
// Force the the opened status to close
|
||||
this.opened = false;
|
||||
|
||||
// Hide the sidebar
|
||||
this._hideSidebar();
|
||||
}
|
||||
|
||||
// Store the new active status
|
||||
@@ -250,6 +313,152 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the backdrop
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _showBackdrop(): void
|
||||
{
|
||||
// Create the backdrop element
|
||||
this._backdrop = this._renderer.createElement('div');
|
||||
|
||||
// Add a class to the backdrop element
|
||||
this._backdrop.classList.add('fuse-sidebar-overlay');
|
||||
|
||||
// Add a class depending on the invisibleOverlay option
|
||||
if ( this.invisibleOverlay )
|
||||
{
|
||||
this._backdrop.classList.add('fuse-sidebar-overlay-invisible');
|
||||
}
|
||||
|
||||
// Append the backdrop to the parent of the sidebar
|
||||
this._renderer.appendChild(this._elementRef.nativeElement.parentElement, this._backdrop);
|
||||
|
||||
// Create the enter animation and attach it to the player
|
||||
this._player =
|
||||
this._animationBuilder
|
||||
.build([
|
||||
animate('300ms ease', style({opacity: 1}))
|
||||
]).create(this._backdrop);
|
||||
|
||||
// Play the animation
|
||||
this._player.play();
|
||||
|
||||
// Add an event listener to the overlay
|
||||
this._backdrop.addEventListener('click', () => {
|
||||
this.close();
|
||||
}
|
||||
);
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the backdrop
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _hideBackdrop(): void
|
||||
{
|
||||
if ( !this._backdrop )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the leave animation and attach it to the player
|
||||
this._player =
|
||||
this._animationBuilder
|
||||
.build([
|
||||
animate('300ms ease', style({opacity: 0}))
|
||||
]).create(this._backdrop);
|
||||
|
||||
// Play the animation
|
||||
this._player.play();
|
||||
|
||||
// Once the animation is done...
|
||||
this._player.onDone(() => {
|
||||
|
||||
// If the backdrop still exists...
|
||||
if ( this._backdrop )
|
||||
{
|
||||
// Remove the backdrop
|
||||
this._backdrop.parentNode.removeChild(this._backdrop);
|
||||
this._backdrop = null;
|
||||
}
|
||||
});
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change some properties of the sidebar
|
||||
* and make it visible
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _showSidebar(): void
|
||||
{
|
||||
// Remove the box-shadow style
|
||||
this._renderer.removeStyle(this._elementRef.nativeElement, 'box-shadow');
|
||||
|
||||
// Make the sidebar invisible
|
||||
this._renderer.removeStyle(this._elementRef.nativeElement, 'visibility');
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change some properties of the sidebar
|
||||
* and make it invisible
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _hideSidebar(delay = true): void
|
||||
{
|
||||
const delayAmount = delay ? 300 : 0;
|
||||
|
||||
// Add a delay so close animation can play
|
||||
setTimeout(() => {
|
||||
|
||||
// Remove the box-shadow
|
||||
this._renderer.setStyle(this._elementRef.nativeElement, 'box-shadow', 'none');
|
||||
|
||||
// Make the sidebar invisible
|
||||
this._renderer.setStyle(this._elementRef.nativeElement, 'visibility', 'hidden');
|
||||
}, delayAmount);
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the animations
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _enableAnimations(): void
|
||||
{
|
||||
// Return if animations already enabled
|
||||
if ( this._animationsEnabled )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable the animations
|
||||
this._animationsEnabled = true;
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Open the sidebar
|
||||
*/
|
||||
@@ -260,11 +469,20 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable the animations
|
||||
this._enableAnimations();
|
||||
|
||||
// Show the sidebar
|
||||
this._showSidebar();
|
||||
|
||||
// Show the backdrop
|
||||
this.showBackdrop();
|
||||
this._showBackdrop();
|
||||
|
||||
// Set the opened status
|
||||
this.opened = true;
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,11 +495,20 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable the animations
|
||||
this._enableAnimations();
|
||||
|
||||
// Hide the backdrop
|
||||
this.hideBackdrop();
|
||||
this._hideBackdrop();
|
||||
|
||||
// Set the opened status
|
||||
this.opened = false;
|
||||
|
||||
// Hide the sidebar
|
||||
this._hideSidebar();
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,8 +538,14 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable the animations
|
||||
this._enableAnimations();
|
||||
|
||||
// Unfold the sidebar temporarily
|
||||
this.unfolded = true;
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -327,8 +560,14 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable the animations
|
||||
this._enableAnimations();
|
||||
|
||||
// Fold the sidebar back
|
||||
this.unfolded = false;
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,8 +581,14 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable the animations
|
||||
this._enableAnimations();
|
||||
|
||||
// Fold
|
||||
this.folded = true;
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,8 +602,14 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable the animations
|
||||
this._enableAnimations();
|
||||
|
||||
// Unfold
|
||||
this.folded = false;
|
||||
|
||||
// Mark for check
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -375,68 +626,4 @@ export class FuseSidebarComponent implements OnInit, OnDestroy
|
||||
this.fold();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the backdrop
|
||||
*/
|
||||
showBackdrop(): void
|
||||
{
|
||||
// Create the backdrop element
|
||||
this._backdrop = this.renderer.createElement('div');
|
||||
|
||||
// Add a class to the backdrop element
|
||||
this._backdrop.classList.add('fuse-sidebar-overlay');
|
||||
|
||||
// Append the backdrop to the parent of the sidebar
|
||||
this.renderer.appendChild(this.elementRef.nativeElement.parentElement, this._backdrop);
|
||||
|
||||
// Create the enter animation and attach it to the player
|
||||
this._player =
|
||||
this.animationBuilder
|
||||
.build([
|
||||
animate('300ms ease', style({opacity: 1}))
|
||||
]).create(this._backdrop);
|
||||
|
||||
// Play the animation
|
||||
this._player.play();
|
||||
|
||||
// Add an event listener to the overlay
|
||||
this._backdrop.addEventListener('click', () => {
|
||||
this.close();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the backdrop
|
||||
*/
|
||||
hideBackdrop(): void
|
||||
{
|
||||
if ( !this._backdrop )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the leave animation and attach it to the player
|
||||
this._player =
|
||||
this.animationBuilder
|
||||
.build([
|
||||
animate('300ms ease', style({opacity: 0}))
|
||||
]).create(this._backdrop);
|
||||
|
||||
// Play the animation
|
||||
this._player.play();
|
||||
|
||||
// Once the animation is done...
|
||||
this._player.onDone(() => {
|
||||
|
||||
// If the backdrop still exists...
|
||||
if ( this._backdrop )
|
||||
{
|
||||
// Remove the backdrop
|
||||
this._backdrop.parentNode.removeChild(this._backdrop);
|
||||
this._backdrop = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,105 +1,372 @@
|
||||
<button #openButton mat-icon-button class="open-button mat-primary-bg mat-elevation-z2" (click)="openBar()">
|
||||
<mat-icon>settings</mat-icon>
|
||||
</button>
|
||||
<div class="theme-options-panel" fusePerfectScrollbar>
|
||||
|
||||
<div class="theme-options-panel-overlay" #overlay [fxHide]="barClosed" [@fadeInOut]="!barClosed"></div>
|
||||
<div class="header">
|
||||
|
||||
<div #panel class="theme-options-panel mat-white-bg mat-elevation-z8">
|
||||
<span class="title">Theme Options</span>
|
||||
|
||||
<button mat-icon-button class="close-button" (click)="closeBar()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button class="close-button" (click)="toggleSidebarOpen('themeOptionsPanel')">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="theme-options-panel-inner" fxLayout="column" fxLayoutAlign="start start">
|
||||
</div>
|
||||
|
||||
<h3>Navigation:</h3>
|
||||
<mat-radio-group [(ngModel)]="config.layout.navigation" (ngModelChange)="onSettingsChange()"
|
||||
fxLayout="column" fxLayout.gt-xs="row wrap" fxLayoutAlign="start start">
|
||||
<mat-radio-button class="mr-8 mb-8" value="top">Top</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="left">Left</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="right">Right</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="none">None</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<form [formGroup]="form">
|
||||
|
||||
<h3>Navigation Fold (for vertical navigation):</h3>
|
||||
<mat-slide-toggle [(ngModel)]="config.layout.navigationFolded"
|
||||
(change)="onSettingsChange()">
|
||||
Folded
|
||||
</mat-slide-toggle>
|
||||
<!-- LAYOUT STYLES -->
|
||||
<div class="group" formGroupName="layout">
|
||||
|
||||
<h3 class="mt-24">Toolbar:</h3>
|
||||
<mat-radio-group [(ngModel)]="config.layout.toolbar" (ngModelChange)="onSettingsChange()"
|
||||
fxLayout="column" fxLayout.gt-xs="row wrap" fxLayoutAlign="start start">
|
||||
<mat-radio-button class="mr-8 mb-8" value="below">Below</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="above">Above</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="none">None</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<h2>Layout Styles</h2>
|
||||
|
||||
<h3 class="mt-24">Footer:</h3>
|
||||
<mat-radio-group [(ngModel)]="config.layout.footer" (ngModelChange)="onSettingsChange()"
|
||||
fxLayout="column" fxLayout.gt-xs="row wrap" fxLayoutAlign="start start">
|
||||
<mat-radio-button class="mr-8 mb-8" value="below">Below</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="above">Above</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="none">None</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="style">
|
||||
|
||||
<h3 class="mt-24">Layout Mode:</h3>
|
||||
<mat-radio-group [(ngModel)]="config.layout.mode" (ngModelChange)="onSettingsChange()"
|
||||
fxLayout="column" fxLayout.gt-xs="row wrap" fxLayoutAlign="start start">
|
||||
<mat-radio-button class="mr-8 mb-8" value="boxed">Boxed</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="fullwidth">Fullwidth</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<mat-radio-button class="mb-12" value="vertical-layout-1">
|
||||
Vertical Layout #1
|
||||
</mat-radio-button>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
<mat-radio-button class="mb-12" value="vertical-layout-2">
|
||||
Vertical Layout #2
|
||||
</mat-radio-button>
|
||||
|
||||
<h3>Colors:</h3>
|
||||
<div class="colors">
|
||||
<mat-radio-button class="mb-12" value="vertical-layout-3">
|
||||
Vertical Layout #3
|
||||
</mat-radio-button>
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<h4 class="mr-8">Toolbar Color</h4>
|
||||
<fuse-material-color-picker [(selectedClass)]="config.colorClasses.toolbar"
|
||||
(onValueChange)="onSettingsChange()"></fuse-material-color-picker>
|
||||
</div>
|
||||
<mat-radio-button class="mb-12" value="horizontal-layout-1">
|
||||
Horizontal Layout #1
|
||||
</mat-radio-button>
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<h4 class="mr-8">Navigation Bar Color</h4>
|
||||
<fuse-material-color-picker [(selectedClass)]="config.colorClasses.navbar"
|
||||
(onValueChange)="onSettingsChange()"></fuse-material-color-picker>
|
||||
</div>
|
||||
</mat-radio-group>
|
||||
|
||||
<!-- DIFFERENT FORMS BASED ON LAYOUT STYLES -->
|
||||
<ng-container [ngSwitch]="fuseConfig.layout.style">
|
||||
|
||||
<!-- VERTICAL LAYOUT #1 -->
|
||||
<ng-container *ngSwitchCase="'vertical-layout-1'">
|
||||
|
||||
<!-- LAYOUT WIDTH -->
|
||||
<div class="group mt-32">
|
||||
|
||||
<h2>Layout Width</h2>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="width">
|
||||
<mat-radio-button class="mb-12" value="fullwidth">Fullwidth</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="boxed">Boxed</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- NAVBAR -->
|
||||
<div class="group" formGroupName="navbar">
|
||||
|
||||
<h2>Navbar</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-slide-toggle class="mt-24" formControlName="folded">
|
||||
Folded
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-16" value="left">Left</mat-radio-button>
|
||||
<mat-radio-button class="mb-16" value="right">Right</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- TOOLBAR -->
|
||||
<div class="group" formGroupName="toolbar">
|
||||
|
||||
<h2>Toolbar</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-12" value="above">Above</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="below-static">Below Static</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="below-fixed">Below Fixed</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<div class="group" formGroupName="footer">
|
||||
|
||||
<h2>Footer</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-12" value="above">Above</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="below-static">Below Static</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="below-fixed">Below Fixed</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<!-- VERTICAL LAYOUT #2 -->
|
||||
<ng-container *ngSwitchCase="'vertical-layout-2'">
|
||||
|
||||
<!-- LAYOUT WIDTH -->
|
||||
<div class="group mt-32">
|
||||
|
||||
<h2>Layout Width</h2>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="width">
|
||||
<mat-radio-button class="mb-12" value="fullwidth">Fullwidth</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="boxed">Boxed</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- NAVBAR -->
|
||||
<div class="group" formGroupName="navbar">
|
||||
|
||||
<h2>Navbar</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-slide-toggle class="mt-24" formControlName="folded">
|
||||
Folded
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-16" value="left">Left</mat-radio-button>
|
||||
<mat-radio-button class="mb-16" value="right">Right</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- TOOLBAR -->
|
||||
<div class="group" formGroupName="toolbar">
|
||||
|
||||
<h2>Toolbar</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-12" value="above-static">Above Static</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="above-fixed">Above Fixed</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="below">Below</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<div class="group" formGroupName="footer">
|
||||
|
||||
<h2>Footer</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-12" value="above-static">Above Static</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="above-fixed">Above Fixed</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="below">Below</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<!-- VERTICAL LAYOUT #3 -->
|
||||
<ng-container *ngSwitchCase="'vertical-layout-3'">
|
||||
|
||||
<!-- LAYOUT WIDTH -->
|
||||
<div class="group mt-32">
|
||||
|
||||
<h2>Layout Width</h2>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="width">
|
||||
<mat-radio-button class="mb-12" value="fullwidth">Fullwidth</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="boxed">Boxed</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- NAVBAR -->
|
||||
<div class="group" formGroupName="navbar">
|
||||
|
||||
<h2>Navbar</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-slide-toggle class="mt-24" formControlName="folded">
|
||||
Folded
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-16" value="left">Left</mat-radio-button>
|
||||
<mat-radio-button class="mb-16" value="right">Right</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- TOOLBAR -->
|
||||
<div class="group" formGroupName="toolbar">
|
||||
|
||||
<h2>Toolbar</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-12" value="above-static">Above Static</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="above-fixed">Above Fixed</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<div class="group" formGroupName="footer">
|
||||
|
||||
<h2>Footer</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-12" value="above-static">Above Static</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="above-fixed">Above Fixed</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<!-- HORIZONTAL LAYOUT #1 -->
|
||||
<ng-container *ngSwitchCase="'horizontal-layout-1'">
|
||||
|
||||
<!-- LAYOUT WIDTH -->
|
||||
<div class="group mt-32">
|
||||
|
||||
<h2>Layout Width</h2>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="width">
|
||||
<mat-radio-button class="mb-12" value="fullwidth">Fullwidth</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="boxed">Boxed</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- NAVBAR -->
|
||||
<div class="group" formGroupName="navbar">
|
||||
|
||||
<h2>Navbar</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-16" value="top">Top</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- TOOLBAR -->
|
||||
<div class="group" formGroupName="toolbar">
|
||||
|
||||
<h2>Toolbar</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-12" value="above">Above</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="below">Below</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<div class="group" formGroupName="footer">
|
||||
|
||||
<h2>Footer</h2>
|
||||
|
||||
<mat-slide-toggle formControlName="hidden">
|
||||
Hide
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Position:</h3>
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
|
||||
<mat-radio-button class="mb-12" value="above-fixed">Above Fixed</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="above-static">Above Static</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- CUSTOM SCROLLBARS -->
|
||||
<div class="group">
|
||||
|
||||
<h2>Custom scrollbars</h2>
|
||||
|
||||
<mat-slide-toggle class="mb-12" formControlName="customScrollbars">
|
||||
Enable custom scrollbars
|
||||
</mat-slide-toggle>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- COLORS -->
|
||||
<div class="group">
|
||||
|
||||
<h2>Colors</h2>
|
||||
|
||||
<div class="colors">
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<h4 class="mr-8">Toolbar Color</h4>
|
||||
<fuse-material-color-picker
|
||||
[(selectedClass)]="fuseConfig.layout.toolbar.background"></fuse-material-color-picker>
|
||||
</div>
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<h4 class="mr-8">Navbar Color</h4>
|
||||
<fuse-material-color-picker
|
||||
[(selectedClass)]="fuseConfig.layout.navbar.background"></fuse-material-color-picker>
|
||||
</div>
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<h4 class="mr-8">Footer Color</h4>
|
||||
<fuse-material-color-picker
|
||||
[(selectedClass)]="fuseConfig.layout.footer.background"></fuse-material-color-picker>
|
||||
</div>
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<h4 class="mr-8">Footer Color</h4>
|
||||
<fuse-material-color-picker [(selectedClass)]="config.colorClasses.footer"
|
||||
(onValueChange)="onSettingsChange()"></fuse-material-color-picker>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<h3>Router Animation:</h3>
|
||||
<mat-form-field class="w-100-p">
|
||||
<mat-select class="p-0" [(ngModel)]="config.routerAnimation">
|
||||
<mat-option value="none">
|
||||
None
|
||||
</mat-option>
|
||||
<mat-option value="slideUp">
|
||||
Slide up
|
||||
</mat-option>
|
||||
<mat-option value="slideDown">
|
||||
Slide down
|
||||
</mat-option>
|
||||
<mat-option value="slideRight">
|
||||
Slide right
|
||||
</mat-option>
|
||||
<mat-option value="slideLeft">
|
||||
Slide left
|
||||
</mat-option>
|
||||
<mat-option value="fadeIn">
|
||||
Fade in
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -10,106 +10,74 @@
|
||||
}
|
||||
|
||||
:host {
|
||||
position: fixed;
|
||||
display: block;
|
||||
right: 0;
|
||||
top: 160px;
|
||||
z-index: 998;
|
||||
|
||||
&.bar-closed .theme-options-panel {
|
||||
display: none;
|
||||
}
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
.theme-options-panel {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 360px;
|
||||
transform: translate3d(100%, 0, 0);
|
||||
z-index: 999;
|
||||
max-height: calc(100vh - 200px);
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 0 auto;
|
||||
padding: 40px 24px 24px 24px;
|
||||
overflow: auto;
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
top: -120px;
|
||||
max-height: calc(100vh - 100px);
|
||||
width: 90vw;
|
||||
.header {
|
||||
display: flex;
|
||||
flex: 0 1 auto;
|
||||
margin-bottom: 32px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
padding-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.close-button {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
}
|
||||
form {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-direction: column;
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
.group {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: 2px;
|
||||
padding: 28px 16px 8px 16px;
|
||||
margin: 16px 0;
|
||||
|
||||
.mat-divider {
|
||||
display: block !important;
|
||||
width: 100%;
|
||||
margin: 24px 0 16px 0;
|
||||
}
|
||||
h2 {
|
||||
position: absolute;
|
||||
top: -11px;
|
||||
left: 8px;
|
||||
margin: 0;
|
||||
padding: 0 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
background: white;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
.colors {
|
||||
display: block !important;
|
||||
width: 100%;
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
margin: 24px 0 16px 0;
|
||||
padding: 0;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.colors {
|
||||
display: block !important;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.theme-options-panel-overlay {
|
||||
position: fixed;
|
||||
display: block;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 998;
|
||||
|
||||
@include media-breakpoint-down('sm') {
|
||||
background: rgba(0, 0, 0, 0.37);
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-list .mat-list-item {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.mat-divider {
|
||||
margin: 16px;
|
||||
}
|
||||
|
||||
.open-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -48px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
pointer-events: auto;
|
||||
opacity: .75;
|
||||
z-index: 998;
|
||||
|
||||
mat-icon {
|
||||
animation: rotating 3s linear infinite;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Component, ElementRef, HostBinding, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
|
||||
import { style, animate, AnimationBuilder, AnimationPlayer } from '@angular/animations';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Component, HostBinding, OnDestroy, OnInit, Renderer2 } from '@angular/core';
|
||||
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-theme-options',
|
||||
@@ -14,50 +16,113 @@ import { FuseNavigationService } from '@fuse/components/navigation/navigation.se
|
||||
})
|
||||
export class FuseThemeOptionsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@Input() navigation;
|
||||
@ViewChild('openButton') openButton;
|
||||
@ViewChild('panel') panel;
|
||||
@ViewChild('overlay') overlay: ElementRef;
|
||||
fuseConfig: any;
|
||||
form: FormGroup;
|
||||
|
||||
public player: AnimationPlayer;
|
||||
config: any;
|
||||
@HostBinding('class.bar-closed')
|
||||
barClosed: boolean;
|
||||
|
||||
onConfigChanged: Subscription;
|
||||
|
||||
@HostBinding('class.bar-closed') barClosed: boolean;
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FormBuilder} _formBuilder
|
||||
* @param {FuseConfigService} _fuseConfigService
|
||||
* @param {FuseNavigationService} _fuseNavigationService
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
* @param {Renderer2} _renderer
|
||||
*/
|
||||
constructor(
|
||||
private animationBuilder: AnimationBuilder,
|
||||
private fuseConfig: FuseConfigService,
|
||||
private navigationService: FuseNavigationService,
|
||||
private renderer: Renderer2
|
||||
private _formBuilder: FormBuilder,
|
||||
private _fuseConfigService: FuseConfigService,
|
||||
private _fuseNavigationService: FuseNavigationService,
|
||||
private _fuseSidebarService: FuseSidebarService,
|
||||
private _renderer: Renderer2
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.barClosed = true;
|
||||
|
||||
this.onConfigChanged =
|
||||
this.fuseConfig.onConfigChanged
|
||||
.subscribe(
|
||||
(newConfig) => {
|
||||
this.config = newConfig;
|
||||
}
|
||||
);
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.renderer.listen(this.overlay.nativeElement, 'click', () => {
|
||||
this.closeBar();
|
||||
// Build the config form
|
||||
// noinspection TypeScriptValidateTypes
|
||||
this.form = this._formBuilder.group({
|
||||
layout : this._formBuilder.group({
|
||||
style : new FormControl(),
|
||||
width : new FormControl(),
|
||||
navbar : this._formBuilder.group({
|
||||
hidden : new FormControl(),
|
||||
position : new FormControl(),
|
||||
folded : new FormControl(),
|
||||
background: new FormControl()
|
||||
}),
|
||||
toolbar: this._formBuilder.group({
|
||||
hidden : new FormControl(),
|
||||
position : new FormControl(),
|
||||
background: new FormControl()
|
||||
}),
|
||||
footer : this._formBuilder.group({
|
||||
hidden : new FormControl(),
|
||||
position : new FormControl(),
|
||||
background: new FormControl()
|
||||
})
|
||||
}),
|
||||
customScrollbars: new FormControl()
|
||||
});
|
||||
|
||||
// Get the nav model and add customize nav item
|
||||
// that opens the bar programmatically
|
||||
const nav: any = this.navigation;
|
||||
// Subscribe to the config changes
|
||||
this._fuseConfigService.config
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((config) => {
|
||||
|
||||
nav.push({
|
||||
// Update the stored config
|
||||
this.fuseConfig = config;
|
||||
|
||||
// Set the config form values without emitting an event
|
||||
// so that we don't end up with an infinite loop
|
||||
this.form.setValue(config, {emitEvent: false});
|
||||
});
|
||||
|
||||
// Subscribe to the specific form value changes (layout.style)
|
||||
this.form.get('layout.style').valueChanges
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((value) => {
|
||||
|
||||
// Reset the form values based on the
|
||||
// selected layout style
|
||||
this._resetFormValues(value);
|
||||
|
||||
});
|
||||
|
||||
// Subscribe to the form value changes
|
||||
this.form.valueChanges
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((config) => {
|
||||
|
||||
// Update the config
|
||||
this._fuseConfigService.config = config;
|
||||
});
|
||||
|
||||
// Add customize nav item that opens the bar programmatically
|
||||
const customFunctionNavItem = {
|
||||
'id' : 'custom-function',
|
||||
'title' : 'Custom Function',
|
||||
'type' : 'group',
|
||||
'icon' : 'settings',
|
||||
'children': [
|
||||
{
|
||||
'id' : 'customize',
|
||||
@@ -65,50 +130,169 @@ export class FuseThemeOptionsComponent implements OnInit, OnDestroy
|
||||
'type' : 'item',
|
||||
'icon' : 'settings',
|
||||
'function': () => {
|
||||
this.openBar();
|
||||
this.toggleSidebarOpen('themeOptionsPanel');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
this._fuseNavigationService.addNavigationItem(customFunctionNavItem, 'end');
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
this.onConfigChanged.unsubscribe();
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
|
||||
// Remove the custom function menu
|
||||
this._fuseNavigationService.removeNavigationItem('custom-function');
|
||||
}
|
||||
|
||||
onSettingsChange()
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Reset the form values based on the
|
||||
* selected layout style
|
||||
*
|
||||
* @param value
|
||||
* @private
|
||||
*/
|
||||
private _resetFormValues(value): void
|
||||
{
|
||||
this.fuseConfig.setConfig(this.config);
|
||||
switch ( value )
|
||||
{
|
||||
// Vertical Layout #1
|
||||
case 'vertical-layout-1':
|
||||
{
|
||||
this.form.patchValue({
|
||||
layout: {
|
||||
width : 'fullwidth',
|
||||
navbar : {
|
||||
hidden : false,
|
||||
position : 'left',
|
||||
folded : false,
|
||||
background: 'mat-fuse-dark-700-bg'
|
||||
},
|
||||
toolbar: {
|
||||
hidden : false,
|
||||
position : 'below-static',
|
||||
background: 'mat-white-500-bg'
|
||||
},
|
||||
footer : {
|
||||
hidden : false,
|
||||
position : 'below-static',
|
||||
background: 'mat-fuse-dark-900-bg'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Vertical Layout #2
|
||||
case 'vertical-layout-2':
|
||||
{
|
||||
this.form.patchValue({
|
||||
layout: {
|
||||
width : 'fullwidth',
|
||||
navbar : {
|
||||
hidden : false,
|
||||
position : 'left',
|
||||
folded : false,
|
||||
background: 'mat-fuse-dark-700-bg'
|
||||
},
|
||||
toolbar: {
|
||||
hidden : false,
|
||||
position : 'below',
|
||||
background: 'mat-white-500-bg'
|
||||
},
|
||||
footer : {
|
||||
hidden : false,
|
||||
position : 'below',
|
||||
background: 'mat-fuse-dark-900-bg'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Vertical Layout #3
|
||||
case 'vertical-layout-3':
|
||||
{
|
||||
this.form.patchValue({
|
||||
layout: {
|
||||
width : 'fullwidth',
|
||||
navbar : {
|
||||
hidden : false,
|
||||
position : 'left',
|
||||
folded : false,
|
||||
background: 'mat-fuse-dark-700-bg'
|
||||
},
|
||||
toolbar: {
|
||||
hidden : false,
|
||||
position : 'above-static',
|
||||
background: 'mat-white-500-bg'
|
||||
},
|
||||
footer : {
|
||||
hidden : false,
|
||||
position : 'above-static',
|
||||
background: 'mat-fuse-dark-900-bg'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Horizontal Layout #1
|
||||
case 'horizontal-layout-1':
|
||||
{
|
||||
this.form.patchValue({
|
||||
layout: {
|
||||
width : 'fullwidth',
|
||||
navbar : {
|
||||
hidden : false,
|
||||
position : 'top',
|
||||
folded : false,
|
||||
background: 'mat-fuse-dark-700-bg'
|
||||
},
|
||||
toolbar: {
|
||||
hidden : false,
|
||||
position : 'above',
|
||||
background: 'mat-white-500-bg'
|
||||
},
|
||||
footer : {
|
||||
hidden : false,
|
||||
position : 'above-fixed',
|
||||
background: 'mat-fuse-dark-900-bg'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closeBar()
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle sidebar open
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
toggleSidebarOpen(key): void
|
||||
{
|
||||
this.player =
|
||||
this.animationBuilder
|
||||
.build([
|
||||
style({transform: 'translate3d(0,0,0)'}),
|
||||
animate('400ms ease', style({transform: 'translate3d(100%,0,0)'}))
|
||||
]).create(this.panel.nativeElement);
|
||||
|
||||
this.player.play();
|
||||
|
||||
this.player.onDone(() => {
|
||||
this.barClosed = true;
|
||||
});
|
||||
this._fuseSidebarService.getSidebar(key).toggleOpen();
|
||||
}
|
||||
|
||||
openBar()
|
||||
{
|
||||
this.barClosed = false;
|
||||
|
||||
this.player =
|
||||
this.animationBuilder
|
||||
.build([
|
||||
style({transform: 'translate3d(100%,0,0)'}),
|
||||
animate('400ms ease', style({transform: 'translate3d(0,0,0)'}))
|
||||
]).create(this.panel.nativeElement);
|
||||
|
||||
this.player.play();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { MatButtonModule, MatDividerModule, MatFormFieldModule, MatIconModule, MatOptionModule, MatRadioModule, MatSelectModule, MatSlideToggleModule } from '@angular/material';
|
||||
|
||||
import { FuseDirectivesModule } from '@fuse/directives/directives';
|
||||
import { FuseSidebarModule } from '@fuse/components/sidebar/sidebar.module';
|
||||
import { FuseMaterialColorPickerModule } from '@fuse/components/material-color-picker/material-color-picker.module';
|
||||
|
||||
import { FuseThemeOptionsComponent } from '@fuse/components/theme-options/theme-options.component';
|
||||
|
||||
@NgModule({
|
||||
@@ -14,6 +17,7 @@ import { FuseThemeOptionsComponent } from '@fuse/components/theme-options/theme-
|
||||
imports : [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
|
||||
FlexLayoutModule,
|
||||
|
||||
@@ -26,7 +30,9 @@ import { FuseThemeOptionsComponent } from '@fuse/components/theme-options/theme-
|
||||
MatSelectModule,
|
||||
MatSlideToggleModule,
|
||||
|
||||
FuseMaterialColorPickerModule
|
||||
FuseDirectivesModule,
|
||||
FuseMaterialColorPickerModule,
|
||||
FuseSidebarModule
|
||||
],
|
||||
exports : [
|
||||
FuseThemeOptionsComponent
|
||||
|
||||
@@ -5,7 +5,14 @@ import { Directive, ElementRef } from '@angular/core';
|
||||
})
|
||||
export class FuseWidgetToggleDirective
|
||||
{
|
||||
constructor(public el: ElementRef)
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ElementRef} elementRef
|
||||
*/
|
||||
constructor(
|
||||
public elementRef: ElementRef
|
||||
)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,19 +10,38 @@ import { FuseWidgetToggleDirective } from './widget-toggle.directive';
|
||||
|
||||
export class FuseWidgetComponent implements AfterContentInit
|
||||
{
|
||||
@HostBinding('class.flipped') flipped = false;
|
||||
@ContentChildren(FuseWidgetToggleDirective, {descendants: true}) toggleButtons: QueryList<FuseWidgetToggleDirective>;
|
||||
@HostBinding('class.flipped')
|
||||
flipped = false;
|
||||
|
||||
constructor(private el: ElementRef, private renderer: Renderer2)
|
||||
@ContentChildren(FuseWidgetToggleDirective, {descendants: true})
|
||||
toggleButtons: QueryList<FuseWidgetToggleDirective>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ElementRef} _elementRef
|
||||
* @param {Renderer2} _renderer
|
||||
*/
|
||||
constructor(
|
||||
private _elementRef: ElementRef,
|
||||
private _renderer: Renderer2
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
ngAfterContentInit()
|
||||
{
|
||||
setTimeout(() => {
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* After content init
|
||||
*/
|
||||
ngAfterContentInit(): void
|
||||
{
|
||||
// Listen for the flip button click
|
||||
setTimeout(() => {
|
||||
this.toggleButtons.forEach(flipButton => {
|
||||
this.renderer.listen(flipButton.el.nativeElement, 'click', (event) => {
|
||||
this._renderer.listen(flipButton.elementRef.nativeElement, 'click', (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.toggle();
|
||||
@@ -31,7 +50,14 @@ export class FuseWidgetComponent implements AfterContentInit
|
||||
});
|
||||
}
|
||||
|
||||
toggle()
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle the flipped status
|
||||
*/
|
||||
toggle(): void
|
||||
{
|
||||
this.flipped = !this.flipped;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { FuseIfOnDomDirective } from '@fuse/directives/fuse-if-on-dom/fuse-if-on-dom.directive';
|
||||
import { FuseInnerScrollDirective } from '@fuse/directives/fuse-inner-scroll/fuse-inner-scroll.directive';
|
||||
import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
||||
import { FuseMatSidenavHelperDirective, FuseMatSidenavTogglerDirective } from '@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.directive';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseIfOnDomDirective,
|
||||
FuseInnerScrollDirective,
|
||||
FuseMatSidenavHelperDirective,
|
||||
FuseMatSidenavTogglerDirective,
|
||||
FusePerfectScrollbarDirective
|
||||
@@ -14,6 +16,7 @@ import { FuseMatSidenavHelperDirective, FuseMatSidenavTogglerDirective } from '@
|
||||
imports : [],
|
||||
exports : [
|
||||
FuseIfOnDomDirective,
|
||||
FuseInnerScrollDirective,
|
||||
FuseMatSidenavHelperDirective,
|
||||
FuseMatSidenavTogglerDirective,
|
||||
FusePerfectScrollbarDirective
|
||||
|
||||
@@ -5,28 +5,44 @@ import { AfterContentChecked, Directive, ElementRef, TemplateRef, ViewContainerR
|
||||
})
|
||||
export class FuseIfOnDomDirective implements AfterContentChecked
|
||||
{
|
||||
isCreated = false;
|
||||
isCreated: boolean;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ElementRef} _elementRef
|
||||
* @param {TemplateRef<any>} _templateRef
|
||||
* @param {ViewContainerRef} _viewContainerRef
|
||||
*/
|
||||
constructor(
|
||||
private templateRef: TemplateRef<any>,
|
||||
private viewContainer: ViewContainerRef,
|
||||
private element: ElementRef
|
||||
private _elementRef: ElementRef,
|
||||
private _templateRef: TemplateRef<any>,
|
||||
private _viewContainerRef: ViewContainerRef
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.isCreated = false;
|
||||
}
|
||||
|
||||
ngAfterContentChecked()
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* After content checked
|
||||
*/
|
||||
ngAfterContentChecked(): void
|
||||
{
|
||||
if ( document.body.contains(this.element.nativeElement) && !this.isCreated )
|
||||
if ( document.body.contains(this._elementRef.nativeElement) && !this.isCreated )
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.viewContainer.createEmbeddedView(this.templateRef);
|
||||
this._viewContainerRef.createEmbeddedView(this._templateRef);
|
||||
}, 300);
|
||||
this.isCreated = true;
|
||||
}
|
||||
else if ( this.isCreated && !document.body.contains(this.element.nativeElement) )
|
||||
else if ( this.isCreated && !document.body.contains(this._elementRef.nativeElement) )
|
||||
{
|
||||
this.viewContainer.clear();
|
||||
this._viewContainerRef.clear();
|
||||
this.isCreated = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
import { Directive, ElementRef, OnDestroy, OnInit, Renderer2 } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseMatchMediaService } from '@fuse/services/match-media.service';
|
||||
|
||||
@Directive({
|
||||
selector: '.inner-scroll'
|
||||
})
|
||||
export class FuseInnerScrollDirective implements OnInit, OnDestroy
|
||||
{
|
||||
// Private
|
||||
private _parent: any;
|
||||
private _grandParent: any;
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ElementRef} _elementRef
|
||||
* @param {FuseMatchMediaService} _fuseMediaMatchService
|
||||
* @param {Renderer2} _renderer
|
||||
*/
|
||||
constructor(
|
||||
private _elementRef: ElementRef,
|
||||
private _fuseMediaMatchService: FuseMatchMediaService,
|
||||
private _renderer: Renderer2
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Get the parent
|
||||
this._parent = this._renderer.parentNode(this._elementRef.nativeElement);
|
||||
|
||||
// Return, if there is no parent
|
||||
if ( !this._parent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the grand parent
|
||||
this._grandParent = this._renderer.parentNode(this._parent);
|
||||
|
||||
// Register to the media query changes
|
||||
this._fuseMediaMatchService.onMediaChange
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((alias) => {
|
||||
|
||||
if ( alias === 'xs' )
|
||||
{
|
||||
this._removeClass();
|
||||
}
|
||||
else
|
||||
{
|
||||
this._addClass();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Return, if there is no parent
|
||||
if ( !this._parent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the class
|
||||
this._removeClass();
|
||||
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Add the class name
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _addClass(): void
|
||||
{
|
||||
// Add the inner-scroll class
|
||||
this._renderer.addClass(this._grandParent, 'inner-scroll');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the class name
|
||||
* @private
|
||||
*/
|
||||
private _removeClass(): void
|
||||
{
|
||||
|
||||
// Remove the inner-scroll class
|
||||
this._renderer.removeClass(this._grandParent, 'inner-scroll');
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Directive, Input, OnInit, HostListener, OnDestroy, HostBinding } from '@angular/core';
|
||||
import { MatSidenav } from '@angular/material';
|
||||
import { ObservableMedia } from '@angular/flex-layout';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseMatchMediaService } from '@fuse/services/match-media.service';
|
||||
import { FuseMatSidenavHelperService } from '@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service';
|
||||
@@ -11,56 +12,91 @@ import { FuseMatSidenavHelperService } from '@fuse/directives/fuse-mat-sidenav/f
|
||||
})
|
||||
export class FuseMatSidenavHelperDirective implements OnInit, OnDestroy
|
||||
{
|
||||
matchMediaSubscription: Subscription;
|
||||
@HostBinding('class.mat-is-locked-open') isLockedOpen = true;
|
||||
@Input('fuseMatSidenavHelper') id: string;
|
||||
@Input('mat-is-locked-open') matIsLockedOpenBreakpoint: string;
|
||||
@HostBinding('class.mat-is-locked-open')
|
||||
isLockedOpen: boolean;
|
||||
|
||||
@Input('fuseMatSidenavHelper')
|
||||
id: string;
|
||||
|
||||
@Input('mat-is-locked-open')
|
||||
matIsLockedOpenBreakpoint: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseMatchMediaService} _fuseMatchMediaService
|
||||
* @param {FuseMatSidenavHelperService} _fuseMatSidenavHelperService
|
||||
* @param {MatSidenav} _matSidenav
|
||||
* @param {ObservableMedia} _observableMedia
|
||||
*/
|
||||
constructor(
|
||||
private fuseMatSidenavService: FuseMatSidenavHelperService,
|
||||
private fuseMatchMedia: FuseMatchMediaService,
|
||||
private observableMedia: ObservableMedia,
|
||||
private matSidenav: MatSidenav
|
||||
private _fuseMatchMediaService: FuseMatchMediaService,
|
||||
private _fuseMatSidenavHelperService: FuseMatSidenavHelperService,
|
||||
private _matSidenav: MatSidenav,
|
||||
private _observableMedia: ObservableMedia
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.isLockedOpen = true;
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
this.fuseMatSidenavService.setSidenav(this.id, this.matSidenav);
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
if ( this.observableMedia.isActive(this.matIsLockedOpenBreakpoint) )
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Register the sidenav to the service
|
||||
this._fuseMatSidenavHelperService.setSidenav(this.id, this._matSidenav);
|
||||
|
||||
if ( this._observableMedia.isActive(this.matIsLockedOpenBreakpoint) )
|
||||
{
|
||||
this.isLockedOpen = true;
|
||||
this.matSidenav.mode = 'side';
|
||||
this.matSidenav.toggle(true);
|
||||
this._matSidenav.mode = 'side';
|
||||
this._matSidenav.toggle(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.isLockedOpen = false;
|
||||
this.matSidenav.mode = 'over';
|
||||
this.matSidenav.toggle(false);
|
||||
this._matSidenav.mode = 'over';
|
||||
this._matSidenav.toggle(false);
|
||||
}
|
||||
|
||||
this.matchMediaSubscription = this.fuseMatchMedia.onMediaChange.subscribe(() => {
|
||||
if ( this.observableMedia.isActive(this.matIsLockedOpenBreakpoint) )
|
||||
{
|
||||
this.isLockedOpen = true;
|
||||
this.matSidenav.mode = 'side';
|
||||
this.matSidenav.toggle(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.isLockedOpen = false;
|
||||
this.matSidenav.mode = 'over';
|
||||
this.matSidenav.toggle(false);
|
||||
}
|
||||
});
|
||||
this._fuseMatchMediaService.onMediaChange
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(() => {
|
||||
if ( this._observableMedia.isActive(this.matIsLockedOpenBreakpoint) )
|
||||
{
|
||||
this.isLockedOpen = true;
|
||||
this._matSidenav.mode = 'side';
|
||||
this._matSidenav.toggle(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.isLockedOpen = false;
|
||||
this._matSidenav.mode = 'over';
|
||||
this._matSidenav.toggle(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
this.matchMediaSubscription.unsubscribe();
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,15 +105,29 @@ export class FuseMatSidenavHelperDirective implements OnInit, OnDestroy
|
||||
})
|
||||
export class FuseMatSidenavTogglerDirective
|
||||
{
|
||||
@Input('fuseMatSidenavToggler') id;
|
||||
@Input('fuseMatSidenavToggler')
|
||||
id;
|
||||
|
||||
constructor(private fuseMatSidenavService: FuseMatSidenavHelperService)
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseMatSidenavHelperService} _fuseMatSidenavHelperService
|
||||
*/
|
||||
constructor(
|
||||
private _fuseMatSidenavHelperService: FuseMatSidenavHelperService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On click
|
||||
*/
|
||||
@HostListener('click')
|
||||
onClick()
|
||||
{
|
||||
this.fuseMatSidenavService.getSidenav(this.id).toggle();
|
||||
this._fuseMatSidenavHelperService.getSidenav(this.id).toggle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,17 +6,36 @@ export class FuseMatSidenavHelperService
|
||||
{
|
||||
sidenavInstances: MatSidenav[];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
this.sidenavInstances = [];
|
||||
}
|
||||
|
||||
setSidenav(id, instance)
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set sidenav
|
||||
*
|
||||
* @param id
|
||||
* @param instance
|
||||
*/
|
||||
setSidenav(id, instance): void
|
||||
{
|
||||
this.sidenavInstances[id] = instance;
|
||||
}
|
||||
|
||||
getSidenav(id)
|
||||
/**
|
||||
* Get sidenav
|
||||
*
|
||||
* @param id
|
||||
* @returns {any}
|
||||
*/
|
||||
getSidenav(id): any
|
||||
{
|
||||
return this.sidenavInstances[id];
|
||||
}
|
||||
|
||||
@@ -1,72 +1,247 @@
|
||||
import { AfterViewInit, Directive, ElementRef, HostListener, OnDestroy, OnInit } from '@angular/core';
|
||||
import { AfterViewInit, Directive, ElementRef, HostListener, Input, OnDestroy } from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { Platform } from '@angular/cdk/platform';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
import PerfectScrollbar from 'perfect-scrollbar';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
|
||||
@Directive({
|
||||
selector: '[fusePerfectScrollbar]'
|
||||
})
|
||||
export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnDestroy
|
||||
export class FusePerfectScrollbarDirective implements AfterViewInit, OnDestroy
|
||||
{
|
||||
onConfigChanged: Subscription;
|
||||
isDisableCustomScrollbars = false;
|
||||
isMobile = false;
|
||||
isInitialized = true;
|
||||
isInitialized: boolean;
|
||||
isMobile: boolean;
|
||||
ps: PerfectScrollbar;
|
||||
|
||||
// Private
|
||||
private _enabled: boolean | '';
|
||||
private _debouncedUpdate: any;
|
||||
private _options: any;
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ElementRef} elementRef
|
||||
* @param {FuseConfigService} _fuseConfigService
|
||||
* @param {Platform} _platform
|
||||
* @param {Router} _router
|
||||
*/
|
||||
constructor(
|
||||
public element: ElementRef,
|
||||
private fuseConfig: FuseConfigService,
|
||||
private platform: Platform
|
||||
public elementRef: ElementRef,
|
||||
private _fuseConfigService: FuseConfigService,
|
||||
private _platform: Platform,
|
||||
private _router: Router
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.isInitialized = false;
|
||||
this.isMobile = false;
|
||||
|
||||
// Set the private defaults
|
||||
this._enabled = false;
|
||||
this._debouncedUpdate = _.debounce(this.update, 150);
|
||||
this._options = {
|
||||
updateOnRouteChange: false
|
||||
};
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
this.onConfigChanged =
|
||||
this.fuseConfig.onConfigChanged.subscribe(
|
||||
(settings) => {
|
||||
this.isDisableCustomScrollbars = !settings.customScrollbars;
|
||||
}
|
||||
);
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
if ( this.platform.ANDROID || this.platform.IOS )
|
||||
/**
|
||||
* Perfect Scrollbar options
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
@Input()
|
||||
set fusePerfectScrollbarOptions(value)
|
||||
{
|
||||
// Merge the options
|
||||
this._options = _.merge({}, this._options, value);
|
||||
}
|
||||
|
||||
get fusePerfectScrollbarOptions(): any
|
||||
{
|
||||
// Return the options
|
||||
return this._options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is enabled
|
||||
*
|
||||
* @param {boolean | ""} value
|
||||
*/
|
||||
@Input('fusePerfectScrollbar')
|
||||
set enabled(value: boolean | '')
|
||||
{
|
||||
// If nothing is provided with the directive (empty string),
|
||||
// we will take that as a true
|
||||
if ( value === '' )
|
||||
{
|
||||
this.isMobile = true;
|
||||
value = true;
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit()
|
||||
{
|
||||
if ( this.isMobile || this.isDisableCustomScrollbars )
|
||||
// Return, if both values are the same
|
||||
if ( this.enabled === value )
|
||||
{
|
||||
this.isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the value
|
||||
this._enabled = value;
|
||||
|
||||
// If enabled...
|
||||
if ( this.enabled )
|
||||
{
|
||||
// Init the directive
|
||||
this._init();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise destroy it
|
||||
this._destroy();
|
||||
}
|
||||
}
|
||||
|
||||
get enabled(): boolean | ''
|
||||
{
|
||||
// Return the enabled status
|
||||
return this._enabled;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* After view init
|
||||
*/
|
||||
ngAfterViewInit(): void
|
||||
{
|
||||
// Check if scrollbars enabled or not from the main config
|
||||
this._fuseConfigService.config
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(
|
||||
(settings) => {
|
||||
this.enabled = settings.customScrollbars;
|
||||
}
|
||||
);
|
||||
|
||||
// Scroll to the top on every route change
|
||||
if ( this.fusePerfectScrollbarOptions.updateOnRouteChange )
|
||||
{
|
||||
this._router.events
|
||||
.pipe(
|
||||
takeUntil(this._unsubscribeAll),
|
||||
filter(event => event instanceof NavigationEnd)
|
||||
)
|
||||
.subscribe(() => {
|
||||
setTimeout(() => {
|
||||
this.scrollToTop();
|
||||
this.update();
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
this._destroy();
|
||||
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_init(): void
|
||||
{
|
||||
// Return, if already initialized
|
||||
if ( this.isInitialized )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if is mobile
|
||||
if ( this._platform.ANDROID || this._platform.IOS )
|
||||
{
|
||||
this.isMobile = true;
|
||||
}
|
||||
|
||||
// Return if it's mobile
|
||||
if ( this.isMobile )
|
||||
{
|
||||
// Return...
|
||||
return;
|
||||
}
|
||||
|
||||
// Set as initialized
|
||||
this.isInitialized = true;
|
||||
|
||||
// Initialize the perfect-scrollbar
|
||||
this.ps = new PerfectScrollbar(this.element.nativeElement, {
|
||||
wheelPropagation: true
|
||||
this.ps = new PerfectScrollbar(this.elementRef.nativeElement, {
|
||||
...this.fusePerfectScrollbarOptions
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
/**
|
||||
* Destroy
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_destroy(): void
|
||||
{
|
||||
if ( !this.isInitialized || !this.ps )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onConfigChanged.unsubscribe();
|
||||
|
||||
// Destroy the perfect-scrollbar
|
||||
this.ps.destroy();
|
||||
|
||||
// Clean up
|
||||
this.ps = null;
|
||||
this.isInitialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update scrollbars on window resize
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
@HostListener('window:resize')
|
||||
_updateOnResize(): void
|
||||
{
|
||||
this._debouncedUpdate();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Document click
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
@HostListener('document:click', ['$event'])
|
||||
documentClick(event: Event): void
|
||||
{
|
||||
@@ -82,7 +257,10 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD
|
||||
this.ps.update();
|
||||
}
|
||||
|
||||
update()
|
||||
/**
|
||||
* Update the scrollbar
|
||||
*/
|
||||
update(): void
|
||||
{
|
||||
if ( !this.isInitialized )
|
||||
{
|
||||
@@ -93,62 +271,108 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD
|
||||
this.ps.update();
|
||||
}
|
||||
|
||||
destroy()
|
||||
/**
|
||||
* Destroy the scrollbar
|
||||
*/
|
||||
destroy(): void
|
||||
{
|
||||
this.ngOnDestroy();
|
||||
}
|
||||
|
||||
scrollToX(x: number, speed?: number)
|
||||
/**
|
||||
* Scroll to X
|
||||
*
|
||||
* @param {number} x
|
||||
* @param {number} speed
|
||||
*/
|
||||
scrollToX(x: number, speed?: number): void
|
||||
{
|
||||
this.animateScrolling('scrollLeft', x, speed);
|
||||
}
|
||||
|
||||
scrollToY(y: number, speed?: number)
|
||||
/**
|
||||
* Scroll to Y
|
||||
*
|
||||
* @param {number} y
|
||||
* @param {number} speed
|
||||
*/
|
||||
scrollToY(y: number, speed?: number): void
|
||||
{
|
||||
this.animateScrolling('scrollTop', y, speed);
|
||||
}
|
||||
|
||||
scrollToTop(offset?: number, speed?: number)
|
||||
/**
|
||||
* Scroll to top
|
||||
*
|
||||
* @param {number} offset
|
||||
* @param {number} speed
|
||||
*/
|
||||
scrollToTop(offset?: number, speed?: number): void
|
||||
{
|
||||
this.animateScrolling('scrollTop', (offset || 0), speed);
|
||||
}
|
||||
|
||||
scrollToLeft(offset?: number, speed?: number)
|
||||
/**
|
||||
* Scroll to left
|
||||
*
|
||||
* @param {number} offset
|
||||
* @param {number} speed
|
||||
*/
|
||||
scrollToLeft(offset?: number, speed?: number): void
|
||||
{
|
||||
this.animateScrolling('scrollLeft', (offset || 0), speed);
|
||||
}
|
||||
|
||||
scrollToRight(offset?: number, speed?: number)
|
||||
/**
|
||||
* Scroll to right
|
||||
*
|
||||
* @param {number} offset
|
||||
* @param {number} speed
|
||||
*/
|
||||
scrollToRight(offset?: number, speed?: number): void
|
||||
{
|
||||
const width = this.element.nativeElement.scrollWidth;
|
||||
const width = this.elementRef.nativeElement.scrollWidth;
|
||||
|
||||
this.animateScrolling('scrollLeft', width - (offset || 0), speed);
|
||||
}
|
||||
|
||||
scrollToBottom(offset?: number, speed?: number)
|
||||
/**
|
||||
* Scroll to bottom
|
||||
*
|
||||
* @param {number} offset
|
||||
* @param {number} speed
|
||||
*/
|
||||
scrollToBottom(offset?: number, speed?: number): void
|
||||
{
|
||||
const height = this.element.nativeElement.scrollHeight;
|
||||
const height = this.elementRef.nativeElement.scrollHeight;
|
||||
|
||||
this.animateScrolling('scrollTop', height - (offset || 0), speed);
|
||||
}
|
||||
|
||||
animateScrolling(target: string, value: number, speed?: number)
|
||||
/**
|
||||
* Animate scrolling
|
||||
*
|
||||
* @param {string} target
|
||||
* @param {number} value
|
||||
* @param {number} speed
|
||||
*/
|
||||
animateScrolling(target: string, value: number, speed?: number): void
|
||||
{
|
||||
if ( !speed )
|
||||
{
|
||||
this.element.nativeElement[target] = value;
|
||||
this.elementRef.nativeElement[target] = value;
|
||||
|
||||
// PS has weird event sending order, this is a workaround for that
|
||||
this.update();
|
||||
this.update();
|
||||
}
|
||||
else if ( value !== this.element.nativeElement[target] )
|
||||
else if ( value !== this.elementRef.nativeElement[target] )
|
||||
{
|
||||
let newValue = 0;
|
||||
let scrollCount = 0;
|
||||
|
||||
let oldTimestamp = performance.now();
|
||||
let oldValue = this.element.nativeElement[target];
|
||||
let oldValue = this.elementRef.nativeElement[target];
|
||||
|
||||
const cosParameter = (oldValue - value) / 2;
|
||||
|
||||
@@ -158,11 +382,11 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD
|
||||
newValue = Math.round(value + cosParameter + cosParameter * Math.cos(scrollCount));
|
||||
|
||||
// Only continue animation if scroll position has not changed
|
||||
if ( this.element.nativeElement[target] === oldValue )
|
||||
if ( this.elementRef.nativeElement[target] === oldValue )
|
||||
{
|
||||
if ( scrollCount >= Math.PI )
|
||||
{
|
||||
this.element.nativeElement[target] = value;
|
||||
this.elementRef.nativeElement[target] = value;
|
||||
|
||||
// PS has weird event sending order, this is a workaround for that
|
||||
this.update();
|
||||
@@ -171,7 +395,7 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD
|
||||
}
|
||||
else
|
||||
{
|
||||
this.element.nativeElement[target] = oldValue = newValue;
|
||||
this.elementRef.nativeElement[target] = oldValue = newValue;
|
||||
|
||||
oldTimestamp = newTimestamp;
|
||||
|
||||
|
||||
@@ -3,7 +3,14 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||
@Pipe({name: 'camelCaseToDash'})
|
||||
export class CamelCaseToDashPipe implements PipeTransform
|
||||
{
|
||||
transform(value: string, args: any[] = [])
|
||||
/**
|
||||
* Transform
|
||||
*
|
||||
* @param {string} value
|
||||
* @param {any[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
transform(value: string, args: any[] = []): string
|
||||
{
|
||||
return value ? String(value).replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`) : '';
|
||||
}
|
||||
|
||||
@@ -4,6 +4,14 @@ import { FuseUtils } from '@fuse/utils';
|
||||
@Pipe({name: 'filter'})
|
||||
export class FilterPipe implements PipeTransform
|
||||
{
|
||||
/**
|
||||
* Transform
|
||||
*
|
||||
* @param {any[]} mainArr
|
||||
* @param {string} searchText
|
||||
* @param {string} property
|
||||
* @returns {any}
|
||||
*/
|
||||
transform(mainArr: any[], searchText: string, property: string): any
|
||||
{
|
||||
return FuseUtils.filterArrayByString(mainArr, searchText);
|
||||
|
||||
@@ -6,6 +6,14 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||
})
|
||||
export class GetByIdPipe implements PipeTransform
|
||||
{
|
||||
/**
|
||||
* Transform
|
||||
*
|
||||
* @param {any[]} value
|
||||
* @param {number} id
|
||||
* @param {string} property
|
||||
* @returns {any}
|
||||
*/
|
||||
transform(value: any[], id: number, property: string): any
|
||||
{
|
||||
const foundItem = value.find(item => {
|
||||
|
||||
@@ -3,7 +3,14 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||
@Pipe({name: 'htmlToPlaintext'})
|
||||
export class HtmlToPlaintextPipe implements PipeTransform
|
||||
{
|
||||
transform(value: string, args: any[] = [])
|
||||
/**
|
||||
* Transform
|
||||
*
|
||||
* @param {string} value
|
||||
* @param {any[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
transform(value: string, args: any[] = []): string
|
||||
{
|
||||
return value ? String(value).replace(/<[^>]+>/gm, '') : '';
|
||||
}
|
||||
|
||||
@@ -3,6 +3,13 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||
@Pipe({name: 'keys'})
|
||||
export class KeysPipe implements PipeTransform
|
||||
{
|
||||
/**
|
||||
* Transform
|
||||
*
|
||||
* @param value
|
||||
* @param {string[]} args
|
||||
* @returns {any}
|
||||
*/
|
||||
transform(value: any, args: string[]): any
|
||||
{
|
||||
const keys: any[] = [];
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
@import "partials/material";
|
||||
@import "partials/angular-material-fix";
|
||||
@import "partials/typography";
|
||||
@import "partials/docs";
|
||||
@import "partials/page-layouts";
|
||||
@import "partials/cards";
|
||||
@import "partials/navigation";
|
||||
|
||||
@@ -84,4 +84,9 @@ mat-chip {
|
||||
min-width: 0 !important;
|
||||
min-height: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix: Mat-card-image requires a bigger width than 100%
|
||||
.mat-card-image {
|
||||
max-width: none !important;
|
||||
}
|
||||
@@ -227,6 +227,35 @@ $matColorHues: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200, A400
|
||||
}
|
||||
}
|
||||
|
||||
@mixin generateFuseColorClasses($primary, $accent, $warn) {
|
||||
|
||||
$colorMap: (
|
||||
primary: $primary,
|
||||
accent: $accent,
|
||||
warn: $warn
|
||||
);
|
||||
|
||||
// Generate the color classes...
|
||||
@each $name, $map in $colorMap {
|
||||
|
||||
@each $hue in $matColorHues {
|
||||
|
||||
$color: map-get($map, $hue);
|
||||
$contrastColor: map-get(map-get($map, 'contrast'), $hue);
|
||||
|
||||
@if ($color != null and $contrastColor != null) {
|
||||
|
||||
@include generateColorClasses($name, $color, $contrastColor, '-#{$hue}');
|
||||
|
||||
// Run the generator one more time for default values (500)
|
||||
@if ($hue == 500) {
|
||||
@include generateColorClasses($name, $color, $contrastColor, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the color classes...
|
||||
@each $colorName, $colorMap in $matColorsMap {
|
||||
|
||||
|
||||
42
src/@fuse/scss/partials/_docs.scss
Normal file
42
src/@fuse/scss/partials/_docs.scss
Normal file
@@ -0,0 +1,42 @@
|
||||
.docs {
|
||||
font-size: 16px;
|
||||
|
||||
> .content {
|
||||
max-width: 980px;
|
||||
|
||||
> .main-title {
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main-title {
|
||||
display: flex;
|
||||
margin-top: 72px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: inline-flex;
|
||||
font-size: 18px;
|
||||
margin-top: 24px;
|
||||
border-bottom: 1px solid #F44336;
|
||||
color: #F44336;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
|
||||
li {
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.7;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
html,
|
||||
body {
|
||||
|
||||
> mat-sidenav-container {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
min-height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background: #F5F5F5;
|
||||
}
|
||||
@@ -42,7 +42,7 @@
|
||||
color: currentColor;
|
||||
|
||||
> .nav-link-title {
|
||||
flex: 1;
|
||||
flex: 1 1 auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
transition: opacity 0.2s ease-in-out 0.1s;
|
||||
margin-left: 8px;
|
||||
|
||||
+ .collapse-arrow {
|
||||
+ .collapsable-arrow {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
@@ -72,14 +72,9 @@
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: mat-color($accent);
|
||||
|
||||
.mat-ripple-element {
|
||||
background-color: mat-color($accent, default-contrast, 0.1);
|
||||
}
|
||||
|
||||
&, .nav-link-icon {
|
||||
color: mat-color($accent, default-contrast);
|
||||
.nav-link-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.nav-link-badge {
|
||||
@@ -90,10 +85,11 @@
|
||||
|
||||
.nav-link-icon {
|
||||
margin-right: 16px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.nav-link-icon,
|
||||
.collapse-arrow {
|
||||
.collapsable-arrow {
|
||||
font-size: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
@@ -103,7 +99,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.nav-collapse {
|
||||
&.nav-collapsable {
|
||||
display: block;
|
||||
|
||||
> .children {
|
||||
@@ -135,7 +131,7 @@
|
||||
|
||||
> .nav-item {
|
||||
|
||||
&.nav-collapse {
|
||||
&.nav-collapsable {
|
||||
background: transparent;
|
||||
transition: background 200ms ease-in-out;
|
||||
|
||||
@@ -149,7 +145,7 @@
|
||||
|
||||
> .group-items {
|
||||
|
||||
> .nav-collapse {
|
||||
> .nav-collapsable {
|
||||
background: transparent;
|
||||
transition: background 200ms ease-in-out;
|
||||
|
||||
@@ -176,7 +172,7 @@
|
||||
|
||||
.nav-item {
|
||||
|
||||
&.nav-collapse {
|
||||
&.nav-collapsable {
|
||||
position: relative;
|
||||
|
||||
.children {
|
||||
@@ -205,13 +201,13 @@
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
&.nav-collapse {
|
||||
&.nav-collapsable {
|
||||
position: relative;
|
||||
|
||||
> .nav-link {
|
||||
height: 56px;
|
||||
|
||||
.collapse-arrow {
|
||||
.collapsable-arrow {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,13 +10,9 @@ $header-height-sm: 100px !default;
|
||||
$carded-header-height-without-toolbar: $carded-header-height - $carded-toolbar-height;
|
||||
$carded-header-height-without-toolbar-sm: $carded-header-height-sm - $carded-toolbar-height;
|
||||
|
||||
// Top bg image
|
||||
$top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
|
||||
.page-layout {
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overflow: hidden;
|
||||
|
||||
// Carded layout
|
||||
&.carded {
|
||||
@@ -27,15 +23,13 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
min-width: 100%;
|
||||
|
||||
// Top bg
|
||||
.top-bg {
|
||||
> .top-bg {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: $carded-header-height;
|
||||
background-image: $top-bg-image;
|
||||
background-size: cover;
|
||||
|
||||
@include media-breakpoint-down('sm') {
|
||||
height: $carded-header-height-sm;
|
||||
@@ -45,48 +39,39 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
// Fullwidth
|
||||
&.fullwidth {
|
||||
|
||||
// Single scroll
|
||||
&.single-scroll {
|
||||
|
||||
> .center {
|
||||
flex: 1 0 auto;
|
||||
max-height: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Center
|
||||
> .center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
flex: 1 0 auto;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 0 32px;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
|
||||
.header {
|
||||
height: $carded-header-height-without-toolbar;
|
||||
min-height: $carded-header-height-without-toolbar;
|
||||
max-height: $carded-header-height-without-toolbar;
|
||||
> .header {
|
||||
height: $carded-header-height-without-toolbar !important;
|
||||
min-height: $carded-header-height-without-toolbar !important;
|
||||
max-height: $carded-header-height-without-toolbar !important;
|
||||
|
||||
@include media-breakpoint-down('sm') {
|
||||
height: $carded-header-height-without-toolbar-sm;
|
||||
min-height: $carded-header-height-without-toolbar-sm;
|
||||
max-height: $carded-header-height-without-toolbar-sm;
|
||||
height: $carded-header-height-without-toolbar-sm !important;
|
||||
min-height: $carded-header-height-without-toolbar-sm !important;
|
||||
max-height: $carded-header-height-without-toolbar-sm !important;
|
||||
}
|
||||
}
|
||||
|
||||
.content-card {
|
||||
> .content-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
flex: 1 0 auto;
|
||||
overflow: hidden;
|
||||
@include mat-elevation(7);
|
||||
|
||||
.toolbar {
|
||||
> .toolbar {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
@@ -97,128 +82,7 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
}
|
||||
|
||||
> .content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Left sidenav - Right sidenav
|
||||
&.left-sidenav,
|
||||
&.right-sidenav {
|
||||
|
||||
// Single scroll
|
||||
&.single-scroll {
|
||||
|
||||
> mat-sidenav-container {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
> mat-sidenav-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
background: none;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
|
||||
.sidenav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
width: 240px;
|
||||
min-width: 240px;
|
||||
max-width: 240px;
|
||||
height: auto;
|
||||
z-index: 4;
|
||||
overflow-y: hidden;
|
||||
@include mat-elevation(7);
|
||||
|
||||
&.mat-is-locked-open {
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: $carded-header-height;
|
||||
min-height: $carded-header-height;
|
||||
max-height: $carded-header-height;
|
||||
|
||||
@include media-breakpoint-down('sm') {
|
||||
height: $carded-header-height-sm;
|
||||
min-height: $carded-header-height-sm;
|
||||
max-height: $carded-header-height-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
background: transparent;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
> .mat-sidenav-content,
|
||||
> .mat-drawer-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
|
||||
// Center
|
||||
.center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
margin-left: 32px;
|
||||
margin-right: 32px;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
height: $carded-header-height-without-toolbar;
|
||||
min-height: $carded-header-height-without-toolbar;
|
||||
max-height: $carded-header-height-without-toolbar;
|
||||
|
||||
@include media-breakpoint-down('sm') {
|
||||
height: $carded-header-height-without-toolbar-sm;
|
||||
min-height: $carded-header-height-without-toolbar-sm;
|
||||
max-height: $carded-header-height-without-toolbar-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.content-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
@include mat-elevation(7);
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
height: $carded-toolbar-height;
|
||||
min-height: $carded-toolbar-height;
|
||||
max-height: $carded-toolbar-height;
|
||||
|
||||
.sidenav-toggle {
|
||||
margin: 0 8px 0 0 !important;
|
||||
padding: 0 !important;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,51 +90,82 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
// Tabbed
|
||||
&.tabbed {
|
||||
|
||||
> mat-sidenav-container {
|
||||
> .center {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
|
||||
> .mat-sidenav-content,
|
||||
> .mat-drawer-content {
|
||||
width: calc(100% - 240px);
|
||||
min-width: 0;
|
||||
> .header {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.center {
|
||||
width: calc(100% - 32px);
|
||||
min-width: 0;
|
||||
> .content-card {
|
||||
|
||||
@include media-breakpoint-down('md') {
|
||||
width: calc(100% - 64px);
|
||||
}
|
||||
> .content {
|
||||
display: flex;
|
||||
|
||||
.header {
|
||||
flex: 1;
|
||||
}
|
||||
> .mat-tab-group {
|
||||
overflow: hidden;
|
||||
|
||||
.content-card {
|
||||
.mat-tab-header {
|
||||
|
||||
.content {
|
||||
.mat-tab-label {
|
||||
height: 64px;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-tab-group {
|
||||
.mat-tab-body {
|
||||
overflow: hidden;
|
||||
|
||||
.mat-tab-body-content {
|
||||
overflow: hidden;
|
||||
|
||||
.mat-tab-header {
|
||||
|
||||
.mat-tab-label {
|
||||
height: 64px;
|
||||
}
|
||||
.tab-content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mat-tab-body {
|
||||
overflow: hidden;
|
||||
// Inner scroll
|
||||
&.inner-scroll {
|
||||
flex: 1 1 auto;
|
||||
|
||||
.mat-tab-body-content {
|
||||
overflow: hidden;
|
||||
> .center {
|
||||
flex: 1 1 auto;
|
||||
|
||||
.tab-content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
> .content-card {
|
||||
flex: 1 1 auto;
|
||||
|
||||
> .content {
|
||||
overflow: auto;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tabbed
|
||||
&.tabbed {
|
||||
|
||||
> .center {
|
||||
|
||||
> .content-card {
|
||||
|
||||
> .content {
|
||||
|
||||
> .mat-tab-group {
|
||||
|
||||
.mat-tab-body {
|
||||
|
||||
.mat-tab-body-content {
|
||||
|
||||
.tab-content {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,21 +177,212 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
}
|
||||
}
|
||||
|
||||
// Left sidenav
|
||||
&.left-sidenav {
|
||||
// Left / Right sidebar
|
||||
&.left-sidebar,
|
||||
&.right-sidebar {
|
||||
flex-direction: row;
|
||||
|
||||
// Sidenav
|
||||
> mat-sidenav-container {
|
||||
// Sidebar
|
||||
> .sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 auto;
|
||||
width: 240px;
|
||||
min-width: 240px;
|
||||
max-width: 240px;
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
@include mat-elevation(7);
|
||||
|
||||
.sidenav {
|
||||
&.locked-open {
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
|
||||
&.mat-is-locked-open {
|
||||
+ .center {
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
~ .mat-sidenav-content,
|
||||
~ .mat-drawer-content {
|
||||
&.left-positioned {
|
||||
|
||||
.center {
|
||||
margin-left: 0;
|
||||
+ .center {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.right-positioned {
|
||||
|
||||
+ .center {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
height: $carded-header-height;
|
||||
min-height: $carded-header-height;
|
||||
max-height: $carded-header-height;
|
||||
|
||||
@include media-breakpoint-down('sm') {
|
||||
height: $carded-header-height-sm;
|
||||
min-height: $carded-header-height-sm;
|
||||
max-height: $carded-header-height-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
background: transparent;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
// Center
|
||||
> .center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 auto;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
margin-left: 32px;
|
||||
margin-right: 32px;
|
||||
min-width: 0;
|
||||
|
||||
> .header {
|
||||
display: flex;
|
||||
height: $carded-header-height-without-toolbar;
|
||||
min-height: $carded-header-height-without-toolbar;
|
||||
max-height: $carded-header-height-without-toolbar;
|
||||
|
||||
@include media-breakpoint-down('sm') {
|
||||
height: $carded-header-height-without-toolbar-sm;
|
||||
min-height: $carded-header-height-without-toolbar-sm;
|
||||
max-height: $carded-header-height-without-toolbar-sm;
|
||||
}
|
||||
}
|
||||
|
||||
> .content-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
@include mat-elevation(7);
|
||||
|
||||
> .toolbar {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex: 1 1 auto;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
height: $carded-toolbar-height;
|
||||
min-height: $carded-toolbar-height;
|
||||
max-height: $carded-toolbar-height;
|
||||
|
||||
.sidebar-toggle {
|
||||
margin: 0 8px 0 0 !important;
|
||||
padding: 0 !important;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .content {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tabbed
|
||||
&.tabbed {
|
||||
|
||||
> .center {
|
||||
width: calc(100% - 32px);
|
||||
min-width: 0;
|
||||
|
||||
@include media-breakpoint-down('md') {
|
||||
width: calc(100% - 64px);
|
||||
}
|
||||
|
||||
> .header {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
> .content-card {
|
||||
|
||||
> .content {
|
||||
display: flex;
|
||||
|
||||
> .mat-tab-group {
|
||||
overflow: hidden;
|
||||
|
||||
.mat-tab-header {
|
||||
|
||||
.mat-tab-label {
|
||||
height: 64px;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-tab-body {
|
||||
overflow: hidden;
|
||||
|
||||
.mat-tab-body-content {
|
||||
overflow: hidden;
|
||||
|
||||
.tab-content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inner scroll
|
||||
&.inner-scroll {
|
||||
flex: 1 1 auto;
|
||||
|
||||
> .sidebar {
|
||||
|
||||
.content {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
> .center {
|
||||
flex: 1 1 auto;
|
||||
|
||||
> .content-card {
|
||||
flex: 1 1 auto;
|
||||
|
||||
> .content {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tabbed
|
||||
&.tabbed {
|
||||
|
||||
> .center {
|
||||
|
||||
> .content-card {
|
||||
|
||||
> .content {
|
||||
|
||||
> .mat-tab-group {
|
||||
|
||||
.mat-tab-body {
|
||||
|
||||
.mat-tab-body-content {
|
||||
|
||||
.tab-content {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -304,26 +390,15 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
}
|
||||
}
|
||||
|
||||
// Right sidenav
|
||||
&.right-sidenav {
|
||||
// Right sidebar specific
|
||||
&.right-sidebar {
|
||||
|
||||
// Sidenav
|
||||
> mat-sidenav-container {
|
||||
> .sidebar {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.sidenav {
|
||||
order: 999;
|
||||
|
||||
&.mat-is-locked-open {
|
||||
|
||||
~ .mat-sidenav-content,
|
||||
~ .mat-drawer-content {
|
||||
|
||||
.center {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .center {
|
||||
order: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -336,20 +411,17 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
|
||||
// Top bg
|
||||
> .header {
|
||||
background-image: $top-bg-image;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
// Fullwidth
|
||||
&.fullwidth {
|
||||
overflow: auto;
|
||||
|
||||
> .content {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.fullwidth,
|
||||
&.inner-sidenav {
|
||||
min-height: 100%;
|
||||
&.inner-sidebar {
|
||||
|
||||
> .header {
|
||||
height: $header-height;
|
||||
@@ -358,109 +430,138 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
}
|
||||
}
|
||||
|
||||
// Left sidenav - Right sidenav
|
||||
&.left-sidenav,
|
||||
&.right-sidenav {
|
||||
// Left / Right sidebar
|
||||
&.left-sidebar,
|
||||
&.right-sidebar {
|
||||
flex-direction: row;
|
||||
|
||||
// Single scroll
|
||||
&.single-scroll {
|
||||
// Sidebar
|
||||
> .sidebar {
|
||||
width: 240px;
|
||||
min-width: 240px;
|
||||
max-width: 240px;
|
||||
overflow: hidden;
|
||||
@include mat-elevation(7);
|
||||
|
||||
> mat-sidenav-container {
|
||||
flex: 1 0 auto;
|
||||
&.locked-open {
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
|
||||
> .mat-sidenav-content,
|
||||
> .mat-drawer-content {
|
||||
flex: 1 0 auto;
|
||||
max-height: none;
|
||||
+ .center {
|
||||
z-index: 1001;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inner Sidenav
|
||||
&.inner-sidenav {
|
||||
&.left-positioned {
|
||||
|
||||
> mat-sidenav-container {
|
||||
flex: 1;
|
||||
|
||||
.sidenav {
|
||||
|
||||
.sidenav-content {
|
||||
height: 100%;
|
||||
+ .center {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .mat-sidenav-content,
|
||||
> .mat-drawer-content {
|
||||
display: flex;
|
||||
height: auto;
|
||||
&.right-positioned {
|
||||
|
||||
.center {
|
||||
flex: 1;
|
||||
min-height: 100%;
|
||||
@include mat-elevation(0);
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
+ .center {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
> mat-sidenav-container {
|
||||
// Center
|
||||
> .center {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
background: none;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
flex: 1 1 auto;
|
||||
z-index: 3;
|
||||
min-width: 0;
|
||||
@include mat-elevation(7);
|
||||
|
||||
.sidenav {
|
||||
width: 240px;
|
||||
min-width: 240px;
|
||||
max-width: 240px;
|
||||
z-index: 51;
|
||||
@include mat-elevation(7);
|
||||
> .header {
|
||||
height: $header-height;
|
||||
min-height: $header-height;
|
||||
max-height: $header-height;
|
||||
}
|
||||
|
||||
&.mat-is-locked-open {
|
||||
width: 220px;
|
||||
min-width: 220px;
|
||||
max-width: 220px;
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
}
|
||||
> .content {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.sidenav-content {
|
||||
height: 100%;
|
||||
// Inner scroll
|
||||
&.inner-scroll {
|
||||
flex: 1 1 auto;
|
||||
|
||||
> .sidebar {
|
||||
|
||||
.content {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
> .mat-sidenav-content,
|
||||
> .mat-drawer-content {
|
||||
> .center {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// Inner Sidebar
|
||||
&.inner-sidebar {
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
|
||||
> .content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
max-height: 100%;
|
||||
min-height: 0;
|
||||
|
||||
.header {
|
||||
height: $header-height;
|
||||
min-height: $header-height;
|
||||
max-height: $header-height;
|
||||
background-image: $top-bg-image;
|
||||
}
|
||||
> .sidebar {
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
@include mat-elevation(7);
|
||||
&.locked-open {
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
> .center {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Right sidebar specific
|
||||
&.right-sidebar {
|
||||
|
||||
> .sidebar {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
> .center {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
// Inner sidebar
|
||||
&.inner-sidebar {
|
||||
|
||||
> .content {
|
||||
|
||||
> .sidebar {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
> .center {
|
||||
order: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -469,7 +570,7 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
&.tabbed {
|
||||
min-height: 100%;
|
||||
|
||||
.header {
|
||||
> .header {
|
||||
height: $header-height;
|
||||
min-height: $header-height;
|
||||
max-height: $header-height;
|
||||
@@ -477,7 +578,7 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
|
||||
> .content {
|
||||
|
||||
.mat-tab-group {
|
||||
> .mat-tab-group {
|
||||
|
||||
.mat-tab-labels {
|
||||
padding: 0 24px;
|
||||
@@ -495,50 +596,6 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
|
||||
// Activate single-scroll
|
||||
&.carded {
|
||||
|
||||
&.fullwidth {
|
||||
|
||||
> .center {
|
||||
flex: 1 0 auto;
|
||||
max-height: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.left-sidenav,
|
||||
&.right-sidenav {
|
||||
|
||||
> mat-sidenav-container {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.simple {
|
||||
|
||||
&.fullwidth {
|
||||
|
||||
> .content {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.left-sidenav,
|
||||
&.right-sidenav {
|
||||
|
||||
> mat-sidenav-container {
|
||||
flex: 1 0 auto !important;
|
||||
|
||||
> .mat-sidenav-content,
|
||||
> .mat-drawer-content {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// End - Activate single-scroll
|
||||
|
||||
// Smaller margins
|
||||
&.carded {
|
||||
|
||||
@@ -549,18 +606,11 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
|
||||
}
|
||||
}
|
||||
|
||||
&.left-sidenav,
|
||||
&.right-sidenav {
|
||||
&.left-sidebar,
|
||||
&.right-sidebar {
|
||||
|
||||
> mat-sidenav-container {
|
||||
|
||||
> .mat-sidenav-content,
|
||||
> .mat-drawer-content {
|
||||
|
||||
.center {
|
||||
margin: 0 16px;
|
||||
}
|
||||
}
|
||||
> .center {
|
||||
margin: 0 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
}
|
||||
|
||||
/* General styles */
|
||||
fuse-root {
|
||||
app {
|
||||
|
||||
fuse-navbar-vertical,
|
||||
fuse-navbar-horizontal,
|
||||
|
||||
@@ -274,4 +274,119 @@ strong {
|
||||
// Nowrap
|
||||
.text-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// Changelog
|
||||
.changelog {
|
||||
|
||||
.entry {
|
||||
background: white;
|
||||
margin-bottom: 24px;
|
||||
padding: 24px 32px;
|
||||
@include mat-elevation(2);
|
||||
|
||||
> .title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.version {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.date {
|
||||
margin-left: 8px;
|
||||
font-size: 17px;
|
||||
opacity: 0.54;
|
||||
}
|
||||
}
|
||||
|
||||
.groups {
|
||||
|
||||
div {
|
||||
margin-bottom: 32px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
display: inline-flex;
|
||||
font-size: 13px;
|
||||
color: white;
|
||||
letter-spacing: 0.015em;
|
||||
line-height: 1;
|
||||
padding: 5px 8px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.breaking-changes {
|
||||
|
||||
.title {
|
||||
background: #F44336;
|
||||
}
|
||||
}
|
||||
|
||||
.new {
|
||||
|
||||
.title {
|
||||
background: #43A047;
|
||||
}
|
||||
}
|
||||
|
||||
.improved {
|
||||
|
||||
.title {
|
||||
background: #673AB7;
|
||||
}
|
||||
}
|
||||
|
||||
.fixed {
|
||||
|
||||
.title {
|
||||
background: #2196F3;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
|
||||
li {
|
||||
margin-bottom: 6px;
|
||||
letter-spacing: 0.015em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Message boxes
|
||||
.message-box {
|
||||
padding: 16px;
|
||||
background: #607D8B;
|
||||
border-left: 6px solid #37474F;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
|
||||
&.error {
|
||||
background: #EF5350;
|
||||
border-left-color: #B71C1C;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background: #FFECB3;
|
||||
border-left-color: #FFC107;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
&.success {
|
||||
background: #4CAF50;
|
||||
border-left-color: #2E7D32;
|
||||
}
|
||||
|
||||
&.info {
|
||||
background: #B3E5FC;
|
||||
border-left-color: #03A9F4;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
}
|
||||
@@ -104,9 +104,9 @@ $code-color-attr-name: #B65611 !default;
|
||||
|
||||
// whitespace management
|
||||
white-space: pre; // fallback
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
//white-space: pre-wrap;
|
||||
//word-break: break-all;
|
||||
//word-wrap: break-word;
|
||||
|
||||
font-family: $code-font-family;
|
||||
font-size: $code-font-size;
|
||||
|
||||
@@ -1,93 +1,155 @@
|
||||
import { Inject, Injectable, InjectionToken } from '@angular/core';
|
||||
import { NavigationEnd, NavigationStart, Router } from '@angular/router';
|
||||
import { NavigationStart, Router } from '@angular/router';
|
||||
import { Platform } from '@angular/cdk/platform';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
// Create the injection token for the custom config
|
||||
// Create the injection token for the custom settings
|
||||
export const FUSE_CONFIG = new InjectionToken('fuseCustomConfig');
|
||||
|
||||
@Injectable()
|
||||
export class FuseConfigService
|
||||
{
|
||||
config: any;
|
||||
defaultConfig: any;
|
||||
isSetConfigRan = false;
|
||||
|
||||
onConfigChanged: BehaviorSubject<any>;
|
||||
// Private
|
||||
private _configSubject: BehaviorSubject<any>;
|
||||
private readonly _defaultConfig: any;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param router
|
||||
* @param platform
|
||||
* @param config
|
||||
* @param {Platform} _platform
|
||||
* @param {Router} _router
|
||||
* @param _config
|
||||
*/
|
||||
constructor(
|
||||
private router: Router,
|
||||
public platform: Platform,
|
||||
@Inject(FUSE_CONFIG) config
|
||||
private _platform: Platform,
|
||||
private _router: Router,
|
||||
@Inject(FUSE_CONFIG) private _config
|
||||
)
|
||||
{
|
||||
// Set the default config from the user provided one (forRoot)
|
||||
this.defaultConfig = config;
|
||||
// Set the default config from the user provided config (from forRoot)
|
||||
this._defaultConfig = _config;
|
||||
|
||||
/**
|
||||
* Disable Custom Scrollbars if Browser is Mobile
|
||||
*/
|
||||
if ( this.platform.ANDROID || this.platform.IOS )
|
||||
{
|
||||
this.defaultConfig.customScrollbars = false;
|
||||
}
|
||||
// Initialize the service
|
||||
this._init();
|
||||
}
|
||||
|
||||
// Set the config from the default config
|
||||
this.config = _.cloneDeep(this.defaultConfig);
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// Reload the default settings for the
|
||||
// layout on every navigation start
|
||||
router.events.subscribe(
|
||||
(event) => {
|
||||
/**
|
||||
* Set and get the config
|
||||
*/
|
||||
set config(value)
|
||||
{
|
||||
// Get the value from the behavior subject
|
||||
let config = this._configSubject.getValue();
|
||||
|
||||
if ( event instanceof NavigationStart )
|
||||
{
|
||||
this.isSetConfigRan = false;
|
||||
}
|
||||
// Merge the new config
|
||||
config = _.merge({}, config, value);
|
||||
|
||||
if ( event instanceof NavigationEnd )
|
||||
{
|
||||
if ( this.isSetConfigRan )
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Notify the observers
|
||||
this._configSubject.next(config);
|
||||
}
|
||||
|
||||
this.setConfig({
|
||||
layout: this.defaultConfig.layout
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Create the behavior subject
|
||||
this.onConfigChanged = new BehaviorSubject(this.config);
|
||||
get config(): any | Observable<any>
|
||||
{
|
||||
return this._configSubject.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the new config from given object
|
||||
* Get default config
|
||||
*
|
||||
* @param config
|
||||
* @returns {any}
|
||||
*/
|
||||
setConfig(config): void
|
||||
get defaultConfig(): any
|
||||
{
|
||||
// Set the SetConfigRan true
|
||||
this.isSetConfigRan = true;
|
||||
return this._defaultConfig;
|
||||
}
|
||||
|
||||
// Merge the config
|
||||
this.config = _.merge({}, this.config, config);
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// Trigger the event
|
||||
this.onConfigChanged.next(this.config);
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _init(): void
|
||||
{
|
||||
/**
|
||||
* Disable custom scrollbars if browser is mobile
|
||||
*/
|
||||
if ( this._platform.ANDROID || this._platform.IOS )
|
||||
{
|
||||
this._defaultConfig.customScrollbars = false;
|
||||
}
|
||||
|
||||
// Set the config from the default config
|
||||
this._configSubject = new BehaviorSubject(_.cloneDeep(this._defaultConfig));
|
||||
|
||||
// Reload the default config on every navigation start if
|
||||
// the current config is different from the default one
|
||||
this._router.events
|
||||
.pipe(filter(event => event instanceof NavigationStart))
|
||||
.subscribe(() => {
|
||||
if ( !_.isEqual(this._configSubject.getValue(), this._defaultConfig) )
|
||||
{
|
||||
// Clone the default config
|
||||
const config = _.cloneDeep(this._defaultConfig);
|
||||
|
||||
// Set the config
|
||||
this._configSubject.next(config);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set config
|
||||
*
|
||||
* @param value
|
||||
* @param {{emitEvent: boolean}} opts
|
||||
*/
|
||||
setConfig(value, opts = {emitEvent: true}): void
|
||||
{
|
||||
// Get the value from the behavior subject
|
||||
let config = this._configSubject.getValue();
|
||||
|
||||
// Merge the new config
|
||||
config = _.merge({}, config, value);
|
||||
|
||||
// If emitEvent option is true...
|
||||
if ( opts.emitEvent === true )
|
||||
{
|
||||
// Notify the observers
|
||||
this._configSubject.next(config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config
|
||||
*
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
getConfig(): Observable<any>
|
||||
{
|
||||
return this._configSubject.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset to the default config
|
||||
*/
|
||||
resetToDefaults(): void
|
||||
{
|
||||
// Set the config from the default config
|
||||
this._configSubject.next(_.cloneDeep(this._defaultConfig));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,16 +11,20 @@ import { Injectable } from '@angular/core';
|
||||
@Injectable()
|
||||
export class FuseCopierService
|
||||
{
|
||||
|
||||
private textarea: HTMLTextAreaElement;
|
||||
|
||||
/** Copy the text value to the clipboard. */
|
||||
/**
|
||||
* Copy the text value to the clipboard
|
||||
*
|
||||
* @param {string} text
|
||||
* @returns {boolean}
|
||||
*/
|
||||
copyText(text: string): boolean
|
||||
{
|
||||
this.createTextareaAndSelect(text);
|
||||
|
||||
const copySuccessful = document.execCommand('copy');
|
||||
this.removeFake();
|
||||
this._removeFake();
|
||||
|
||||
return copySuccessful;
|
||||
}
|
||||
@@ -28,8 +32,10 @@ export class FuseCopierService
|
||||
/**
|
||||
* Creates a hidden textarea element, sets its value from `text` property,
|
||||
* and makes a selection on it.
|
||||
*
|
||||
* @param {string} text
|
||||
*/
|
||||
private createTextareaAndSelect(text: string)
|
||||
private createTextareaAndSelect(text: string): void
|
||||
{
|
||||
// Create a fake element to hold the contents to copy
|
||||
this.textarea = document.createElement('textarea');
|
||||
@@ -53,8 +59,12 @@ export class FuseCopierService
|
||||
this.textarea.setSelectionRange(0, this.textarea.value.length);
|
||||
}
|
||||
|
||||
/** Remove the text area from the DOM. */
|
||||
private removeFake()
|
||||
/**
|
||||
* Remove the text area from the DOM
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _removeFake(): void
|
||||
{
|
||||
if ( this.textarea )
|
||||
{
|
||||
|
||||
@@ -8,16 +8,42 @@ export class FuseMatchMediaService
|
||||
activeMediaQuery: string;
|
||||
onMediaChange: BehaviorSubject<string> = new BehaviorSubject<string>('');
|
||||
|
||||
constructor(private observableMedia: ObservableMedia)
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ObservableMedia} _observableMedia
|
||||
*/
|
||||
constructor(
|
||||
private _observableMedia: ObservableMedia
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.activeMediaQuery = '';
|
||||
|
||||
this.observableMedia.subscribe((change: MediaChange) => {
|
||||
if ( this.activeMediaQuery !== change.mqAlias )
|
||||
{
|
||||
this.activeMediaQuery = change.mqAlias;
|
||||
this.onMediaChange.next(change.mqAlias);
|
||||
}
|
||||
});
|
||||
// Initialize
|
||||
this._init();
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _init(): void
|
||||
{
|
||||
this._observableMedia
|
||||
.subscribe((change: MediaChange) => {
|
||||
if ( this.activeMediaQuery !== change.mqAlias )
|
||||
{
|
||||
this.activeMediaQuery = change.mqAlias;
|
||||
this.onMediaChange.next(change.mqAlias);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,23 +6,45 @@ import { NavigationEnd, Router } from '@angular/router';
|
||||
@Injectable()
|
||||
export class FuseSplashScreenService
|
||||
{
|
||||
splashScreenEl;
|
||||
public player: AnimationPlayer;
|
||||
splashScreenEl: any;
|
||||
player: AnimationPlayer;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {AnimationBuilder} _animationBuilder
|
||||
* @param _document
|
||||
* @param {Router} _router
|
||||
*/
|
||||
constructor(
|
||||
private animationBuilder: AnimationBuilder,
|
||||
@Inject(DOCUMENT) private document: any,
|
||||
private router: Router
|
||||
private _animationBuilder: AnimationBuilder,
|
||||
@Inject(DOCUMENT) private _document: any,
|
||||
private _router: Router
|
||||
)
|
||||
{
|
||||
// Initialize
|
||||
this._init();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _init(): void
|
||||
{
|
||||
// Get the splash screen element
|
||||
this.splashScreenEl = this.document.body.querySelector('#fuse-splash-screen');
|
||||
this.splashScreenEl = this._document.body.querySelector('#fuse-splash-screen');
|
||||
|
||||
// If the splash screen element exists...
|
||||
if ( this.splashScreenEl )
|
||||
{
|
||||
// Hide it on the first NavigationEnd event
|
||||
const hideOnLoad = this.router.events.subscribe((event) => {
|
||||
const hideOnLoad = this._router.events.subscribe((event) => {
|
||||
if ( event instanceof NavigationEnd )
|
||||
{
|
||||
setTimeout(() => {
|
||||
@@ -38,10 +60,17 @@ export class FuseSplashScreenService
|
||||
}
|
||||
}
|
||||
|
||||
show()
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Show the splash screen
|
||||
*/
|
||||
show(): void
|
||||
{
|
||||
this.player =
|
||||
this.animationBuilder
|
||||
this._animationBuilder
|
||||
.build([
|
||||
style({
|
||||
opacity: '0',
|
||||
@@ -55,10 +84,13 @@ export class FuseSplashScreenService
|
||||
}, 0);
|
||||
}
|
||||
|
||||
hide()
|
||||
/**
|
||||
* Hide the splash screen
|
||||
*/
|
||||
hide(): void
|
||||
{
|
||||
this.player =
|
||||
this.animationBuilder
|
||||
this._animationBuilder
|
||||
.build([
|
||||
style({opacity: '1'}),
|
||||
animate('400ms ease', style({
|
||||
|
||||
@@ -10,18 +10,34 @@ export interface Locale
|
||||
@Injectable()
|
||||
export class FuseTranslationLoaderService
|
||||
{
|
||||
constructor(private translate: TranslateService)
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {TranslateService} _translateService
|
||||
*/
|
||||
constructor(
|
||||
private _translateService: TranslateService
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public loadTranslations(...args: Locale[]): void
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Load translations
|
||||
*
|
||||
* @param {Locale} args
|
||||
*/
|
||||
loadTranslations(...args: Locale[]): void
|
||||
{
|
||||
const locales = [...args];
|
||||
|
||||
locales.forEach((locale) => {
|
||||
// use setTranslation() with the third argument set to true
|
||||
// to append translations instead of replacing them
|
||||
this.translate.setTranslation(locale.lang, locale.data, true);
|
||||
this._translateService.setTranslation(locale.lang, locale.data, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
24
src/@fuse/types/fuse-config.ts
Normal file
24
src/@fuse/types/fuse-config.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export interface FuseConfig
|
||||
{
|
||||
layout: {
|
||||
style: string,
|
||||
width: 'fullwidth' | 'boxed',
|
||||
navbar: {
|
||||
hidden: boolean,
|
||||
folded: boolean,
|
||||
position: 'left' | 'right' | 'top',
|
||||
background: string
|
||||
},
|
||||
toolbar: {
|
||||
hidden: boolean,
|
||||
position: 'above' | 'above-static' | 'above-fixed' | 'below' | 'below-static' | 'below-fixed',
|
||||
background: string
|
||||
}
|
||||
footer: {
|
||||
hidden: boolean,
|
||||
position: 'above' | 'above-static' | 'above-fixed' | 'below' | 'below-static' | 'below-fixed',
|
||||
background: string
|
||||
}
|
||||
};
|
||||
customScrollbars: boolean;
|
||||
}
|
||||
26
src/@fuse/types/fuse-navigation.ts
Normal file
26
src/@fuse/types/fuse-navigation.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
export interface FuseNavigationItem
|
||||
{
|
||||
id: string;
|
||||
title: string;
|
||||
type: 'item' | 'group' | 'collapsable';
|
||||
translate?: string;
|
||||
icon?: string;
|
||||
hidden?: boolean;
|
||||
url?: string;
|
||||
exactMatch?: boolean;
|
||||
externalUrl?: boolean;
|
||||
openInNewTab?: boolean;
|
||||
function?: any;
|
||||
badge?: {
|
||||
title?: string;
|
||||
translate?: string;
|
||||
bg?: string;
|
||||
fg?: string;
|
||||
};
|
||||
children?: FuseNavigationItem[];
|
||||
}
|
||||
|
||||
export interface FuseNavigation extends FuseNavigationItem
|
||||
{
|
||||
children?: FuseNavigationItem[];
|
||||
}
|
||||
2
src/@fuse/types/index.ts
Normal file
2
src/@fuse/types/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './fuse-config';
|
||||
export * from './fuse-navigation';
|
||||
@@ -1,6 +1,13 @@
|
||||
export class FuseUtils
|
||||
{
|
||||
public static filterArrayByString(mainArr, searchText)
|
||||
/**
|
||||
* Filter array by string
|
||||
*
|
||||
* @param mainArr
|
||||
* @param searchText
|
||||
* @returns {any}
|
||||
*/
|
||||
public static filterArrayByString(mainArr, searchText): any
|
||||
{
|
||||
if ( searchText === '' )
|
||||
{
|
||||
@@ -14,7 +21,14 @@ export class FuseUtils
|
||||
});
|
||||
}
|
||||
|
||||
public static searchInObj(itemObj, searchText)
|
||||
/**
|
||||
* Search in object
|
||||
*
|
||||
* @param itemObj
|
||||
* @param searchText
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static searchInObj(itemObj, searchText): boolean
|
||||
{
|
||||
for ( const prop in itemObj )
|
||||
{
|
||||
@@ -51,7 +65,14 @@ export class FuseUtils
|
||||
}
|
||||
}
|
||||
|
||||
public static searchInArray(arr, searchText)
|
||||
/**
|
||||
* Search in array
|
||||
*
|
||||
* @param arr
|
||||
* @param searchText
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static searchInArray(arr, searchText): boolean
|
||||
{
|
||||
for ( const value of arr )
|
||||
{
|
||||
@@ -73,14 +94,26 @@ export class FuseUtils
|
||||
}
|
||||
}
|
||||
|
||||
public static searchInString(value, searchText)
|
||||
/**
|
||||
* Search in string
|
||||
*
|
||||
* @param value
|
||||
* @param searchText
|
||||
* @returns {any}
|
||||
*/
|
||||
public static searchInString(value, searchText): any
|
||||
{
|
||||
return value.toLowerCase().includes(searchText);
|
||||
}
|
||||
|
||||
public static generateGUID()
|
||||
/**
|
||||
* Generate a unique GUID
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
public static generateGUID(): string
|
||||
{
|
||||
function S4()
|
||||
function S4(): string
|
||||
{
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
@@ -90,7 +123,13 @@ export class FuseUtils
|
||||
return S4() + S4();
|
||||
}
|
||||
|
||||
public static toggleInArray(item, array)
|
||||
/**
|
||||
* Toggle in array
|
||||
*
|
||||
* @param item
|
||||
* @param array
|
||||
*/
|
||||
public static toggleInArray(item, array): void
|
||||
{
|
||||
if ( array.indexOf(item) === -1 )
|
||||
{
|
||||
@@ -102,7 +141,13 @@ export class FuseUtils
|
||||
}
|
||||
}
|
||||
|
||||
public static handleize(text)
|
||||
/**
|
||||
* Handleize
|
||||
*
|
||||
* @param text
|
||||
* @returns {string}
|
||||
*/
|
||||
public static handleize(text): string
|
||||
{
|
||||
return text.toString().toLowerCase()
|
||||
.replace(/\s+/g, '-') // Replace spaces with -
|
||||
|
||||
@@ -1 +1,29 @@
|
||||
<fuse-main></fuse-main>
|
||||
<!-- VERTICAL LAYOUT 1 -->
|
||||
<ng-container *ngIf="fuseConfig.layout.style === 'vertical-layout-1'">
|
||||
<vertical-layout-1></vertical-layout-1>
|
||||
</ng-container>
|
||||
|
||||
<!-- VERTICAL LAYOUT 2 -->
|
||||
<ng-container *ngIf="fuseConfig.layout.style === 'vertical-layout-2'">
|
||||
<vertical-layout-2></vertical-layout-2>
|
||||
</ng-container>
|
||||
|
||||
<!-- VERTICAL LAYOUT 3 -->
|
||||
<ng-container *ngIf="fuseConfig.layout.style === 'vertical-layout-3'">
|
||||
<vertical-layout-3></vertical-layout-3>
|
||||
</ng-container>
|
||||
|
||||
<!-- HORIZONTAL LAYOUT 1 -->
|
||||
<ng-container *ngIf="fuseConfig.layout.style === 'horizontal-layout-1'">
|
||||
<horizontal-layout-1></horizontal-layout-1>
|
||||
</ng-container>
|
||||
|
||||
<!-- THEME OPTIONS PANEL -->
|
||||
<button mat-icon-button class="mat-primary-bg mat-elevation-z2 theme-options-button"
|
||||
(click)="toggleSidebarOpen('themeOptionsPanel')">
|
||||
<mat-icon>settings</mat-icon>
|
||||
</button>
|
||||
|
||||
<fuse-sidebar name="themeOptionsPanel" class="theme-options-sidebar" position="right" [invisibleOverlay]="true">
|
||||
<fuse-theme-options></fuse-theme-options>
|
||||
</fuse-sidebar>
|
||||
@@ -0,0 +1,38 @@
|
||||
:host {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
|
||||
.theme-options-button {
|
||||
position: absolute;
|
||||
top: 160px;
|
||||
right: 0;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
pointer-events: auto;
|
||||
opacity: .75;
|
||||
z-index: 998;
|
||||
|
||||
mat-icon {
|
||||
animation: rotating 3s linear infinite;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.theme-options-sidebar {
|
||||
width: 360px;
|
||||
min-width: 360px;
|
||||
max-width: 360px;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,113 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
import { FuseSplashScreenService } from '@fuse/services/splash-screen.service';
|
||||
import { FuseTranslationLoaderService } from '@fuse/services/translation-loader.service';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
|
||||
import { locale as navigationEnglish } from './navigation/i18n/en';
|
||||
import { locale as navigationTurkish } from './navigation/i18n/tr';
|
||||
import { navigation } from 'app/navigation/navigation';
|
||||
import { locale as navigationEnglish } from 'app/navigation/i18n/en';
|
||||
import { locale as navigationTurkish } from 'app/navigation/i18n/tr';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-root',
|
||||
selector : 'app',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls : ['./app.component.scss']
|
||||
})
|
||||
export class AppComponent
|
||||
export class AppComponent implements OnInit, OnDestroy
|
||||
{
|
||||
navigation: any;
|
||||
fuseConfig: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseConfigService} _fuseConfigService
|
||||
* @param {FuseNavigationService} _fuseNavigationService
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
* @param {FuseSplashScreenService} _fuseSplashScreenService
|
||||
* @param {FuseTranslationLoaderService} _fuseTranslationLoaderService
|
||||
* @param {TranslateService} _translateService
|
||||
*/
|
||||
constructor(
|
||||
private translate: TranslateService,
|
||||
private fuseNavigationService: FuseNavigationService,
|
||||
private fuseSplashScreen: FuseSplashScreenService,
|
||||
private fuseTranslationLoader: FuseTranslationLoaderService
|
||||
private _fuseConfigService: FuseConfigService,
|
||||
private _fuseNavigationService: FuseNavigationService,
|
||||
private _fuseSidebarService: FuseSidebarService,
|
||||
private _fuseSplashScreenService: FuseSplashScreenService,
|
||||
private _fuseTranslationLoaderService: FuseTranslationLoaderService,
|
||||
private _translateService: TranslateService
|
||||
)
|
||||
{
|
||||
// Get default navigation
|
||||
this.navigation = navigation;
|
||||
|
||||
// Register the navigation to the service
|
||||
this._fuseNavigationService.register('main', this.navigation);
|
||||
|
||||
// Set the main navigation as our current navigation
|
||||
this._fuseNavigationService.setCurrentNavigation('main');
|
||||
|
||||
// Add languages
|
||||
this.translate.addLangs(['en', 'tr']);
|
||||
this._translateService.addLangs(['en', 'tr']);
|
||||
|
||||
// Set the default language
|
||||
this.translate.setDefaultLang('en');
|
||||
this._translateService.setDefaultLang('en');
|
||||
|
||||
// Set the navigation translations
|
||||
this.fuseTranslationLoader.loadTranslations(navigationEnglish, navigationTurkish);
|
||||
this._fuseTranslationLoaderService.loadTranslations(navigationEnglish, navigationTurkish);
|
||||
|
||||
// Use a language
|
||||
this.translate.use('en');
|
||||
this._translateService.use('en');
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to config changes
|
||||
this._fuseConfigService.config
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((config) => {
|
||||
this.fuseConfig = config;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle sidebar open
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
toggleSidebarOpen(key): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(key).toggleOpen();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,22 +3,47 @@ import { BrowserModule } from '@angular/platform-browser';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { MatMomentDateModule } from '@angular/material-moment-adapter';
|
||||
import { MatButtonModule, MatIconModule } from '@angular/material';
|
||||
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import 'hammerjs';
|
||||
|
||||
import { FuseModule } from '@fuse/fuse.module';
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseSidebarModule, FuseThemeOptionsModule } from '@fuse/components';
|
||||
|
||||
import { fuseConfig } from './fuse-config';
|
||||
import { fuseConfig } from 'app/fuse-config';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { FuseMainModule } from './main/main.module';
|
||||
import { FuseSampleModule } from './main/content/sample/sample.module';
|
||||
import { FakeDbService } from 'app/fake-db/fake-db.service';
|
||||
import { AppComponent } from 'app/app.component';
|
||||
import { AppStoreModule } from 'app/store/store.module';
|
||||
import { LayoutModule } from 'app/layout/layout.module';
|
||||
|
||||
const appRoutes: Routes = [
|
||||
{
|
||||
path : 'apps',
|
||||
loadChildren: './main/apps/apps.module#AppsModule'
|
||||
},
|
||||
{
|
||||
path : 'pages',
|
||||
loadChildren: './main/pages/pages.module#PagesModule'
|
||||
},
|
||||
{
|
||||
path : 'ui',
|
||||
loadChildren: './main/ui/ui.module#UIModule'
|
||||
},
|
||||
{
|
||||
path : 'documentation',
|
||||
loadChildren: './main/documentation/documentation.module#DocumentationModule'
|
||||
},
|
||||
{
|
||||
path : 'angular-material-elements',
|
||||
loadChildren: './main/angular-material-elements/angular-material-elements.module#AngularMaterialElementsModule'
|
||||
},
|
||||
{
|
||||
path : '**',
|
||||
redirectTo: 'sample'
|
||||
redirectTo: 'apps/dashboards/analytics'
|
||||
}
|
||||
];
|
||||
|
||||
@@ -31,13 +56,29 @@ const appRoutes: Routes = [
|
||||
BrowserAnimationsModule,
|
||||
HttpClientModule,
|
||||
RouterModule.forRoot(appRoutes),
|
||||
TranslateModule.forRoot(),
|
||||
|
||||
// Fuse Main and Shared modules
|
||||
TranslateModule.forRoot(),
|
||||
InMemoryWebApiModule.forRoot(FakeDbService, {
|
||||
delay : 0,
|
||||
passThruUnknownUrl: true
|
||||
}),
|
||||
|
||||
// Material moment date module
|
||||
MatMomentDateModule,
|
||||
|
||||
// Material
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
|
||||
// Fuse modules
|
||||
FuseModule.forRoot(fuseConfig),
|
||||
FuseSharedModule,
|
||||
FuseMainModule,
|
||||
FuseSampleModule
|
||||
FuseSidebarModule,
|
||||
FuseThemeOptionsModule,
|
||||
|
||||
// App modules
|
||||
LayoutModule,
|
||||
AppStoreModule
|
||||
],
|
||||
bootstrap : [
|
||||
AppComponent
|
||||
|
||||
773
src/app/fake-db/academy.ts
Normal file
773
src/app/fake-db/academy.ts
Normal file
@@ -0,0 +1,773 @@
|
||||
export class AcademyFakeDb
|
||||
{
|
||||
public static courses = [
|
||||
{
|
||||
'id' : '15459251a6d6b397565',
|
||||
'title' : 'Basics of Angular',
|
||||
'slug' : 'basics-of-angular',
|
||||
'category': 'web',
|
||||
'length' : 30,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '154588a0864d2881124',
|
||||
'title' : 'Basics of TypeScript',
|
||||
'slug' : 'basics-of-typeScript',
|
||||
'category': 'web',
|
||||
'length' : 60,
|
||||
'updated' : 'Nov 01, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '15453ba60d3baa5daaf',
|
||||
'title' : 'Android N: Quick Settings',
|
||||
'slug' : 'android-n-quick-settings',
|
||||
'category': 'android',
|
||||
'length' : 120,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '15453a06c08fb021776',
|
||||
'title' : 'Keep Sensitive Data Safe and Private',
|
||||
'slug' : 'keep-sensitive-data-safe-and-private',
|
||||
'category': 'android',
|
||||
'length' : 45,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '15427f4c1b7f3953234',
|
||||
'title' : 'Building a gRPC Service with Java',
|
||||
'slug' : 'building-a-grpc-service-with-java',
|
||||
'category': 'cloud',
|
||||
'length' : 30,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1542d75d929a603125',
|
||||
'title' : 'Build a PWA Using Workbox',
|
||||
'slug' : 'build-a-pwa-using-workbox',
|
||||
'category': 'web',
|
||||
'length' : 120,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1543ee3a5b43e0f9f45',
|
||||
'title' : 'Build an App for the Google Assistant with Firebase and Dialogflow',
|
||||
'slug' : 'build-an-app-for-the-google-assistant-with-firebase-and-dialogflow',
|
||||
'category': 'firebase',
|
||||
'length' : 30,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1543cc4515df3146112',
|
||||
'title' : 'Cloud Functions for Firebase',
|
||||
'slug' : 'cloud-functions-for-firebase',
|
||||
'category': 'firebase',
|
||||
'length' : 45,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '154398a4770d7aaf9a2',
|
||||
'title' : 'Manage Your Pivotal Cloud Foundry App\'s Using Apigee Edge',
|
||||
'slug' : 'manage-your-pivotal-cloud-foundry-apps-using-apigee-Edge',
|
||||
'category': 'cloud',
|
||||
'length' : 90,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '15438351f87dcd68567',
|
||||
'title' : 'Building Beautiful UIs with Flutter',
|
||||
'your' : 'building-beautiful-uis-with-flutter',
|
||||
'category': 'web',
|
||||
'length' : 90,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1544e43dcdae6ebf876',
|
||||
'title' : 'Cloud Firestore',
|
||||
'slug' : 'cloud-firestore',
|
||||
'category': 'firebase',
|
||||
'length' : 90,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1541ca7af66da284177',
|
||||
'title' : 'Customize Network Topology with Subnetworks',
|
||||
'slug' : 'customize-network-topology-with-subnetworks',
|
||||
'category': 'web',
|
||||
'length' : 45,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '154297167e781781745',
|
||||
'title' : 'Looking at Campaign Finance with BigQuery',
|
||||
'slug' : 'looking-at-campaign-finance-with-bigquery',
|
||||
'category': 'cloud',
|
||||
'length' : 60,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '154537435d5b32bf11a',
|
||||
'title' : 'Firebase Android',
|
||||
'slug' : 'firebase-android',
|
||||
'category': 'android',
|
||||
'length' : 45,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '154204e45a59b168453',
|
||||
'title' : 'Simulating a Thread Network Using OpenThread',
|
||||
'slug' : 'simulating-a-thread-network-using-openthread',
|
||||
'category': 'web',
|
||||
'length' : 45,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1541dd1e05dfc439216',
|
||||
'title' : 'Your First Progressive Web App',
|
||||
'slug' : 'your-first-progressive-web-app',
|
||||
'category': 'web',
|
||||
'length' : 30,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1532dfc67e704e48515',
|
||||
'title' : 'Launch Cloud Datalab',
|
||||
'slug' : 'launch-cloud-datalab',
|
||||
'category': 'cloud',
|
||||
'length' : 60,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1542e43dfaae6ebf226',
|
||||
'title' : 'Personalize Your iOS App with Firebase User Management',
|
||||
'slug' : 'personalize-your-ios-app-with-firebase-user-management',
|
||||
'category': 'firebase',
|
||||
'length' : 90,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
}
|
||||
];
|
||||
|
||||
public static categories = [
|
||||
{
|
||||
'id' : 0,
|
||||
'value': 'web',
|
||||
'label': 'Web'
|
||||
},
|
||||
{
|
||||
'id' : 1,
|
||||
'value': 'firebase',
|
||||
'label': 'Firebase'
|
||||
},
|
||||
{
|
||||
'id' : 2,
|
||||
'value': 'cloud',
|
||||
'label': 'Cloud'
|
||||
},
|
||||
{
|
||||
'id' : 3,
|
||||
'value': 'android',
|
||||
'label': 'Android'
|
||||
}
|
||||
];
|
||||
|
||||
private static demoSteps = [
|
||||
{
|
||||
'title' : 'Introduction',
|
||||
'content': '<h1>Step 1 - Introduction</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Get the sample code',
|
||||
'content': '<h1>Step 2 - Get the sample code</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Create a Firebase project and Set up your app',
|
||||
'content': '<h1>Step 3 - Create a Firebase project and Set up your app</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Install the Firebase Command Line Interface',
|
||||
'content': '<h1>Step 4 - Install the Firebase Command Line Interface</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Deploy and run the web app',
|
||||
'content': '<h1>Step 5 - Deploy and run the web app</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'The Functions Directory',
|
||||
'content': '<h1>Step 6 - The Functions Directory</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Import the Cloud Functions and Firebase Admin modules',
|
||||
'content': '<h1>Step 7 - Import the Cloud Functions and Firebase Admin modules</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Welcome New Users',
|
||||
'content': '<h1>Step 8 - Welcome New Users</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Images moderation',
|
||||
'content': '<h1>Step 9 - Images moderation</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'New Message Notifications',
|
||||
'content': '<h1>Step 10 - New Message Notifications</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Congratulations!',
|
||||
'content': '<h1>Step 11 - Congratulations!</h1>' +
|
||||
'<br>' +
|
||||
'You\'ve built a full-fidelity, offline-capable progressive web app by leveraging the power of reusable Web Components and Firebase. Why bother with a native app when you know how to do all that?!'
|
||||
}
|
||||
];
|
||||
|
||||
public static course = [
|
||||
{
|
||||
'id' : '15459251a6d6b397565',
|
||||
'title' : 'Basics of Angular',
|
||||
'slug' : 'basics-of-angular',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 30,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '154588a0864d2881124',
|
||||
'title' : 'Basics of TypeScript',
|
||||
'slug' : 'basics-of-typeScript',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 60,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Nov 01, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '15453ba60d3baa5daaf',
|
||||
'title' : 'Android N: Quick Settings',
|
||||
'slug' : 'android-n-quick-settings',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'android',
|
||||
'length' : 120,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '15453a06c08fb021776',
|
||||
'title' : 'Keep Sensitive Data Safe and Private',
|
||||
'slug' : 'keep-sensitive-data-safe-and-private',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'android',
|
||||
'length' : 45,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '15427f4c1b7f3953234',
|
||||
'title' : 'Building a gRPC Service with Java',
|
||||
'slug' : 'building-a-grpc-service-with-java',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'cloud',
|
||||
'length' : 30,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1542d75d929a603125',
|
||||
'title' : 'Build a PWA Using Workbox',
|
||||
'slug' : 'build-a-pwa-using-workbox',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 120,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1543ee3a5b43e0f9f45',
|
||||
'title' : 'Build an App for the Google Assistant with Firebase and Dialogflow',
|
||||
'slug' : 'build-an-app-for-the-google-assistant-with-firebase-and-dialogflow',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'firebase',
|
||||
'length' : 30,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1543cc4515df3146112',
|
||||
'title' : 'Cloud Functions for Firebase',
|
||||
'slug' : 'cloud-functions-for-firebase',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'firebase',
|
||||
'length' : 45,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '154398a4770d7aaf9a2',
|
||||
'title' : 'Manage Your Pivotal Cloud Foundry App\'s Using Apigee Edge',
|
||||
'slug' : 'manage-your-pivotal-cloud-foundry-apps-using-apigee-Edge',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'cloud',
|
||||
'length' : 90,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '15438351f87dcd68567',
|
||||
'title' : 'Building Beautiful UIs with Flutter',
|
||||
'your' : 'building-beautiful-uis-with-flutter',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 90,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1544e43dcdae6ebf876',
|
||||
'title' : 'Cloud Firestore',
|
||||
'slug' : 'cloud-firestore',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'firebase',
|
||||
'length' : 90,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1541ca7af66da284177',
|
||||
'title' : 'Customize Network Topology with Subnetworks',
|
||||
'slug' : 'customize-network-topology-with-subnetworks',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 45,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '154297167e781781745',
|
||||
'title' : 'Looking at Campaign Finance with BigQuery',
|
||||
'slug' : 'looking-at-campaign-finance-with-bigquery',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'cloud',
|
||||
'length' : 60,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '154537435d5b32bf11a',
|
||||
'title' : 'Firebase Android',
|
||||
'slug' : 'firebase-android',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'android',
|
||||
'length' : 45,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '154204e45a59b168453',
|
||||
'title' : 'Simulating a Thread Network Using OpenThread',
|
||||
'slug' : 'simulating-a-thread-network-using-openthread',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 45,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1541dd1e05dfc439216',
|
||||
'title' : 'Your First Progressive Web App',
|
||||
'slug' : 'your-first-progressive-web-app',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 30,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1532dfc67e704e48515',
|
||||
'title' : 'Launch Cloud Datalab',
|
||||
'slug' : 'launch-cloud-datalab',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'cloud',
|
||||
'length' : 60,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1542e43dfaae6ebf226',
|
||||
'title' : 'Personalize Your iOS App with Firebase User Management',
|
||||
'slug' : 'personalize-your-ios-app-with-firebase-user-management',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'firebase',
|
||||
'length' : 90,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
97
src/app/fake-db/calendar.ts
Normal file
97
src/app/fake-db/calendar.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import {
|
||||
startOfDay,
|
||||
endOfDay,
|
||||
subDays,
|
||||
addDays,
|
||||
endOfMonth,
|
||||
isSameDay,
|
||||
isSameMonth,
|
||||
addHours
|
||||
} from 'date-fns';
|
||||
|
||||
export class CalendarFakeDb
|
||||
{
|
||||
|
||||
public static data = [
|
||||
{
|
||||
id : 'events',
|
||||
data: [
|
||||
{
|
||||
start : subDays(startOfDay(new Date()), 1),
|
||||
end : addDays(new Date(), 1),
|
||||
title : 'A 3 day event',
|
||||
allDay : false,
|
||||
color : {
|
||||
primary : '#ad2121',
|
||||
secondary: '#FAE3E3'
|
||||
},
|
||||
resizable: {
|
||||
beforeStart: true,
|
||||
afterEnd : true
|
||||
},
|
||||
draggable: true,
|
||||
meta : {
|
||||
location: 'Los Angeles',
|
||||
notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.'
|
||||
}
|
||||
},
|
||||
{
|
||||
start : startOfDay(new Date()),
|
||||
title : 'An event with no end date',
|
||||
allDay : false,
|
||||
color : {
|
||||
primary : '#e3bc08',
|
||||
secondary: '#FDF1BA'
|
||||
},
|
||||
resizable: {
|
||||
beforeStart: true,
|
||||
afterEnd : true
|
||||
},
|
||||
draggable: true,
|
||||
meta : {
|
||||
location: 'Los Angeles',
|
||||
notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.'
|
||||
}
|
||||
},
|
||||
{
|
||||
start : subDays(endOfMonth(new Date()), 3),
|
||||
end : addDays(endOfMonth(new Date()), 3),
|
||||
title : 'A long event that spans 2 months',
|
||||
allDay : false,
|
||||
color : {
|
||||
primary : '#1e90ff',
|
||||
secondary: '#D1E8FF'
|
||||
},
|
||||
resizable: {
|
||||
beforeStart: true,
|
||||
afterEnd : true
|
||||
},
|
||||
draggable: true,
|
||||
meta : {
|
||||
location: 'Los Angeles',
|
||||
notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.'
|
||||
}
|
||||
},
|
||||
{
|
||||
start : addHours(startOfDay(new Date()), 2),
|
||||
end : new Date(),
|
||||
title : 'A draggable and resizable event',
|
||||
allDay : false,
|
||||
color : {
|
||||
primary : '#e3bc08',
|
||||
secondary: '#FDF1BA'
|
||||
},
|
||||
resizable: {
|
||||
beforeStart: true,
|
||||
afterEnd : true
|
||||
},
|
||||
draggable: true,
|
||||
meta : {
|
||||
location: 'Los Angeles',
|
||||
notes : 'Eos eu verear adipiscing, ex ornatus denique iracundia sed, quodsi oportere appellantur an pri.'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
325
src/app/fake-db/chat.ts
Normal file
325
src/app/fake-db/chat.ts
Normal file
@@ -0,0 +1,325 @@
|
||||
export class ChatFakeDb
|
||||
{
|
||||
public static contacts = [
|
||||
{
|
||||
'id' : '5725a680b3249760ea21de52',
|
||||
'name' : 'Alice Freeman',
|
||||
'avatar': 'assets/images/avatars/alice.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680606588342058356d',
|
||||
'name' : 'Arnold',
|
||||
'avatar': 'assets/images/avatars/Arnold.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a68009e20d0a9e9acf2a',
|
||||
'name' : 'Barrera',
|
||||
'avatar': 'assets/images/avatars/Barrera.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...',
|
||||
'unread': null
|
||||
},
|
||||
{
|
||||
'id' : '5725a6809fdd915739187ed5',
|
||||
'name' : 'Blair',
|
||||
'avatar': 'assets/images/avatars/Blair.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...',
|
||||
'unread': 3
|
||||
},
|
||||
{
|
||||
'id' : '5725a68007920cf75051da64',
|
||||
'name' : 'Boyle',
|
||||
'avatar': 'assets/images/avatars/Boyle.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a68031fdbb1db2c1af47',
|
||||
'name' : 'Christy',
|
||||
'avatar': 'assets/images/avatars/Christy.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680bc670af746c435e2',
|
||||
'name' : 'Copeland',
|
||||
'avatar': 'assets/images/avatars/Copeland.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680e7eb988a58ddf303',
|
||||
'name' : 'Estes',
|
||||
'avatar': 'assets/images/avatars/Estes.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680dcb077889f758961',
|
||||
'name' : 'Harper',
|
||||
'avatar': 'assets/images/avatars/Harper.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6806acf030f9341e925',
|
||||
'name' : 'Helen',
|
||||
'avatar': 'assets/images/avatars/Helen.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680ae1ae9a3c960d487',
|
||||
'name' : 'Henderson',
|
||||
'avatar': 'assets/images/avatars/Henderson.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680b8d240c011dd224b',
|
||||
'name' : 'Josefina',
|
||||
'avatar': 'assets/images/avatars/Josefina.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a68034cb3968e1f79eac',
|
||||
'name' : 'Katina',
|
||||
'avatar': 'assets/images/avatars/Katina.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6801146cce777df2a08',
|
||||
'name' : 'Lily',
|
||||
'avatar': 'assets/images/avatars/Lily.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6808a178bfd034d6ecf',
|
||||
'name' : 'Mai',
|
||||
'avatar': 'assets/images/avatars/Mai.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680653c265f5c79b5a9',
|
||||
'name' : 'Nancy',
|
||||
'avatar': 'assets/images/avatars/Nancy.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680bbcec3cc32a8488a',
|
||||
'name' : 'Nora',
|
||||
'avatar': 'assets/images/avatars/Nora.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6803d87f1b77e17b62b',
|
||||
'name' : 'Odessa',
|
||||
'avatar': 'assets/images/avatars/Odessa.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680e87cb319bd9bd673',
|
||||
'name' : 'Reyna',
|
||||
'avatar': 'assets/images/avatars/Reyna.jpg',
|
||||
'status': 'offline',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35775',
|
||||
'name' : 'Shauna',
|
||||
'avatar': 'assets/images/avatars/Shauna.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...',
|
||||
'unread': null
|
||||
},
|
||||
{
|
||||
'id' : '5725a680aef1e5cf26dd3d1f',
|
||||
'name' : 'Shepard',
|
||||
'avatar': 'assets/images/avatars/Shepard.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a680cd7efa56a45aea5d',
|
||||
'name' : 'Tillman',
|
||||
'avatar': 'assets/images/avatars/Tillman.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680fb65c91a82cb35e2',
|
||||
'name' : 'Trevino',
|
||||
'avatar': 'assets/images/avatars/Trevino.jpg',
|
||||
'status': 'away',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a68018c663044be49cbf',
|
||||
'name' : 'Tyson',
|
||||
'avatar': 'assets/images/avatars/Tyson.jpg',
|
||||
'status': 'do-not-disturb',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
},
|
||||
{
|
||||
'id' : '5725a6809413bf8a0a5272b1',
|
||||
'name' : 'Velazquez',
|
||||
'avatar': 'assets/images/avatars/Velazquez.jpg',
|
||||
'status': 'online',
|
||||
'mood' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
|
||||
}
|
||||
];
|
||||
|
||||
public static chats = [
|
||||
{
|
||||
'id' : '1725a680b3249760ea21de52',
|
||||
'dialog': [
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'Quickly come to the meeting room 1B, we have a big server issue',
|
||||
'time' : '2017-03-22T08:54:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'I’m having breakfast right now, can’t you wait for 10 minutes?',
|
||||
'time' : '2017-03-22T08:55:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'We are losing money! Quick!',
|
||||
'time' : '2017-03-22T09:00:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'It’s not my money, you know. I will eat my breakfast and then I will come to the meeting room.',
|
||||
'time' : '2017-03-22T09:02:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'You are the worst!',
|
||||
'time' : '2017-03-22T09:05:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'We are losing money! Quick!',
|
||||
'time' : '2017-03-22T09:15:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'It’s not my money, you know. I will eat my breakfast and then I will come to the meeting room.',
|
||||
'time' : '2017-03-22T09:20:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'You are the worst!',
|
||||
'time' : '2017-03-22T09:22:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'We are losing money! Quick!',
|
||||
'time' : '2017-03-22T09:25:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'It’s not my money, you know. I will eat my breakfast and then I will come to the meeting room.',
|
||||
'time' : '2017-03-22T09:27:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'You are the worst!',
|
||||
'time' : '2017-03-22T09:33:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'We are losing money! Quick!',
|
||||
'time' : '2017-03-22T09:35:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'It’s not my money, you know. I will eat my breakfast and then I will come to the meeting room.',
|
||||
'time' : '2017-03-22T09:45:28.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b3249760ea21de52',
|
||||
'message': 'You are the worst!',
|
||||
'time' : '2017-03-22T10:00:28.299Z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '2725a680b8d240c011dd2243',
|
||||
'dialog': [
|
||||
{
|
||||
'who' : '5725a680b8d240c011dd224b',
|
||||
'message': 'Quickly come to the meeting room 1B, we have a big server issue',
|
||||
'time' : '2017-04-22T01:00:00.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a6802d10e277a0f35724',
|
||||
'message': 'I’m having breakfast right now, can’t you wait for 10 minutes?',
|
||||
'time' : '2017-04-22T01:05:00.299Z'
|
||||
},
|
||||
{
|
||||
'who' : '5725a680b8d240c011dd224b',
|
||||
'message': 'We are losing money! Quick!',
|
||||
'time' : '2017-04-22T01:10:00.299Z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '3725a6809413bf8a0a5272b4',
|
||||
'dialog': [
|
||||
{
|
||||
'who' : '5725a6809413bf8a0a5272b1',
|
||||
'message': 'Quickly come to the meeting room 1B, we have a big server issue',
|
||||
'time' : '2017-04-22T02:10:00.299Z'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
public static user = [
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35724',
|
||||
'name' : 'John Doe',
|
||||
'avatar' : 'assets/images/avatars/profile.jpg',
|
||||
'status' : 'online',
|
||||
'mood' : 'it\'s a status....not your diary...',
|
||||
'chatList': [
|
||||
{
|
||||
'id' : '1725a680b3249760ea21de52',
|
||||
'contactId' : '5725a680b3249760ea21de52',
|
||||
'name' : 'Alice Freeman',
|
||||
'unread' : 4,
|
||||
'lastMessageTime': '2017-06-12T02:10:18.931Z'
|
||||
},
|
||||
{
|
||||
'id' : '2725a680b8d240c011dd2243',
|
||||
'contactId' : '5725a680b8d240c011dd224b',
|
||||
'name' : 'Josefina',
|
||||
'unread' : null,
|
||||
'lastMessageTime': '2017-02-18T10:30:18.931Z'
|
||||
},
|
||||
{
|
||||
'id' : '3725a6809413bf8a0a5272b4',
|
||||
'contactId' : '5725a6809413bf8a0a5272b1',
|
||||
'name' : 'Velazquez',
|
||||
'unread' : 2,
|
||||
'lastMessageTime': '2017-03-18T12:30:18.931Z'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
411
src/app/fake-db/contacts.ts
Normal file
411
src/app/fake-db/contacts.ts
Normal file
@@ -0,0 +1,411 @@
|
||||
export class ContactsFakeDb
|
||||
{
|
||||
public static contacts = [
|
||||
{
|
||||
'id' : '5725a680b3249760ea21de52',
|
||||
'name' : 'Abbott',
|
||||
'lastName': 'Keitch',
|
||||
'avatar' : 'assets/images/avatars/Abbott.jpg',
|
||||
'nickname': 'Royalguard',
|
||||
'company' : 'Saois',
|
||||
'jobTitle': 'Digital Archivist',
|
||||
'email' : 'abbott@withinpixels.com',
|
||||
'phone' : '+1-202-555-0175',
|
||||
'address' : '933 8th Street Stamford, CT 06902',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680606588342058356d',
|
||||
'name' : 'Arnold',
|
||||
'lastName': 'Matlock',
|
||||
'avatar' : 'assets/images/avatars/Arnold.jpg',
|
||||
'nickname': 'Wanderer',
|
||||
'company' : 'Laotcone',
|
||||
'jobTitle': 'Graphic Artist',
|
||||
'email' : 'arnold@withinpixels.com',
|
||||
'phone' : '+1-202-555-0141',
|
||||
'address' : '906 Valley Road Michigan City, IN 46360',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a68009e20d0a9e9acf2a',
|
||||
'name' : 'Barrera',
|
||||
'lastName': 'Bradbury',
|
||||
'avatar' : 'assets/images/avatars/Barrera.jpg',
|
||||
'nickname': 'Jackal',
|
||||
'company' : 'Unizim',
|
||||
'jobTitle': 'Graphic Designer',
|
||||
'email' : 'barrera@withinpixels.com',
|
||||
'phone' : '+1-202-555-0196',
|
||||
'address' : '183 River Street Passaic, NJ 07055',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6809fdd915739187ed5',
|
||||
'name' : 'Blair',
|
||||
'lastName': 'Strangeway',
|
||||
'avatar' : 'assets/images/avatars/Blair.jpg',
|
||||
'nickname': 'Knight',
|
||||
'company' : 'Conedubdax',
|
||||
'jobTitle': 'Visual Designer',
|
||||
'email' : 'blair@withinpixels.com',
|
||||
'phone' : '+1-202-555-0118',
|
||||
'address' : '143 Jones Street Eau Claire, WI 54701',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a68007920cf75051da64',
|
||||
'name' : 'Boyle',
|
||||
'lastName': 'Winters',
|
||||
'avatar' : 'assets/images/avatars/Boyle.jpg',
|
||||
'nickname': 'Jester',
|
||||
'company' : 'Newo',
|
||||
'jobTitle': 'Catalogue Illustrator',
|
||||
'email' : 'boyle@withinpixels.com',
|
||||
'phone' : '+1-202-555-0177',
|
||||
'address' : '218 Pearl Street Brandon, FL 33510',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a68031fdbb1db2c1af47',
|
||||
'name' : 'Christy',
|
||||
'lastName': 'Camacho',
|
||||
'avatar' : 'assets/images/avatars/Christy.jpg',
|
||||
'nickname': 'Mist',
|
||||
'company' : 'uniway',
|
||||
'jobTitle': '3D Animator',
|
||||
'email' : 'christy@withinpixels.com',
|
||||
'phone' : '+1-202-555-0136',
|
||||
'address' : '329 Bridge Street Desoto, TX 75115',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680bc670af746c435e2',
|
||||
'name' : 'Copeland',
|
||||
'lastName': 'Redcliff',
|
||||
'avatar' : 'assets/images/avatars/Copeland.jpg',
|
||||
'nickname': 'Cloudlaw',
|
||||
'company' : 'Tempron',
|
||||
'jobTitle': 'Multimedia Artist',
|
||||
'email' : 'copeland@withinpixels.com',
|
||||
'phone' : '+1-202-555-0107',
|
||||
'address' : '956 6th Avenue North Bergen, NJ 0704',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680e7eb988a58ddf303',
|
||||
'name' : 'Estes',
|
||||
'lastName': 'Stevens',
|
||||
'avatar' : 'assets/images/avatars/Estes.jpg',
|
||||
'nickname': 'Roamer',
|
||||
'company' : 'nam-dex',
|
||||
'jobTitle': 'Special Effects Artist',
|
||||
'email' : 'estes@withinpixels.com',
|
||||
'phone' : '+1-202-555-0113',
|
||||
'address' : '664 York Street Cambridge, MA 02138',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680dcb077889f758961',
|
||||
'name' : 'Harper',
|
||||
'lastName': 'MacGuffin',
|
||||
'avatar' : 'assets/images/avatars/Harper.jpg',
|
||||
'nickname': 'Tempest',
|
||||
'company' : 'runcane',
|
||||
'jobTitle': 'Application Developer',
|
||||
'email' : 'harper@withinpixels.com',
|
||||
'phone' : '+1-202-555-0173',
|
||||
'address' : '738 Route 11 Cornelius, NC 28031',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6806acf030f9341e925',
|
||||
'name' : 'Helen',
|
||||
'lastName': 'Sheridan',
|
||||
'avatar' : 'assets/images/avatars/Helen.jpg',
|
||||
'nickname': 'Magicbattler',
|
||||
'company' : 'Subhow',
|
||||
'jobTitle': 'Content Developer',
|
||||
'email' : 'helen@withinpixels.com',
|
||||
'phone' : '+1-202-555-0163',
|
||||
'address' : '194 Washington Avenue Saint Petersburg, FL 33702',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680ae1ae9a3c960d487',
|
||||
'name' : 'Henderson',
|
||||
'lastName': 'Cambias',
|
||||
'avatar' : 'assets/images/avatars/Henderson.jpg',
|
||||
'nickname': 'Blizzard',
|
||||
'company' : 'Howcom',
|
||||
'jobTitle': 'Web Designer',
|
||||
'email' : 'henderson@withinpixels.com',
|
||||
'phone' : '+1-202-555-0151',
|
||||
'address' : '686 Roosevelt Avenue Oviedo, FL 32765',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680b8d240c011dd224b',
|
||||
'name' : 'Josefina',
|
||||
'lastName': 'Lakefield',
|
||||
'avatar' : 'assets/images/avatars/Josefina.jpg',
|
||||
'nickname': 'Violet',
|
||||
'company' : 'Gecko',
|
||||
'jobTitle': 'Web Developer',
|
||||
'email' : 'josefina@withinpixels.com',
|
||||
'phone' : '+1-202-555-0160',
|
||||
'address' : '202 Hartford Road Lynchburg, VA 24502',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a68034cb3968e1f79eac',
|
||||
'name' : 'Katina',
|
||||
'lastName': 'Bletchley',
|
||||
'avatar' : 'assets/images/avatars/Katina.jpg',
|
||||
'nickname': 'Rose',
|
||||
'company' : 'Lexicom',
|
||||
'jobTitle': 'Software Designer',
|
||||
'email' : 'katina@withinpixels.com',
|
||||
'phone' : '+1-202-555-0186',
|
||||
'address' : '219 Woodland Road Valrico, FL 33594',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6801146cce777df2a08',
|
||||
'name' : 'Lily',
|
||||
'lastName': 'Peasegood',
|
||||
'avatar' : 'assets/images/avatars/Lily.jpg',
|
||||
'nickname': 'Star',
|
||||
'company' : 'zooflex',
|
||||
'jobTitle': 'Software Specialist',
|
||||
'email' : 'lily@withinpixels.com',
|
||||
'phone' : '+1-202-555-0115',
|
||||
'address' : '305 Willow Drive Superior, WI 54880',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6808a178bfd034d6ecf',
|
||||
'name' : 'Mai',
|
||||
'lastName': 'Nox',
|
||||
'avatar' : 'assets/images/avatars/Mai.jpg',
|
||||
'nickname': 'Violetmage',
|
||||
'company' : 'quadzone',
|
||||
'jobTitle': 'Software Engineer',
|
||||
'email' : 'mai@withinpixels.com',
|
||||
'phone' : '+1-202-555-0199',
|
||||
'address' : '148 Heather Lane Mcminnville, TN 37110',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680653c265f5c79b5a9',
|
||||
'name' : 'Nancy',
|
||||
'lastName': 'Jaggers',
|
||||
'avatar' : 'assets/images/avatars/Nancy.jpg',
|
||||
'nickname': 'Silverwarden',
|
||||
'company' : 'Opetamnix',
|
||||
'jobTitle': 'Software Architect',
|
||||
'email' : 'nancy@withinpixels.com',
|
||||
'phone' : '+1-202-555-0120',
|
||||
'address' : '345 Laurel Lane Union City, NJ 07087',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680bbcec3cc32a8488a',
|
||||
'name' : 'Nora',
|
||||
'lastName': 'Franklin',
|
||||
'avatar' : 'assets/images/avatars/Nora.jpg',
|
||||
'nickname': 'Katanachanter',
|
||||
'company' : 'Saoway',
|
||||
'jobTitle': 'Database Coordinator',
|
||||
'email' : 'nora@withinpixels.com',
|
||||
'phone' : '+1-202-555-0172',
|
||||
'address' : '572 Rose Street Summerfield, FL 34491',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6803d87f1b77e17b62b',
|
||||
'name' : 'Odessa',
|
||||
'lastName': 'Goodman',
|
||||
'avatar' : 'assets/images/avatars/Odessa.jpg',
|
||||
'nickname': 'Rose',
|
||||
'company' : 'transace',
|
||||
'jobTitle': 'Database Administration Manager',
|
||||
'email' : 'odessa@withinpixels.com',
|
||||
'phone' : '+1-202-555-0190',
|
||||
'address' : '527 Jefferson Court Conyers, GA 30012',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680e87cb319bd9bd673',
|
||||
'name' : 'Reyna',
|
||||
'lastName': 'Preece',
|
||||
'avatar' : 'assets/images/avatars/Reyna.jpg',
|
||||
'nickname': 'Holydawn',
|
||||
'company' : 'Dingex',
|
||||
'jobTitle': 'Data Processing Planner',
|
||||
'email' : 'reyna@withinpixels.com',
|
||||
'phone' : '+1-202-555-0116',
|
||||
'address' : '297 Strawberry Lane Faribault, MN 55021',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35775',
|
||||
'name' : 'Shauna',
|
||||
'lastName': 'Atherton',
|
||||
'avatar' : 'assets/images/avatars/Shauna.jpg',
|
||||
'nickname': 'Faunasoul',
|
||||
'company' : 'Vivaflex',
|
||||
'jobTitle': 'Art Director',
|
||||
'email' : 'shauna@withinpixels.com',
|
||||
'phone' : '+1-202-555-0159',
|
||||
'address' : '928 Canterbury Court Pittsburgh, PA 15206',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680aef1e5cf26dd3d1f',
|
||||
'name' : 'Shepard',
|
||||
'lastName': 'Rosco',
|
||||
'avatar' : 'assets/images/avatars/Shepard.jpg',
|
||||
'nickname': 'Fireking',
|
||||
'company' : 'Goldenla',
|
||||
'jobTitle': 'Magazine Designer',
|
||||
'email' : 'shepard@withinpixels.com',
|
||||
'phone' : '+1-202-555-0173',
|
||||
'address' : '904 Ridge Road Pickerington, OH 43147',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680cd7efa56a45aea5d',
|
||||
'name' : 'Tillman',
|
||||
'lastName': 'Lee',
|
||||
'avatar' : 'assets/images/avatars/Tillman.jpg',
|
||||
'nickname': 'Gust',
|
||||
'company' : 'K-techno',
|
||||
'jobTitle': 'News Photographer',
|
||||
'email' : 'tillman@withinpixels.com',
|
||||
'phone' : '+1-202-555-0183',
|
||||
'address' : '447 Charles Street Dorchester, MA 02125',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a680fb65c91a82cb35e2',
|
||||
'name' : 'Trevino',
|
||||
'lastName': 'Bush',
|
||||
'avatar' : 'assets/images/avatars/Trevino.jpg',
|
||||
'nickname': 'Wolf',
|
||||
'company' : 'Dalthex',
|
||||
'jobTitle': 'Photojournalist',
|
||||
'email' : 'trevino@withinpixels.com',
|
||||
'phone' : '+1-202-555-0138',
|
||||
'address' : '84 Valley View Road Norman, OK 73072',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a68018c663044be49cbf',
|
||||
'name' : 'Tyson',
|
||||
'lastName': 'Marshall',
|
||||
'avatar' : 'assets/images/avatars/Tyson.jpg',
|
||||
'nickname': 'Honordread',
|
||||
'company' : 'Geocon',
|
||||
'jobTitle': 'Manuscript Editor',
|
||||
'email' : 'tyson@withinpixels.com',
|
||||
'phone' : '+1-202-555-0146',
|
||||
'address' : '204 Clark Street Monsey, NY 10952',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
},
|
||||
{
|
||||
'id' : '5725a6809413bf8a0a5272b1',
|
||||
'name' : 'Velazquez',
|
||||
'lastName': 'Smethley',
|
||||
'avatar' : 'assets/images/avatars/Velazquez.jpg',
|
||||
'nickname': 'Strifedream',
|
||||
'company' : 'ranex',
|
||||
'jobTitle': 'Publications Editor',
|
||||
'email' : 'velezquez@withinpixels.com',
|
||||
'phone' : '+1-202-555-0146',
|
||||
'address' : '261 Cleveland Street Riverside, NJ 08075',
|
||||
'birthday': null,
|
||||
'notes' : ''
|
||||
}
|
||||
];
|
||||
|
||||
public static user = [
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35724',
|
||||
'name' : 'John Doe',
|
||||
'avatar' : 'assets/images/avatars/profile.jpg',
|
||||
'starred' : [
|
||||
'5725a680ae1ae9a3c960d487',
|
||||
'5725a6801146cce777df2a08',
|
||||
'5725a680bbcec3cc32a8488a',
|
||||
'5725a680bc670af746c435e2',
|
||||
'5725a68009e20d0a9e9acf2a'
|
||||
],
|
||||
'frequentContacts': [
|
||||
'5725a6809fdd915739187ed5',
|
||||
'5725a68031fdbb1db2c1af47',
|
||||
'5725a680606588342058356d',
|
||||
'5725a680e7eb988a58ddf303',
|
||||
'5725a6806acf030f9341e925',
|
||||
'5725a68034cb3968e1f79eac',
|
||||
'5725a6801146cce777df2a08',
|
||||
'5725a680653c265f5c79b5a9'
|
||||
],
|
||||
'groups' : [
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35739',
|
||||
'name' : 'Friends',
|
||||
'contactIds': [
|
||||
'5725a680bbcec3cc32a8488a',
|
||||
'5725a680e87cb319bd9bd673',
|
||||
'5725a6802d10e277a0f35775'
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35749',
|
||||
'name' : 'Clients',
|
||||
'contactIds': [
|
||||
'5725a680cd7efa56a45aea5d',
|
||||
'5725a68018c663044be49cbf',
|
||||
'5725a6809413bf8a0a5272b1',
|
||||
'5725a6803d87f1b77e17b62b'
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : '5725a6802d10e277a0f35329',
|
||||
'name' : 'Recent Workers',
|
||||
'contactIds': [
|
||||
'5725a680bbcec3cc32a8488a',
|
||||
'5725a680653c265f5c79b5a9',
|
||||
'5725a6808a178bfd034d6ecf',
|
||||
'5725a6801146cce777df2a08'
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
602
src/app/fake-db/dashboard-analytics.ts
Normal file
602
src/app/fake-db/dashboard-analytics.ts
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
1998
src/app/fake-db/dashboard-project.ts
Normal file
1998
src/app/fake-db/dashboard-project.ts
Normal file
File diff suppressed because it is too large
Load Diff
3762
src/app/fake-db/e-commerce.ts
Normal file
3762
src/app/fake-db/e-commerce.ts
Normal file
File diff suppressed because it is too large
Load Diff
97
src/app/fake-db/fake-db.service.ts
Normal file
97
src/app/fake-db/fake-db.service.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { InMemoryDbService } from 'angular-in-memory-web-api';
|
||||
|
||||
import { ProjectDashboardDb } from 'app/fake-db/dashboard-project';
|
||||
import { AnalyticsDashboardDb } from 'app/fake-db/dashboard-analytics';
|
||||
import { CalendarFakeDb } from 'app/fake-db/calendar';
|
||||
import { ECommerceFakeDb } from 'app/fake-db/e-commerce';
|
||||
import { AcademyFakeDb } from 'app/fake-db/academy';
|
||||
import { MailFakeDb } from 'app/fake-db/mail';
|
||||
import { ChatFakeDb } from 'app/fake-db/chat';
|
||||
import { FileManagerFakeDb } from 'app/fake-db/file-manager';
|
||||
import { ContactsFakeDb } from 'app/fake-db/contacts';
|
||||
import { TodoFakeDb } from 'app/fake-db/todo';
|
||||
import { ScrumboardFakeDb } from 'app/fake-db/scrumboard';
|
||||
import { InvoiceFakeDb } from 'app/fake-db/invoice';
|
||||
import { ProfileFakeDb } from 'app/fake-db/profile';
|
||||
import { SearchFakeDb } from 'app/fake-db/search';
|
||||
import { FaqFakeDb } from 'app/fake-db/faq';
|
||||
import { KnowledgeBaseFakeDb } from 'app/fake-db/knowledge-base';
|
||||
import { IconsFakeDb } from 'app/fake-db/icons';
|
||||
import { QuickPanelFakeDb } from 'app/fake-db/quick-panel';
|
||||
|
||||
export class FakeDbService implements InMemoryDbService
|
||||
{
|
||||
createDb(): any
|
||||
{
|
||||
return {
|
||||
// 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
|
||||
};
|
||||
}
|
||||
}
|
||||
61
src/app/fake-db/faq.ts
Normal file
61
src/app/fake-db/faq.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
export class FaqFakeDb
|
||||
{
|
||||
public static data = [
|
||||
{
|
||||
'question': 'Proident tempor est nulla irure ad est?',
|
||||
'answer': 'Id nulla nulla proident deserunt deserunt proident in quis. Cillum reprehenderit labore id anim laborum.'
|
||||
},
|
||||
{
|
||||
'question': 'Ullamco duis commodo sint ad aliqua aute?',
|
||||
'answer': 'Sunt laborum enim nostrud ea fugiat cillum mollit aliqua exercitation ad elit.'
|
||||
},
|
||||
{
|
||||
'question': 'Eiusmod non occaecat pariatur Lorem in ex?',
|
||||
'answer': 'Nostrud anim mollit incididunt qui qui sit commodo duis. Anim amet irure aliquip duis nostrud sit quis fugiat ullamco non dolor labore. Lorem sunt voluptate laboris culpa proident. Aute eiusmod aliqua exercitation irure exercitation qui laboris mollit occaecat eu occaecat fugiat.'
|
||||
},
|
||||
{
|
||||
'question': 'Lorem magna cillum consequat consequat mollit?',
|
||||
'answer': 'Velit ipsum proident ea incididunt et. Consectetur eiusmod laborum voluptate duis occaecat ullamco sint enim proident.'
|
||||
},
|
||||
{
|
||||
'question': 'Quis irure cupidatat ad consequat reprehenderit excepteur?',
|
||||
'answer': 'Esse nisi mollit aliquip mollit aute consequat adipisicing. Do excepteur dolore proident cupidatat pariatur irure consequat incididunt.'
|
||||
},
|
||||
{
|
||||
'question': 'Officia voluptate tempor ut mollit ea cillum?',
|
||||
'answer': 'Deserunt veniam reprehenderit do elit magna ut.'
|
||||
},
|
||||
{
|
||||
'question': 'Sunt fugiat officia nisi minim sunt duis?',
|
||||
'answer': 'Eiusmod eiusmod sint aliquip exercitation cillum. Magna nulla officia ex consectetur ea ad excepteur in qui.'
|
||||
},
|
||||
{
|
||||
'question': 'Non cupidatat enim quis aliquip minim laborum?',
|
||||
'answer': 'Qui cillum eiusmod nostrud sunt dolore velit nostrud labore voluptate ad dolore. Eu Lorem anim pariatur aliqua. Ullamco ut dolor velit esse occaecat dolore eu cillum commodo qui. Nulla dolor consequat voluptate magna ut commodo magna consectetur non aute proident.'
|
||||
},
|
||||
{
|
||||
'question': 'Dolor ex occaecat magna labore laboris qui?',
|
||||
'answer': 'Incididunt qui excepteur eiusmod elit cillum occaecat voluptate cillum nostrud. Dolor ullamco ullamco eiusmod do sunt adipisicing pariatur. In esse esse labore id reprehenderit sint do. Pariatur culpa dolor tempor qui excepteur duis do anim minim ipsum.'
|
||||
},
|
||||
{
|
||||
'question': 'Nisi et ullamco minim ea proident tempor?',
|
||||
'answer': 'Dolor veniam dolor cillum Lorem magna nisi in occaecat nulla dolor ea eiusmod.'
|
||||
},
|
||||
{
|
||||
'question': 'Amet sunt et quis amet commodo quis?',
|
||||
'answer': 'Nulla dolore consequat aliqua sint consequat elit qui occaecat et.'
|
||||
},
|
||||
{
|
||||
'question': 'Ut eiusmod ex ea eiusmod culpa incididunt?',
|
||||
'answer': 'Fugiat non incididunt officia ex incididunt occaecat. Voluptate nostrud culpa aliquip mollit incididunt non dolore.'
|
||||
},
|
||||
{
|
||||
'question': 'Proident reprehenderit laboris pariatur ut et nisi?',
|
||||
'answer': 'Reprehenderit proident ut ad cillum quis velit quis aliqua ut aliquip tempor ullamco.'
|
||||
},
|
||||
{
|
||||
'question': 'Aliqua aliquip aliquip aliquip et exercitation aute?',
|
||||
'answer': 'Adipisicing Lorem tempor ex anim. Labore tempor laboris nostrud dolore voluptate ullamco. Fugiat ex deserunt anim minim esse velit laboris aute ea duis incididunt. Elit irure id Lorem incididunt laborum aliquip consectetur est irure sunt. Ut labore anim nisi aliqua tempor laborum nulla cillum. Duis irure consequat cillum magna cillum eiusmod ut. Et exercitation voluptate quis deserunt elit quis dolor deserunt ex ex esse ex.'
|
||||
}
|
||||
];
|
||||
}
|
||||
146
src/app/fake-db/file-manager.ts
Normal file
146
src/app/fake-db/file-manager.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
export class FileManagerFakeDb
|
||||
{
|
||||
public static files = [
|
||||
{
|
||||
'name' : 'Work Documents',
|
||||
'type' : 'folder',
|
||||
'owner' : 'me',
|
||||
'size' : '',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true
|
||||
},
|
||||
{
|
||||
'name' : 'Public Documents',
|
||||
'type' : 'folder',
|
||||
'owner' : 'public',
|
||||
'size' : '',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true
|
||||
},
|
||||
{
|
||||
'name' : 'Private Documents',
|
||||
'type' : 'folder',
|
||||
'owner' : 'me',
|
||||
'size' : '',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true
|
||||
},
|
||||
{
|
||||
'name' : 'Ongoing projects',
|
||||
'type' : 'document',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '1.2 Mb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Shopping list',
|
||||
'type' : 'document',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '980 Kb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Invoices',
|
||||
'type' : 'spreadsheet',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '750 Kb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Crash logs',
|
||||
'type' : 'document',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '980 Mb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'System logs',
|
||||
'type' : 'document',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '52 Kb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Prices',
|
||||
'type' : 'spreadsheet',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '27 Mb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Anabelle Manual',
|
||||
'type' : 'document',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '1.1 Kb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
},
|
||||
{
|
||||
'name' : 'Steam summer sale budget',
|
||||
'type' : 'spreadsheet',
|
||||
'owner' : 'Emily Bennett',
|
||||
'size' : '505 Kb',
|
||||
'modified' : 'July 8, 2017',
|
||||
'opened' : 'July 8, 2017',
|
||||
'created' : 'July 8, 2017',
|
||||
'extention': '',
|
||||
'location' : 'My Files > Documents',
|
||||
'offline' : true,
|
||||
'preview' : 'assets/images/etc/sample-file-preview.jpg'
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
938
src/app/fake-db/icons.ts
Normal file
938
src/app/fake-db/icons.ts
Normal file
@@ -0,0 +1,938 @@
|
||||
export class IconsFakeDb
|
||||
{
|
||||
public static icons = [
|
||||
'3d_rotation',
|
||||
'ac_unit',
|
||||
'access_alarm',
|
||||
'access_alarms',
|
||||
'access_time',
|
||||
'accessibility',
|
||||
'accessible',
|
||||
'account_balance',
|
||||
'account_balance_wallet',
|
||||
'account_box',
|
||||
'account_circle',
|
||||
'adb',
|
||||
'add',
|
||||
'add_a_photo',
|
||||
'add_alarm',
|
||||
'add_alert',
|
||||
'add_box',
|
||||
'add_circle',
|
||||
'add_circle_outline',
|
||||
'add_location',
|
||||
'add_shopping_cart',
|
||||
'add_to_photos',
|
||||
'add_to_queue',
|
||||
'adjust',
|
||||
'airline_seat_flat',
|
||||
'airline_seat_flat_angled',
|
||||
'airline_seat_individual_suite',
|
||||
'airline_seat_legroom_extra',
|
||||
'airline_seat_legroom_normal',
|
||||
'airline_seat_legroom_reduced',
|
||||
'airline_seat_recline_extra',
|
||||
'airline_seat_recline_normal',
|
||||
'airplanemode_active',
|
||||
'airplanemode_inactive',
|
||||
'airplay',
|
||||
'airport_shuttle',
|
||||
'alarm',
|
||||
'alarm_add',
|
||||
'alarm_off',
|
||||
'alarm_on',
|
||||
'album',
|
||||
'all_inclusive',
|
||||
'all_out',
|
||||
'android',
|
||||
'announcement',
|
||||
'apps',
|
||||
'archive',
|
||||
'arrow_back',
|
||||
'arrow_downward',
|
||||
'arrow_drop_down',
|
||||
'arrow_drop_down_circle',
|
||||
'arrow_drop_up',
|
||||
'arrow_forward',
|
||||
'arrow_upward',
|
||||
'art_track',
|
||||
'aspect_ratio',
|
||||
'assessment',
|
||||
'assignment',
|
||||
'assignment_ind',
|
||||
'assignment_late',
|
||||
'assignment_return',
|
||||
'assignment_returned',
|
||||
'assignment_turned_in',
|
||||
'assistant',
|
||||
'assistant_photo',
|
||||
'attach_file',
|
||||
'attach_money',
|
||||
'attachment',
|
||||
'audiotrack',
|
||||
'autorenew',
|
||||
'av_timer',
|
||||
'backspace',
|
||||
'backup',
|
||||
'battery_alert',
|
||||
'battery_charging_full',
|
||||
'battery_full',
|
||||
'battery_std',
|
||||
'battery_unknown',
|
||||
'beach_access',
|
||||
'beenhere',
|
||||
'block',
|
||||
'bluetooth',
|
||||
'bluetooth_audio',
|
||||
'bluetooth_connected',
|
||||
'bluetooth_disabled',
|
||||
'bluetooth_searching',
|
||||
'blur_circular',
|
||||
'blur_linear',
|
||||
'blur_off',
|
||||
'blur_on',
|
||||
'book',
|
||||
'bookmark',
|
||||
'bookmark_border',
|
||||
'border_all',
|
||||
'border_bottom',
|
||||
'border_clear',
|
||||
'border_color',
|
||||
'border_horizontal',
|
||||
'border_inner',
|
||||
'border_left',
|
||||
'border_outer',
|
||||
'border_right',
|
||||
'border_style',
|
||||
'border_top',
|
||||
'border_vertical',
|
||||
'branding_watermark',
|
||||
'brightness_1',
|
||||
'brightness_2',
|
||||
'brightness_3',
|
||||
'brightness_4',
|
||||
'brightness_5',
|
||||
'brightness_6',
|
||||
'brightness_7',
|
||||
'brightness_auto',
|
||||
'brightness_high',
|
||||
'brightness_low',
|
||||
'brightness_medium',
|
||||
'broken_image',
|
||||
'brush',
|
||||
'bubble_chart',
|
||||
'bug_report',
|
||||
'build',
|
||||
'burst_mode',
|
||||
'business',
|
||||
'business_center',
|
||||
'cached',
|
||||
'cake',
|
||||
'call',
|
||||
'call_end',
|
||||
'call_made',
|
||||
'call_merge',
|
||||
'call_missed',
|
||||
'call_missed_outgoing',
|
||||
'call_received',
|
||||
'call_split',
|
||||
'call_to_action',
|
||||
'camera',
|
||||
'camera_alt',
|
||||
'camera_enhance',
|
||||
'camera_front',
|
||||
'camera_rear',
|
||||
'camera_roll',
|
||||
'cancel',
|
||||
'card_giftcard',
|
||||
'card_membership',
|
||||
'card_travel',
|
||||
'casino',
|
||||
'cast',
|
||||
'cast_connected',
|
||||
'center_focus_strong',
|
||||
'center_focus_weak',
|
||||
'change_history',
|
||||
'chat',
|
||||
'chat_bubble',
|
||||
'chat_bubble_outline',
|
||||
'check',
|
||||
'check_box',
|
||||
'check_box_outline_blank',
|
||||
'check_circle',
|
||||
'chevron_left',
|
||||
'chevron_right',
|
||||
'child_care',
|
||||
'child_friendly',
|
||||
'chrome_reader_mode',
|
||||
'class',
|
||||
'clear',
|
||||
'clear_all',
|
||||
'close',
|
||||
'closed_caption',
|
||||
'cloud',
|
||||
'cloud_circle',
|
||||
'cloud_done',
|
||||
'cloud_download',
|
||||
'cloud_off',
|
||||
'cloud_queue',
|
||||
'cloud_upload',
|
||||
'code',
|
||||
'collections',
|
||||
'collections_bookmark',
|
||||
'color_lens',
|
||||
'colorize',
|
||||
'comment',
|
||||
'compare',
|
||||
'compare_arrows',
|
||||
'computer',
|
||||
'confirmation_number',
|
||||
'contact_mail',
|
||||
'contact_phone',
|
||||
'contacts',
|
||||
'content_copy',
|
||||
'content_cut',
|
||||
'content_paste',
|
||||
'control_point',
|
||||
'control_point_duplicate',
|
||||
'copyright',
|
||||
'create',
|
||||
'create_new_folder',
|
||||
'credit_card',
|
||||
'crop',
|
||||
'crop_16_9',
|
||||
'crop_3_2',
|
||||
'crop_5_4',
|
||||
'crop_7_5',
|
||||
'crop_din',
|
||||
'crop_free',
|
||||
'crop_landscape',
|
||||
'crop_original',
|
||||
'crop_portrait',
|
||||
'crop_rotate',
|
||||
'crop_square',
|
||||
'dashboard',
|
||||
'data_usage',
|
||||
'date_range',
|
||||
'dehaze',
|
||||
'delete',
|
||||
'delete_forever',
|
||||
'delete_sweep',
|
||||
'description',
|
||||
'desktop_mac',
|
||||
'desktop_windows',
|
||||
'details',
|
||||
'developer_board',
|
||||
'developer_mode',
|
||||
'device_hub',
|
||||
'devices',
|
||||
'devices_other',
|
||||
'dialer_sip',
|
||||
'dialpad',
|
||||
'directions',
|
||||
'directions_bike',
|
||||
'directions_boat',
|
||||
'directions_bus',
|
||||
'directions_car',
|
||||
'directions_railway',
|
||||
'directions_run',
|
||||
'directions_subway',
|
||||
'directions_transit',
|
||||
'directions_walk',
|
||||
'disc_full',
|
||||
'dns',
|
||||
'do_not_disturb',
|
||||
'do_not_disturb_alt',
|
||||
'do_not_disturb_off',
|
||||
'do_not_disturb_on',
|
||||
'dock',
|
||||
'domain',
|
||||
'done',
|
||||
'done_all',
|
||||
'donut_large',
|
||||
'donut_small',
|
||||
'drafts',
|
||||
'drag_handle',
|
||||
'drive_eta',
|
||||
'dvr',
|
||||
'edit',
|
||||
'edit_location',
|
||||
'eject',
|
||||
'email',
|
||||
'enhanced_encryption',
|
||||
'equalizer',
|
||||
'error',
|
||||
'error_outline',
|
||||
'euro_symbol',
|
||||
'ev_station',
|
||||
'event',
|
||||
'event_available',
|
||||
'event_busy',
|
||||
'event_note',
|
||||
'event_seat',
|
||||
'exit_to_app',
|
||||
'expand_less',
|
||||
'expand_more',
|
||||
'explicit',
|
||||
'explore',
|
||||
'exposure',
|
||||
'exposure_neg_1',
|
||||
'exposure_neg_2',
|
||||
'exposure_plus_1',
|
||||
'exposure_plus_2',
|
||||
'exposure_zero',
|
||||
'extension',
|
||||
'face',
|
||||
'fast_forward',
|
||||
'fast_rewind',
|
||||
'favorite',
|
||||
'favorite_border',
|
||||
'featured_play_list',
|
||||
'featured_video',
|
||||
'feedback',
|
||||
'fiber_dvr',
|
||||
'fiber_manual_record',
|
||||
'fiber_new',
|
||||
'fiber_pin',
|
||||
'fiber_smart_record',
|
||||
'file_download',
|
||||
'file_upload',
|
||||
'filter',
|
||||
'filter_1',
|
||||
'filter_2',
|
||||
'filter_3',
|
||||
'filter_4',
|
||||
'filter_5',
|
||||
'filter_6',
|
||||
'filter_7',
|
||||
'filter_8',
|
||||
'filter_9',
|
||||
'filter_9_plus',
|
||||
'filter_b_and_w',
|
||||
'filter_center_focus',
|
||||
'filter_drama',
|
||||
'filter_frames',
|
||||
'filter_hdr',
|
||||
'filter_list',
|
||||
'filter_none',
|
||||
'filter_tilt_shift',
|
||||
'filter_vintage',
|
||||
'find_in_page',
|
||||
'find_replace',
|
||||
'fingerprint',
|
||||
'first_page',
|
||||
'fitness_center',
|
||||
'flag',
|
||||
'flare',
|
||||
'flash_auto',
|
||||
'flash_off',
|
||||
'flash_on',
|
||||
'flight',
|
||||
'flight_land',
|
||||
'flight_takeoff',
|
||||
'flip',
|
||||
'flip_to_back',
|
||||
'flip_to_front',
|
||||
'folder',
|
||||
'folder_open',
|
||||
'folder_shared',
|
||||
'folder_special',
|
||||
'font_download',
|
||||
'format_align_center',
|
||||
'format_align_justify',
|
||||
'format_align_left',
|
||||
'format_align_right',
|
||||
'format_bold',
|
||||
'format_clear',
|
||||
'format_color_fill',
|
||||
'format_color_reset',
|
||||
'format_color_text',
|
||||
'format_indent_decrease',
|
||||
'format_indent_increase',
|
||||
'format_italic',
|
||||
'format_line_spacing',
|
||||
'format_list_bulleted',
|
||||
'format_list_numbered',
|
||||
'format_paint',
|
||||
'format_quote',
|
||||
'format_shapes',
|
||||
'format_size',
|
||||
'format_strikethrough',
|
||||
'format_textdirection_l_to_r',
|
||||
'format_textdirection_r_to_l',
|
||||
'format_underlined',
|
||||
'forum',
|
||||
'forward',
|
||||
'forward_10',
|
||||
'forward_30',
|
||||
'forward_5',
|
||||
'free_breakfast',
|
||||
'fullscreen',
|
||||
'fullscreen_exit',
|
||||
'functions',
|
||||
'g_translate',
|
||||
'gamepad',
|
||||
'games',
|
||||
'gavel',
|
||||
'gesture',
|
||||
'get_app',
|
||||
'gif',
|
||||
'golf_course',
|
||||
'gps_fixed',
|
||||
'gps_not_fixed',
|
||||
'gps_off',
|
||||
'grade',
|
||||
'gradient',
|
||||
'grain',
|
||||
'graphic_eq',
|
||||
'grid_off',
|
||||
'grid_on',
|
||||
'group',
|
||||
'group_add',
|
||||
'group_work',
|
||||
'hd',
|
||||
'hdr_off',
|
||||
'hdr_on',
|
||||
'hdr_strong',
|
||||
'hdr_weak',
|
||||
'headset',
|
||||
'headset_mic',
|
||||
'healing',
|
||||
'hearing',
|
||||
'help',
|
||||
'help_outline',
|
||||
'high_quality',
|
||||
'highlight',
|
||||
'highlight_off',
|
||||
'history',
|
||||
'home',
|
||||
'hot_tub',
|
||||
'hotel',
|
||||
'hourglass_empty',
|
||||
'hourglass_full',
|
||||
'http',
|
||||
'https',
|
||||
'image',
|
||||
'image_aspect_ratio',
|
||||
'import_contacts',
|
||||
'import_export',
|
||||
'important_devices',
|
||||
'inbox',
|
||||
'indeterminate_check_box',
|
||||
'info',
|
||||
'info_outline',
|
||||
'input',
|
||||
'insert_chart',
|
||||
'insert_comment',
|
||||
'insert_drive_file',
|
||||
'insert_emoticon',
|
||||
'insert_invitation',
|
||||
'insert_link',
|
||||
'insert_photo',
|
||||
'invert_colors',
|
||||
'invert_colors_off',
|
||||
'iso',
|
||||
'keyboard',
|
||||
'keyboard_arrow_down',
|
||||
'keyboard_arrow_left',
|
||||
'keyboard_arrow_right',
|
||||
'keyboard_arrow_up',
|
||||
'keyboard_backspace',
|
||||
'keyboard_capslock',
|
||||
'keyboard_hide',
|
||||
'keyboard_return',
|
||||
'keyboard_tab',
|
||||
'keyboard_voice',
|
||||
'kitchen',
|
||||
'label',
|
||||
'label_outline',
|
||||
'landscape',
|
||||
'language',
|
||||
'laptop',
|
||||
'laptop_chromebook',
|
||||
'laptop_mac',
|
||||
'laptop_windows',
|
||||
'last_page',
|
||||
'launch',
|
||||
'layers',
|
||||
'layers_clear',
|
||||
'leak_add',
|
||||
'leak_remove',
|
||||
'lens',
|
||||
'library_add',
|
||||
'library_books',
|
||||
'library_music',
|
||||
'lightbulb_outline',
|
||||
'line_style',
|
||||
'line_weight',
|
||||
'linear_scale',
|
||||
'link',
|
||||
'linked_camera',
|
||||
'list',
|
||||
'live_help',
|
||||
'live_tv',
|
||||
'local_activity',
|
||||
'local_airport',
|
||||
'local_atm',
|
||||
'local_bar',
|
||||
'local_cafe',
|
||||
'local_car_wash',
|
||||
'local_convenience_store',
|
||||
'local_dining',
|
||||
'local_drink',
|
||||
'local_florist',
|
||||
'local_gas_station',
|
||||
'local_grocery_store',
|
||||
'local_hospital',
|
||||
'local_hotel',
|
||||
'local_laundry_service',
|
||||
'local_library',
|
||||
'local_mall',
|
||||
'local_movies',
|
||||
'local_offer',
|
||||
'local_parking',
|
||||
'local_pharmacy',
|
||||
'local_phone',
|
||||
'local_pizza',
|
||||
'local_play',
|
||||
'local_post_office',
|
||||
'local_printshop',
|
||||
'local_see',
|
||||
'local_shipping',
|
||||
'local_taxi',
|
||||
'location_city',
|
||||
'location_disabled',
|
||||
'location_off',
|
||||
'location_on',
|
||||
'location_searching',
|
||||
'lock',
|
||||
'lock_open',
|
||||
'lock_outline',
|
||||
'looks',
|
||||
'looks_3',
|
||||
'looks_4',
|
||||
'looks_5',
|
||||
'looks_6',
|
||||
'looks_one',
|
||||
'looks_two',
|
||||
'loop',
|
||||
'loupe',
|
||||
'low_priority',
|
||||
'loyalty',
|
||||
'mail',
|
||||
'mail_outline',
|
||||
'map',
|
||||
'markunread',
|
||||
'markunread_mailbox',
|
||||
'memory',
|
||||
'menu',
|
||||
'merge_type',
|
||||
'message',
|
||||
'mic',
|
||||
'mic_none',
|
||||
'mic_off',
|
||||
'mms',
|
||||
'mode_comment',
|
||||
'mode_edit',
|
||||
'monetization_on',
|
||||
'money_off',
|
||||
'monochrome_photos',
|
||||
'mood',
|
||||
'mood_bad',
|
||||
'more',
|
||||
'more_horiz',
|
||||
'more_vert',
|
||||
'motorcycle',
|
||||
'mouse',
|
||||
'move_to_inbox',
|
||||
'movie',
|
||||
'movie_creation',
|
||||
'movie_filter',
|
||||
'multiline_chart',
|
||||
'music_note',
|
||||
'music_video',
|
||||
'my_location',
|
||||
'nature',
|
||||
'nature_people',
|
||||
'navigate_before',
|
||||
'navigate_next',
|
||||
'navigation',
|
||||
'near_me',
|
||||
'network_cell',
|
||||
'network_check',
|
||||
'network_locked',
|
||||
'network_wifi',
|
||||
'new_releases',
|
||||
'next_week',
|
||||
'nfc',
|
||||
'no_encryption',
|
||||
'no_sim',
|
||||
'not_interested',
|
||||
'note',
|
||||
'note_add',
|
||||
'notifications',
|
||||
'notifications_active',
|
||||
'notifications_none',
|
||||
'notifications_off',
|
||||
'notifications_paused',
|
||||
'offline_pin',
|
||||
'ondemand_video',
|
||||
'opacity',
|
||||
'open_in_browser',
|
||||
'open_in_new',
|
||||
'open_with',
|
||||
'pages',
|
||||
'pageview',
|
||||
'palette',
|
||||
'pan_tool',
|
||||
'panorama',
|
||||
'panorama_fish_eye',
|
||||
'panorama_horizontal',
|
||||
'panorama_vertical',
|
||||
'panorama_wide_angle',
|
||||
'party_mode',
|
||||
'pause',
|
||||
'pause_circle_filled',
|
||||
'pause_circle_outline',
|
||||
'payment',
|
||||
'people',
|
||||
'people_outline',
|
||||
'perm_camera_mic',
|
||||
'perm_contact_calendar',
|
||||
'perm_data_setting',
|
||||
'perm_device_information',
|
||||
'perm_identity',
|
||||
'perm_media',
|
||||
'perm_phone_msg',
|
||||
'perm_scan_wifi',
|
||||
'person',
|
||||
'person_add',
|
||||
'person_outline',
|
||||
'person_pin',
|
||||
'person_pin_circle',
|
||||
'personal_video',
|
||||
'pets',
|
||||
'phone',
|
||||
'phone_android',
|
||||
'phone_bluetooth_speaker',
|
||||
'phone_forwarded',
|
||||
'phone_in_talk',
|
||||
'phone_iphone',
|
||||
'phone_locked',
|
||||
'phone_missed',
|
||||
'phone_paused',
|
||||
'phonelink',
|
||||
'phonelink_erase',
|
||||
'phonelink_lock',
|
||||
'phonelink_off',
|
||||
'phonelink_ring',
|
||||
'phonelink_setup',
|
||||
'photo',
|
||||
'photo_album',
|
||||
'photo_camera',
|
||||
'photo_filter',
|
||||
'photo_library',
|
||||
'photo_size_select_actual',
|
||||
'photo_size_select_large',
|
||||
'photo_size_select_small',
|
||||
'picture_as_pdf',
|
||||
'picture_in_picture',
|
||||
'picture_in_picture_alt',
|
||||
'pie_chart',
|
||||
'pie_chart_outlined',
|
||||
'pin_drop',
|
||||
'place',
|
||||
'play_arrow',
|
||||
'play_circle_filled',
|
||||
'play_circle_outline',
|
||||
'play_for_work',
|
||||
'playlist_add',
|
||||
'playlist_add_check',
|
||||
'playlist_play',
|
||||
'plus_one',
|
||||
'poll',
|
||||
'polymer',
|
||||
'pool',
|
||||
'portable_wifi_off',
|
||||
'portrait',
|
||||
'power',
|
||||
'power_input',
|
||||
'power_settings_new',
|
||||
'pregnant_woman',
|
||||
'present_to_all',
|
||||
'print',
|
||||
'priority_high',
|
||||
'public',
|
||||
'publish',
|
||||
'query_builder',
|
||||
'question_answer',
|
||||
'queue',
|
||||
'queue_music',
|
||||
'queue_play_next',
|
||||
'radio',
|
||||
'radio_button_checked',
|
||||
'radio_button_unchecked',
|
||||
'rate_review',
|
||||
'receipt',
|
||||
'recent_actors',
|
||||
'record_voice_over',
|
||||
'redeem',
|
||||
'redo',
|
||||
'refresh',
|
||||
'remove',
|
||||
'remove_circle',
|
||||
'remove_circle_outline',
|
||||
'remove_from_queue',
|
||||
'remove_red_eye',
|
||||
'remove_shopping_cart',
|
||||
'reorder',
|
||||
'repeat',
|
||||
'repeat_one',
|
||||
'replay',
|
||||
'replay_10',
|
||||
'replay_30',
|
||||
'replay_5',
|
||||
'reply',
|
||||
'reply_all',
|
||||
'report',
|
||||
'report_problem',
|
||||
'restaurant',
|
||||
'restaurant_menu',
|
||||
'restore',
|
||||
'restore_page',
|
||||
'ring_volume',
|
||||
'room',
|
||||
'room_service',
|
||||
'rotate_90_degrees_ccw',
|
||||
'rotate_left',
|
||||
'rotate_right',
|
||||
'rounded_corner',
|
||||
'router',
|
||||
'rowing',
|
||||
'rss_feed',
|
||||
'rv_hookup',
|
||||
'satellite',
|
||||
'save',
|
||||
'scanner',
|
||||
'schedule',
|
||||
'school',
|
||||
'screen_lock_landscape',
|
||||
'screen_lock_portrait',
|
||||
'screen_lock_rotation',
|
||||
'screen_rotation',
|
||||
'screen_share',
|
||||
'sd_card',
|
||||
'sd_storage',
|
||||
'search',
|
||||
'security',
|
||||
'select_all',
|
||||
'send',
|
||||
'sentiment_dissatisfied',
|
||||
'sentiment_neutral',
|
||||
'sentiment_satisfied',
|
||||
'sentiment_very_dissatisfied',
|
||||
'sentiment_very_satisfied',
|
||||
'settings',
|
||||
'settings_applications',
|
||||
'settings_backup_restore',
|
||||
'settings_bluetooth',
|
||||
'settings_brightness',
|
||||
'settings_cell',
|
||||
'settings_ethernet',
|
||||
'settings_input_antenna',
|
||||
'settings_input_component',
|
||||
'settings_input_composite',
|
||||
'settings_input_hdmi',
|
||||
'settings_input_svideo',
|
||||
'settings_overscan',
|
||||
'settings_phone',
|
||||
'settings_power',
|
||||
'settings_remote',
|
||||
'settings_system_daydream',
|
||||
'settings_voice',
|
||||
'share',
|
||||
'shop',
|
||||
'shop_two',
|
||||
'shopping_basket',
|
||||
'shopping_cart',
|
||||
'short_text',
|
||||
'show_chart',
|
||||
'shuffle',
|
||||
'signal_cellular_4_bar',
|
||||
'signal_cellular_connected_no_internet_4_bar',
|
||||
'signal_cellular_no_sim',
|
||||
'signal_cellular_null',
|
||||
'signal_cellular_off',
|
||||
'signal_wifi_4_bar',
|
||||
'signal_wifi_4_bar_lock',
|
||||
'signal_wifi_off',
|
||||
'sim_card',
|
||||
'sim_card_alert',
|
||||
'skip_next',
|
||||
'skip_previous',
|
||||
'slideshow',
|
||||
'slow_motion_video',
|
||||
'smartphone',
|
||||
'smoke_free',
|
||||
'smoking_rooms',
|
||||
'sms',
|
||||
'sms_failed',
|
||||
'snooze',
|
||||
'sort',
|
||||
'sort_by_alpha',
|
||||
'spa',
|
||||
'space_bar',
|
||||
'speaker',
|
||||
'speaker_group',
|
||||
'speaker_notes',
|
||||
'speaker_notes_off',
|
||||
'speaker_phone',
|
||||
'spellcheck',
|
||||
'star',
|
||||
'star_border',
|
||||
'star_half',
|
||||
'stars',
|
||||
'stay_current_landscape',
|
||||
'stay_current_portrait',
|
||||
'stay_primary_landscape',
|
||||
'stay_primary_portrait',
|
||||
'stop',
|
||||
'stop_screen_share',
|
||||
'storage',
|
||||
'store',
|
||||
'store_mall_directory',
|
||||
'straighten',
|
||||
'streetview',
|
||||
'strikethrough_s',
|
||||
'style',
|
||||
'subdirectory_arrow_left',
|
||||
'subdirectory_arrow_right',
|
||||
'subject',
|
||||
'subscriptions',
|
||||
'subtitles',
|
||||
'subway',
|
||||
'supervisor_account',
|
||||
'surround_sound',
|
||||
'swap_calls',
|
||||
'swap_horiz',
|
||||
'swap_vert',
|
||||
'swap_vertical_circle',
|
||||
'switch_camera',
|
||||
'switch_video',
|
||||
'sync',
|
||||
'sync_disabled',
|
||||
'sync_problem',
|
||||
'system_update',
|
||||
'system_update_alt',
|
||||
'tab',
|
||||
'tab_unselected',
|
||||
'tablet',
|
||||
'tablet_android',
|
||||
'tablet_mac',
|
||||
'tag_faces',
|
||||
'tap_and_play',
|
||||
'terrain',
|
||||
'text_fields',
|
||||
'text_format',
|
||||
'textsms',
|
||||
'texture',
|
||||
'theaters',
|
||||
'thumb_down',
|
||||
'thumb_up',
|
||||
'thumbs_up_down',
|
||||
'time_to_leave',
|
||||
'timelapse',
|
||||
'timeline',
|
||||
'timer',
|
||||
'timer_10',
|
||||
'timer_3',
|
||||
'timer_off',
|
||||
'title',
|
||||
'toc',
|
||||
'today',
|
||||
'toll',
|
||||
'tonality',
|
||||
'touch_app',
|
||||
'toys',
|
||||
'track_changes',
|
||||
'traffic',
|
||||
'train',
|
||||
'tram',
|
||||
'transfer_within_a_station',
|
||||
'transform',
|
||||
'translate',
|
||||
'trending_down',
|
||||
'trending_flat',
|
||||
'trending_up',
|
||||
'tune',
|
||||
'turned_in',
|
||||
'turned_in_not',
|
||||
'tv',
|
||||
'unarchive',
|
||||
'undo',
|
||||
'unfold_less',
|
||||
'unfold_more',
|
||||
'update',
|
||||
'usb',
|
||||
'verified_user',
|
||||
'vertical_align_bottom',
|
||||
'vertical_align_center',
|
||||
'vertical_align_top',
|
||||
'vibration',
|
||||
'video_call',
|
||||
'video_label',
|
||||
'video_library',
|
||||
'videocam',
|
||||
'videocam_off',
|
||||
'videogame_asset',
|
||||
'view_agenda',
|
||||
'view_array',
|
||||
'view_carousel',
|
||||
'view_column',
|
||||
'view_comfy',
|
||||
'view_compact',
|
||||
'view_day',
|
||||
'view_headline',
|
||||
'view_list',
|
||||
'view_module',
|
||||
'view_quilt',
|
||||
'view_stream',
|
||||
'view_week',
|
||||
'vignette',
|
||||
'visibility',
|
||||
'visibility_off',
|
||||
'voice_chat',
|
||||
'voicemail',
|
||||
'volume_down',
|
||||
'volume_mute',
|
||||
'volume_off',
|
||||
'volume_up',
|
||||
'vpn_key',
|
||||
'vpn_lock',
|
||||
'wallpaper',
|
||||
'warning',
|
||||
'watch',
|
||||
'watch_later',
|
||||
'wb_auto',
|
||||
'wb_cloudy',
|
||||
'wb_incandescent',
|
||||
'wb_iridescent',
|
||||
'wb_sunny',
|
||||
'wc',
|
||||
'web',
|
||||
'web_asset',
|
||||
'weekend',
|
||||
'whatshot',
|
||||
'widgets',
|
||||
'wifi',
|
||||
'wifi_lock',
|
||||
'wifi_tethering',
|
||||
'work',
|
||||
'wrap_text',
|
||||
'youtube_searched_for',
|
||||
'zoom_in',
|
||||
'zoom_out',
|
||||
'zoom_out_map'
|
||||
];
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user