mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-12-22 10:57:09 +00:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43b85ca3b6 | ||
|
|
99696cabf7 | ||
|
|
f246fab1f4 | ||
|
|
b0101a1f8c | ||
|
|
8f5e947c28 | ||
|
|
dfd430712d | ||
|
|
8431c19133 | ||
|
|
6ee6934e0d | ||
|
|
3253fbfaf4 | ||
|
|
985a8dd3a9 | ||
|
|
0c99c075f3 | ||
|
|
c79db27092 | ||
|
|
a92cb8b7b6 | ||
|
|
bb3d6d4839 | ||
|
|
9c06622efb | ||
|
|
8b590408b0 | ||
|
|
18b2bdf5ab | ||
|
|
ba49621e79 | ||
|
|
416f1997a9 | ||
|
|
fcfbedfd74 | ||
|
|
35f3512e89 | ||
|
|
2288905cbd | ||
|
|
5a40116c7b | ||
|
|
b7c10a515c | ||
|
|
65e637eeb9 | ||
|
|
b56088948c | ||
|
|
0c5066e7d0 | ||
|
|
751497556a | ||
|
|
5f2372cc08 | ||
|
|
6f315aa38e | ||
|
|
0653b5f36b | ||
|
|
f13120bc01 | ||
|
|
a6c56518bc | ||
|
|
ecae48f3d0 | ||
|
|
c74751e0f4 | ||
|
|
2b755fa669 | ||
|
|
ca0f46b414 | ||
|
|
528fa31df6 | ||
|
|
abfb2a6706 | ||
|
|
b1ab11393e | ||
|
|
786883eb10 |
@@ -2,6 +2,12 @@
|
||||
|
||||
Material Design Admin Template with Angular 5+ and Angular Material 2
|
||||
|
||||
## The Community
|
||||
|
||||
Share your ideas, discuss Fuse and help each other.
|
||||
|
||||
[Click here](https://join.slack.com/t/fuse-theme/shared_invite/enQtMzA1NDE4NzYwMjcyLWQxODE4ODM1MWU4MWJjMDhlMGEwYzM4Mzg3N2E4YzVlZThhZjNlOTQ1Y2Q5OTBlNDNkMzJhZDIwMjgxOWQ3YWU) to join our Slack workspace.
|
||||
|
||||
## Development server
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
6910
package-lock.json
generated
6910
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
101
package.json
101
package.json
@@ -1,80 +1,85 @@
|
||||
{
|
||||
"name": "fuse2",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.6",
|
||||
"license": "https://themeforest.net/licenses/terms/regular",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"start": "ng serve --open",
|
||||
"start-hmr": "ng serve --hmr -e=hmr -sm=false",
|
||||
"start-hmr-sourcemaps": "ng serve --hmr -e=hmr",
|
||||
"build": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --dev",
|
||||
"build-stats": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --dev --stats-json",
|
||||
"build-prod": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --prod",
|
||||
"build-prod-stats": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --prod --stats-json",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
"e2e": "ng e2e",
|
||||
"bundle-report": "webpack-bundle-analyzer dist/stats.json"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@agm/core": "1.0.0-beta.2",
|
||||
"@angular/animations": "5.1.1",
|
||||
"@angular/cdk": "5.0.1",
|
||||
"@angular/common": "5.1.1",
|
||||
"@angular/compiler": "5.1.1",
|
||||
"@angular/core": "5.1.1",
|
||||
"@angular/flex-layout": "2.0.0-beta.10-4905443",
|
||||
"@angular/forms": "5.1.1",
|
||||
"@angular/http": "5.1.1",
|
||||
"@angular/material": "5.0.1",
|
||||
"@angular/material-moment-adapter": "5.0.1",
|
||||
"@angular/platform-browser": "5.1.1",
|
||||
"@angular/platform-browser-dynamic": "5.1.1",
|
||||
"@angular/router": "5.1.1",
|
||||
"@ngx-translate/core": "9.0.1",
|
||||
"@angular/animations": "5.2.3",
|
||||
"@angular/cdk": "5.1.1",
|
||||
"@angular/common": "5.2.3",
|
||||
"@angular/compiler": "5.2.3",
|
||||
"@angular/core": "5.2.3",
|
||||
"@angular/flex-layout": "2.0.0-beta.12",
|
||||
"@angular/forms": "5.2.3",
|
||||
"@angular/http": "5.2.3",
|
||||
"@angular/material": "5.1.1",
|
||||
"@angular/material-moment-adapter": "5.1.1",
|
||||
"@angular/platform-browser": "5.2.3",
|
||||
"@angular/platform-browser-dynamic": "5.2.3",
|
||||
"@angular/router": "5.2.3",
|
||||
"@ngrx/effects": "5.0.0",
|
||||
"@ngrx/router-store": "5.0.0",
|
||||
"@ngrx/store": "5.0.0",
|
||||
"@ngrx/store-devtools": "5.0.0",
|
||||
"@ngx-translate/core": "9.1.1",
|
||||
"@swimlane/ngx-charts": "7.0.1",
|
||||
"@swimlane/ngx-datatable": "11.1.5",
|
||||
"@swimlane/ngx-datatable": "11.1.7",
|
||||
"@swimlane/ngx-dnd": "3.1.0",
|
||||
"angular-calendar": "0.22.1",
|
||||
"angular-in-memory-web-api": "0.5.2",
|
||||
"angular2-markdown": "1.6.0",
|
||||
"@types/prismjs": "1.9.0",
|
||||
"angular-calendar": "0.23.3",
|
||||
"angular-in-memory-web-api": "0.5.3",
|
||||
"chart.js": "2.7.1",
|
||||
"classlist.js": "1.1.20150312",
|
||||
"core-js": "2.5.3",
|
||||
"d3": "4.12.0",
|
||||
"d3": "4.13.0",
|
||||
"hammerjs": "2.0.8",
|
||||
"highlight.js": "9.12.0",
|
||||
"intl": "1.2.5",
|
||||
"moment": "2.19.3",
|
||||
"@ngrx/effects": "4.1.1",
|
||||
"@ngrx/router-store": "4.1.1",
|
||||
"@ngrx/store": "4.1.1",
|
||||
"@ngrx/store-devtools": "4.1.1",
|
||||
"ngrx-store-freeze": "0.2.0",
|
||||
"ngx-color-picker": "5.1.0",
|
||||
"ngx-cookie-service": "1.0.9",
|
||||
"moment": "2.20.1",
|
||||
"ng2-charts": "1.6.0",
|
||||
"ngrx-store-freeze": "0.2.1",
|
||||
"ngx-color-picker": "5.3.1",
|
||||
"ngx-cookie-service": "1.0.10",
|
||||
"perfect-scrollbar": "1.3.0",
|
||||
"rxjs": "5.5.5",
|
||||
"prismjs": "1.11.0",
|
||||
"rxjs": "5.5.6",
|
||||
"web-animations-js": "2.3.1",
|
||||
"zone.js": "0.8.18"
|
||||
"zone.js": "0.8.20"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "1.6.1",
|
||||
"@angular/compiler-cli": "5.1.1",
|
||||
"@angular/language-service": "5.1.1",
|
||||
"@angular/cli": "1.6.7",
|
||||
"@angular/compiler-cli": "5.2.3",
|
||||
"@angular/language-service": "5.2.3",
|
||||
"@angularclass/hmr": "2.1.3",
|
||||
"@types/jasmine": "2.5.54",
|
||||
"@types/jasmine": "2.8.6",
|
||||
"@types/jasminewd2": "2.0.3",
|
||||
"@types/node": "6.0.94",
|
||||
"codelyzer": "4.0.2",
|
||||
"jasmine-core": "2.6.4",
|
||||
"jasmine-spec-reporter": "4.1.1",
|
||||
"karma": "1.7.1",
|
||||
"karma-chrome-launcher": "2.1.1",
|
||||
"karma-cli": "1.0.1",
|
||||
"karma-coverage-istanbul-reporter": "1.3.0",
|
||||
"@types/node": "6.0.96",
|
||||
"codelyzer": "4.1.0",
|
||||
"jasmine-core": "2.8.0",
|
||||
"jasmine-spec-reporter": "4.2.1",
|
||||
"karma": "2.0.0",
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "1.4.1",
|
||||
"karma-jasmine": "1.1.1",
|
||||
"karma-jasmine-html-reporter": "0.2.2",
|
||||
"protractor": "5.1.2",
|
||||
"ts-node": "3.2.2",
|
||||
"tslint": "5.7.0",
|
||||
"typescript": "2.4.2"
|
||||
"ts-node": "4.1.0",
|
||||
"tslint": "5.9.1",
|
||||
"typescript": "2.6.2",
|
||||
"webpack-bundle-analyzer": "2.10.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,62 +7,42 @@ import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
|
||||
import 'hammerjs';
|
||||
import { SharedModule } from './core/modules/shared.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { ProjectModule } from './main/content/apps/dashboards/project/project.module';
|
||||
import { FuseFakeDbService } from './fuse-fake-db/fuse-fake-db.service';
|
||||
import { FuseMainModule } from './main/main.module';
|
||||
import { PagesModule } from './main/content/pages/pages.module';
|
||||
import { UIModule } from './main/content/ui/ui.module';
|
||||
import { ComponentsModule } from './main/content/components/components.module';
|
||||
import { FuseSplashScreenService } from './core/services/splash-screen.service';
|
||||
import { FuseConfigService } from './core/services/config.service';
|
||||
import { FuseNavigationService } from './core/components/navigation/navigation.service';
|
||||
import { ComponentsThirdPartyModule } from './main/content/components-third-party/components-third-party.module';
|
||||
import { ServicesModule } from './main/content/services/services.module';
|
||||
import { FuseAngularMaterialModule } from './main/content/components/angular-material/angular-material.module';
|
||||
import { MarkdownModule } from 'angular2-markdown';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AppStoreModule } from './store/store.module';
|
||||
|
||||
const appRoutes: Routes = [
|
||||
{
|
||||
path : 'apps/mail',
|
||||
loadChildren: './main/content/apps/mail/mail.module#FuseMailModule'
|
||||
path : 'apps',
|
||||
loadChildren: './main/content/apps/apps.module#FuseAppsModule'
|
||||
},
|
||||
{
|
||||
path : 'apps/mail-ngrx',
|
||||
loadChildren: './main/content/apps/mail-ngrx/mail.module#FuseMailNgrxModule'
|
||||
path : 'pages',
|
||||
loadChildren: './main/content/pages/pages.module#FusePagesModule'
|
||||
},
|
||||
{
|
||||
path : 'apps/chat',
|
||||
loadChildren: './main/content/apps/chat/chat.module#FuseChatModule'
|
||||
path : 'ui',
|
||||
loadChildren: './main/content/ui/ui.module#FuseUIModule'
|
||||
},
|
||||
{
|
||||
path : 'apps/calendar',
|
||||
loadChildren: './main/content/apps/calendar/calendar.module#FuseCalendarModule'
|
||||
path : 'services',
|
||||
loadChildren: './main/content/services/services.module#FuseServicesModule'
|
||||
},
|
||||
{
|
||||
path : 'apps/e-commerce',
|
||||
loadChildren: './main/content/apps/e-commerce/e-commerce.module#FuseEcommerceModule'
|
||||
path : 'components',
|
||||
loadChildren: './main/content/components/components.module#FuseComponentsModule'
|
||||
},
|
||||
{
|
||||
path : 'apps/todo',
|
||||
loadChildren: './main/content/apps/todo/todo.module#FuseTodoModule'
|
||||
},
|
||||
{
|
||||
path : 'apps/file-manager',
|
||||
loadChildren: './main/content/apps/file-manager/file-manager.module#FuseFileManagerModule'
|
||||
},
|
||||
{
|
||||
path : 'apps/contacts',
|
||||
loadChildren: './main/content/apps/contacts/contacts.module#FuseContactsModule'
|
||||
},
|
||||
{
|
||||
path : 'apps/scrumboard',
|
||||
loadChildren: './main/content/apps/scrumboard/scrumboard.module#FuseScrumboardModule'
|
||||
path : 'components-third-party',
|
||||
loadChildren: './main/content/components-third-party/components-third-party.module#FuseComponentsThirdPartyModule'
|
||||
},
|
||||
{
|
||||
path : '**',
|
||||
redirectTo: 'apps/dashboards/project'
|
||||
redirectTo: 'apps/dashboards/analytics'
|
||||
}
|
||||
];
|
||||
|
||||
@@ -76,21 +56,13 @@ const appRoutes: Routes = [
|
||||
BrowserAnimationsModule,
|
||||
RouterModule.forRoot(appRoutes),
|
||||
SharedModule,
|
||||
MarkdownModule.forRoot(),
|
||||
TranslateModule.forRoot(),
|
||||
InMemoryWebApiModule.forRoot(FuseFakeDbService, {
|
||||
delay : 0,
|
||||
passThruUnknownUrl: true
|
||||
}),
|
||||
AppStoreModule,
|
||||
FuseMainModule,
|
||||
ProjectModule,
|
||||
PagesModule,
|
||||
UIModule,
|
||||
ServicesModule,
|
||||
ComponentsModule,
|
||||
FuseAngularMaterialModule,
|
||||
ComponentsThirdPartyModule
|
||||
FuseMainModule
|
||||
],
|
||||
providers : [
|
||||
FuseSplashScreenService,
|
||||
|
||||
@@ -76,6 +76,53 @@ export const fuseAnimations = [
|
||||
transition('0 => 1', animate('300ms ease-in'))
|
||||
]),
|
||||
|
||||
trigger('slideIn', [
|
||||
transition('void => left', [
|
||||
style({
|
||||
transform: 'translateX(100%)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
transition('left => void', [
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(-100%)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
transition('void => right', [
|
||||
style({
|
||||
transform: 'translateX(-100%)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
transition('right => void', [
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(100%)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
]),
|
||||
|
||||
trigger('slideInLeft', [
|
||||
state('void', style({
|
||||
transform: 'translateX(-100%)',
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
:host {
|
||||
display: block;
|
||||
padding: 8px;
|
||||
background: #263238;
|
||||
cursor: text;
|
||||
}
|
||||
102
src/app/core/components/highlight/highlight.component.ts
Normal file
102
src/app/core/components/highlight/highlight.component.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { Component, ContentChild, ElementRef, Input, OnInit } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
import * as Prism from 'prismjs/prism';
|
||||
import './prism-languages';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-highlight',
|
||||
template : ' ',
|
||||
styleUrls: ['./highlight.component.scss']
|
||||
})
|
||||
export class FuseHighlightComponent implements OnInit
|
||||
{
|
||||
@ContentChild('source') source: ElementRef;
|
||||
@Input('lang') lang: string;
|
||||
@Input('path') path: string;
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
private http: HttpClient
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
// If there is no language defined, return...
|
||||
if ( !this.lang )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the path is defined...
|
||||
if ( this.path )
|
||||
{
|
||||
// Get the source
|
||||
this.http.get(this.path, {responseType: 'text'}).subscribe((response) => {
|
||||
|
||||
// Highlight it
|
||||
this.highlight(response);
|
||||
});
|
||||
}
|
||||
|
||||
// If the path is not defined and the source element exists...
|
||||
if ( !this.path && this.source )
|
||||
{
|
||||
// Highlight it
|
||||
this.highlight(this.source.nativeElement.value);
|
||||
}
|
||||
}
|
||||
|
||||
highlight(sourceCode)
|
||||
{
|
||||
// Split the source into lines
|
||||
const sourceLines = sourceCode.split('\n');
|
||||
|
||||
// Remove the first and the last line of the source
|
||||
// code if they are blank lines. This way, the html
|
||||
// can be formatted properly while using fuse-highlight
|
||||
// component
|
||||
if ( !sourceLines[0].trim() )
|
||||
{
|
||||
sourceLines.shift();
|
||||
}
|
||||
|
||||
if ( !sourceLines[sourceLines.length - 1].trim() )
|
||||
{
|
||||
sourceLines.pop();
|
||||
}
|
||||
|
||||
// Find the first non-whitespace char index in
|
||||
// the first line of the source code
|
||||
const indexOfFirstChar = sourceLines[0].search(/\S|$/);
|
||||
|
||||
// Generate the trimmed source
|
||||
let source = '';
|
||||
|
||||
// Iterate through all the lines
|
||||
sourceLines.forEach((line, index) => {
|
||||
|
||||
// Trim the beginning white space depending on the index
|
||||
// and concat the source code
|
||||
source = source + line.substr(indexOfFirstChar, line.length);
|
||||
|
||||
// If it's not the last line...
|
||||
if ( index !== sourceLines.length - 1 )
|
||||
{
|
||||
// Add a line break at the end
|
||||
source = source + '\n';
|
||||
}
|
||||
});
|
||||
|
||||
// Generate the highlighted code
|
||||
const highlightedCode = Prism.highlight(source, Prism.languages[this.lang]);
|
||||
|
||||
// Replace the innerHTML of the component with the highlighted code
|
||||
this.elementRef.nativeElement.innerHTML =
|
||||
'<pre><code class="highlight language-' + this.lang + '">' + highlightedCode + '</code></pre>';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
16
src/app/core/components/highlight/prism-languages.ts
Normal file
16
src/app/core/components/highlight/prism-languages.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import 'prismjs/prism';
|
||||
import 'prismjs/components/prism-c';
|
||||
import 'prismjs/components/prism-cpp';
|
||||
import 'prismjs/components/prism-csharp';
|
||||
import 'prismjs/components/prism-css';
|
||||
import 'prismjs/components/prism-diff';
|
||||
import 'prismjs/components/prism-markup';
|
||||
import 'prismjs/components/prism-java';
|
||||
import 'prismjs/components/prism-javascript';
|
||||
import 'prismjs/components/prism-json';
|
||||
import 'prismjs/components/prism-perl';
|
||||
import 'prismjs/components/prism-php';
|
||||
import 'prismjs/components/prism-python';
|
||||
import 'prismjs/components/prism-sass';
|
||||
import 'prismjs/components/prism-scss';
|
||||
import 'prismjs/components/prism-typescript';
|
||||
@@ -1,3 +0,0 @@
|
||||
:host {
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import { Component, ContentChild, ElementRef, Input, OnInit } from '@angular/core';
|
||||
import * as hljs from 'highlight.js';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-hljs',
|
||||
template : ' ',
|
||||
styleUrls: ['./hljs.component.scss']
|
||||
})
|
||||
export class FuseHljsComponent implements OnInit
|
||||
{
|
||||
hljs: any;
|
||||
|
||||
@ContentChild('source') source: ElementRef;
|
||||
@Input('lang') lang: string;
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef
|
||||
)
|
||||
{
|
||||
this.hljs = hljs;
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
const originalSource = this.source.nativeElement.value;
|
||||
|
||||
if ( !originalSource || !this.lang )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Split the source into lines
|
||||
const sourceLines = originalSource.split('\n');
|
||||
|
||||
// Find the first non-whitespace char index in
|
||||
// the first line of the source code
|
||||
const indexOfFirstChar = sourceLines[0].search(/\S|$/);
|
||||
|
||||
// Generate the trimmed source
|
||||
let source = '';
|
||||
|
||||
// Iterate through all the lines and trim the
|
||||
// beginning white space depending on the index
|
||||
sourceLines.forEach((line, index) => {
|
||||
|
||||
source = source + line.substr(indexOfFirstChar, line.length);
|
||||
|
||||
if ( index !== sourceLines.length - 1 )
|
||||
{
|
||||
source = source + '\n';
|
||||
}
|
||||
});
|
||||
|
||||
this.elementRef.nativeElement.innerHTML =
|
||||
`<pre><code class="highlight">` + this.hljs.highlight(this.lang, source).value + `</code></pre>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import { AfterViewInit, Directive, ElementRef, OnDestroy, OnInit } from '@angular/core';
|
||||
import PerfectScrollbar from 'perfect-scrollbar';
|
||||
import { AfterViewInit, Directive, ElementRef, HostListener, OnDestroy } from '@angular/core';
|
||||
import { FuseConfigService } from '../../services/config.service';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { Platform } from '@angular/cdk/platform';
|
||||
import PerfectScrollbar from 'perfect-scrollbar';
|
||||
|
||||
@Directive({
|
||||
selector: '[fusePerfectScrollbar]'
|
||||
})
|
||||
export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnDestroy
|
||||
export class FusePerfectScrollbarDirective implements AfterViewInit, OnDestroy
|
||||
{
|
||||
onSettingsChanged: Subscription;
|
||||
isDisableCustomScrollbars = false;
|
||||
isMobile = false;
|
||||
isInitialized = true;
|
||||
ps;
|
||||
ps: PerfectScrollbar;
|
||||
|
||||
constructor(
|
||||
private element: ElementRef,
|
||||
public element: ElementRef,
|
||||
private fuseConfig: FuseConfigService,
|
||||
private platform: Platform
|
||||
)
|
||||
@@ -35,11 +35,6 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ngAfterViewInit()
|
||||
{
|
||||
if ( this.isMobile || this.isDisableCustomScrollbars )
|
||||
@@ -49,7 +44,9 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD
|
||||
}
|
||||
|
||||
// Initialize the perfect-scrollbar
|
||||
this.ps = new PerfectScrollbar(this.element.nativeElement);
|
||||
this.ps = new PerfectScrollbar(this.element.nativeElement, {
|
||||
wheelPropagation: true
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
@@ -65,6 +62,21 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD
|
||||
this.ps.destroy();
|
||||
}
|
||||
|
||||
@HostListener('document:click', ['$event'])
|
||||
documentClick(event: Event): void
|
||||
{
|
||||
if ( !this.isInitialized || !this.ps )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the scrollbar on document click..
|
||||
// This isn't the most elegant solution but there is no other way
|
||||
// of knowing when the contents of the scrollable container changes.
|
||||
// Therefore, we update scrollbars on every document click.
|
||||
this.ps.update();
|
||||
}
|
||||
|
||||
update()
|
||||
{
|
||||
if ( !this.isInitialized )
|
||||
|
||||
@@ -15,14 +15,14 @@ import { FuseConfirmDialogComponent } from '../components/confirm-dialog/confirm
|
||||
import { FuseCountdownComponent } from '../components/countdown/countdown.component';
|
||||
import { FuseMatchMedia } from '../services/match-media.service';
|
||||
import { FuseNavbarVerticalService } from '../../main/navbar/vertical/navbar-vertical.service';
|
||||
import { FuseHljsComponent } from '../components/hljs/hljs.component';
|
||||
import { FuseHighlightComponent } from '../components/highlight/highlight.component';
|
||||
import { FusePerfectScrollbarDirective } from '../directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
||||
import { FuseIfOnDomDirective } from '../directives/fuse-if-on-dom/fuse-if-on-dom.directive';
|
||||
import { FuseMaterialColorPickerComponent } from '../components/material-color-picker/material-color-picker.component';
|
||||
import { FuseTranslationLoaderService } from '../services/translation-loader.service';
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
import { MarkdownModule } from 'angular2-markdown';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ChartsModule } from 'ng2-charts';
|
||||
|
||||
@NgModule({
|
||||
declarations : [
|
||||
@@ -30,7 +30,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
FuseMatSidenavTogglerDirective,
|
||||
FuseConfirmDialogComponent,
|
||||
FuseCountdownComponent,
|
||||
FuseHljsComponent,
|
||||
FuseHighlightComponent,
|
||||
FuseIfOnDomDirective,
|
||||
FusePerfectScrollbarDirective,
|
||||
FuseMaterialColorPickerComponent
|
||||
@@ -45,7 +45,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
ColorPickerModule,
|
||||
NgxDnDModule,
|
||||
NgxDatatableModule,
|
||||
MarkdownModule
|
||||
ChartsModule
|
||||
],
|
||||
exports : [
|
||||
FlexLayoutModule,
|
||||
@@ -56,7 +56,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
FuseMatSidenavTogglerDirective,
|
||||
FusePipesModule,
|
||||
FuseCountdownComponent,
|
||||
FuseHljsComponent,
|
||||
FuseHighlightComponent,
|
||||
FusePerfectScrollbarDirective,
|
||||
ReactiveFormsModule,
|
||||
ColorPickerModule,
|
||||
@@ -64,8 +64,8 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
NgxDatatableModule,
|
||||
FuseIfOnDomDirective,
|
||||
FuseMaterialColorPickerComponent,
|
||||
MarkdownModule,
|
||||
TranslateModule
|
||||
TranslateModule,
|
||||
ChartsModule
|
||||
],
|
||||
entryComponents: [
|
||||
FuseConfirmDialogComponent
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// ngx-datatable
|
||||
@import '~@swimlane/ngx-datatable/release/index.css';
|
||||
@import '~@swimlane/ngx-datatable/release/themes/material.css';
|
||||
@import '~@swimlane/ngx-datatable/release/assets/icons.css';
|
||||
@import '~@swimlane/ngx-datatable/release/themes/material';
|
||||
|
||||
// Perfect scrollbar
|
||||
@import '~perfect-scrollbar/css/perfect-scrollbar.css';
|
||||
@import '~perfect-scrollbar/css/perfect-scrollbar';
|
||||
|
||||
// Fuse
|
||||
@import "fuse";
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
}
|
||||
|
||||
.mat-pseudo-checkbox-checked:after {
|
||||
width: 14px;
|
||||
height: 7px;
|
||||
width: 14px !important;
|
||||
height: 7px !important;
|
||||
}
|
||||
|
||||
// Fix: "Input underlines has wrong color opacity value"
|
||||
|
||||
@@ -9,145 +9,52 @@
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.card-rich-media {
|
||||
position: relative;
|
||||
&.auto-width {
|
||||
min-width: 0;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
left: 16px;
|
||||
font-size: 20px;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.card-media-header {
|
||||
display: flex;
|
||||
padding: 16px;
|
||||
align-items: center;
|
||||
|
||||
&.medium {
|
||||
align-items: flex-start;
|
||||
|
||||
.card-rich-media {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
&.large {
|
||||
align-items: flex-start;
|
||||
|
||||
.card-rich-media {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
.card-primary-title {
|
||||
padding: 0 16px 0 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.card-rich-media {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
+ div {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.card-avatar-header {
|
||||
display: flex;
|
||||
padding: 16px;
|
||||
align-items: center;
|
||||
|
||||
.card-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 100%;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.card-avatar-title {
|
||||
|
||||
.card-title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card-subtitle {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-primary-title {
|
||||
padding: 16px;
|
||||
|
||||
.card-title {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.card-subtitle {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
+ div {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.card-supporting-text {
|
||||
padding: 16px;
|
||||
font-size: 14px;
|
||||
line-height: 1.75;
|
||||
|
||||
+ div {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.card-actions {
|
||||
display: flex;
|
||||
padding: 8px;
|
||||
|
||||
&.icon-buttons {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
&.align-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&.align-right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.mat-button {
|
||||
min-width: 0 !important;
|
||||
padding: 0 8px !important;
|
||||
}
|
||||
|
||||
.card-expander {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
+ div {
|
||||
padding-top: 0;
|
||||
// Buttons
|
||||
.mat-button {
|
||||
min-width: 0 !important;
|
||||
padding: 0 8px !important;
|
||||
}
|
||||
|
||||
// Button Toggle Group
|
||||
.mat-button-toggle-group,
|
||||
.mat-button-toggle-standalone {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
// Tabs
|
||||
.mat-tab-labels {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mat-tab-label {
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
// Divider
|
||||
.card-divider {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.12);
|
||||
margin: 16px;
|
||||
|
||||
&.light {
|
||||
border-top-color: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
&.full-width {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Expand Area
|
||||
.card-expand-area {
|
||||
overflow: hidden;
|
||||
|
||||
.card-expanded-supporting-text {
|
||||
.card-expanded-content {
|
||||
padding: 8px 16px 16px 16px;
|
||||
font-size: 14px;
|
||||
line-height: 1.75;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,59 @@
|
||||
// ######################
|
||||
// POSITION HELPERS
|
||||
// ######################
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
|
||||
@include media-breakpoint-up($breakpoint) {
|
||||
|
||||
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||
|
||||
.position#{$infix}-relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.position#{$infix}-absolute {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.position#{$infix}-static {
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ####################################
|
||||
// ABSOLUTE POSITION ALIGNMENT HELPERS
|
||||
// ####################################
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
|
||||
@include media-breakpoint-up($breakpoint) {
|
||||
|
||||
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||
|
||||
.align#{$infix}-top {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.align#{$infix}-right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.align#{$infix}-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.align#{$infix}-left {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ######################
|
||||
// SIZE HELPERS
|
||||
// ######################
|
||||
@each $prop, $abbrev in (height: h, width: w) {
|
||||
|
||||
@for $index from 0 through 128 {
|
||||
@for $index from 0 through 180 {
|
||||
$size: $index * 4;
|
||||
$length: #{$size}px;
|
||||
|
||||
@@ -28,7 +78,6 @@
|
||||
// ######################
|
||||
// SPACING HELPERS
|
||||
// ######################
|
||||
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
|
||||
@include media-breakpoint-up($breakpoint) {
|
||||
@@ -83,47 +132,45 @@
|
||||
}
|
||||
|
||||
@if ($abbrev == m) {
|
||||
@for $index from 0 through 64 {
|
||||
$size: $index * 4;
|
||||
$length: #{$size}px;
|
||||
|
||||
// Some special margin utils for flex alignments
|
||||
.m#{$infix}-auto {
|
||||
margin: auto !important;
|
||||
}
|
||||
// Some special margin utils for flex alignments
|
||||
.m#{$infix}-auto {
|
||||
margin: auto !important;
|
||||
}
|
||||
|
||||
.mt#{$infix}-auto {
|
||||
margin-top: auto !important;
|
||||
}
|
||||
.mt#{$infix}-auto {
|
||||
margin-top: auto !important;
|
||||
}
|
||||
|
||||
.mr#{$infix}-auto {
|
||||
margin-right: auto !important;
|
||||
}
|
||||
.mr#{$infix}-auto {
|
||||
margin-right: auto !important;
|
||||
}
|
||||
|
||||
.mb#{$infix}-auto {
|
||||
margin-bottom: auto !important;
|
||||
}
|
||||
.mb#{$infix}-auto {
|
||||
margin-bottom: auto !important;
|
||||
}
|
||||
|
||||
.ml#{$infix}-auto {
|
||||
margin-left: auto !important;
|
||||
}
|
||||
.ml#{$infix}-auto {
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
.mx#{$infix}-auto {
|
||||
margin-right: auto !important;
|
||||
margin-left: auto !important;
|
||||
}
|
||||
.mx#{$infix}-auto {
|
||||
margin-right: auto !important;
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
.my#{$infix}-auto {
|
||||
margin-top: auto !important;
|
||||
margin-bottom: auto !important;
|
||||
}
|
||||
.my#{$infix}-auto {
|
||||
margin-top: auto !important;
|
||||
margin-bottom: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Border helpers
|
||||
// ######################
|
||||
// BORDER HELPERS
|
||||
// ######################
|
||||
$border-style: 1px solid rgba(0, 0, 0, 0.12);
|
||||
|
||||
.border,
|
||||
@@ -162,3 +209,37 @@ $border-style: 1px solid rgba(0, 0, 0, 0.12);
|
||||
border-top: $border-style;
|
||||
border-bottom: $border-style;
|
||||
}
|
||||
|
||||
// ######################
|
||||
// BORDER RADIUS HELPERS
|
||||
// ######################
|
||||
.border-radius-100 {
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.border-radius-2 {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.border-radius-4 {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.border-radius-8 {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.border-radius-16 {
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
// ######################
|
||||
// CURSOR HELPERS
|
||||
// ######################
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cursor-default {
|
||||
cursor: default;
|
||||
}
|
||||
@@ -411,7 +411,6 @@ table {
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
white-space: nowrap;
|
||||
min-width: 120px;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 24px;
|
||||
|
||||
@@ -229,6 +229,22 @@ strong {
|
||||
}
|
||||
}
|
||||
|
||||
.line-height-1 {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.line-height-1\.25 {
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.line-height-1\.50 {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.line-height-1\.75 {
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
// Boxed text
|
||||
.text-boxed {
|
||||
border-radius: 2px;
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
|
||||
*/
|
||||
|
||||
hljs,
|
||||
[hljs] {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
// padding: 0.5em;
|
||||
color: #333;
|
||||
background: #F8F8F8;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.diff .hljs-header {
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.css .rule .hljs-keyword,
|
||||
.hljs-winutils,
|
||||
.nginx .hljs-title,
|
||||
.hljs-subst,
|
||||
.hljs-request,
|
||||
.hljs-status {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-hexcolor,
|
||||
.ruby .hljs-constant {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-tag .hljs-value,
|
||||
.hljs-doctag,
|
||||
.tex .hljs-formula {
|
||||
color: #D14;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-id,
|
||||
.scss .hljs-preprocessor {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-list .hljs-keyword,
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-class .hljs-title,
|
||||
.hljs-type,
|
||||
.vhdl .hljs-literal,
|
||||
.tex .hljs-command {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-tag .hljs-title,
|
||||
.hljs-rule .hljs-property,
|
||||
.django .hljs-tag .hljs-keyword {
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-attribute,
|
||||
.hljs-variable,
|
||||
.lisp .hljs-body,
|
||||
.hljs-name {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-regexp {
|
||||
color: #009926;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.ruby .hljs-symbol .hljs-string,
|
||||
.lisp .hljs-keyword,
|
||||
.clojure .hljs-keyword,
|
||||
.scheme .hljs-keyword,
|
||||
.tex .hljs-special,
|
||||
.hljs-prompt {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.hljs-built_in {
|
||||
color: #0086B3;
|
||||
}
|
||||
|
||||
.hljs-preprocessor,
|
||||
.hljs-pragma,
|
||||
.hljs-pi,
|
||||
.hljs-doctype,
|
||||
.hljs-shebang,
|
||||
.hljs-cdata {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #FDD;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #DFD;
|
||||
}
|
||||
|
||||
.diff .hljs-change {
|
||||
background: #0086B3;
|
||||
}
|
||||
|
||||
.hljs-chunk {
|
||||
color: #AAA;
|
||||
}
|
||||
@@ -98,3 +98,68 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[class*="datatable-icon-"] {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-feature-settings: 'liga';
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.datatable-icon-filter:before {
|
||||
content: "filter_list";
|
||||
}
|
||||
.datatable-icon-collapse:before {
|
||||
content: "unfold_less";
|
||||
}
|
||||
.datatable-icon-expand:before {
|
||||
content: "unfold_more";
|
||||
}
|
||||
.datatable-icon-close:before {
|
||||
content: "close";
|
||||
}
|
||||
.datatable-icon-up:before {
|
||||
content: "keyboard_arrow_up";
|
||||
}
|
||||
.datatable-icon-down:before {
|
||||
content: "keyboard_arrow_down";
|
||||
}
|
||||
.datatable-icon-sort:before {
|
||||
content: "sort";
|
||||
}
|
||||
.datatable-icon-done:before {
|
||||
content: "done";
|
||||
}
|
||||
.datatable-icon-done-all:before {
|
||||
content: "done_all";
|
||||
}
|
||||
.datatable-icon-search:before {
|
||||
content: "search";
|
||||
}
|
||||
.datatable-icon-pin:before {
|
||||
content: "lock";
|
||||
}
|
||||
.datatable-icon-add:before {
|
||||
content: "add";
|
||||
}
|
||||
.datatable-icon-left:before {
|
||||
content: "chevron_left";
|
||||
}
|
||||
.datatable-icon-right:before {
|
||||
content: "chevron_right";
|
||||
}
|
||||
.datatable-icon-skip:before {
|
||||
content: "skip_next";
|
||||
}
|
||||
.datatable-icon-prev:before {
|
||||
content: "skip_previous";
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
@import "highlight";
|
||||
@import "prism";
|
||||
@import "perfect-scrollbar";
|
||||
@import "ngx-datatable";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
$base00: #263238;
|
||||
$base01: #2C393F;
|
||||
$base02: #37474F;
|
||||
$base02: #62727A;
|
||||
$base03: #707880;
|
||||
$base04: #C9CCD3;
|
||||
$base05: #CDD3DE;
|
||||
|
||||
@@ -34,7 +34,7 @@ export class FuseConfigService
|
||||
footer : 'mat-fuse-dark-900-bg'
|
||||
},
|
||||
customScrollbars: true,
|
||||
routerAnimation : 'fadeIn' // fadeIn, slideUp, slideDown, slideRight, slideLeft
|
||||
routerAnimation : 'fadeIn' // fadeIn, slideUp, slideDown, slideRight, slideLeft, none
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,18 +15,27 @@ export class FuseSplashScreenService
|
||||
private router: Router
|
||||
)
|
||||
{
|
||||
// Get the splash screen element
|
||||
this.splashScreenEl = this.document.body.querySelector('#fuse-splash-screen');
|
||||
|
||||
const hideOnLoad = this.router.events.subscribe((event) => {
|
||||
if ( event instanceof NavigationEnd )
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.hide();
|
||||
hideOnLoad.unsubscribe();
|
||||
}, 0);
|
||||
// If the splash screen element exists...
|
||||
if ( this.splashScreenEl )
|
||||
{
|
||||
// Hide it on the first NavigationEnd event
|
||||
const hideOnLoad = this.router.events.subscribe((event) => {
|
||||
if ( event instanceof NavigationEnd )
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.hide();
|
||||
|
||||
// Unsubscribe from this event so it
|
||||
// won't get triggered again
|
||||
hideOnLoad.unsubscribe();
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
show()
|
||||
|
||||
773
src/app/fuse-fake-db/academy.ts
Normal file
773
src/app/fuse-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
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
602
src/app/fuse-fake-db/dashboard-analytics.ts
Normal file
602
src/app/fuse-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
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
export class ProjectsDashboardDb
|
||||
export class ProjectDashboardDb
|
||||
{
|
||||
public static projects = [
|
||||
{
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,58 +1,97 @@
|
||||
import { InMemoryDbService } from 'angular-in-memory-web-api';
|
||||
|
||||
import { ProjectDashboardDb } from './dashboard-project';
|
||||
import { AnalyticsDashboardDb } from './dashboard-analytics';
|
||||
import { CalendarFakeDb } from './calendar';
|
||||
import { ECommerceFakeDb } from './e-commerce';
|
||||
import { AcademyFakeDb } from './academy';
|
||||
import { MailFakeDb } from './mail';
|
||||
import { ChatFakeDb } from './chat';
|
||||
import { CalendarFakeDb } from './calendar';
|
||||
import { TodoFakeDb } from './todo';
|
||||
import { ProfileFakeDb } from './profile';
|
||||
import { ContactsFakeDb } from './contacts';
|
||||
import { InvoiceFakeDb } from './invoice';
|
||||
import { FileManagerFakeDb } from './file-manager';
|
||||
import { SearchFakeDb } from './search';
|
||||
import { QuickPanelFakeDb } from './quick-panel';
|
||||
import { IconsFakeDb } from './icons';
|
||||
import { ProjectsDashboardDb } from './projects-dashboard';
|
||||
import { ContactsFakeDb } from './contacts';
|
||||
import { TodoFakeDb } from './todo';
|
||||
import { ScrumboardFakeDb } from './scrumboard';
|
||||
import { InvoiceFakeDb } from './invoice';
|
||||
import { ProfileFakeDb } from './profile';
|
||||
import { SearchFakeDb } from './search';
|
||||
import { FaqFakeDb } from './faq';
|
||||
import { KnowledgeBaseFakeDb } from './knowledge-base';
|
||||
import { ECommerceFakeDb } from './e-commerce';
|
||||
import { IconsFakeDb } from './icons';
|
||||
import { QuickPanelFakeDb } from './quick-panel';
|
||||
|
||||
export class FuseFakeDbService implements InMemoryDbService
|
||||
{
|
||||
createDb()
|
||||
{
|
||||
return {
|
||||
'mail-mails' : MailFakeDb.mails,
|
||||
'mail-folders' : MailFakeDb.folders,
|
||||
'mail-filters' : MailFakeDb.filters,
|
||||
'mail-labels' : MailFakeDb.labels,
|
||||
'chat-contacts' : ChatFakeDb.contacts,
|
||||
'chat-chats' : ChatFakeDb.chats,
|
||||
'chat-user' : ChatFakeDb.user,
|
||||
'calendar' : CalendarFakeDb.data,
|
||||
'todo-todos' : TodoFakeDb.todos,
|
||||
'todo-filters' : TodoFakeDb.filters,
|
||||
'todo-tags' : TodoFakeDb.tags,
|
||||
'profile-timeline' : ProfileFakeDb.timeline,
|
||||
'profile-photos-videos' : ProfileFakeDb.photosVideos,
|
||||
'profile-about' : ProfileFakeDb.about,
|
||||
'contacts-contacts' : ContactsFakeDb.contacts,
|
||||
'contacts-user' : ContactsFakeDb.user,
|
||||
'invoice' : InvoiceFakeDb.invoice,
|
||||
'file-manager' : FileManagerFakeDb.files,
|
||||
'search-classic' : SearchFakeDb.classic,
|
||||
'search-table' : SearchFakeDb.table,
|
||||
'quick-panel-notes' : QuickPanelFakeDb.notes,
|
||||
'quick-panel-events' : QuickPanelFakeDb.events,
|
||||
'icons' : IconsFakeDb.icons,
|
||||
'projects-dashboard-projects': ProjectsDashboardDb.projects,
|
||||
'projects-dashboard-widgets' : ProjectsDashboardDb.widgets,
|
||||
'scrumboard-boards' : ScrumboardFakeDb.boards,
|
||||
'faq' : FaqFakeDb.data,
|
||||
'knowledge-base' : KnowledgeBaseFakeDb.data,
|
||||
'e-commerce-dashboard' : ECommerceFakeDb.dashboard,
|
||||
'e-commerce-products' : ECommerceFakeDb.products,
|
||||
'e-commerce-orders' : ECommerceFakeDb.orders
|
||||
// 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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
47
src/app/main/content/apps/academy/academy.module.ts
Normal file
47
src/app/main/content/apps/academy/academy.module.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SharedModule } from '../../../../core/modules/shared.module';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { FuseAcademyCoursesComponent } from './courses/courses.component';
|
||||
import { FuseAcademyCourseComponent } from './course/course.component';
|
||||
import { AcademyCoursesService } from './courses.service';
|
||||
import { AcademyCourseService } from './course.service';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'courses',
|
||||
component: FuseAcademyCoursesComponent,
|
||||
resolve : {
|
||||
academy: AcademyCoursesService
|
||||
}
|
||||
},
|
||||
{
|
||||
path : 'courses/:courseId/:courseSlug',
|
||||
component: FuseAcademyCourseComponent,
|
||||
resolve : {
|
||||
academy: AcademyCourseService
|
||||
}
|
||||
},
|
||||
{
|
||||
path : '**',
|
||||
redirectTo: 'courses'
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports : [
|
||||
SharedModule,
|
||||
RouterModule.forChild(routes)
|
||||
],
|
||||
declarations: [
|
||||
FuseAcademyCoursesComponent,
|
||||
FuseAcademyCourseComponent
|
||||
],
|
||||
providers : [
|
||||
AcademyCoursesService,
|
||||
AcademyCourseService
|
||||
]
|
||||
})
|
||||
export class FuseAcademyModule
|
||||
{
|
||||
}
|
||||
49
src/app/main/content/apps/academy/course.service.ts
Normal file
49
src/app/main/content/apps/academy/course.service.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
||||
@Injectable()
|
||||
export class AcademyCourseService implements Resolve<any>
|
||||
{
|
||||
onCourseChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
||||
|
||||
constructor(private http: HttpClient)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The Academy App Main Resolver
|
||||
*
|
||||
* @param {ActivatedRouteSnapshot} route
|
||||
* @param {RouterStateSnapshot} state
|
||||
* @returns {Observable<any> | Promise<any> | any}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
Promise.all([
|
||||
this.getCourse(route.params.courseId, route.params.courseSlug)
|
||||
]).then(
|
||||
() => {
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getCourse(courseId, courseSlug): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http.get('api/academy-course/' + courseId + '/' + courseSlug)
|
||||
.subscribe((response: any) => {
|
||||
this.onCourseChanged.next(response);
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
100
src/app/main/content/apps/academy/course/course.component.html
Normal file
100
src/app/main/content/apps/academy/course/course.component.html
Normal file
@@ -0,0 +1,100 @@
|
||||
<div id="academy-course" class="page-layout simple left-sidenav">
|
||||
|
||||
<mat-sidenav-container>
|
||||
|
||||
<!-- SIDENAV -->
|
||||
<mat-sidenav class="sidenav" align="start" opened="true" mode="side"
|
||||
fuseMatSidenavHelper="academy-left-sidenav" mat-is-locked-open="gt-md">
|
||||
|
||||
<div class="sidenav-content" fusePerfectScrollbar>
|
||||
|
||||
<div class="steps">
|
||||
|
||||
<div class="step"
|
||||
*ngFor="let step of course.steps; let i = index; let last = last; let first = first"
|
||||
(click)="gotoStep(i)"
|
||||
[ngClass]="{'current': currentStep === i, 'completed': currentStep > i, 'last': last, 'first': first}">
|
||||
<div class="index">
|
||||
<span>{{i + 1}}</span>
|
||||
</div>
|
||||
<div class="title">{{step.title}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</mat-sidenav>
|
||||
<!-- / SIDENAV -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<button mat-button class="mat-icon-button mr-16 sidenav-toggle"
|
||||
fuseMatSidenavToggler="academy-left-sidenav" fxHide.gt-md>
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-button class="mat-icon-button mr-16" [routerLink]="'/apps/academy/courses'">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
<h2>{{course.title}}</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div id="course-content" class="content">
|
||||
|
||||
<ng-container *ngFor="let step of course.steps; let i = index;">
|
||||
|
||||
<div class="course-step" fusePerfectScrollbar
|
||||
*ngIf="currentStep === i"
|
||||
[@slideIn]="animationDirection">
|
||||
|
||||
<div id="course-step-content" class="course-step-content" [innerHTML]="step.content"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
<div class="step-navigation">
|
||||
|
||||
<button mat-fab class="previous mat-accent white-fg"
|
||||
(click)="gotoPreviousStep()"
|
||||
[disabled]="currentStep === 0"
|
||||
[fxHide]="currentStep === 0">
|
||||
<mat-icon>chevron_left</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-fab class="next mat-accent white-fg"
|
||||
(click)="gotoNextStep()"
|
||||
[disabled]="currentStep === course.totalSteps - 1"
|
||||
[fxHide]="currentStep === course.totalSteps - 1">
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-fab class="done mat-green-600-bg"
|
||||
routerLink="/apps/academy/courses"
|
||||
[disabled]="currentStep !== course.totalSteps - 1"
|
||||
[fxShow]="currentStep === course.totalSteps - 1">
|
||||
<mat-icon>check</mat-icon>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / CENTER -->
|
||||
|
||||
</mat-sidenav-container>
|
||||
|
||||
</div>
|
||||
203
src/app/main/content/apps/academy/course/course.component.scss
Normal file
203
src/app/main/content/apps/academy/course/course.component.scss
Normal file
@@ -0,0 +1,203 @@
|
||||
@import "src/app/core/scss/fuse";
|
||||
|
||||
#academy-course {
|
||||
|
||||
.mat-drawer-container {
|
||||
flex: 1 !important;
|
||||
|
||||
> .mat-drawer-content {
|
||||
flex: 1 !important;
|
||||
|
||||
@include media-breakpoint-up('lg') {
|
||||
z-index: 52;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidenav {
|
||||
|
||||
.steps {
|
||||
padding: 16px 0;
|
||||
|
||||
.step {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
cursor: pointer;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
|
||||
&.current {
|
||||
background: mat-color($mat-blue, 50);
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
|
||||
.index {
|
||||
|
||||
span {
|
||||
border: 2px solid mat-color($mat-blue, 500);
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
&.completed {
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
|
||||
.index {
|
||||
|
||||
span {
|
||||
border: 2px solid mat-color($mat-blue, 500);
|
||||
}
|
||||
|
||||
&:after {
|
||||
border-left-color: mat-color($mat-blue, 500);
|
||||
}
|
||||
}
|
||||
|
||||
+ .step {
|
||||
|
||||
.index {
|
||||
|
||||
&:before {
|
||||
border-left-color: mat-color($mat-blue, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.first {
|
||||
|
||||
.index {
|
||||
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.last {
|
||||
|
||||
.index {
|
||||
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.index {
|
||||
display: flex;
|
||||
margin-right: 12px;
|
||||
|
||||
span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
width: 28px;
|
||||
min-width: 28px;
|
||||
max-width: 28px;
|
||||
height: 28px;
|
||||
background: white;
|
||||
border-radius: 100%;
|
||||
border: 2px solid mat-color($mat-grey, 500);
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: ' ';
|
||||
border-left: 1px solid mat-color($mat-grey, 300);
|
||||
width: 1px;
|
||||
height: 50%;
|
||||
left: 29px;
|
||||
z-index: 8;
|
||||
}
|
||||
|
||||
&:before {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:after {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
position: relative;
|
||||
|
||||
.header {
|
||||
height: 72px;
|
||||
min-height: 72px;
|
||||
max-height: 72px;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
background: mat-color($mat-grey, 200);
|
||||
|
||||
.course-step {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 48px;
|
||||
overflow: auto;
|
||||
|
||||
@media (max-width: 720px) {
|
||||
padding: 0 0 120px 0;
|
||||
}
|
||||
|
||||
.course-step-content {
|
||||
padding: 24px;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
background: white;
|
||||
@include mat-elevation(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-navigation {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
bottom: 32px;
|
||||
max-width: 944px;
|
||||
padding: 0 24px;
|
||||
width: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
.previous {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.next,
|
||||
.done {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
101
src/app/main/content/apps/academy/course/course.component.ts
Normal file
101
src/app/main/content/apps/academy/course/course.component.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, QueryList, ViewChildren, ViewEncapsulation } from '@angular/core';
|
||||
import { AcademyCourseService } from '../course.service';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { FusePerfectScrollbarDirective } from '../../../../../core/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
||||
import { fuseAnimations } from '../../../../../core/animations';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-academy-course',
|
||||
templateUrl : './course.component.html',
|
||||
styleUrls : ['./course.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseAcademyCourseComponent implements OnInit, OnDestroy, AfterViewInit
|
||||
{
|
||||
course: any;
|
||||
courseSubscription: Subscription;
|
||||
currentStep = 0;
|
||||
courseStepContent;
|
||||
animationDirection: 'left' | 'right' | 'none' = 'none';
|
||||
@ViewChildren(FusePerfectScrollbarDirective) fuseScrollbarDirectives: QueryList<FusePerfectScrollbarDirective>;
|
||||
|
||||
constructor(
|
||||
private courseService: AcademyCourseService,
|
||||
private changeDetectorRef: ChangeDetectorRef
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
// Subscribe to courses
|
||||
this.courseSubscription =
|
||||
this.courseService.onCourseChanged
|
||||
.subscribe(course => {
|
||||
this.course = course;
|
||||
});
|
||||
}
|
||||
|
||||
ngAfterViewInit()
|
||||
{
|
||||
this.courseStepContent = this.fuseScrollbarDirectives.find((fuseScrollbarDirective) => {
|
||||
return fuseScrollbarDirective.element.nativeElement.id === 'course-step-content';
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
{
|
||||
this.courseSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
gotoStep(step)
|
||||
{
|
||||
// Decide the animation direction
|
||||
this.animationDirection = this.currentStep < step ? 'left' : 'right';
|
||||
|
||||
// Run change detection so the change
|
||||
// in the animation direction registered
|
||||
this.changeDetectorRef.detectChanges();
|
||||
|
||||
// Set the current step
|
||||
this.currentStep = step;
|
||||
}
|
||||
|
||||
gotoNextStep()
|
||||
{
|
||||
if ( this.currentStep === this.course.totalSteps - 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the animation direction
|
||||
this.animationDirection = 'left';
|
||||
|
||||
// Run change detection so the change
|
||||
// in the animation direction registered
|
||||
this.changeDetectorRef.detectChanges();
|
||||
|
||||
// Increase the current step
|
||||
this.currentStep++;
|
||||
}
|
||||
|
||||
gotoPreviousStep()
|
||||
{
|
||||
if ( this.currentStep === 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the animation direction
|
||||
this.animationDirection = 'right';
|
||||
|
||||
// Run change detection so the change
|
||||
// in the animation direction registered
|
||||
this.changeDetectorRef.detectChanges();
|
||||
|
||||
// Decrease the current step
|
||||
this.currentStep--;
|
||||
}
|
||||
}
|
||||
62
src/app/main/content/apps/academy/courses.service.ts
Normal file
62
src/app/main/content/apps/academy/courses.service.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
||||
@Injectable()
|
||||
export class AcademyCoursesService implements Resolve<any>
|
||||
{
|
||||
onCategoriesChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
||||
onCoursesChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
||||
|
||||
constructor(private http: HttpClient)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The Academy App Main Resolver
|
||||
*
|
||||
* @param {ActivatedRouteSnapshot} route
|
||||
* @param {RouterStateSnapshot} state
|
||||
* @returns {Observable<any> | Promise<any> | any}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
Promise.all([
|
||||
this.getCategories(),
|
||||
this.getCourses()
|
||||
]).then(
|
||||
() => {
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getCategories(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http.get('api/academy-categories')
|
||||
.subscribe((response: any) => {
|
||||
this.onCategoriesChanged.next(response);
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
getCourses(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http.get('api/academy-courses')
|
||||
.subscribe((response: any) => {
|
||||
this.onCoursesChanged.next(response);
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<div id="academy-courses" class="page-layout simple" fusePerfectScrollbar>
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-16 p-sm-24" fxLayout="column" fxLayoutAlign="center center">
|
||||
|
||||
<div class="hero-text">
|
||||
<mat-icon class="hero-icon">school</mat-icon>
|
||||
<h1>WELCOME TO ACADEMY</h1>
|
||||
<h3>
|
||||
Our courses will step you through the process of building a small application, or adding a new feature
|
||||
to an existing application.
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<div fxLayout="column" fxLayoutAlign="center">
|
||||
|
||||
<div class="filters" fxLayout="column" fxLayoutAlign="center center"
|
||||
fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="space-between center">
|
||||
|
||||
<mat-form-field class="course-search">
|
||||
|
||||
<input matInput placeholder="Search for a course" [(ngModel)]="searchTerm"
|
||||
(input)="filterCoursesByTerm()">
|
||||
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="category-selector">
|
||||
|
||||
<mat-select placeholder="Select Category" [(ngModel)]="currentCategory"
|
||||
(change)="filterCoursesByCategory()">
|
||||
<mat-option [value]="'all'">
|
||||
All
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let category of categories" [value]="category.value">
|
||||
{{ category.label }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="courses" fxLayout="row" fxLayoutAlign="center" fxLayoutWrap>
|
||||
|
||||
<div class="course" *ngFor="let course of filteredCourses" fxFlex="100" fxFlex.gt-xs="50"
|
||||
fxFlex.gt-sm="33" [ngClass]="course.category">
|
||||
|
||||
<div class="course-content" fxLayout="column">
|
||||
|
||||
<div class="header" fxLayout="row" fxLayoutAlign="center center"
|
||||
[ngClass]="course.category + '-bg'">
|
||||
|
||||
<div class="category" fxFlex>
|
||||
{{course.category}}
|
||||
</div>
|
||||
|
||||
<div class="length" fxLayout="row" fxLayoutAlign="center center">
|
||||
<mat-icon class="length-icon s-20">access_time</mat-icon>
|
||||
<div class="min">{{course.length}} min</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content" fxLayout="column" fxLayoutAlign="center center" fxFlex>
|
||||
<div class="h1">{{course.title}}</div>
|
||||
<div class="updated">Updated {{course.updated}}</div>
|
||||
</div>
|
||||
|
||||
<div class="footer" fxLayout="row" fxLayoutAlign="center center">
|
||||
<button mat-button color="accent"
|
||||
[routerLink]="'/apps/academy/courses/' + course.id + '/' + course.slug">
|
||||
START
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="no-courses" *ngIf="filteredCourses.length === 0">
|
||||
No courses found!
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
||||
188
src/app/main/content/apps/academy/courses/courses.component.scss
Normal file
188
src/app/main/content/apps/academy/courses/courses.component.scss
Normal file
@@ -0,0 +1,188 @@
|
||||
@import "src/app/core/scss/fuse";
|
||||
|
||||
#academy-courses {
|
||||
|
||||
.header {
|
||||
position: relative;
|
||||
flex: 1 0 auto;
|
||||
height: 280px;
|
||||
max-height: 280px;
|
||||
background: #1A237E;
|
||||
background: linear-gradient(to right, #0E2A3B 0%, #34306B 100%);
|
||||
text-align: center;
|
||||
|
||||
@include media-breakpoint('xs') {
|
||||
height: 240px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.hero-text {
|
||||
|
||||
.hero-icon {
|
||||
position: absolute;
|
||||
top: -64px;
|
||||
left: 0px;
|
||||
opacity: 0.04;
|
||||
font-size: 512px !important;
|
||||
width: 512px !important;
|
||||
height: 512px !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
font-size: 40px;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.01em;
|
||||
text-align: center;
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
max-width: 480px;
|
||||
text-align: center;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.03em;
|
||||
margin: 0;
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
|
||||
.category-selector {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
width: 100%;
|
||||
max-width: 1040px;
|
||||
margin: 24px auto;
|
||||
padding: 0 20px;
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.course-search {
|
||||
width: 200px;
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up('sm') {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.courses {
|
||||
width: 100%;
|
||||
max-width: 1040px;
|
||||
margin: 0 auto;
|
||||
|
||||
.no-courses {
|
||||
font-size: 24px;
|
||||
margin: 24px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.course {
|
||||
padding: 16px;
|
||||
|
||||
&:hover {
|
||||
|
||||
.course-content {
|
||||
@include mat-elevation(8);
|
||||
}
|
||||
}
|
||||
|
||||
.course-content {
|
||||
background: white;
|
||||
min-height: 240px;
|
||||
transition: box-shadow 150ms ease-in-out;
|
||||
|
||||
@include mat-elevation(1);
|
||||
|
||||
.header {
|
||||
color: white;
|
||||
padding: 16px 24px;
|
||||
height: 64px !important;
|
||||
min-height: 64px !important;
|
||||
max-height: 64px !important;
|
||||
|
||||
&.web-bg {
|
||||
background: mat-color($mat-blue, 500);
|
||||
}
|
||||
|
||||
&.android-bg {
|
||||
background: mat-color($mat-green, 500);
|
||||
}
|
||||
|
||||
&.firebase-bg {
|
||||
background: mat-color($mat-amber, 800);
|
||||
}
|
||||
|
||||
&.cloud-bg {
|
||||
background: mat-color($mat-blue-grey, 500);
|
||||
}
|
||||
|
||||
.category {
|
||||
text-transform: capitalize;
|
||||
text-align: left;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
.length {
|
||||
|
||||
.length-icon {
|
||||
margin-right: 8px;
|
||||
color: rgba(0, 0, 0, 0.54) !important;
|
||||
}
|
||||
|
||||
.min {
|
||||
font-size: 16px;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 24px;
|
||||
|
||||
.h1 {
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.updated {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
margin-top: 4px;
|
||||
color: rgba(0, 0, 0, 0.37);
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
padding: 16px;
|
||||
height: 48px !important;
|
||||
min-height: 48px !important;
|
||||
max-height: 48px !important;
|
||||
box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { AcademyCoursesService } from '../courses.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-academy-courses',
|
||||
templateUrl: './courses.component.html',
|
||||
styleUrls : ['./courses.component.scss']
|
||||
})
|
||||
export class FuseAcademyCoursesComponent implements OnInit, OnDestroy
|
||||
{
|
||||
categories: any[];
|
||||
courses: any[];
|
||||
coursesFilteredByCategory: any[];
|
||||
filteredCourses: any[];
|
||||
|
||||
categoriesSubscription: Subscription;
|
||||
coursesSubscription: Subscription;
|
||||
|
||||
currentCategory = 'all';
|
||||
searchTerm = '';
|
||||
|
||||
constructor(
|
||||
private coursesService: AcademyCoursesService
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
// Subscribe to categories
|
||||
this.categoriesSubscription =
|
||||
this.coursesService.onCategoriesChanged
|
||||
.subscribe(categories => {
|
||||
this.categories = categories;
|
||||
});
|
||||
|
||||
// Subscribe to courses
|
||||
this.coursesSubscription =
|
||||
this.coursesService.onCoursesChanged
|
||||
.subscribe(courses => {
|
||||
this.filteredCourses = this.coursesFilteredByCategory = this.courses = courses;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
{
|
||||
this.categoriesSubscription.unsubscribe();
|
||||
this.coursesSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
filterCoursesByCategory()
|
||||
{
|
||||
// Filter
|
||||
if ( this.currentCategory === 'all' )
|
||||
{
|
||||
this.coursesFilteredByCategory = this.courses;
|
||||
this.filteredCourses = this.courses;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.coursesFilteredByCategory = this.courses.filter((course) => {
|
||||
return course.category === this.currentCategory;
|
||||
});
|
||||
|
||||
this.filteredCourses = [...this.coursesFilteredByCategory];
|
||||
|
||||
}
|
||||
|
||||
// Re-filter by search term
|
||||
this.filterCoursesByTerm();
|
||||
}
|
||||
|
||||
filterCoursesByTerm()
|
||||
{
|
||||
const searchTerm = this.searchTerm.toLowerCase();
|
||||
|
||||
// Search
|
||||
if ( searchTerm === '' )
|
||||
{
|
||||
this.filteredCourses = this.coursesFilteredByCategory;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.filteredCourses = this.coursesFilteredByCategory.filter((course) => {
|
||||
return course.title.toLowerCase().includes(searchTerm);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/app/main/content/apps/apps.module.ts
Normal file
67
src/app/main/content/apps/apps.module.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SharedModule } from '../../../core/modules/shared.module';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { FuseAngularMaterialModule } from '../components/angular-material/angular-material.module';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'dashboards/project',
|
||||
loadChildren: './dashboards/project/project.module#FuseProjectDashboardModule'
|
||||
},
|
||||
{
|
||||
path : 'dashboards/analytics',
|
||||
loadChildren: './dashboards/analytics/analytics.module#FuseAnalyticsDashboardModule'
|
||||
},
|
||||
{
|
||||
path : 'mail',
|
||||
loadChildren: './mail/mail.module#FuseMailModule'
|
||||
},
|
||||
{
|
||||
path : 'mail-ngrx',
|
||||
loadChildren: './mail-ngrx/mail.module#FuseMailNgrxModule'
|
||||
},
|
||||
{
|
||||
path : 'chat',
|
||||
loadChildren: './chat/chat.module#FuseChatModule'
|
||||
},
|
||||
{
|
||||
path : 'calendar',
|
||||
loadChildren: './calendar/calendar.module#FuseCalendarModule'
|
||||
},
|
||||
{
|
||||
path : 'e-commerce',
|
||||
loadChildren: './e-commerce/e-commerce.module#FuseEcommerceModule'
|
||||
},
|
||||
{
|
||||
path : 'academy',
|
||||
loadChildren: './academy/academy.module#FuseAcademyModule'
|
||||
},
|
||||
{
|
||||
path : 'todo',
|
||||
loadChildren: './todo/todo.module#FuseTodoModule'
|
||||
},
|
||||
{
|
||||
path : 'file-manager',
|
||||
loadChildren: './file-manager/file-manager.module#FuseFileManagerModule'
|
||||
},
|
||||
{
|
||||
path : 'contacts',
|
||||
loadChildren: './contacts/contacts.module#FuseContactsModule'
|
||||
},
|
||||
{
|
||||
path : 'scrumboard',
|
||||
loadChildren: './scrumboard/scrumboard.module#FuseScrumboardModule'
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports : [
|
||||
SharedModule,
|
||||
RouterModule.forChild(routes),
|
||||
FuseAngularMaterialModule
|
||||
],
|
||||
declarations: []
|
||||
})
|
||||
export class FuseAppsModule
|
||||
{
|
||||
}
|
||||
@@ -217,35 +217,35 @@
|
||||
|
||||
&.Jan {
|
||||
background-image: url('/assets/images/backgrounds/winter.jpg');
|
||||
background-position: 0 65%;
|
||||
background-position: 0 85%;
|
||||
}
|
||||
&.Feb {
|
||||
background-image: url('/assets/images/backgrounds/winter.jpg');
|
||||
background-position: 0 65%;
|
||||
background-position: 0 85%;
|
||||
}
|
||||
&.Mar {
|
||||
background-image: url('/assets/images/backgrounds/spring.jpg');
|
||||
background-position: 0 19%;
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.Apr {
|
||||
background-image: url('/assets/images/backgrounds/spring.jpg');
|
||||
background-position: 0 19%;
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.May {
|
||||
background-image: url('/assets/images/backgrounds/spring.jpg');
|
||||
background-position: 0 19%;
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.Jun {
|
||||
background-image: url('/assets/images/backgrounds/summer.jpg');
|
||||
background-position: 0 91%;
|
||||
background-position: 0 80%;
|
||||
}
|
||||
&.Jul {
|
||||
background-image: url('/assets/images/backgrounds/summer.jpg');
|
||||
background-position: 0 91%;
|
||||
background-position: 0 80%;
|
||||
}
|
||||
&.Aug {
|
||||
background-image: url('/assets/images/backgrounds/summer.jpg');
|
||||
background-position: 0 91%;
|
||||
background-position: 0 80%;
|
||||
}
|
||||
&.Sep {
|
||||
background-image: url('/assets/images/backgrounds/autumn.jpg');
|
||||
@@ -261,7 +261,7 @@
|
||||
}
|
||||
&.Dec {
|
||||
background-image: url('/assets/images/backgrounds/winter.jpg');
|
||||
background-position: 0 65%;
|
||||
background-position: 0 85%;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
|
||||
@@ -25,21 +25,13 @@ import { fuseAnimations } from '../../../../core/animations';
|
||||
export class FuseCalendarComponent implements OnInit
|
||||
{
|
||||
view: string;
|
||||
|
||||
viewDate: Date;
|
||||
|
||||
events: CalendarEvent[];
|
||||
|
||||
public actions: CalendarEventAction[];
|
||||
|
||||
activeDayIsOpen: boolean;
|
||||
|
||||
refresh: Subject<any> = new Subject();
|
||||
|
||||
dialogRef: any;
|
||||
|
||||
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
||||
|
||||
selectedDay: any;
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ChatService } from '../../../chat.service';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import 'rxjs/add/operator/debounceTime';
|
||||
import 'rxjs/add/operator/distinctUntilChanged';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -4,6 +4,7 @@ import { fuseAnimations } from '../../../../core/animations';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { FuseContactsContactFormDialogComponent } from './contact-form/contact-form.component';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import 'rxjs/add/operator/debounceTime';
|
||||
import 'rxjs/add/operator/distinctUntilChanged';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { ContactsService } from '../../contacts.service';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-contacts-main-sidenav',
|
||||
templateUrl: './main.component.html',
|
||||
styleUrls : ['./main.component.scss']
|
||||
})
|
||||
export class FuseContactsMainSidenavComponent implements OnInit
|
||||
export class FuseContactsMainSidenavComponent implements OnDestroy
|
||||
{
|
||||
user: any;
|
||||
filterBy: string;
|
||||
onUserDataChangedSubscription: Subscription;
|
||||
|
||||
constructor(private contactsService: ContactsService)
|
||||
{
|
||||
this.filterBy = 'all';
|
||||
this.contactsService.onUserDataChanged.subscribe(user => {
|
||||
this.user = user;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
this.filterBy = this.contactsService.filterBy || 'all';
|
||||
this.onUserDataChangedSubscription =
|
||||
this.contactsService.onUserDataChanged.subscribe(user => {
|
||||
this.user = user;
|
||||
});
|
||||
}
|
||||
|
||||
changeFilter(filter)
|
||||
@@ -28,4 +27,9 @@ export class FuseContactsMainSidenavComponent implements OnInit
|
||||
this.filterBy = filter;
|
||||
this.contactsService.onFilterChanged.next(this.filterBy);
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
{
|
||||
this.onUserDataChangedSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,510 @@
|
||||
<div id="dashboard-analytics" class="page-layout blank grey-100-bg" fusePerfectScrollbar>
|
||||
|
||||
<div class="main-widget">
|
||||
|
||||
<div class="position-relative p-24 mat-blue-600-bg"
|
||||
fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div fxLayout="column" fxLayoutAlign="start start">
|
||||
<span class="h2">Visitors</span>
|
||||
<span class="h5 secondary-text">Unique visitors by month</span>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<div class="py-8 px-12 border-radius-2 line-height-1 mr-8 cursor-pointer"
|
||||
(click)="widget1SelectedYear = '2015'"
|
||||
[ngClass]="{'blue-300-bg': widget1SelectedYear === '2015'}">
|
||||
2015
|
||||
</div>
|
||||
<div class="py-8 px-12 border-radius-2 line-height-1 mr-8 cursor-pointer"
|
||||
(click)="widget1SelectedYear = '2016'"
|
||||
[ngClass]="{'blue-300-bg': widget1SelectedYear === '2016'}">
|
||||
2016
|
||||
</div>
|
||||
<div class="py-8 px-12 border-radius-2 line-height-1 cursor-pointer"
|
||||
(click)="widget1SelectedYear = '2017'"
|
||||
[ngClass]="{'blue-300-bg': widget1SelectedYear === '2017'}">
|
||||
2017
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="position-relative h-256 pb-16 mat-blue-600-bg">
|
||||
<canvas baseChart
|
||||
[datasets]="widgets.widget1.datasets[widget1SelectedYear]"
|
||||
[labels]="widgets.widget1.labels"
|
||||
[colors]="widgets.widget1.colors"
|
||||
[options]="widgets.widget1.options"
|
||||
[chartType]="widgets.widget1.chartType">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
<div class="left mr-32">
|
||||
|
||||
<div class="pb-24 font-size-18 font-weight-300">
|
||||
How are your active users trending over time?
|
||||
</div>
|
||||
|
||||
<div fxLayout="column" fxLayoutAlign="start"
|
||||
fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start start">
|
||||
|
||||
<!-- Widget 2 -->
|
||||
<div class="widget" fxFlex="100" fxFlex.gt-sm="33">
|
||||
|
||||
<div class="fuse-card auto-width mb-32" [ngClass.gt-sm]="'mb-0 mr-32'">
|
||||
|
||||
<div class="p-16 pb-0" fxLayout="row" fxLayoutAlign="start end" fxLayoutWrap>
|
||||
|
||||
<div class="pr-16">
|
||||
<div class="h3 secondary-text">Conversion</div>
|
||||
<div class="font-size-54 font-weight-300 line-height-1 mt-8">
|
||||
{{widgets.widget2.conversion.value}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="py-4 font-size-16" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxFlex="row" fxLayoutAlign="start center" class="green-fg"
|
||||
*ngIf="widgets.widget2.conversion.ofTarget > 0">
|
||||
<mat-icon class="green-fg mr-4">trending_up</mat-icon>
|
||||
<span>{{widgets.widget2.conversion.ofTarget}}%</span>
|
||||
</div>
|
||||
<div fxFlex="row" fxLayoutAlign="start center" class="red-fg"
|
||||
*ngIf="widgets.widget2.conversion.ofTarget < 0">
|
||||
<mat-icon class="red-fg mr-4">trending_down</mat-icon>
|
||||
<span>{{widgets.widget2.conversion.ofTarget}}%</span>
|
||||
</div>
|
||||
<div class="ml-4 text-nowrap">of target</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="h-96 w-100-p">
|
||||
<canvas baseChart
|
||||
[datasets]="widgets.widget2.datasets"
|
||||
[labels]="widgets.widget2.labels"
|
||||
[colors]="widgets.widget2.colors"
|
||||
[options]="widgets.widget2.options"
|
||||
[chartType]="widgets.widget2.chartType">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / Widget 2 -->
|
||||
|
||||
<!-- Widget 3 -->
|
||||
<div class="widget" fxFlex="100" fxFlex.gt-sm="34">
|
||||
|
||||
<div class="fuse-card auto-width mb-32" [ngClass.gt-sm]="'mb-0 mr-32'">
|
||||
|
||||
<div class="p-16 pb-0" fxLayout="row" fxLayoutAlign="start end" fxLayoutWrap>
|
||||
|
||||
<div class="pr-16">
|
||||
<div class="h3 secondary-text">Impressions</div>
|
||||
<div class="font-size-54 font-weight-300 line-height-1 mt-8">
|
||||
{{widgets.widget3.impressions.value}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="py-4 font-size-16" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxFlex="row" fxLayoutAlign="start center" class="green-fg"
|
||||
*ngIf="widgets.widget3.impressions.ofTarget > 0">
|
||||
<mat-icon class="green-fg mr-4">trending_up</mat-icon>
|
||||
<span>{{widgets.widget3.impressions.ofTarget}}%</span>
|
||||
</div>
|
||||
<div fxFlex="row" fxLayoutAlign="start center" class="red-fg"
|
||||
*ngIf="widgets.widget3.impressions.ofTarget < 0">
|
||||
<mat-icon class="red-fg mr-4">trending_down</mat-icon>
|
||||
<span>{{widgets.widget3.impressions.ofTarget}}%</span>
|
||||
</div>
|
||||
<div class="ml-4 text-nowrap">of target</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="h-96 w-100-p">
|
||||
<canvas baseChart
|
||||
[datasets]="widgets.widget3.datasets"
|
||||
[labels]="widgets.widget3.labels"
|
||||
[colors]="widgets.widget3.colors"
|
||||
[options]="widgets.widget3.options"
|
||||
[chartType]="widgets.widget3.chartType">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / Widget 3 -->
|
||||
|
||||
<!-- Widget 4 -->
|
||||
<div class="widget" fxFlex="100" fxFlex.gt-sm="33">
|
||||
|
||||
<div class="fuse-card auto-width">
|
||||
|
||||
<div class="p-16 pb-0" fxLayout="row" fxLayoutAlign="start end" fxLayoutWrap>
|
||||
|
||||
<div class="pr-16">
|
||||
<div class="h3 secondary-text">Visits</div>
|
||||
<div class="font-size-54 font-weight-300 line-height-1 mt-8">
|
||||
{{widgets.widget4.visits.value}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="py-4 font-size-16" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxFlex="row" fxLayoutAlign="start center" class="green-fg"
|
||||
*ngIf="widgets.widget4.visits.ofTarget > 0">
|
||||
<mat-icon class="green-fg mr-4">trending_up</mat-icon>
|
||||
<span>{{widgets.widget4.visits.ofTarget}}%</span>
|
||||
</div>
|
||||
<div fxFlex="row" fxLayoutAlign="start center" class="red-fg"
|
||||
*ngIf="widgets.widget4.visits.ofTarget < 0">
|
||||
<mat-icon class="red-fg mr-4">trending_down</mat-icon>
|
||||
<span>{{widgets.widget4.visits.ofTarget}}%</span>
|
||||
</div>
|
||||
<div class="ml-4 text-nowrap">of target</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="h-96 w-100-p">
|
||||
<canvas baseChart
|
||||
[datasets]="widgets.widget4.datasets"
|
||||
[labels]="widgets.widget4.labels"
|
||||
[colors]="widgets.widget4.colors"
|
||||
[options]="widgets.widget4.options"
|
||||
[chartType]="widgets.widget4.chartType">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / Widget 4 -->
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Widget 5 -->
|
||||
<div class="pt-48 pb-24 font-size-18 font-weight-300">
|
||||
How many pages your users visit?
|
||||
</div>
|
||||
|
||||
<div class="fuse-card auto-width">
|
||||
|
||||
<div class="position-relative p-24"
|
||||
fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div fxLayout="column" fxLayoutAlign="start start">
|
||||
<span class="h2">Visitors & Page views</span>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<div class="py-8 px-12 border-radius-2 line-height-1 mr-8 cursor-pointer"
|
||||
(click)="widget5SelectedDay = 'yesterday'"
|
||||
[ngClass]="{'grey-300-bg': widget5SelectedDay === 'yesterday'}">
|
||||
Yesterday
|
||||
</div>
|
||||
<div class="py-8 px-12 border-radius-2 line-height-1 mr-8 cursor-pointer"
|
||||
(click)="widget5SelectedDay = 'today'"
|
||||
[ngClass]="{'grey-300-bg': widget5SelectedDay === 'today'}">
|
||||
Today
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="position-relative h-368 pb-16">
|
||||
<canvas baseChart
|
||||
[datasets]="widgets.widget5.datasets[widget5SelectedDay]"
|
||||
[labels]="widgets.widget5.labels"
|
||||
[colors]="widgets.widget5.colors"
|
||||
[options]="widgets.widget5.options"
|
||||
[chartType]="widgets.widget5.chartType">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / Widget 5 -->
|
||||
|
||||
<!-- Widget 6 -->
|
||||
<div class="pt-48 pb-24 font-size-18 font-weight-300">
|
||||
Where are your users?
|
||||
</div>
|
||||
|
||||
<div class="fuse-card auto-width p-16">
|
||||
|
||||
<agm-map class="h-640 w-100-p"
|
||||
[minZoom]="2"
|
||||
[maxZoom]="2"
|
||||
[fullscreenControl]="false"
|
||||
[rotateControl]="false"
|
||||
[zoomControl]="false"
|
||||
[scaleControl]="false"
|
||||
[streetViewControl]="false"
|
||||
[scrollwheel]="false"
|
||||
[styles]="widgets.widget6.styles">
|
||||
<agm-marker
|
||||
*ngFor="let marker of widgets.widget6.markers"
|
||||
[latitude]="marker.lat"
|
||||
[longitude]="marker.lng">
|
||||
|
||||
<agm-info-window>
|
||||
<strong>{{marker.label}}</strong>
|
||||
</agm-info-window>
|
||||
|
||||
</agm-marker>
|
||||
</agm-map>
|
||||
|
||||
</div>
|
||||
<!-- / Widget 6 -->
|
||||
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
|
||||
<div fxLayout="row" fxLayoutWrap
|
||||
fxLayout.gt-md="column">
|
||||
|
||||
<!-- Widget 7 -->
|
||||
<div class="mb-48" [ngClass.lt-lg]="'mr-32'">
|
||||
|
||||
<div class="pb-24 font-size-18 font-weight-300">
|
||||
What are your top devices?
|
||||
</div>
|
||||
|
||||
<div class="fuse-card">
|
||||
|
||||
<div class="p-16">
|
||||
<div class="h1 font-weight-300">Sessions by device</div>
|
||||
</div>
|
||||
|
||||
<div class="h-200">
|
||||
<ngx-charts-pie-chart
|
||||
*fuseIfOnDom
|
||||
[scheme]="widgets.widget7.scheme"
|
||||
[results]="widgets.widget7.devices"
|
||||
[doughnut]="true">
|
||||
</ngx-charts-pie-chart>
|
||||
</div>
|
||||
|
||||
<div class="p-16" fxLayout="row" fxLayoutAlign="center center">
|
||||
|
||||
<div class="px-16" fxLayout="column" fxLayoutAlign="start center"
|
||||
*ngFor="let device of widgets.widget7.devices">
|
||||
|
||||
<div class="h4 secondary-text">{{device.name}}</div>
|
||||
<div class="h2 font-weight-300 py-8">{{device.value}}%</div>
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="center center">
|
||||
<mat-icon class="s-18 pr-4 red-fg"
|
||||
*ngIf="device.change < 0">
|
||||
arrow_downward
|
||||
</mat-icon>
|
||||
|
||||
<mat-icon class="s-18 pr-4 green-fg"
|
||||
*ngIf="device.change > 0">
|
||||
arrow_upward
|
||||
</mat-icon>
|
||||
|
||||
<div class="h5 red-fg"
|
||||
[ngClass]="{'red-fg': device.change < 0, 'green-fg': device.change > 0}">
|
||||
{{device.change}}%
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-divider mb-0"></div>
|
||||
|
||||
<div class="px-16" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<mat-form-field>
|
||||
<mat-select class="simplified" value="7days">
|
||||
<mat-option value="today">Today</mat-option>
|
||||
<mat-option value="yesterday">Yesterday</mat-option>
|
||||
<mat-option value="7days">Last 7 days</mat-option>
|
||||
<mat-option value="28days">Last 28 days</mat-option>
|
||||
<mat-option value="90days">Last 90 days</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<button mat-button color="accent">OVERVIEW</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / Widget 7 -->
|
||||
|
||||
<!-- Widget 8 -->
|
||||
<div class="mb-48" [ngClass.lt-lg]="'mr-32'">
|
||||
|
||||
<div class="pb-24 font-size-18 font-weight-300">
|
||||
How are your sales?
|
||||
</div>
|
||||
|
||||
<div class="fuse-card">
|
||||
|
||||
<div class="mat-light-blue-600-bg">
|
||||
|
||||
<div class="p-16" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div class="pr-16">
|
||||
<div class="h1 font-weight-300">Sales</div>
|
||||
<div class="h5 secondary-text">Lifetime sum of your sales</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button mat-icon-button [matMenuTriggerFor]="card19Menu" aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #card19Menu="matMenu">
|
||||
<button mat-menu-item>
|
||||
<mat-icon>trending_up</mat-icon>
|
||||
<span>Trend</span>
|
||||
</button>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>history</mat-icon>
|
||||
<span>History</span>
|
||||
</button>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>notifications_off</mat-icon>
|
||||
<span>Disable alerts</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 pt-8" fxLayout="row" fxLayoutAlign="space-between end">
|
||||
<div class="font-size-48 font-weight-300 line-height-1">{{widgets.widget8.today}}</div>
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon *ngIf="widgets.widget8.change.value > 0">trending_up</mat-icon>
|
||||
<mat-icon *ngIf="widgets.widget8.change.value < 0">trending_down</mat-icon>
|
||||
<div class="ml-8">{{widgets.widget8.change.value}}
|
||||
({{widgets.widget8.change.percentage}}%)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<mat-tab-group backgroundColor="accent">
|
||||
<mat-tab label="1DAY">
|
||||
<div class="h-200 my-16">
|
||||
<ngx-charts-line-chart
|
||||
*fuseIfOnDom
|
||||
[scheme]="widgets.widget8.scheme"
|
||||
[results]="widgets.widget8.data"
|
||||
[xAxis]="false"
|
||||
[yAxis]="true"
|
||||
[yScaleMin]="widgets.widget8.dataMin"
|
||||
[yScaleMax]="widgets.widget8.dataMax">
|
||||
</ngx-charts-line-chart>
|
||||
</div>
|
||||
</mat-tab>
|
||||
|
||||
<mat-tab label="1WEEK">
|
||||
<div class="h-200 my-16">
|
||||
<ngx-charts-line-chart
|
||||
*fuseIfOnDom
|
||||
[scheme]="widgets.widget8.scheme"
|
||||
[results]="widgets.widget8.data"
|
||||
[xAxis]="false"
|
||||
[yAxis]="true"
|
||||
[yScaleMin]="widgets.widget8.dataMin"
|
||||
[yScaleMax]="widgets.widget8.dataMax">
|
||||
</ngx-charts-line-chart>
|
||||
</div>
|
||||
</mat-tab>
|
||||
|
||||
<mat-tab label="1MONTH">
|
||||
<div class="h-200 my-16">
|
||||
<ngx-charts-line-chart
|
||||
*fuseIfOnDom
|
||||
[scheme]="widgets.widget8.scheme"
|
||||
[results]="widgets.widget8.data"
|
||||
[xAxis]="false"
|
||||
[yAxis]="true"
|
||||
[yScaleMin]="widgets.widget8.dataMin"
|
||||
[yScaleMax]="widgets.widget8.dataMax">
|
||||
</ngx-charts-line-chart>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- / Widget 8 -->
|
||||
|
||||
<!-- Widget 9 -->
|
||||
<div class="mb-48" [ngClass.lt-lg]="'mr-32'">
|
||||
|
||||
<div class="pb-24 font-size-18 font-weight-300" [ngClass.lt-lg]="'pt-0'">
|
||||
What are your top campaigns?
|
||||
</div>
|
||||
|
||||
<div class="fuse-card">
|
||||
|
||||
<div class="p-16" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div class="h1 pr-16">Top campaigns</div>
|
||||
|
||||
<div>
|
||||
<button mat-icon-button [matMenuTriggerFor]="card20Menu" aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #card20Menu="matMenu">
|
||||
<button fxLayout="row" fxLayoutAlign="start center" mat-menu-item>
|
||||
<mat-icon color="accent">check_box</mat-icon>
|
||||
<span>Show Clicks</span>
|
||||
</button>
|
||||
<button fxLayout="row" fxLayoutAlign="start center" mat-menu-item>
|
||||
<mat-icon color="accent">check_box</mat-icon>
|
||||
<span>Show Conversion</span>
|
||||
</button>
|
||||
<button fxLayout="row" fxLayoutAlign="start center" mat-menu-item>
|
||||
<mat-icon>check_box_outline_blank</mat-icon>
|
||||
<span>Show CPC</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="simple clickable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="text-right">Clicks</th>
|
||||
<th class="text-right">Conv</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let row of widgets.widget9.rows">
|
||||
<td>{{row.title}}</td>
|
||||
<td class="text-right">{{row.clicks}}</td>
|
||||
<td class="text-right">{{row.conversion}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="card-divider full-width"></div>
|
||||
|
||||
<div class="p-8 pt-16" fxLayout="row" fxLayoutAlign="start center">
|
||||
<button mat-button color="accent">GO TO CAMPAIGNS</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / widget 9 -->
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,49 @@
|
||||
@import "src/app/core/scss/fuse";
|
||||
|
||||
#dashboard-analytics {
|
||||
|
||||
.main-widget {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
padding: 32px;
|
||||
min-width: 0;
|
||||
|
||||
@include media-breakpoint-down('md') {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
|
||||
.widget {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
width: 320px;
|
||||
min-width: 320px;
|
||||
max-width: 320px;
|
||||
|
||||
@include media-breakpoint-down('md') {
|
||||
flex: 1 0 100%;
|
||||
margin-top: 32px;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { Component, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
import { AnalyticsDashboardService } from './analytics.service';
|
||||
import { fuseAnimations } from '../../../../../core/animations';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-analytics-dashboard',
|
||||
templateUrl : './analytics.component.html',
|
||||
styleUrls : ['./analytics.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseAnalyticsDashboardComponent
|
||||
{
|
||||
widgets: any;
|
||||
widget1SelectedYear = '2016';
|
||||
widget5SelectedDay = 'today';
|
||||
|
||||
constructor(
|
||||
private analyticsDashboardService: AnalyticsDashboardService
|
||||
)
|
||||
{
|
||||
// Get the widgets from the service
|
||||
this.widgets = this.analyticsDashboardService.widgets;
|
||||
|
||||
// Register the custom chart.js plugin
|
||||
this.registerCustomChartJSPlugin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a custom plugin
|
||||
*/
|
||||
registerCustomChartJSPlugin()
|
||||
{
|
||||
(<any>window).Chart.plugins.register({
|
||||
afterDatasetsDraw: function (chart, easing) {
|
||||
// Only activate the plugin if it's made available
|
||||
// in the options
|
||||
if (
|
||||
!chart.options.plugins.xLabelsOnTop ||
|
||||
(chart.options.plugins.xLabelsOnTop && chart.options.plugins.xLabelsOnTop.active === false)
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// To only draw at the end of animation, check for easing === 1
|
||||
const ctx = chart.ctx;
|
||||
|
||||
chart.data.datasets.forEach(function (dataset, i) {
|
||||
const meta = chart.getDatasetMeta(i);
|
||||
if ( !meta.hidden )
|
||||
{
|
||||
meta.data.forEach(function (element, index) {
|
||||
|
||||
// Draw the text in black, with the specified font
|
||||
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
|
||||
const fontSize = 13;
|
||||
const fontStyle = 'normal';
|
||||
const fontFamily = 'Roboto, Helvetica Neue, Arial';
|
||||
ctx.font = (<any>window).Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
|
||||
|
||||
// Just naively convert to string for now
|
||||
const dataString = dataset.data[index].toString() + 'k';
|
||||
|
||||
// Make sure alignment settings are correct
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
const padding = 15;
|
||||
const startY = 24;
|
||||
const position = element.tooltipPosition();
|
||||
ctx.fillText(dataString, position.x, startY);
|
||||
|
||||
ctx.save();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.setLineDash([5, 3]);
|
||||
ctx.moveTo(position.x, startY + padding);
|
||||
ctx.lineTo(position.x, position.y - padding);
|
||||
ctx.strokeStyle = 'rgba(255,255,255,0.12)';
|
||||
ctx.stroke();
|
||||
|
||||
ctx.restore();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { SharedModule } from '../../../../../core/modules/shared.module';
|
||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||
import { AgmCoreModule } from '@agm/core';
|
||||
|
||||
import { FuseAnalyticsDashboardComponent } from './analytics.component';
|
||||
import { AnalyticsDashboardService } from './analytics.service';
|
||||
import { FuseWidgetModule } from '../../../../../core/components/widget/widget.module';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '**',
|
||||
component: FuseAnalyticsDashboardComponent,
|
||||
resolve : {
|
||||
data: AnalyticsDashboardService
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports : [
|
||||
SharedModule,
|
||||
RouterModule.forChild(routes),
|
||||
FuseWidgetModule,
|
||||
NgxChartsModule,
|
||||
AgmCoreModule.forRoot({
|
||||
apiKey: 'AIzaSyD81ecsCj4yYpcXSLFcYU97PvRsE_X8Bx8'
|
||||
})
|
||||
],
|
||||
declarations: [
|
||||
FuseAnalyticsDashboardComponent
|
||||
],
|
||||
providers : [
|
||||
AnalyticsDashboardService
|
||||
]
|
||||
})
|
||||
export class FuseAnalyticsDashboardModule
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
@Injectable()
|
||||
export class AnalyticsDashboardService implements Resolve<any>
|
||||
{
|
||||
widgets: any[];
|
||||
|
||||
constructor(
|
||||
private http: HttpClient
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve
|
||||
* @param {ActivatedRouteSnapshot} route
|
||||
* @param {RouterStateSnapshot} state
|
||||
* @returns {Observable<any> | Promise<any> | any}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
Promise.all([
|
||||
this.getWidgets()
|
||||
]).then(
|
||||
() => {
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getWidgets(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http.get('api/analytics-dashboard-widgets')
|
||||
.subscribe((response: any) => {
|
||||
this.widgets = response;
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="space-between start">
|
||||
|
||||
<span class="mat-display-1 mb-0 welcome-message" *fuseIfOnDom [@animate]="{value:'*',params:{x:'50px'}}">Welcome back, John!</span>
|
||||
<span class="mat-display-1 mb-0 welcome-message" *fuseIfOnDom
|
||||
[@animate]="{value:'*',params:{x:'50px'}}">Welcome back, John!
|
||||
</span>
|
||||
|
||||
<button mat-icon-button fuseMatSidenavToggler="dashboards-right-sidenav" fxHide.gt-md>
|
||||
<mat-icon>menu</mat-icon>
|
||||
@@ -21,7 +23,8 @@
|
||||
|
||||
<div class="selected-project">{{selectedProject.name}}</div>
|
||||
|
||||
<button mat-icon-button class="project-selector" [matMenuTriggerFor]="projectsMenu" aria-label="Select project">
|
||||
<button mat-icon-button class="project-selector" [matMenuTriggerFor]="projectsMenu"
|
||||
aria-label="Select project">
|
||||
<mat-icon>more_horiz</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -41,16 +44,20 @@
|
||||
|
||||
<mat-tab label="Home">
|
||||
|
||||
<div class="widget-group p-12" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom [@animateStagger]="{value:'50'}">
|
||||
<div class="widget-group grey-100-bg p-12" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom
|
||||
[@animateStagger]="{value:'50'}">
|
||||
|
||||
<!-- WIDGET 1 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<mat-form-field>
|
||||
<mat-select class="simplified font-size-16" [(ngModel)]="widgets.widget1.currentRange"
|
||||
<mat-select class="simplified font-size-16"
|
||||
[(ngModel)]="widgets.widget1.currentRange"
|
||||
aria-label="Change range">
|
||||
<mat-option *ngFor="let range of widgets.widget1.ranges | keys"
|
||||
[value]="range.key">
|
||||
@@ -67,12 +74,17 @@
|
||||
<div class="light-blue-fg font-size-72 line-height-72">
|
||||
{{widgets.widget1.data.count[widgets.widget1.currentRange]}}
|
||||
</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget1.data.label}}</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget1.data.label}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span class="h4 secondary-text text-truncate">{{widgets.widget1.data.extra.label}}:</span>
|
||||
<span class="h4 ml-8">{{widgets.widget1.data.extra.count[widgets.widget1.currentRange]}}</span>
|
||||
<span class="h4 secondary-text text-truncate">
|
||||
{{widgets.widget1.data.extra.label}}:
|
||||
</span>
|
||||
<span class="h4 ml-8">
|
||||
{{widgets.widget1.data.extra.count[widgets.widget1.currentRange]}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
@@ -94,14 +106,17 @@
|
||||
<!-- / WIDGET 1 -->
|
||||
|
||||
<!-- WIDGET 2 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget2.title}}</div>
|
||||
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button" aria-label="more">
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
@@ -110,11 +125,14 @@
|
||||
<div class="red-fg font-size-72 line-height-72">
|
||||
{{widgets.widget2.data.count}}
|
||||
</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget2.data.label}}</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget2.data.label}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span class="h4 secondary-text text-truncate">{{widgets.widget2.data.extra.label}}:</span>
|
||||
<span class="h4 secondary-text text-truncate">
|
||||
{{widgets.widget2.data.extra.label}}:
|
||||
</span>
|
||||
<span class="h4 ml-8">{{widgets.widget2.data.extra.count}}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -137,14 +155,17 @@
|
||||
<!-- / WIDGET 2 -->
|
||||
|
||||
<!-- WIDGET 3 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget3.title}}</div>
|
||||
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button" aria-label="more">
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
@@ -153,11 +174,14 @@
|
||||
<div class="orange-fg font-size-72 line-height-72">
|
||||
{{widgets.widget3.data.count}}
|
||||
</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget3.data.label}}</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget3.data.label}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span class="h4 secondary-text text-truncate">{{widgets.widget3.data.extra.label}}:</span>
|
||||
<span class="h4 secondary-text text-truncate">
|
||||
{{widgets.widget3.data.extra.label}}:
|
||||
</span>
|
||||
<span class="h4 ml-8">{{widgets.widget3.data.extra.count}}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -180,26 +204,33 @@
|
||||
<!-- / WIDGET 3 -->
|
||||
|
||||
<!-- WIDGET 4 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget4.title}}</div>
|
||||
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button" aria-label="more">
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
|
||||
<div class="blue-grey-fg font-size-72 line-height-72">{{widgets.widget4.data.count}}
|
||||
<div class="blue-grey-fg font-size-72 line-height-72">
|
||||
{{widgets.widget4.data.count}}
|
||||
</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget4.data.label}}
|
||||
</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget4.data.label}}</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span class="h4 secondary-text text-truncate">{{widgets.widget4.data.extra.label}}:</span>
|
||||
<span class="h4 secondary-text text-truncate">
|
||||
{{widgets.widget4.data.extra.label}}:
|
||||
</span>
|
||||
<span class="h4 ml-8">{{widgets.widget4.data.extra.count}}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -221,18 +252,19 @@
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 4 -->
|
||||
|
||||
|
||||
<!-- WIDGET 5 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row" fxFlex="100">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" fxLayout="row" fxFlex="100"
|
||||
class="widget widget5">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
|
||||
<div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center" fxLayoutWrap>
|
||||
<div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center"
|
||||
fxLayoutWrap>
|
||||
|
||||
<div fxFlex class="py-8 h3">{{widgets.widget5.title}}</div>
|
||||
<div fxFlex class="py-16 h3">{{widgets.widget5.title}}</div>
|
||||
|
||||
<div fxFlex="0 1 auto" class="py-8" fxLayout="row">
|
||||
<div fxFlex="0 1 auto" class="py-16" fxLayout="row">
|
||||
<button mat-button class="px-16"
|
||||
*ngFor="let range of widgets.widget5.ranges | keys"
|
||||
(click)="widget5.currentRange = range.key"
|
||||
@@ -242,8 +274,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start end" fxLayoutWrap>
|
||||
<div class="h-420 mb-16" fxLayout="row" fxFlex="100" fxFlex.gt-sm="50">
|
||||
<div fxLayout="row" fxLayoutAlign="start start" fxLayoutWrap>
|
||||
|
||||
<div class="h-420 my-16" fxLayout="row" fxFlex="100" fxFlex.gt-sm="50">
|
||||
<ngx-charts-bar-vertical-stacked
|
||||
*fuseIfOnDom
|
||||
[scheme]="widget5.scheme"
|
||||
@@ -260,10 +293,12 @@
|
||||
</ngx-charts-bar-vertical-stacked>
|
||||
</div>
|
||||
|
||||
<div class="mb-16" fxFlex="100" fxFlex.gt-sm="50" fxLayoutAlign="row" fxLayoutWrap>
|
||||
<div class="my-16" fxFlex="100" fxFlex.gt-sm="50" fxLayoutAlign="row"
|
||||
fxLayoutWrap>
|
||||
|
||||
<div fxLayout="column" fxFlex="100" fxFlex.gt-sm="50" fxLayoutAlign="center"
|
||||
*ngFor="let widget of widgets.widget5.supporting | keys">
|
||||
*ngFor="let widget of widgets.widget5.supporting | keys"
|
||||
class="mb-24">
|
||||
|
||||
<div class="px-24">
|
||||
<div class="h4 secondary-text">{{widget.value.label}}</div>
|
||||
@@ -297,17 +332,19 @@
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 5 -->
|
||||
|
||||
|
||||
<!-- WIDGET 6 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-sm="50">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-sm="50">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
|
||||
<div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div class="px-16 py-8 border-bottom" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget6.title}}</div>
|
||||
<mat-form-field>
|
||||
<mat-select class="simplified" [(ngModel)]="widget6.currentRange" aria-label="Change range">
|
||||
<mat-select class="simplified" [(ngModel)]="widget6.currentRange"
|
||||
aria-label="Change range">
|
||||
<mat-option *ngFor="let range of widgets.widget6.ranges | keys"
|
||||
[value]="range.key">
|
||||
{{range.value}}
|
||||
@@ -330,14 +367,21 @@
|
||||
</ngx-charts-pie-chart>
|
||||
</div>
|
||||
|
||||
<div class="py-8 mh-16 border-top" fxLayout="row" fxLayoutAlign="start center" fxLayoutWrap>
|
||||
<div class="py-8 border-right" fxLayout="column" fxLayoutAlign="center center" fxFlex="100" fxFlex.gt-sm="50">
|
||||
<span class="mat-display-1 mb-0">{{widgets.widget6.footerLeft.count[widget6.currentRange]}}</span>
|
||||
<div class="py-8 mh-16 border-top" fxLayout="row" fxLayoutAlign="start center"
|
||||
fxLayoutWrap>
|
||||
<div class="py-8 border-right" fxLayout="column" fxLayoutAlign="center center"
|
||||
fxFlex="100" fxFlex.gt-sm="50">
|
||||
<span class="mat-display-1 mb-0">
|
||||
{{widgets.widget6.footerLeft.count[widget6.currentRange]}}
|
||||
</span>
|
||||
<span class="h4">{{widgets.widget6.footerLeft.title}}</span>
|
||||
</div>
|
||||
|
||||
<div class="py-8" fxLayout="column" fxLayoutAlign="center center" fxFlex="100" fxFlex.gt-sm="50">
|
||||
<span class="mat-display-1 mb-0">{{widgets.widget6.footerRight.count[widget6.currentRange]}}</span>
|
||||
<div class="py-8" fxLayout="column" fxLayoutAlign="center center" fxFlex="100"
|
||||
fxFlex.gt-sm="50">
|
||||
<span class="mat-display-1 mb-0">
|
||||
{{widgets.widget6.footerRight.count[widget6.currentRange]}}
|
||||
</span>
|
||||
<span class="h4">{{widgets.widget6.footerRight.title}}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -349,12 +393,14 @@
|
||||
<!-- / WIDGET 6 -->
|
||||
|
||||
<!-- WIDGET 7 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-sm="50">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-sm="50">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
|
||||
<div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div class="px-16 py-8 border-bottom" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget7.title}}</div>
|
||||
<mat-form-field>
|
||||
<mat-select class="simplified" [(ngModel)]="widget7.currentRange"
|
||||
@@ -391,20 +437,21 @@
|
||||
</div>
|
||||
<!-- / WIDGET GROUP -->
|
||||
|
||||
|
||||
</mat-tab>
|
||||
|
||||
<mat-tab label="Budget Summary">
|
||||
|
||||
<!-- WIDGET GROUP -->
|
||||
<div class="widget-group" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom [@animateStagger]="{value:'50'}">
|
||||
<div class="widget-group grey-100-bg" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom
|
||||
[@animateStagger]="{value:'50'}">
|
||||
|
||||
<!-- WIDGET 8 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-sm="50">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-sm="50">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="h3 p-16">
|
||||
<div class="h3 px-16 py-24">
|
||||
{{widgets.widget8.title}}
|
||||
</div>
|
||||
|
||||
@@ -431,11 +478,13 @@
|
||||
<!-- / WIDGET 8 -->
|
||||
|
||||
<!-- WIDGET 9 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-sm="50">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-sm="50">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div class="px-16 py-12 border-bottom" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget9.title}}</div>
|
||||
<mat-form-field>
|
||||
<mat-select [(ngModel)]="widget9.currentRange" aria-label="Change range">
|
||||
@@ -447,7 +496,7 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="p-16" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
|
||||
<div class="px-16 py-24" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
|
||||
fxLayoutAlign.gt-xs="space-between end">
|
||||
<div fxFlex="0 1 auto">
|
||||
<div class="h4 secondary-text">{{widgets.widget9.weeklySpent.title}}</div>
|
||||
@@ -474,7 +523,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
|
||||
<div class="px-16 py-24" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
|
||||
fxLayoutAlign.gt-xs="space-between end">
|
||||
<div fxFlex="0 1 auto">
|
||||
<div class="h4 secondary-text">{{widgets.widget9.totalSpent.title}}</div>
|
||||
@@ -501,7 +550,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
|
||||
<div class="px-16 py-24" fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row"
|
||||
fxLayoutAlign.gt-xs="space-between end">
|
||||
<div fxFlex="0 1 auto">
|
||||
<div class="h4 secondary-text">{{widgets.widget9.remaining.title}}</div>
|
||||
@@ -528,7 +577,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 border-top">
|
||||
<div class="px-16 py-24 border-top">
|
||||
<div class="h4 secondary-text">{{widgets.widget9.totalBudget.title}}</div>
|
||||
<div class="pt-8 mat-display-1 m-0 font-weight-300">
|
||||
<span class="secondary-text">$</span>
|
||||
@@ -543,7 +592,8 @@
|
||||
<!-- / WIDGET 9 -->
|
||||
|
||||
<!-- WIDGET 10 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row" fxFlex="100">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row"
|
||||
fxFlex="100">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
@@ -569,7 +619,8 @@
|
||||
<span class="p-4" [ngClass]="cell.classes">
|
||||
{{cell.value}}
|
||||
</span>
|
||||
<mat-icon *ngIf="cell.icon" class="s-16">{{cell.icon}}</mat-icon>
|
||||
<mat-icon *ngIf="cell.icon" class="s-16">{{cell.icon}}
|
||||
</mat-icon>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -590,17 +641,21 @@
|
||||
<mat-tab label="Team Members">
|
||||
|
||||
<!-- WIDGET GROUP -->
|
||||
<div class="widget-group" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom [@animateStagger]="{value:'50'}">
|
||||
<div class="widget-group grey-100-bg" fxLayout="row" fxFlex="100" fxLayoutWrap *fuseIfOnDom
|
||||
[@animateStagger]="{value:'50'}">
|
||||
|
||||
<!-- WIDGET 11 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row" fxFlex="100">
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row"
|
||||
fxFlex="100">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
|
||||
<div class="p-24 mb-8 border-bottom" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div class="p-24 mb-8 border-bottom" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h2">{{widgets.widget11.title}}</div>
|
||||
<div class="text-boxed red-bg white-fg m-0">{{widgets.widget11.table.rows.length}}
|
||||
<div class="text-boxed red-bg white-fg m-0">
|
||||
{{widgets.widget11.table.rows.length}}
|
||||
members
|
||||
</div>
|
||||
</div>
|
||||
@@ -620,13 +675,15 @@
|
||||
<ng-container cdkColumnDef="name">
|
||||
<mat-header-cell *cdkHeaderCellDef>Name</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact">
|
||||
<p class="text-truncate font-weight-600">{{contact.name}} {{contact.lastName}}</p>
|
||||
<p class="text-truncate font-weight-600">{{contact.name}}
|
||||
{{contact.lastName}}</p>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Position Column -->
|
||||
<ng-container cdkColumnDef="position">
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-sm>Position</mat-header-cell>
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-sm>Position
|
||||
</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-sm>
|
||||
<p class="position text-truncate">
|
||||
{{contact.position}}
|
||||
@@ -636,7 +693,8 @@
|
||||
|
||||
<!-- Office Column -->
|
||||
<ng-container cdkColumnDef="office">
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-md>Office</mat-header-cell>
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-md>Office
|
||||
</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-md>
|
||||
<p class="office text-truncate">
|
||||
{{contact.office}}
|
||||
@@ -644,10 +702,10 @@
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<!-- Email Column -->
|
||||
<ng-container cdkColumnDef="email">
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-sm>Email</mat-header-cell>
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-sm>Email
|
||||
</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-sm>
|
||||
<p class="email text-truncate">
|
||||
{{contact.email}}
|
||||
@@ -657,7 +715,8 @@
|
||||
|
||||
<!-- Phone Column -->
|
||||
<ng-container cdkColumnDef="phone">
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-md>Phone</mat-header-cell>
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-md>Phone
|
||||
</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-md>
|
||||
<p class="phone text-truncate">
|
||||
{{contact.phone}}
|
||||
@@ -665,7 +724,8 @@
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *cdkHeaderRowDef="widgets.widget11.table.columns"></mat-header-row>
|
||||
<mat-header-row
|
||||
*cdkHeaderRowDef="widgets.widget11.table.columns"></mat-header-row>
|
||||
<mat-row *cdkRowDef="let contact; columns: widgets.widget11.table.columns;">
|
||||
</mat-row>
|
||||
</mat-table>
|
||||
@@ -688,7 +748,8 @@
|
||||
<!-- / CENTER -->
|
||||
|
||||
<!-- SIDENAV -->
|
||||
<mat-sidenav class="sidenav" align="end" mode="side" opened="true" fuseMatSidenavHelper="dashboards-right-sidenav" mat-is-locked-open="gt-md">
|
||||
<mat-sidenav class="sidenav" align="end" mode="side" opened="true"
|
||||
fuseMatSidenavHelper="dashboards-right-sidenav" mat-is-locked-open="gt-md">
|
||||
|
||||
<div class="sidenav-content" fusePerfectScrollbar>
|
||||
|
||||
@@ -768,7 +829,8 @@
|
||||
<div class="p-16 pb-32" fxLayout="column" fxLayoutAlign="center center">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="center center">
|
||||
<mat-icon fontSet="meteocons" [fontIcon]="widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].icon"
|
||||
<mat-icon fontSet="meteocons"
|
||||
[fontIcon]="widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].icon"
|
||||
class="icon s-40 mr-16"></mat-icon>
|
||||
<span class="mat-display-2 m-0 font-weight-300 secondary-text">
|
||||
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].temp[widgets.weatherWidget.tempUnit]}}
|
||||
@@ -789,12 +851,16 @@
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon fontSet="meteocons" fontIcon="icon-compass" class="mr-8 s-16"></mat-icon>
|
||||
<span>{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].windDirection}}</span>
|
||||
<span>
|
||||
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].windDirection}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon fontSet="meteocons" fontIcon="icon-rainy" class="mr-8 s-16"></mat-icon>
|
||||
<span>{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].rainProbability}}</span>
|
||||
<span>
|
||||
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].rainProbability}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -806,7 +872,9 @@
|
||||
<mat-icon fontSet="meteocons" [fontIcon]="day.icon" class="mr-16"></mat-icon>
|
||||
<span class="h2">{{day.temp[widgets.weatherWidget.tempUnit]}}</span>
|
||||
<span class="h2 font-weight-300 secondary-text text-super">°</span>
|
||||
<span class="h2 font-weight-300 secondary-text">{{widgets.weatherWidget.tempUnit}}</span>
|
||||
<span class="h2 font-weight-300 secondary-text">
|
||||
{{widgets.weatherWidget.tempUnit}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -56,5 +56,15 @@
|
||||
min-width: 250px !important;
|
||||
max-width: 250px !important;
|
||||
}
|
||||
|
||||
.widget {
|
||||
|
||||
&.widget5 {
|
||||
|
||||
.gridline-path.gridline-path-horizontal {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ProjectsDashboardService } from './projects.service';
|
||||
import * as shape from 'd3-shape';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { DataSource } from '@angular/cdk/collections';
|
||||
|
||||
import { ProjectDashboardService } from './project.service';
|
||||
import { fuseAnimations } from '../../../../../core/animations';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-project',
|
||||
selector : 'fuse-project-dashboard',
|
||||
templateUrl : './project.component.html',
|
||||
styleUrls : ['./project.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseProjectComponent implements OnInit, OnDestroy
|
||||
export class FuseProjectDashboardComponent implements OnInit, OnDestroy
|
||||
{
|
||||
projects: any[];
|
||||
selectedProject: any;
|
||||
@@ -28,13 +29,11 @@ export class FuseProjectComponent implements OnInit, OnDestroy
|
||||
|
||||
dateNow = Date.now();
|
||||
|
||||
constructor(private projectsDashboardService: ProjectsDashboardService)
|
||||
constructor(private projectDashboardService: ProjectDashboardService)
|
||||
{
|
||||
this.projects = this.projectsDashboardService.projects;
|
||||
|
||||
this.projects = this.projectDashboardService.projects;
|
||||
this.selectedProject = this.projects[0];
|
||||
|
||||
this.widgets = this.projectsDashboardService.widgets;
|
||||
this.widgets = this.projectDashboardService.widgets;
|
||||
|
||||
/**
|
||||
* Widget 5
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { FuseProjectComponent } from './project.component';
|
||||
import { SharedModule } from '../../../../../core/modules/shared.module';
|
||||
import { ProjectsDashboardService } from './projects.service';
|
||||
|
||||
import { FuseProjectDashboardComponent } from './project.component';
|
||||
import { ProjectDashboardService } from './project.service';
|
||||
import { FuseWidgetModule } from '../../../../../core/components/widget/widget.module';
|
||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : 'apps/dashboards/project',
|
||||
component: FuseProjectComponent,
|
||||
path : '**',
|
||||
component: FuseProjectDashboardComponent,
|
||||
resolve : {
|
||||
data: ProjectsDashboardService
|
||||
data: ProjectDashboardService
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -24,13 +25,13 @@ const routes: Routes = [
|
||||
NgxChartsModule
|
||||
],
|
||||
declarations: [
|
||||
FuseProjectComponent
|
||||
FuseProjectDashboardComponent
|
||||
],
|
||||
providers : [
|
||||
ProjectsDashboardService
|
||||
ProjectDashboardService
|
||||
]
|
||||
})
|
||||
export class ProjectModule
|
||||
export class FuseProjectDashboardModule
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Observable } from 'rxjs/Observable';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
@Injectable()
|
||||
export class ProjectsDashboardService implements Resolve<any>
|
||||
export class ProjectDashboardService implements Resolve<any>
|
||||
{
|
||||
projects: any[];
|
||||
widgets: any[];
|
||||
@@ -41,7 +41,7 @@ export class ProjectsDashboardService implements Resolve<any>
|
||||
getProjects(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http.get('api/projects-dashboard-projects')
|
||||
this.http.get('api/project-dashboard-projects')
|
||||
.subscribe((response: any) => {
|
||||
this.projects = response;
|
||||
resolve(response);
|
||||
@@ -52,7 +52,7 @@ export class ProjectsDashboardService implements Resolve<any>
|
||||
getWidgets(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http.get('api/projects-dashboard-widgets')
|
||||
this.http.get('api/project-dashboard-widgets')
|
||||
.subscribe((response: any) => {
|
||||
this.widgets = response;
|
||||
resolve(response);
|
||||
@@ -41,7 +41,7 @@ export class EcommerceDashboardService implements Resolve<any>
|
||||
getProjects(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http.get('api/projects-dashboard-projects')
|
||||
this.http.get('api/project-dashboard-projects')
|
||||
.subscribe((response: any) => {
|
||||
this.projects = response;
|
||||
resolve(response);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
.orders-table {
|
||||
flex: 1 1 auto;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .12);
|
||||
overflow: auto;
|
||||
|
||||
.mat-header-row {
|
||||
min-height: 64px;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
.products-table {
|
||||
flex: 1 1 auto;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .12);
|
||||
overflow: auto;
|
||||
|
||||
.mat-header-row {
|
||||
min-height: 64px;
|
||||
|
||||
@@ -7,7 +7,10 @@ import { locale as english } from './i18n/en';
|
||||
import { locale as turkish } from './i18n/tr';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import 'rxjs/add/operator/debounceTime';
|
||||
import 'rxjs/add/operator/distinctUntilChanged';
|
||||
import * as fromStore from './store';
|
||||
import { FuseConfigService } from '../../../../core/services/config.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-mail',
|
||||
@@ -30,6 +33,7 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy
|
||||
selectedMailIds: string[];
|
||||
|
||||
constructor(
|
||||
private configService: FuseConfigService,
|
||||
private mailService: MailNgrxService,
|
||||
private translationLoader: FuseTranslationLoaderService,
|
||||
private store: Store<fromStore.MailAppState>,
|
||||
@@ -46,6 +50,10 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy
|
||||
this.searchText$ = this.store.select(fromStore.getSearchText);
|
||||
this.mails = [];
|
||||
this.selectedMailIds = [];
|
||||
|
||||
this.configService.setSettings({
|
||||
routerAnimation: 'none'
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Actions, Effect } from '@ngrx/effects';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { of } from 'rxjs/observable/of';
|
||||
import { map, mergeMap, exhaustMap, withLatestFrom } from 'rxjs/operators';
|
||||
import 'rxjs/add/operator/debounceTime';
|
||||
import { getRouterState, State } from '../../../../../../store/reducers';
|
||||
import { getMailsState } from '../selectors';
|
||||
import * as MailsActions from '../actions/mails.actions';
|
||||
|
||||
@@ -28,7 +28,12 @@
|
||||
type="email" required>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<div class="show-hide-extra-fields" (click)="toggleExtraToFields()">
|
||||
<span [fxShow]="!showExtraToFields">Show CC & BCC</span>
|
||||
<span [fxShow]="showExtraToFields">Hide CC & BCC</span>
|
||||
</div>
|
||||
|
||||
<mat-form-field [fxShow]="showExtraToFields">
|
||||
<input matInput
|
||||
name="cc"
|
||||
placeholder="Cc"
|
||||
@@ -36,7 +41,7 @@
|
||||
type="email">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field [fxShow]="showExtraToFields">
|
||||
<input matInput
|
||||
name="bcc"
|
||||
placeholder="Bcc"
|
||||
@@ -51,11 +56,11 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<textarea matInput name="message"
|
||||
placeholder="Message"
|
||||
formControlName="message"
|
||||
rows="6">
|
||||
</textarea>
|
||||
<textarea matInput name="message"
|
||||
placeholder="Message"
|
||||
formControlName="message"
|
||||
rows="6">
|
||||
</textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="attachment-list">
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
@import "src/app/core/scss/fuse";
|
||||
|
||||
.mail-compose-dialog {
|
||||
|
||||
@include media-breakpoint('xs') {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up('sm') {
|
||||
width: 640px;
|
||||
}
|
||||
|
||||
.mat-dialog-container {
|
||||
padding: 0;
|
||||
width: 720px;
|
||||
|
||||
.compose-form {
|
||||
|
||||
@@ -9,6 +19,12 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.show-hide-extra-fields {
|
||||
text-align: right;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.attachment-list {
|
||||
font-size: 13px;
|
||||
padding-top: 16px;
|
||||
|
||||
@@ -10,6 +10,7 @@ import { FormControl, FormGroup } from '@angular/forms';
|
||||
})
|
||||
export class FuseMailComposeDialogComponent implements OnInit
|
||||
{
|
||||
showExtraToFields = false;
|
||||
composeForm: FormGroup;
|
||||
|
||||
constructor(
|
||||
@@ -39,4 +40,8 @@ export class FuseMailComposeDialogComponent implements OnInit
|
||||
});
|
||||
}
|
||||
|
||||
toggleExtraToFields()
|
||||
{
|
||||
this.showExtraToFields = !this.showExtraToFields;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
background-color: white;
|
||||
margin: 16px 0 !important;
|
||||
background-color: white !important;
|
||||
color: #000;
|
||||
border-radius: 2px;
|
||||
transition: box-shadow 150ms ease;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
width: 344px;
|
||||
min-width: 344px;
|
||||
max-width: 344px;
|
||||
padding-right: 24px;
|
||||
padding-right: 24px !important;
|
||||
height: 100%;
|
||||
|
||||
.list {
|
||||
@@ -36,6 +36,7 @@
|
||||
position: relative;
|
||||
min-height: 32px;
|
||||
padding: 0 16px;
|
||||
background: mat-color($mat-grey, 200) !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Subscription } from 'rxjs/Subscription';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { FuseUtils } from '../../../../../core/fuseUtils';
|
||||
import { fuseAnimations } from '../../../../../core/animations';
|
||||
import 'rxjs/add/operator/debounceTime';
|
||||
import 'rxjs/add/operator/distinctUntilChanged';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -10,13 +10,6 @@
|
||||
flex-shrink: 0;
|
||||
background: #FFFFFF;
|
||||
|
||||
&.todo-item-placeholder {
|
||||
background: rgba(0, 0, 0, 0.12);
|
||||
* {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.handle {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
|
||||
@@ -4,6 +4,7 @@ import { TodoService } from './todo.service';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { Todo } from './todo.model';
|
||||
import { fuseAnimations } from '../../../../core/animations';
|
||||
import 'rxjs/add/operator/debounceTime';
|
||||
import 'rxjs/add/operator/distinctUntilChanged';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -6,7 +6,7 @@ import { GoogleMapsModule } from './google-maps/google-maps.module';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'components-third-party/datatables/ngx-datatable',
|
||||
path : 'datatables/ngx-datatable',
|
||||
component: FuseNgxDatatableComponent
|
||||
}
|
||||
];
|
||||
@@ -21,6 +21,6 @@ const routes = [
|
||||
FuseNgxDatatableComponent
|
||||
]
|
||||
})
|
||||
export class ComponentsThirdPartyModule
|
||||
export class FuseComponentsThirdPartyModule
|
||||
{
|
||||
}
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
<div class="my-48">
|
||||
<h2>Usage</h2>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="html" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<agm-map [latitude]="lat" [longitude]="lng">
|
||||
<agm-marker [latitude]="lat" [longitude]="lng"></agm-marker>
|
||||
</agm-map>
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { AgmCoreModule } from '@agm/core';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'components-third-party/google-maps',
|
||||
path : 'google-maps',
|
||||
component: FuseGoogleMapsDocsComponent
|
||||
}
|
||||
];
|
||||
|
||||
@@ -8,7 +8,7 @@ import { FuseAngularMaterialComponent } from './angular-material.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : 'components/angular-material',
|
||||
path : 'angular-material',
|
||||
children: [
|
||||
{
|
||||
path : ':id',
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
<button mat-icon-button type="button" (click)="toggleSourceView()"
|
||||
[matTooltip]="'View source'">
|
||||
<mat-icon>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 24 24" fit="" preserveAspectRatio="xMidYMid meet" focusable="false">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 24 24" fit=""
|
||||
preserveAspectRatio="xMidYMid meet" focusable="false">
|
||||
<path fill="none" d="M0 0h24v24H0V0z"></path>
|
||||
<path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path>
|
||||
<path
|
||||
d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path>
|
||||
</svg>
|
||||
</mat-icon>
|
||||
</button>
|
||||
@@ -23,29 +25,40 @@
|
||||
<mat-tab label="CSS"></mat-tab>
|
||||
</mat-tab-group>
|
||||
<div class="tab-content">
|
||||
<section class="tab" *ngIf="selectedIndex === 0" [@animate]="{value:'*',params:{opacity:'0',duration:'200ms'}}">
|
||||
<section class="tab" *ngIf="selectedIndex === 0"
|
||||
[@animate]="{value:'*',params:{opacity:'0',duration:'200ms'}}">
|
||||
<button mat-icon-button type="button" class="example-source-copy"
|
||||
title="Copy example source" aria-label="Copy example source to clipboard"
|
||||
(click)="copySource(htmlView.el.nativeElement.innerText)">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
</button>
|
||||
<div Markdown #htmlView class="example-source" [path]="'/assets/angular-material-examples/'+example+'/'+example+'-example.html'"></div>
|
||||
<fuse-highlight lang="html"
|
||||
[path]="'/assets/angular-material-examples/'+example+'/'+example+'-example.html'">
|
||||
</fuse-highlight>
|
||||
</section>
|
||||
<section class="tab" *ngIf="selectedIndex === 1" [@animate]="{value:'*',params:{opacity:'0',duration:'200ms'}}">
|
||||
|
||||
<section class="tab" *ngIf="selectedIndex === 1"
|
||||
[@animate]="{value:'*',params:{opacity:'0',duration:'200ms'}}">
|
||||
<button mat-icon-button type="button" class="example-source-copy"
|
||||
title="Copy example source" aria-label="Copy example source to clipboard"
|
||||
(click)="copySource(tsView.el.nativeElement.innerText)">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
</button>
|
||||
<div Markdown #tsView class="example-source" [path]="'/assets/angular-material-examples/'+example+'/'+example+'-example.ts'"></div>
|
||||
<fuse-highlight lang="typescript"
|
||||
[path]="'/assets/angular-material-examples/'+example+'/'+example+'-example.ts'">
|
||||
</fuse-highlight>
|
||||
</section>
|
||||
<section class="tab" *ngIf="selectedIndex === 2" [@animate]="{value:'*',params:{opacity:'0',duration:'200ms'}}">
|
||||
|
||||
<section class="tab" *ngIf="selectedIndex === 2"
|
||||
[@animate]="{value:'*',params:{opacity:'0',duration:'200ms'}}">
|
||||
<button mat-icon-button type="button" class="example-source-copy"
|
||||
title="Copy example source" aria-label="Copy example source to clipboard"
|
||||
(click)="copySource(cssView.el.nativeElement.innerText)">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
</button>
|
||||
<div Markdown #cssView class="example-source" [path]="'/assets/angular-material-examples/'+example+'/'+example+'-example.css'"></div>
|
||||
<fuse-highlight lang="css"
|
||||
[path]="'/assets/angular-material-examples/'+example+'/'+example+'-example.css'">
|
||||
</fuse-highlight>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,25 +4,50 @@
|
||||
|
||||
.content {
|
||||
|
||||
.card-row {
|
||||
.cards {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 24px 24px 48px 24px;
|
||||
margin-bottom: 24px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
|
||||
.card-preview {
|
||||
.card {
|
||||
display: flex;
|
||||
min-width: 320px;
|
||||
align-items: flex-start;
|
||||
padding: 24px 24px 48px 24px;
|
||||
margin-bottom: 96px;
|
||||
|
||||
.card-preview {
|
||||
display: flex;
|
||||
min-width: 320px;
|
||||
}
|
||||
|
||||
.card-source {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-source {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
min-width: 400px;
|
||||
margin-left: 24px;
|
||||
&.source {
|
||||
|
||||
.cards {
|
||||
flex-direction: column;
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
margin-bottom: 24px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
|
||||
.card-source {
|
||||
background: #263238;
|
||||
display: flex !important;
|
||||
flex: 1;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
min-width: 400px;
|
||||
margin-left: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component } from '@angular/core';
|
||||
import * as shape from 'd3-shape';
|
||||
import { fuseAnimations } from '../../../../core/animations';
|
||||
|
||||
@Component({
|
||||
@@ -9,11 +10,207 @@ import { fuseAnimations } from '../../../../core/animations';
|
||||
})
|
||||
export class FuseCardsDocsComponent
|
||||
{
|
||||
view = 'preview';
|
||||
|
||||
// Card 9
|
||||
card9Expanded = false;
|
||||
|
||||
// Card 10
|
||||
card10Expanded = false;
|
||||
|
||||
// Card 19
|
||||
card19 = {
|
||||
scheme: {
|
||||
domain: ['#5c84f1']
|
||||
},
|
||||
data : [
|
||||
{
|
||||
'name' : 'GOOG',
|
||||
'series': [
|
||||
{
|
||||
'name' : 'Jan 1',
|
||||
'value': 540.2
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 2',
|
||||
'value': 539.4
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 3',
|
||||
'value': 538.9
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 4',
|
||||
'value': 539.6
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 5',
|
||||
'value': 540
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 6',
|
||||
'value': 540.2
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 7',
|
||||
'value': 540.48
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
curve : shape.curveBasis
|
||||
};
|
||||
|
||||
// Card 24
|
||||
card24 = {
|
||||
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
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Card 25
|
||||
card25 = {
|
||||
scheme: {
|
||||
domain: ['#5c84f1']
|
||||
},
|
||||
data : [
|
||||
{
|
||||
'name' : 'Monday',
|
||||
'value': 221
|
||||
},
|
||||
{
|
||||
'name' : 'Tuesday',
|
||||
'value': 428
|
||||
},
|
||||
{
|
||||
'name' : 'Wednesday',
|
||||
'value': 492
|
||||
},
|
||||
{
|
||||
'name' : 'Thursday',
|
||||
'value': 471
|
||||
},
|
||||
{
|
||||
'name' : 'Friday',
|
||||
'value': 413
|
||||
},
|
||||
{
|
||||
'name' : 'Saturday',
|
||||
'value': 344
|
||||
},
|
||||
{
|
||||
'name' : 'Sunday',
|
||||
'value': 294
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Card 26
|
||||
card26 = {
|
||||
scheme: {
|
||||
domain: ['#5c84f1']
|
||||
},
|
||||
data : [
|
||||
{
|
||||
'name' : 'Impressions',
|
||||
'series': [
|
||||
{
|
||||
'name' : 'Jan 1',
|
||||
'value': 670000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 2',
|
||||
'value': 540000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 3',
|
||||
'value': 820000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 4',
|
||||
'value': 570000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 5',
|
||||
'value': 720000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 6',
|
||||
'value': 570000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 7',
|
||||
'value': 870000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 8',
|
||||
'value': 720000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 9',
|
||||
'value': 890000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 10',
|
||||
'value': 987000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 11',
|
||||
'value': 1120000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 12',
|
||||
'value': 1360000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 13',
|
||||
'value': 1100000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 14',
|
||||
'value': 1490000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 15',
|
||||
'value': 980000
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
curve : shape.curveBasis
|
||||
};
|
||||
|
||||
constructor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
toggleView()
|
||||
{
|
||||
if ( this.view === 'preview' )
|
||||
{
|
||||
this.view = 'source';
|
||||
}
|
||||
else
|
||||
{
|
||||
this.view = 'preview';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,50 +3,52 @@ import { SharedModule } from '../../../core/modules/shared.module';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { FuseCardsDocsComponent } from './cards/cards.component';
|
||||
import { FuseCountdownDocsComponent } from './countdown/countdown.component';
|
||||
import { FuseHljsDocsComponent } from './hljs/hljs.component';
|
||||
import { FuseHighlightDocsComponent } from './highlight/highlight.component';
|
||||
import { FuseMaterialColorPickerDocsComponent } from './material-color-picker/material-color-picker.component';
|
||||
import { FuseMultiLanguageDocsComponent } from './multi-language/multi-language.component';
|
||||
import { FuseNavigationDocsComponent } from './navigation/navigation.component';
|
||||
import { FuseSearchBarDocsComponent } from './search-bar/search-bar.component';
|
||||
import { FuseShortcutsDocsComponent } from './shortcuts/shortcuts.component';
|
||||
import { FuseSearchBarDocsComponent } from 'app/main/content/components/search-bar/search-bar.component';
|
||||
import { FuseWidgetDocsComponent } from './widget/widget.component';
|
||||
import { FuseWidgetModule } from '../../../core/components/widget/widget.module';
|
||||
import { FuseAngularMaterialModule } from './angular-material/angular-material.module';
|
||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'components/cards',
|
||||
path : 'cards',
|
||||
component: FuseCardsDocsComponent
|
||||
},
|
||||
{
|
||||
path : 'components/countdown',
|
||||
path : 'countdown',
|
||||
component: FuseCountdownDocsComponent
|
||||
},
|
||||
{
|
||||
path : 'components/highlightjs',
|
||||
component: FuseHljsDocsComponent
|
||||
path : 'highlight',
|
||||
component: FuseHighlightDocsComponent
|
||||
},
|
||||
{
|
||||
path : 'components/material-color-picker',
|
||||
path : 'material-color-picker',
|
||||
component: FuseMaterialColorPickerDocsComponent
|
||||
},
|
||||
{
|
||||
path : 'components/multi-language',
|
||||
path : 'multi-language',
|
||||
component: FuseMultiLanguageDocsComponent
|
||||
},
|
||||
{
|
||||
path : 'components/navigation',
|
||||
path : 'navigation',
|
||||
component: FuseNavigationDocsComponent
|
||||
},
|
||||
{
|
||||
path : 'components/search-bar',
|
||||
path : 'search-bar',
|
||||
component: FuseSearchBarDocsComponent
|
||||
},
|
||||
{
|
||||
path : 'components/shortcuts',
|
||||
path : 'shortcuts',
|
||||
component: FuseShortcutsDocsComponent
|
||||
},
|
||||
{
|
||||
path : 'components/widget',
|
||||
path : 'widget',
|
||||
component: FuseWidgetDocsComponent
|
||||
}
|
||||
];
|
||||
@@ -55,12 +57,14 @@ const routes = [
|
||||
imports : [
|
||||
SharedModule,
|
||||
RouterModule.forChild(routes),
|
||||
FuseWidgetModule
|
||||
FuseWidgetModule,
|
||||
FuseAngularMaterialModule,
|
||||
NgxChartsModule
|
||||
],
|
||||
declarations: [
|
||||
FuseCardsDocsComponent,
|
||||
FuseCountdownDocsComponent,
|
||||
FuseHljsDocsComponent,
|
||||
FuseHighlightDocsComponent,
|
||||
FuseMaterialColorPickerDocsComponent,
|
||||
FuseMultiLanguageDocsComponent,
|
||||
FuseNavigationDocsComponent,
|
||||
@@ -69,6 +73,6 @@ const routes = [
|
||||
FuseWidgetDocsComponent
|
||||
]
|
||||
})
|
||||
export class ComponentsModule
|
||||
export class FuseComponentsModule
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,12 +29,12 @@
|
||||
|
||||
<div class="my-48">
|
||||
<h2>Usage</h2>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="html" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-countdown eventDate="2019-07-28"></fuse-countdown>
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div id="hljs" class="page-layout simple fullwidth" fusePerfectScrollbar>
|
||||
<div id="highlight" class="page-layout simple fullwidth" fusePerfectScrollbar>
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 h-160" fxLayout="row" fxLayoutAlign="start center">
|
||||
@@ -8,7 +8,7 @@
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Components</span>
|
||||
</div>
|
||||
<div class="h2 mt-16">highlight.js</div>
|
||||
<div class="h2 mt-16">Highlight</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
@@ -17,36 +17,42 @@
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fuse-hljs</code> is a custom built Fuse component allows to show syntax highlighted codes.
|
||||
<code>fuse-highlight</code> is a custom built Fuse component allows to show syntax highlighted codes.
|
||||
</p>
|
||||
|
||||
<div class="my-48">
|
||||
<h2>Sample</h2>
|
||||
<p fxLayout="row" fxLayoutAlign="start start">
|
||||
<fuse-hljs lang="html" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
|
||||
<div class="title">
|
||||
<span>Example Title</span>
|
||||
</div>
|
||||
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="my-48">
|
||||
<h2>Usage</h2>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="html" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<fuse-hljs lang="html" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<div class="title">
|
||||
<span>Example Title</span>
|
||||
</div>
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -55,7 +61,7 @@
|
||||
<p class="py-8" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-16">lang</code>
|
||||
<span>
|
||||
Language of the code to be highlighted. All highlight.js languages can be used.
|
||||
Language of the code to be highlighted.
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-highlight-docs',
|
||||
templateUrl: './highlight.component.html',
|
||||
styleUrls : ['./highlight.component.scss']
|
||||
})
|
||||
export class FuseHighlightDocsComponent
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-hljs-docs',
|
||||
templateUrl: './hljs.component.html',
|
||||
styleUrls : ['./hljs.component.scss']
|
||||
})
|
||||
export class FuseHljsDocsComponent
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -30,14 +30,14 @@
|
||||
|
||||
<div class="my-48">
|
||||
<h2>Usage</h2>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="html" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-material-color-picker [(selectedClass)]="colorClass"
|
||||
(onValueChange)="onSettingsChange()">
|
||||
</fuse-material-color-picker>
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
translation data:
|
||||
</p>
|
||||
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="ts" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
// i18n/en.ts
|
||||
export const locale = {
|
||||
lang: 'en',
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
// i18n/tr.ts
|
||||
export const locale = {
|
||||
lang: 'en',
|
||||
lang: 'tr',
|
||||
data: {
|
||||
'MAIL': {
|
||||
'COMPOSE': 'YENİ E-POSTA'
|
||||
@@ -64,7 +64,7 @@
|
||||
}
|
||||
};
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -75,9 +75,9 @@
|
||||
<code>mail.component.ts</code> file:
|
||||
</p>
|
||||
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="ts" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
// Your imports
|
||||
import { ... } from '..';
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
...
|
||||
}
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -110,9 +110,9 @@
|
||||
Changing the current language can happen instantly. Simply call the <code>use</code> method from the
|
||||
translate service:
|
||||
</p>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="ts" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
constructor(private translate: TranslateService) {}
|
||||
@@ -123,7 +123,7 @@
|
||||
this.translate.use('tr');
|
||||
}
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
<p>
|
||||
More detailed usage of the translation service can be found in the <code>toolbar.component.ts</code>
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
<div class="my-48">
|
||||
<h2>Usage</h2>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="html" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-navigation></fuse-navigation>
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -49,9 +49,9 @@
|
||||
|
||||
<div class="my-48">
|
||||
<h3>Grouping</h3>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="json" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="json">
|
||||
<textarea #source>
|
||||
{
|
||||
'title' : 'COMPONENTS',
|
||||
'translate': 'NAV.COMPONENTS',
|
||||
@@ -65,15 +65,15 @@
|
||||
]
|
||||
},
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="my-48">
|
||||
<h3>Collapsable</h3>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="json" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="json">
|
||||
<textarea #source>
|
||||
{
|
||||
'title' : 'Datatables',
|
||||
'translate': 'NAV.DATATABLES',
|
||||
@@ -88,15 +88,15 @@
|
||||
]
|
||||
},
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="my-48">
|
||||
<h3>Item</h3>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="json" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="json">
|
||||
<textarea #source>
|
||||
{
|
||||
'title' : 'Countdown',
|
||||
'translate': 'NAV.COUNTDOWN',
|
||||
@@ -105,7 +105,7 @@
|
||||
'url' : '/components/countdown'
|
||||
},
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -132,9 +132,9 @@
|
||||
|
||||
<h4>Update navigation item on-the-fly</h4>
|
||||
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="ts" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
updateMailBadge()
|
||||
{
|
||||
// Get the mail nav item
|
||||
@@ -144,7 +144,7 @@
|
||||
mailNavItem.badge.title = 35;
|
||||
}
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="mt-24 mb-64">
|
||||
@@ -157,9 +157,9 @@
|
||||
|
||||
<h4>Add a subitem to the Calendar nav item</h4>
|
||||
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="ts" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
addSubitemToCalendar()
|
||||
{
|
||||
// Prepare the new nav item
|
||||
@@ -174,7 +174,7 @@
|
||||
this.navigationService.addNavigationItem('applications.calendar', newNavItem);
|
||||
}
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="mt-24 mb-64">
|
||||
@@ -187,9 +187,9 @@
|
||||
|
||||
<h4>Add a nav item with custom function</h4>
|
||||
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="ts" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
addNavItemWithCustomFunction()
|
||||
{
|
||||
// Prepare the new nav item
|
||||
@@ -209,7 +209,7 @@
|
||||
applicationsNavItem.children.unshift(newNavItem);
|
||||
}
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="mt-24">
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
<div class="my-48">
|
||||
<h2>Usage</h2>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="html" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-search-bar (onInput)="search($event)"></fuse-search-bar>
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
<div class="my-48">
|
||||
<h2>Usage</h2>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="html" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-shortcuts></fuse-shortcuts>
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -62,9 +62,11 @@
|
||||
|
||||
<div class="my-48">
|
||||
<h2>Usage</h2>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-hljs lang="html" class="source-code">
|
||||
<textarea #source hidden="hidden">
|
||||
<p class="py-8">
|
||||
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
|
||||
<fuse-widget class="" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
@@ -97,8 +99,10 @@
|
||||
<!-- / Back -->
|
||||
|
||||
</fuse-widget>
|
||||
|
||||
</textarea>
|
||||
</fuse-hljs>
|
||||
</fuse-highlight>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
</div>
|
||||
|
||||
<div class="title">RECOVER YOUR PASSWORD</div>
|
||||
<div class="description">Sed mollis velit facilisis facilisis viverra</div>
|
||||
|
||||
<form name="forgoPasswordForm" [formGroup]="forgotPasswordForm" novalidate>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#forgot-password-intro {
|
||||
padding: 128px;
|
||||
color: white;
|
||||
|
||||
@include media-breakpoint('sm') {
|
||||
padding: 128px 64px;
|
||||
@@ -27,9 +28,10 @@
|
||||
}
|
||||
|
||||
.description {
|
||||
padding-top: 8px;
|
||||
padding-top: 16px;
|
||||
font-size: 14px;
|
||||
max-width: 600px;
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FuseForgotPassword2Component } from './forgot-password-2.component';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'pages/auth/forgot-password-2',
|
||||
path : 'auth/forgot-password-2',
|
||||
component: FuseForgotPassword2Component
|
||||
}
|
||||
];
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FuseForgotPasswordComponent } from './forgot-password.component';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'pages/auth/forgot-password',
|
||||
path : 'auth/forgot-password',
|
||||
component: FuseForgotPasswordComponent
|
||||
}
|
||||
];
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FuseLockComponent } from './lock.component';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'pages/auth/lock',
|
||||
path : 'auth/lock',
|
||||
component: FuseLockComponent
|
||||
}
|
||||
];
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
</div>
|
||||
|
||||
<div class="title">LOGIN TO YOUR ACCOUNT</div>
|
||||
<div class="description">Sed mollis velit facilisis facilisis viverra</div>
|
||||
|
||||
<form name="loginForm" [formGroup]="loginForm" novalidate>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#login-intro {
|
||||
padding: 128px;
|
||||
color: white;
|
||||
|
||||
@include media-breakpoint('sm') {
|
||||
padding: 128px 64px;
|
||||
@@ -27,9 +28,10 @@
|
||||
}
|
||||
|
||||
.description {
|
||||
padding-top: 8px;
|
||||
padding-top: 16px;
|
||||
font-size: 14px;
|
||||
max-width: 600px;
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FuseLogin2Component } from './login-2.component';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'pages/auth/login-2',
|
||||
path : 'auth/login-2',
|
||||
component: FuseLogin2Component
|
||||
}
|
||||
];
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FuseLoginComponent } from './login.component';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'pages/auth/login',
|
||||
path : 'auth/login',
|
||||
component: FuseLoginComponent
|
||||
}
|
||||
];
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FuseMailConfirmComponent } from './mail-confirm.component';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'pages/auth/mail-confirm',
|
||||
path : 'auth/mail-confirm',
|
||||
component: FuseMailConfirmComponent
|
||||
}
|
||||
];
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
</div>
|
||||
|
||||
<div class="title">CREATE AN ACCOUNT</div>
|
||||
<div class="description">Sed mollis velit facilisis facilisis viverra</div>
|
||||
|
||||
<form name="registerForm" [formGroup]="registerForm" novalidate>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#register-intro {
|
||||
padding: 128px;
|
||||
color: white;
|
||||
|
||||
@include media-breakpoint('sm') {
|
||||
padding: 128px 64px;
|
||||
@@ -27,9 +28,10 @@
|
||||
}
|
||||
|
||||
.description {
|
||||
padding-top: 8px;
|
||||
padding-top: 16px;
|
||||
font-size: 14px;
|
||||
max-width: 600px;
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FuseRegister2Component } from './register-2.component';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'pages/auth/register-2',
|
||||
path : 'auth/register-2',
|
||||
component: FuseRegister2Component
|
||||
}
|
||||
];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user